xref: /btstack/src/mesh/mesh.c (revision 663808079bc9e4a9f8cc05c41d722c6ac79afac8)
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 
96 static btstack_packet_handler_t provisioning_device_packet_handler;
97 static btstack_packet_callback_registration_t hci_event_callback_registration;
98 static int provisioned;
99 
100 // Mandatory Confiuration Server
101 static mesh_model_t                 mesh_configuration_server_model;
102 
103 // Mandatory Health Server
104 static mesh_model_t                 mesh_health_server_model;
105 static mesh_configuration_server_model_context_t mesh_configuration_server_model_context;
106 
107 // Random UUID on start
108 static btstack_crypto_random_t mesh_access_crypto_random;
109 static uint8_t random_device_uuid[16];
110 
111 // TLV
112 static const btstack_tlv_t * btstack_tlv_singleton_impl;
113 static void *                btstack_tlv_singleton_context;
114 
115 void mesh_access_setup_from_provisioning_data(const mesh_provisioning_data_t * provisioning_data){
116 
117     // set iv_index and iv index update active
118     int iv_index_update_active = (provisioning_data->flags & 2) >> 1;
119     mesh_iv_index_recovered(iv_index_update_active, provisioning_data->iv_index);
120 
121     // set unicast address
122     mesh_node_primary_element_address_set(provisioning_data->unicast_address);
123 
124     // set device_key
125     mesh_transport_set_device_key(provisioning_data->device_key);
126 
127     if (provisioning_data->network_key){
128 
129         // setup primary network with provisioned netkey
130         mesh_network_key_add(provisioning_data->network_key);
131 
132         // setup primary network
133         mesh_subnet_setup_for_netkey_index(provisioning_data->network_key->netkey_index);
134 
135         // start sending Secure Network Beacons
136         mesh_subnet_t * provisioned_subnet = mesh_subnet_get_by_netkey_index(provisioning_data->network_key->netkey_index);
137         beacon_secure_network_start(provisioned_subnet);
138     }
139 
140     // Mesh Proxy
141 #ifdef ENABLE_MESH_PROXY_SERVER
142     // Setup Proxy
143     mesh_proxy_init(provisioning_data->unicast_address);
144     mesh_proxy_start_advertising_with_network_id();
145 #endif
146 }
147 
148 static void mesh_access_setup_unprovisioned_device(void * arg){
149     // set random value
150     if (arg == NULL){
151         mesh_node_set_device_uuid(random_device_uuid);
152     }
153 
154 #ifdef ENABLE_MESH_PB_ADV
155     // PB-ADV
156     beacon_unprovisioned_device_start(mesh_node_get_device_uuid(), 0);
157 #endif
158 #ifdef ENABLE_MESH_PB_GATT
159     mesh_proxy_start_advertising_unprovisioned_device();
160 #endif
161 }
162 
163 void mesh_access_setup_without_provisiong_data(void){
164     const uint8_t * device_uuid = mesh_node_get_device_uuid();
165     if (device_uuid){
166         mesh_access_setup_unprovisioned_device((void *)device_uuid);
167     } else{
168         btstack_crypto_random_generate(&mesh_access_crypto_random, random_device_uuid, 16, &mesh_access_setup_unprovisioned_device, NULL);
169     }
170 }
171 
172 static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
173     mesh_provisioning_data_t provisioning_data;
174 
175     switch(packet[0]){
176         case HCI_EVENT_MESH_META:
177             switch(packet[2]){
178                 case MESH_SUBEVENT_PB_PROV_COMPLETE:
179                     // get provisioning data
180                     provisioning_device_data_get(&provisioning_data);
181 
182                     // and store in TLV
183                     mesh_node_store_provisioning_data(&provisioning_data);
184 
185                     // setup node after provisioned
186                     mesh_access_setup_from_provisioning_data(&provisioning_data);
187 
188                     // start advertising with node id after provisioning
189                     mesh_proxy_set_advertising_with_node_id(provisioning_data.network_key->netkey_index, MESH_NODE_IDENTITY_STATE_ADVERTISING_RUNNING);
190 
191                     provisioned = 1;
192                     break;
193                 default:
194                     break;
195             }
196             break;
197         default:
198             break;
199     }
200     if (provisioning_device_packet_handler == NULL) return;
201 
202     // forward
203     (*provisioning_device_packet_handler)(packet_type, channel, packet, size);
204 }
205 
206 static void hci_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
207     UNUSED(channel);
208     UNUSED(size);
209 
210     switch (packet_type) {
211         case HCI_EVENT_PACKET:
212             switch (hci_event_packet_get_type(packet)) {
213                 case BTSTACK_EVENT_STATE:
214                     if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
215                     // get TLV instance
216                     btstack_tlv_get_instance(&btstack_tlv_singleton_impl, &btstack_tlv_singleton_context);
217 
218                     // startup from provisioning data stored in TLV
219                     provisioned = mesh_node_startup_from_tlv();
220                     break;
221 
222                 case HCI_EVENT_DISCONNECTION_COMPLETE:
223                     // enable PB_GATT
224                     if (provisioned == 0){
225                         mesh_proxy_start_advertising_unprovisioned_device();
226                     } else {
227 #ifdef ENABLE_MESH_PROXY_SERVER
228                         mesh_proxy_start_advertising_with_network_id();
229 #endif
230                     }
231                     break;
232 
233                 case HCI_EVENT_LE_META:
234                     if (hci_event_le_meta_get_subevent_code(packet) !=  HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
235                     // disable PB_GATT
236                     mesh_proxy_stop_advertising_unprovisioned_device();
237                     break;
238                 default:
239                     break;
240             }
241             break;
242     }
243 }
244 
245 
246 // Mesh Network Keys
247 static uint32_t mesh_network_key_tag_for_internal_index(uint16_t internal_index){
248     return ((uint32_t) 'M' << 24) | ((uint32_t) 'N' << 16) | ((uint32_t) internal_index);
249 }
250 
251 void mesh_store_network_key(mesh_network_key_t * network_key){
252     mesh_persistent_net_key_t data;
253     printf("Store NetKey: internal index 0x%x, NetKey Index 0x%06x, NID %02x: ", network_key->internal_index, network_key->netkey_index, network_key->nid);
254     printf_hexdump(network_key->net_key, 16);
255     uint32_t tag = mesh_network_key_tag_for_internal_index(network_key->internal_index);
256     data.netkey_index = network_key->netkey_index;
257     memcpy(data.net_key, network_key->net_key, 16);
258     memcpy(data.identity_key, network_key->identity_key, 16);
259     memcpy(data.beacon_key, network_key->beacon_key, 16);
260     memcpy(data.network_id, network_key->network_id, 8);
261     data.nid = network_key->nid;
262     data.version = network_key->version;
263     memcpy(data.encryption_key, network_key->encryption_key, 16);
264     memcpy(data.privacy_key, network_key->privacy_key, 16);
265     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(mesh_persistent_net_key_t));
266 }
267 
268 void mesh_delete_network_key(uint16_t internal_index){
269     uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index);
270     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
271 }
272 
273 
274 void mesh_load_network_keys(void){
275     printf("Load Network Keys\n");
276     uint16_t internal_index;
277     for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){
278         mesh_persistent_net_key_t data;
279         uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index);
280         int netkey_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
281         if (netkey_len != sizeof(mesh_persistent_net_key_t)) continue;
282 
283         mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
284         if (network_key == NULL) return;
285 
286         network_key->netkey_index = data.netkey_index;
287         memcpy(network_key->net_key, data.net_key, 16);
288         memcpy(network_key->identity_key, data.identity_key, 16);
289         memcpy(network_key->beacon_key, data.beacon_key, 16);
290         memcpy(network_key->network_id, data.network_id, 8);
291         network_key->nid = data.nid;
292         network_key->version = data.version;
293         memcpy(network_key->encryption_key, data.encryption_key, 16);
294         memcpy(network_key->privacy_key, data.privacy_key, 16);
295 
296 #ifdef ENABLE_GATT_BEARER
297         // setup advertisement with network id
298         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);
299 #endif
300 
301         mesh_network_key_add(network_key);
302 
303         mesh_subnet_setup_for_netkey_index(network_key->netkey_index);
304 
305         printf("- internal index 0x%x, NetKey Index 0x%06x, NID %02x: ", network_key->internal_index, network_key->netkey_index, network_key->nid);
306         printf_hexdump(network_key->net_key, 16);
307     }
308 }
309 
310 void mesh_delete_network_keys(void){
311     printf("Delete Network Keys\n");
312 
313     uint16_t internal_index;
314     for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){
315         mesh_delete_network_key(internal_index);
316     }
317 }
318 
319 static void mesh_node_setup_default_models(void){
320     // configure Config Server
321     mesh_configuration_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_CONFIGURATION_SERVER);
322     mesh_configuration_server_model.model_data       = &mesh_configuration_server_model_context;
323     mesh_configuration_server_model.operations       = mesh_configuration_server_get_operations();
324     mesh_element_add_model(mesh_node_get_primary_element(), &mesh_configuration_server_model);
325 
326     // Config Health Server
327     mesh_health_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_HEALTH_SERVER);
328     mesh_element_add_model(mesh_node_get_primary_element(), &mesh_health_server_model);
329 }
330 
331 void mesh_init(void){
332 
333     // register for HCI events
334     hci_event_callback_registration.callback = &hci_packet_handler;
335     hci_add_event_handler(&hci_event_callback_registration);
336 
337     // ADV Bearer also used for GATT Proxy Advertisements and PB-GATT
338     adv_bearer_init();
339 
340 #ifdef ENABLE_MESH_GATT_BEARER
341     // Setup GATT bearer
342     gatt_bearer_init();
343 #endif
344 
345 #ifdef ENABLE_MESH_ADV_BEARER
346     // Setup Unprovisioned Device Beacon
347     beacon_init();
348 #endif
349 
350     provisioning_device_init();
351 
352     // Node Configuration
353     mesh_node_init();
354 
355     // Network layer
356     mesh_network_init();
357 
358     // Transport layers (lower + upper))
359     mesh_lower_transport_init();
360     mesh_upper_transport_init();
361 
362     // Access layer
363     mesh_access_init();
364 
365     mesh_node_setup_default_models();
366 }
367 
368 /**
369  * Register for Mesh Provisioning Device events
370  * @param packet_handler
371  */
372 void mesh_register_provisioning_device_packet_handler(btstack_packet_handler_t packet_handler){
373     provisioning_device_packet_handler = packet_handler;
374     provisioning_device_register_packet_handler(&mesh_provisioning_message_handler);
375 }
376