xref: /btstack/src/mesh/mesh.c (revision 726dac53eadbab19c1e4b2489159d979c15c7daf)
1 /*
2  * Copyright (C) 2019 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define __BTSTACK_FILE__ "mesh.c"
39 
40 #include <string.h>
41 #include <stdio.h>
42 
43 #include "mesh/mesh.h"
44 
45 #include "btstack_util.h"
46 #include "btstack_config.h"
47 #include "btstack_event.h"
48 #include "btstack_tlv.h"
49 #include "btstack_memory.h"
50 
51 #include "mesh/adv_bearer.h"
52 #include "mesh/beacon.h"
53 #include "mesh/gatt_bearer.h"
54 #include "mesh/mesh_access.h"
55 #include "mesh/mesh_configuration_server.h"
56 #include "mesh/mesh_foundation.h"
57 #include "mesh/mesh_generic_model.h"
58 #include "mesh/mesh_generic_server.h"
59 #include "mesh/mesh_iv_index_seq_number.h"
60 #include "mesh/mesh_lower_transport.h"
61 #include "mesh/mesh_peer.h"
62 #include "mesh/mesh_proxy.h"
63 #include "mesh/mesh_upper_transport.h"
64 #include "mesh/mesh_virtual_addresses.h"
65 #include "mesh/pb_adv.h"
66 #include "mesh/pb_gatt.h"
67 #include "mesh/provisioning.h"
68 #include "mesh/provisioning_device.h"
69 
70 // Persistent storage structures
71 
72 typedef struct {
73     uint16_t netkey_index;
74 
75     uint8_t  version;
76 
77     // net_key from provisioner or Config Model Client
78     uint8_t net_key[16];
79 
80     // derived data
81 
82     // k1
83     uint8_t identity_key[16];
84     uint8_t beacon_key[16];
85 
86     // k3
87     uint8_t network_id[8];
88 
89     // k2
90     uint8_t nid;
91     uint8_t encryption_key[16];
92     uint8_t privacy_key[16];
93 } mesh_persistent_net_key_t;
94 
95 typedef struct {
96     uint16_t netkey_index;
97     uint16_t appkey_index;
98     uint8_t  aid;
99     uint8_t  version;
100     uint8_t  key[16];
101 } mesh_persistent_app_key_t;
102 
103 static btstack_packet_handler_t provisioning_device_packet_handler;
104 static btstack_packet_callback_registration_t hci_event_callback_registration;
105 static int provisioned;
106 
107 // Mandatory Confiuration Server
108 static mesh_model_t                 mesh_configuration_server_model;
109 
110 // Mandatory Health Server
111 static mesh_model_t                 mesh_health_server_model;
112 static mesh_configuration_server_model_context_t mesh_configuration_server_model_context;
113 
114 // Random UUID on start
115 static btstack_crypto_random_t mesh_access_crypto_random;
116 static uint8_t random_device_uuid[16];
117 
118 // TLV
119 static const btstack_tlv_t * btstack_tlv_singleton_impl;
120 static void *                btstack_tlv_singleton_context;
121 
122 void mesh_access_setup_from_provisioning_data(const mesh_provisioning_data_t * provisioning_data){
123 
124     // set iv_index and iv index update active
125     int iv_index_update_active = (provisioning_data->flags & 2) >> 1;
126     mesh_iv_index_recovered(iv_index_update_active, provisioning_data->iv_index);
127 
128     // set unicast address
129     mesh_node_primary_element_address_set(provisioning_data->unicast_address);
130 
131     // set device_key
132     mesh_transport_set_device_key(provisioning_data->device_key);
133 
134     if (provisioning_data->network_key){
135 
136         // setup primary network with provisioned netkey
137         mesh_network_key_add(provisioning_data->network_key);
138 
139         // setup primary network
140         mesh_subnet_setup_for_netkey_index(provisioning_data->network_key->netkey_index);
141 
142         // start sending Secure Network Beacons
143         mesh_subnet_t * provisioned_subnet = mesh_subnet_get_by_netkey_index(provisioning_data->network_key->netkey_index);
144         beacon_secure_network_start(provisioned_subnet);
145     }
146 
147     // Mesh Proxy
148 #ifdef ENABLE_MESH_PROXY_SERVER
149     // Setup Proxy
150     mesh_proxy_init(provisioning_data->unicast_address);
151     mesh_proxy_start_advertising_with_network_id();
152 #endif
153 }
154 
155 static void mesh_access_setup_unprovisioned_device(void * arg){
156     // set random value
157     if (arg == NULL){
158         mesh_node_set_device_uuid(random_device_uuid);
159     }
160 
161 #ifdef ENABLE_MESH_PB_ADV
162     // PB-ADV
163     beacon_unprovisioned_device_start(mesh_node_get_device_uuid(), 0);
164 #endif
165 #ifdef ENABLE_MESH_PB_GATT
166     mesh_proxy_start_advertising_unprovisioned_device();
167 #endif
168 }
169 
170 void mesh_access_setup_without_provisiong_data(void){
171     const uint8_t * device_uuid = mesh_node_get_device_uuid();
172     if (device_uuid){
173         mesh_access_setup_unprovisioned_device((void *)device_uuid);
174     } else{
175         btstack_crypto_random_generate(&mesh_access_crypto_random, random_device_uuid, 16, &mesh_access_setup_unprovisioned_device, NULL);
176     }
177 }
178 
179 static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
180     mesh_provisioning_data_t provisioning_data;
181 
182     switch(packet[0]){
183         case HCI_EVENT_MESH_META:
184             switch(packet[2]){
185                 case MESH_SUBEVENT_PB_PROV_COMPLETE:
186                     // get provisioning data
187                     provisioning_device_data_get(&provisioning_data);
188 
189                     // and store in TLV
190                     mesh_node_store_provisioning_data(&provisioning_data);
191 
192                     // setup node after provisioned
193                     mesh_access_setup_from_provisioning_data(&provisioning_data);
194 
195                     // start advertising with node id after provisioning
196                     mesh_proxy_set_advertising_with_node_id(provisioning_data.network_key->netkey_index, MESH_NODE_IDENTITY_STATE_ADVERTISING_RUNNING);
197 
198                     provisioned = 1;
199                     break;
200                 default:
201                     break;
202             }
203             break;
204         default:
205             break;
206     }
207     if (provisioning_device_packet_handler == NULL) return;
208 
209     // forward
210     (*provisioning_device_packet_handler)(packet_type, channel, packet, size);
211 }
212 
213 static void hci_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
214     UNUSED(channel);
215     UNUSED(size);
216 
217     switch (packet_type) {
218         case HCI_EVENT_PACKET:
219             switch (hci_event_packet_get_type(packet)) {
220                 case BTSTACK_EVENT_STATE:
221                     if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
222                     // get TLV instance
223                     btstack_tlv_get_instance(&btstack_tlv_singleton_impl, &btstack_tlv_singleton_context);
224 
225                     // startup from provisioning data stored in TLV
226                     provisioned = mesh_node_startup_from_tlv();
227                     break;
228 
229                 case HCI_EVENT_DISCONNECTION_COMPLETE:
230                     // enable PB_GATT
231                     if (provisioned == 0){
232                         mesh_proxy_start_advertising_unprovisioned_device();
233                     } else {
234 #ifdef ENABLE_MESH_PROXY_SERVER
235                         mesh_proxy_start_advertising_with_network_id();
236 #endif
237                     }
238                     break;
239 
240                 case HCI_EVENT_LE_META:
241                     if (hci_event_le_meta_get_subevent_code(packet) !=  HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
242                     // disable PB_GATT
243                     mesh_proxy_stop_advertising_unprovisioned_device();
244                     break;
245                 default:
246                     break;
247             }
248             break;
249     }
250 }
251 
252 
253 // Mesh Network Keys
254 static uint32_t mesh_network_key_tag_for_internal_index(uint16_t internal_index){
255     return ((uint32_t) 'M' << 24) | ((uint32_t) 'N' << 16) | ((uint32_t) internal_index);
256 }
257 
258 void mesh_store_network_key(mesh_network_key_t * network_key){
259     mesh_persistent_net_key_t data;
260     printf("Store NetKey: internal index 0x%x, NetKey Index 0x%06x, NID %02x: ", network_key->internal_index, network_key->netkey_index, network_key->nid);
261     printf_hexdump(network_key->net_key, 16);
262     uint32_t tag = mesh_network_key_tag_for_internal_index(network_key->internal_index);
263     data.netkey_index = network_key->netkey_index;
264     memcpy(data.net_key, network_key->net_key, 16);
265     memcpy(data.identity_key, network_key->identity_key, 16);
266     memcpy(data.beacon_key, network_key->beacon_key, 16);
267     memcpy(data.network_id, network_key->network_id, 8);
268     data.nid = network_key->nid;
269     data.version = network_key->version;
270     memcpy(data.encryption_key, network_key->encryption_key, 16);
271     memcpy(data.privacy_key, network_key->privacy_key, 16);
272     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(mesh_persistent_net_key_t));
273 }
274 
275 void mesh_delete_network_key(uint16_t internal_index){
276     uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index);
277     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
278 }
279 
280 
281 void mesh_load_network_keys(void){
282     printf("Load Network Keys\n");
283     uint16_t internal_index;
284     for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){
285         mesh_persistent_net_key_t data;
286         uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index);
287         int netkey_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
288         if (netkey_len != sizeof(mesh_persistent_net_key_t)) continue;
289 
290         mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
291         if (network_key == NULL) return;
292 
293         network_key->netkey_index = data.netkey_index;
294         memcpy(network_key->net_key, data.net_key, 16);
295         memcpy(network_key->identity_key, data.identity_key, 16);
296         memcpy(network_key->beacon_key, data.beacon_key, 16);
297         memcpy(network_key->network_id, data.network_id, 8);
298         network_key->nid = data.nid;
299         network_key->version = data.version;
300         memcpy(network_key->encryption_key, data.encryption_key, 16);
301         memcpy(network_key->privacy_key, data.privacy_key, 16);
302 
303 #ifdef ENABLE_GATT_BEARER
304         // setup advertisement with network id
305         network_key->advertisement_with_network_id.adv_length = mesh_proxy_setup_advertising_with_network_id(network_key->advertisement_with_network_id.adv_data, network_key->network_id);
306 #endif
307 
308         mesh_network_key_add(network_key);
309 
310         mesh_subnet_setup_for_netkey_index(network_key->netkey_index);
311 
312         printf("- internal index 0x%x, NetKey Index 0x%06x, NID %02x: ", network_key->internal_index, network_key->netkey_index, network_key->nid);
313         printf_hexdump(network_key->net_key, 16);
314     }
315 }
316 
317 void mesh_delete_network_keys(void){
318     printf("Delete Network Keys\n");
319 
320     uint16_t internal_index;
321     for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){
322         mesh_delete_network_key(internal_index);
323     }
324 }
325 
326 // Mesh App Keys
327 
328 static uint32_t mesh_transport_key_tag_for_internal_index(uint16_t internal_index){
329     return ((uint32_t) 'M' << 24) | ((uint32_t) 'A' << 16) | ((uint32_t) internal_index);
330 }
331 
332 void mesh_store_app_key(mesh_transport_key_t * app_key){
333     mesh_persistent_app_key_t data;
334     printf("Store AppKey: internal index 0x%x, AppKey Index 0x%06x, AID %02x: ", app_key->internal_index, app_key->appkey_index, app_key->aid);
335     printf_hexdump(app_key->key, 16);
336     uint32_t tag = mesh_transport_key_tag_for_internal_index(app_key->internal_index);
337     data.netkey_index = app_key->netkey_index;
338     data.appkey_index = app_key->appkey_index;
339     data.aid = app_key->aid;
340     data.version = app_key->version;
341     memcpy(data.key, app_key->key, 16);
342     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
343 }
344 
345 void mesh_delete_app_key(uint16_t internal_index){
346     uint32_t tag = mesh_transport_key_tag_for_internal_index(internal_index);
347     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
348 }
349 
350 void mesh_load_app_keys(void){
351     printf("Load App Keys\n");
352     uint16_t internal_index;
353     for (internal_index = 0; internal_index < MAX_NR_MESH_TRANSPORT_KEYS; internal_index++){
354         mesh_persistent_app_key_t data;
355         uint32_t tag = mesh_transport_key_tag_for_internal_index(internal_index);
356         int app_key_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
357         if (app_key_len == 0) continue;
358 
359         mesh_transport_key_t * key = btstack_memory_mesh_transport_key_get();
360         if (key == NULL) return;
361 
362         key->internal_index = internal_index;
363         key->appkey_index = data.appkey_index;
364         key->netkey_index = data.netkey_index;
365         key->aid          = data.aid;
366         key->akf          = 1;
367         key->version      = data.version;
368         memcpy(key->key, data.key, 16);
369         mesh_transport_key_add(key);
370         printf("- internal index 0x%x, AppKey Index 0x%06x, AID %02x: ", key->internal_index, key->appkey_index, key->aid);
371         printf_hexdump(key->key, 16);
372     }
373 }
374 
375 void mesh_delete_app_keys(void){
376     printf("Delete App Keys\n");
377 
378     uint16_t internal_index;
379     for (internal_index = 0; internal_index < MAX_NR_MESH_TRANSPORT_KEYS; internal_index++){
380         mesh_delete_app_key(internal_index);
381     }
382 }
383 
384 
385 // Model to Appkey List
386 
387 static uint32_t mesh_model_tag_for_index(uint16_t internal_model_id){
388     return ((uint32_t) 'M' << 24) | ((uint32_t) 'B' << 16) | ((uint32_t) internal_model_id);
389 }
390 
391 static void mesh_load_appkey_list(mesh_model_t * model){
392     uint32_t tag = mesh_model_tag_for_index(model->mid);
393     btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &model->appkey_indices, sizeof(model->appkey_indices));
394 }
395 
396 static void mesh_store_appkey_list(mesh_model_t * model){
397     uint32_t tag = mesh_model_tag_for_index(model->mid);
398     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &model->appkey_indices, sizeof(model->appkey_indices));
399 }
400 
401 static void mesh_delete_appkey_list(mesh_model_t * model){
402     uint32_t tag = mesh_model_tag_for_index(model->mid);
403     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
404 }
405 
406 void mesh_load_appkey_lists(void){
407     printf("Load Appkey Lists\n");
408     // iterate over elements and models
409     mesh_element_iterator_t element_it;
410     mesh_element_iterator_init(&element_it);
411     while (mesh_element_iterator_has_next(&element_it)){
412         mesh_element_t * element = mesh_element_iterator_next(&element_it);
413         mesh_model_iterator_t model_it;
414         mesh_model_iterator_init(&model_it, element);
415         while (mesh_model_iterator_has_next(&model_it)){
416             mesh_model_t * model = mesh_model_iterator_next(&model_it);
417             mesh_load_appkey_list(model);
418         }
419     }
420 }
421 
422 void mesh_delete_appkey_lists(void){
423     printf("Delete Appkey Lists\n");
424     // iterate over elements and models
425     mesh_element_iterator_t element_it;
426     mesh_element_iterator_init(&element_it);
427     while (mesh_element_iterator_has_next(&element_it)){
428         mesh_element_t * element = mesh_element_iterator_next(&element_it);
429         mesh_model_iterator_t model_it;
430         mesh_model_iterator_init(&model_it, element);
431         while (mesh_model_iterator_has_next(&model_it)){
432             mesh_model_t * model = mesh_model_iterator_next(&model_it);
433             mesh_delete_appkey_list(model);
434         }
435     }
436 }
437 
438 void mesh_model_reset_appkeys(mesh_model_t * mesh_model){
439     uint16_t i;
440     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
441         mesh_model->appkey_indices[i] = MESH_APPKEY_INVALID;
442     }
443 }
444 
445 uint8_t mesh_model_bind_appkey(mesh_model_t * mesh_model, uint16_t appkey_index){
446     uint16_t i;
447     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
448         if (mesh_model->appkey_indices[i] == appkey_index) return MESH_FOUNDATION_STATUS_SUCCESS;
449     }
450     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
451         if (mesh_model->appkey_indices[i] == MESH_APPKEY_INVALID) {
452             mesh_model->appkey_indices[i] = appkey_index;
453             mesh_store_appkey_list(mesh_model);
454             return MESH_FOUNDATION_STATUS_SUCCESS;
455         }
456     }
457     return MESH_FOUNDATION_STATUS_INSUFFICIENT_RESOURCES;
458 }
459 
460 void mesh_model_unbind_appkey(mesh_model_t * mesh_model, uint16_t appkey_index){
461     uint16_t i;
462     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
463         if (mesh_model->appkey_indices[i] == appkey_index) {
464             mesh_model->appkey_indices[i] = MESH_APPKEY_INVALID;
465             mesh_store_appkey_list(mesh_model);
466         }
467     }
468 }
469 
470 int mesh_model_contains_appkey(mesh_model_t * mesh_model, uint16_t appkey_index){
471     uint16_t i;
472     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
473         if (mesh_model->appkey_indices[i] == appkey_index) return 1;
474     }
475     return 0;
476 }
477 
478 static void mesh_node_setup_default_models(void){
479     // configure Config Server
480     mesh_configuration_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_CONFIGURATION_SERVER);
481     mesh_configuration_server_model.model_data       = &mesh_configuration_server_model_context;
482     mesh_configuration_server_model.operations       = mesh_configuration_server_get_operations();
483     mesh_element_add_model(mesh_node_get_primary_element(), &mesh_configuration_server_model);
484 
485     // Config Health Server
486     mesh_health_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_HEALTH_SERVER);
487     mesh_element_add_model(mesh_node_get_primary_element(), &mesh_health_server_model);
488 }
489 
490 void mesh_init(void){
491 
492     // register for HCI events
493     hci_event_callback_registration.callback = &hci_packet_handler;
494     hci_add_event_handler(&hci_event_callback_registration);
495 
496     // ADV Bearer also used for GATT Proxy Advertisements and PB-GATT
497     adv_bearer_init();
498 
499 #ifdef ENABLE_MESH_GATT_BEARER
500     // Setup GATT bearer
501     gatt_bearer_init();
502 #endif
503 
504 #ifdef ENABLE_MESH_ADV_BEARER
505     // Setup Unprovisioned Device Beacon
506     beacon_init();
507 #endif
508 
509     provisioning_device_init();
510 
511     // Node Configuration
512     mesh_node_init();
513 
514     // Network layer
515     mesh_network_init();
516 
517     // Transport layers (lower + upper))
518     mesh_lower_transport_init();
519     mesh_upper_transport_init();
520 
521     // Access layer
522     mesh_access_init();
523 
524     mesh_node_setup_default_models();
525 }
526 
527 /**
528  * Register for Mesh Provisioning Device events
529  * @param packet_handler
530  */
531 void mesh_register_provisioning_device_packet_handler(btstack_packet_handler_t packet_handler){
532     provisioning_device_packet_handler = packet_handler;
533     provisioning_device_register_packet_handler(&mesh_provisioning_message_handler);
534 }
535