xref: /btstack/src/mesh/mesh.c (revision d58a1b5f11ada8ddf896c41fff5a35e7f140c37e)
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 #include "btstack_debug.h"
51 
52 #include "mesh/adv_bearer.h"
53 #include "mesh/beacon.h"
54 #include "mesh/gatt_bearer.h"
55 #include "mesh/mesh_access.h"
56 #include "mesh/mesh_configuration_server.h"
57 #include "mesh/mesh_health_server.h"
58 #include "mesh/mesh_foundation.h"
59 #include "mesh/mesh_generic_model.h"
60 #include "mesh/mesh_generic_on_off_server.h"
61 #include "mesh/mesh_iv_index_seq_number.h"
62 #include "mesh/mesh_lower_transport.h"
63 #include "mesh/mesh_peer.h"
64 #include "mesh/mesh_proxy.h"
65 #include "mesh/mesh_upper_transport.h"
66 #include "mesh/mesh_virtual_addresses.h"
67 #include "mesh/pb_adv.h"
68 #include "mesh/pb_gatt.h"
69 #include "mesh/provisioning.h"
70 #include "mesh/provisioning_device.h"
71 
72 static void mesh_node_store_provisioning_data(mesh_provisioning_data_t * provisioning_data);
73 static int mesh_node_startup_from_tlv(void);
74 
75 // Persistent storage structures
76 
77 typedef struct {
78     uint16_t  hash;
79     uint8_t   label_uuid[16];
80 } mesh_persistent_virtual_address_t;
81 
82 typedef struct {
83     uint16_t netkey_index;
84 
85     uint8_t  version;
86 
87     // net_key from provisioner or Config Model Client
88     uint8_t net_key[16];
89 
90     // derived data
91 
92     // k1
93     uint8_t identity_key[16];
94     uint8_t beacon_key[16];
95 
96     // k3
97     uint8_t network_id[8];
98 
99     // k2
100     uint8_t nid;
101     uint8_t encryption_key[16];
102     uint8_t privacy_key[16];
103 } mesh_persistent_net_key_t;
104 
105 typedef struct {
106     uint16_t netkey_index;
107     uint16_t appkey_index;
108     uint8_t  aid;
109     uint8_t  version;
110     uint8_t  key[16];
111 } mesh_persistent_app_key_t;
112 
113 typedef struct {
114     uint8_t gatt_proxy;
115     uint8_t beacon;
116     uint8_t default_ttl;
117     uint8_t network_transmit;
118     uint8_t relay;
119     uint8_t relay_retransmit;
120     uint8_t friend;
121 } mesh_persistent_foundation_t;
122 
123 typedef struct {
124     uint16_t publish_address;
125     uint16_t appkey_index;
126     uint8_t  friendship_credential_flag;
127     uint8_t  publish_period;
128     uint8_t  publish_ttl;
129     uint8_t  publish_retransmit;
130 } mesh_persistent_publication_t;
131 
132 typedef struct {
133     uint32_t iv_index;
134     uint32_t seq_number;
135 } iv_index_and_sequence_number_t;
136 
137 static btstack_packet_handler_t provisioning_device_packet_handler;
138 static btstack_packet_callback_registration_t hci_event_callback_registration;
139 static int provisioned;
140 
141 // Mandatory Confiuration Server
142 static mesh_model_t                 mesh_configuration_server_model;
143 static mesh_configuration_server_model_context_t mesh_configuration_server_model_context;
144 
145 // Mandatory Health Server
146 static mesh_publication_model_t     mesh_health_server_publication;
147 static mesh_model_t                 mesh_health_server_model;
148 static mesh_health_state_t  mesh_health_server_model_context;
149 
150 // Random UUID on start
151 static btstack_crypto_random_t mesh_access_crypto_random;
152 static uint8_t random_device_uuid[16];
153 
154 // TLV
155 static const btstack_tlv_t * btstack_tlv_singleton_impl;
156 static void *                btstack_tlv_singleton_context;
157 
158 // IV Index persistence
159 static uint32_t sequence_number_last_stored;
160 static uint32_t sequence_number_storage_trigger;
161 
162 // Attention Timer
163 static uint8_t                attention_timer_timeout_s;
164 static btstack_timer_source_t attention_timer_timer;
165 
166 // used to log all keys to packet log for log viewer
167 // mesh-appkey-0xxx: 1234567890abcdef1234567890abcdef
168 static void mesh_log_key(const char * prefix, uint16_t id, const uint8_t * key){
169     char line[60];
170     strcpy(line, prefix);
171     uint16_t pos = strlen(line);
172     if (id != 0xffff){
173         line[pos++] = '-';
174         line[pos++] = '0';
175         line[pos++] = char_for_nibble((id >> 8) & 0x0f);
176         line[pos++] = char_for_nibble((id >> 4) & 0x0f);
177         line[pos++] = char_for_nibble( id       & 0x0f);
178     }
179     line[pos++] = ':';
180     line[pos++] = ' ';
181     uint16_t i;
182     for (i=0;i<16;i++){
183         line[pos++] = char_for_nibble((key[i] >> 4) & 0x0f);
184         line[pos++] = char_for_nibble( key[i]       & 0x0f);
185     }
186     line[pos++] = 0;
187     hci_dump_log(HCI_DUMP_LOG_LEVEL_INFO, "%s", line);
188 }
189 
190 static void mesh_setup_from_provisioning_data(const mesh_provisioning_data_t * provisioning_data){
191 
192     // set iv_index and iv index update active
193     int iv_index_update_active = (provisioning_data->flags & 2) >> 1;
194     mesh_iv_index_recovered(iv_index_update_active, provisioning_data->iv_index);
195 
196     // set unicast address
197     mesh_node_primary_element_address_set(provisioning_data->unicast_address);
198 
199     // set device_key
200     mesh_transport_set_device_key(provisioning_data->device_key);
201 
202     if (provisioning_data->network_key){
203 
204         // setup primary network with provisioned netkey
205         mesh_network_key_add(provisioning_data->network_key);
206 
207         // setup primary network
208         mesh_subnet_setup_for_netkey_index(provisioning_data->network_key->netkey_index);
209 
210         // start sending Secure Network Beacons
211         mesh_subnet_t * provisioned_subnet = mesh_subnet_get_by_netkey_index(provisioning_data->network_key->netkey_index);
212         beacon_secure_network_start(provisioned_subnet);
213     }
214 
215     // Mesh Proxy
216 #ifdef ENABLE_MESH_PROXY_SERVER
217     // Setup Proxy
218     mesh_proxy_init(provisioning_data->unicast_address);
219     mesh_proxy_start_advertising_with_network_id();
220 #endif
221 }
222 
223 // Attention Timer state
224 static void mesh_emit_attention_timer_event(uint8_t timer_s){
225     if (!provisioning_device_packet_handler) return;
226     uint8_t event[4] = { HCI_EVENT_MESH_META, 4, MESH_SUBEVENT_ATTENTION_TIMER};
227     event[3] = timer_s;
228     provisioning_device_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event));
229 }
230 
231 static void mesh_attention_timer_handler(btstack_timer_source_t * ts){
232     UNUSED(ts);
233     attention_timer_timeout_s--;
234     mesh_emit_attention_timer_event(attention_timer_timeout_s);
235     if (attention_timer_timeout_s == 0) return;
236 
237     btstack_run_loop_set_timer(&attention_timer_timer, 1000);
238     btstack_run_loop_add_timer(&attention_timer_timer);
239 }
240 
241 void mesh_attention_timer_set(uint8_t timer_s){
242     // stop old timer if running
243     if (attention_timer_timeout_s){
244         btstack_run_loop_remove_timer(&attention_timer_timer);
245     }
246 
247     attention_timer_timeout_s = timer_s;
248     mesh_emit_attention_timer_event(attention_timer_timeout_s);
249 
250     if (attention_timer_timeout_s){
251         btstack_run_loop_set_timer_handler(&attention_timer_timer, &mesh_attention_timer_handler);
252         btstack_run_loop_set_timer(&attention_timer_timer, 1000);
253         btstack_run_loop_add_timer(&attention_timer_timer);
254     }
255 }
256 
257 uint8_t mesh_attention_timer_get(void){
258     return attention_timer_timeout_s;
259 }
260 
261 static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
262     mesh_provisioning_data_t provisioning_data;
263     switch(packet[0]){
264         case HCI_EVENT_MESH_META:
265             switch(packet[2]){
266                 case MESH_SUBEVENT_PB_PROV_ATTENTION_TIMER:
267                     mesh_attention_timer_set(mesh_subevent_pb_prov_attention_timer_get_attention_time(packet));
268                     break;
269                 case MESH_SUBEVENT_PB_PROV_COMPLETE:
270                     // get provisioning data
271                     provisioning_device_data_get(&provisioning_data);
272 
273                     // and store in TLV
274                     mesh_node_store_provisioning_data(&provisioning_data);
275 
276                     // setup node after provisioned
277                     mesh_setup_from_provisioning_data(&provisioning_data);
278 
279 #ifdef ENABLE_MESH_PROXY_SERVER
280                     // start advertising with node id after provisioning
281                     mesh_proxy_set_advertising_with_node_id(provisioning_data.network_key->netkey_index, MESH_NODE_IDENTITY_STATE_ADVERTISING_RUNNING);
282 #endif
283 
284                     provisioned = 1;
285                     break;
286                 default:
287                     break;
288             }
289             break;
290         default:
291             break;
292     }
293     if (provisioning_device_packet_handler == NULL) return;
294 
295     // forward
296     (*provisioning_device_packet_handler)(packet_type, channel, packet, size);
297 }
298 
299 static void hci_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
300     UNUSED(channel);
301     UNUSED(size);
302 
303     switch (packet_type) {
304         case HCI_EVENT_PACKET:
305             switch (hci_event_packet_get_type(packet)) {
306                 case BTSTACK_EVENT_STATE:
307                     if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break;
308                     // get TLV instance
309                     btstack_tlv_get_instance(&btstack_tlv_singleton_impl, &btstack_tlv_singleton_context);
310 
311                     // startup from static provisioning data stored in TLV
312                     provisioned = mesh_node_startup_from_tlv();
313                     break;
314 
315 #ifdef ENABLE_MESH_PROXY_SERVER
316                 case HCI_EVENT_DISCONNECTION_COMPLETE:
317                     // enable PB_GATT
318                     if (provisioned == 0){
319                         mesh_proxy_start_advertising_unprovisioned_device();
320                     } else {
321                         mesh_proxy_start_advertising_with_network_id();
322                     }
323                     break;
324 
325                 case HCI_EVENT_LE_META:
326                     if (hci_event_le_meta_get_subevent_code(packet) !=  HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
327                     // disable PB_GATT
328                     mesh_proxy_stop_advertising_unprovisioned_device();
329                     break;
330 #endif
331                 default:
332                     break;
333             }
334             break;
335     }
336 }
337 
338 // Foundation state
339 static const uint32_t mesh_foundation_state_tag = ((uint32_t) 'M' << 24) | ((uint32_t) 'F' << 16)  | ((uint32_t) 'N' << 8) | ((uint32_t) 'D' << 8);
340 
341 void mesh_foundation_state_load(void){
342     mesh_persistent_foundation_t data;
343 
344     int foundation_state_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, mesh_foundation_state_tag, (uint8_t *) &data, sizeof(data));
345     if (foundation_state_len != sizeof(data)) return;
346 
347     mesh_foundation_gatt_proxy_set(data.gatt_proxy);
348     mesh_foundation_beacon_set(data.beacon);
349     mesh_foundation_default_ttl_set(data.default_ttl);
350     mesh_foundation_friend_set(data.friend);
351     mesh_foundation_network_transmit_set(data.network_transmit);
352     mesh_foundation_relay_set(data.relay);
353     mesh_foundation_relay_retransmit_set(data.relay_retransmit);
354 }
355 
356 void mesh_foundation_state_store(void){
357     mesh_persistent_foundation_t data;
358     data.gatt_proxy       = mesh_foundation_gatt_proxy_get();
359     data.beacon           = mesh_foundation_beacon_get();
360     data.default_ttl      = mesh_foundation_default_ttl_get();
361     data.friend           = mesh_foundation_friend_get();
362     data.network_transmit = mesh_foundation_network_transmit_get();
363     data.relay            = mesh_foundation_relay_get();
364     data.relay_retransmit = mesh_foundation_relay_retransmit_get();
365     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, mesh_foundation_state_tag, (uint8_t *) &data, sizeof(data));
366 }
367 
368 // Mesh Virtual Address Management
369 static uint32_t mesh_virtual_address_tag_for_pseudo_dst(uint16_t pseudo_dst){
370     return ((uint32_t) 'M' << 24) | ((uint32_t) 'V' << 16) | ((uint32_t) pseudo_dst);
371 }
372 
373 static void mesh_store_virtual_address(uint16_t pseudo_dest, uint16_t hash, const uint8_t * label_uuid){
374     mesh_persistent_virtual_address_t data;
375     uint32_t tag = mesh_virtual_address_tag_for_pseudo_dst(pseudo_dest);
376     data.hash = hash;
377     memcpy(data.label_uuid, label_uuid, 16);
378     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
379 }
380 
381 static void mesh_delete_virtual_address(uint16_t pseudo_dest){
382     uint32_t tag = mesh_virtual_address_tag_for_pseudo_dst(pseudo_dest);
383     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
384 }
385 
386 void mesh_load_virtual_addresses(void){
387     uint16_t pseudo_dst;
388     for (pseudo_dst = 0x8000; pseudo_dst < (0x8000 + MAX_NR_MESH_VIRTUAL_ADDRESSES); pseudo_dst++){
389         mesh_virtual_address_tag_for_pseudo_dst(pseudo_dst);
390         mesh_persistent_virtual_address_t data;
391         uint32_t tag = mesh_virtual_address_tag_for_pseudo_dst(pseudo_dst);
392         int virtual_address_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
393         if (virtual_address_len == 0) continue;
394 
395         mesh_virtual_address_t * virtual_address = btstack_memory_mesh_virtual_address_get();
396         if (virtual_address == NULL) return;
397 
398         virtual_address->pseudo_dst = pseudo_dst;
399         virtual_address->hash = data.hash;
400         memcpy(virtual_address->label_uuid, data.label_uuid, 16);
401         mesh_virtual_address_add(virtual_address);
402     }
403 }
404 
405 void mesh_delete_virtual_addresses(void){
406     uint16_t pseudo_dest;
407     for (pseudo_dest = 0x8000; pseudo_dest < (0x8000 + MAX_NR_MESH_VIRTUAL_ADDRESSES); pseudo_dest++){
408         mesh_delete_virtual_address(pseudo_dest);
409     }
410 }
411 
412 void mesh_virtual_address_decrease_refcount(mesh_virtual_address_t * virtual_address){
413     if (virtual_address == NULL){
414         log_error("virtual_address == NULL");
415     }
416     // decrease refcount
417     virtual_address->ref_count--;
418     // Free virtual address if ref count reaches zero
419     if (virtual_address->ref_count > 0) return;
420     // delete from TLV
421     mesh_delete_virtual_address(virtual_address->pseudo_dst);
422     // remove from list
423     mesh_virtual_address_remove(virtual_address);
424     // free memory
425     btstack_memory_mesh_virtual_address_free(virtual_address);
426 }
427 
428 void mesh_virtual_address_increase_refcount(mesh_virtual_address_t * virtual_address){
429     if (virtual_address == NULL){
430         log_error("virtual_address == NULL");
431     }
432     virtual_address->ref_count++;
433     if (virtual_address->ref_count > 1) return;
434     // store in TLV
435     mesh_store_virtual_address(virtual_address->pseudo_dst, virtual_address->hash, virtual_address->label_uuid);
436 }
437 
438 // Mesh Subscriptions
439 static uint32_t mesh_model_subscription_tag_for_index(uint16_t internal_model_id){
440     return ((uint32_t) 'M' << 24) | ((uint32_t) 'S' << 16) | ((uint32_t) internal_model_id);
441 }
442 
443 static void mesh_model_load_subscriptions(mesh_model_t * mesh_model){
444     uint32_t tag = mesh_model_subscription_tag_for_index(mesh_model->mid);
445     btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &mesh_model->subscriptions, sizeof(mesh_model->subscriptions));
446     // update ref count
447 
448     // increase ref counts for virtual subscriptions
449     uint16_t i;
450     for (i = 0; i<MAX_NR_MESH_SUBSCRIPTION_PER_MODEL ; i++){
451         uint16_t src = mesh_model->subscriptions[i];
452         if (mesh_network_address_virtual(src)){
453             mesh_virtual_address_t * virtual_address = mesh_virtual_address_for_pseudo_dst(src);
454             mesh_virtual_address_increase_refcount(virtual_address);
455         }
456     }
457 }
458 
459 void mesh_model_store_subscriptions(mesh_model_t * model){
460     uint32_t tag = mesh_model_subscription_tag_for_index(model->mid);
461     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &model->subscriptions, sizeof(model->subscriptions));
462 }
463 
464 static void mesh_model_delete_subscriptions(mesh_model_t * model){
465     uint32_t tag = mesh_model_subscription_tag_for_index(model->mid);
466     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
467 }
468 
469 void mesh_load_subscriptions(void){
470     printf("Load Model Subscription Lists\n");
471     // iterate over elements and models
472     mesh_element_iterator_t element_it;
473     mesh_element_iterator_init(&element_it);
474     while (mesh_element_iterator_has_next(&element_it)){
475         mesh_element_t * element = mesh_element_iterator_next(&element_it);
476         mesh_model_iterator_t model_it;
477         mesh_model_iterator_init(&model_it, element);
478         while (mesh_model_iterator_has_next(&model_it)){
479             mesh_model_t * model = mesh_model_iterator_next(&model_it);
480             mesh_model_load_subscriptions(model);
481         }
482     }
483 }
484 
485 void mesh_delete_subscriptions(void){
486     printf("Delete Model Subscription Lists\n");
487     // iterate over elements and models
488     mesh_element_iterator_t element_it;
489     mesh_element_iterator_init(&element_it);
490     while (mesh_element_iterator_has_next(&element_it)){
491         mesh_element_t * element = mesh_element_iterator_next(&element_it);
492         mesh_model_iterator_t model_it;
493         mesh_model_iterator_init(&model_it, element);
494         while (mesh_model_iterator_has_next(&model_it)){
495             mesh_model_t * model = mesh_model_iterator_next(&model_it);
496             mesh_model_delete_subscriptions(model);
497         }
498     }
499 }
500 
501 // Model Publication
502 
503 static uint32_t mesh_model_publication_tag_for_index(uint16_t internal_model_id){
504     return ((uint32_t) 'M' << 24) | ((uint32_t) 'P' << 16) | ((uint32_t) internal_model_id);
505 }
506 
507 static void mesh_model_load_publication(mesh_model_t * mesh_model){
508     mesh_publication_model_t * publication = mesh_model->publication_model;
509     if (publication == NULL) return;
510 
511     mesh_persistent_publication_t data;
512     uint32_t tag = mesh_model_publication_tag_for_index(mesh_model->mid);
513     btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(mesh_persistent_publication_t));
514 
515     publication->address                    = data.publish_address;
516     publication->appkey_index               = data.appkey_index;
517     publication->friendship_credential_flag = data.friendship_credential_flag;
518     publication->ttl                        = data.publish_ttl;
519     publication->period                     = data.publish_period;
520     publication->retransmit                 = data.publish_retransmit;
521 
522     // increase ref counts for current virtual publicataion address
523     uint16_t src = publication->address;
524     if (mesh_network_address_virtual(src)){
525         mesh_virtual_address_t * virtual_address = mesh_virtual_address_for_pseudo_dst(src);
526         if (virtual_address){
527             mesh_virtual_address_increase_refcount(virtual_address);
528         }
529     }
530 
531     mesh_model_publication_start(mesh_model);
532 }
533 
534 void mesh_model_store_publication(mesh_model_t * mesh_model){
535     mesh_publication_model_t * publication = mesh_model->publication_model;
536     if (publication == NULL) return;
537 
538     mesh_persistent_publication_t data;
539     data.publish_address            = publication->address;
540     data.appkey_index               = publication->appkey_index;
541     data.friendship_credential_flag = publication->friendship_credential_flag;
542     data.publish_ttl                = publication->ttl;
543     data.publish_period             = publication->period;
544     data.publish_retransmit         = publication->retransmit;
545     uint32_t tag = mesh_model_publication_tag_for_index(mesh_model->mid);
546     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(mesh_persistent_publication_t));
547 }
548 
549 static void mesh_model_delete_publication(mesh_model_t * mesh_model){
550     if (mesh_model->publication_model == NULL) return;
551     uint32_t tag = mesh_model_publication_tag_for_index(mesh_model->mid);
552     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
553 }
554 
555 void mesh_load_publications(void){
556     printf("Load Model Publications\n");
557     // iterate over elements and models
558     mesh_element_iterator_t element_it;
559     mesh_element_iterator_init(&element_it);
560     while (mesh_element_iterator_has_next(&element_it)){
561         mesh_element_t * element = mesh_element_iterator_next(&element_it);
562         mesh_model_iterator_t model_it;
563         mesh_model_iterator_init(&model_it, element);
564         while (mesh_model_iterator_has_next(&model_it)){
565             mesh_model_t * model = mesh_model_iterator_next(&model_it);
566             mesh_model_load_publication(model);
567         }
568     }
569 }
570 
571 void mesh_delete_publications(void){
572     printf("Delete Model Publications\n");
573     // iterate over elements and models
574     mesh_element_iterator_t element_it;
575     mesh_element_iterator_init(&element_it);
576     while (mesh_element_iterator_has_next(&element_it)){
577         mesh_element_t * element = mesh_element_iterator_next(&element_it);
578         mesh_model_iterator_t model_it;
579         mesh_model_iterator_init(&model_it, element);
580         while (mesh_model_iterator_has_next(&model_it)){
581             mesh_model_t * model = mesh_model_iterator_next(&model_it);
582             mesh_model_delete_publication(model);
583         }
584     }
585 }
586 
587 // Mesh Network Keys
588 static uint32_t mesh_network_key_tag_for_internal_index(uint16_t internal_index){
589     return ((uint32_t) 'M' << 24) | ((uint32_t) 'N' << 16) | ((uint32_t) internal_index);
590 }
591 
592 void mesh_store_network_key(mesh_network_key_t * network_key){
593     mesh_persistent_net_key_t data;
594     printf("Store NetKey: internal index 0x%x, NetKey Index 0x%06x, NID %02x: ", network_key->internal_index, network_key->netkey_index, network_key->nid);
595     printf_hexdump(network_key->net_key, 16);
596     uint32_t tag = mesh_network_key_tag_for_internal_index(network_key->internal_index);
597     data.netkey_index = network_key->netkey_index;
598     memcpy(data.net_key, network_key->net_key, 16);
599     memcpy(data.identity_key, network_key->identity_key, 16);
600     memcpy(data.beacon_key, network_key->beacon_key, 16);
601     memcpy(data.network_id, network_key->network_id, 8);
602     data.nid = network_key->nid;
603     data.version = network_key->version;
604     memcpy(data.encryption_key, network_key->encryption_key, 16);
605     memcpy(data.privacy_key, network_key->privacy_key, 16);
606     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(mesh_persistent_net_key_t));
607 }
608 
609 void mesh_delete_network_key(uint16_t internal_index){
610     uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index);
611     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
612 }
613 
614 void mesh_load_network_keys(void){
615     printf("Load Network Keys\n");
616     uint16_t internal_index;
617     for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){
618         mesh_persistent_net_key_t data;
619         uint32_t tag = mesh_network_key_tag_for_internal_index(internal_index);
620         int netkey_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
621         if (netkey_len != sizeof(mesh_persistent_net_key_t)) continue;
622 
623         mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
624         if (network_key == NULL) return;
625 
626         network_key->internal_index = internal_index;
627         network_key->netkey_index = data.netkey_index;
628         memcpy(network_key->net_key, data.net_key, 16);
629         memcpy(network_key->identity_key, data.identity_key, 16);
630         memcpy(network_key->beacon_key, data.beacon_key, 16);
631         memcpy(network_key->network_id, data.network_id, 8);
632         network_key->nid = data.nid;
633         network_key->version = data.version;
634         memcpy(network_key->encryption_key, data.encryption_key, 16);
635         memcpy(network_key->privacy_key, data.privacy_key, 16);
636 
637 #ifdef ENABLE_GATT_BEARER
638         // setup advertisement with network id
639         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);
640 #endif
641 
642         mesh_network_key_add(network_key);
643 
644         mesh_subnet_setup_for_netkey_index(network_key->netkey_index);
645 
646         printf("- internal index 0x%x, NetKey Index 0x%06x, NID %02x: ", network_key->internal_index, network_key->netkey_index, network_key->nid);
647         printf_hexdump(network_key->net_key, 16);
648 
649         // dump into packet log
650         mesh_log_key("mesh-netkey",  network_key->netkey_index, network_key->net_key);
651     }
652 }
653 
654 void mesh_delete_network_keys(void){
655     printf("Delete Network Keys\n");
656 
657     uint16_t internal_index;
658     for (internal_index = 0; internal_index < MAX_NR_MESH_NETWORK_KEYS; internal_index++){
659         mesh_delete_network_key(internal_index);
660     }
661 }
662 
663 // Mesh App Keys
664 
665 static uint32_t mesh_transport_key_tag_for_internal_index(uint16_t internal_index){
666     return ((uint32_t) 'M' << 24) | ((uint32_t) 'A' << 16) | ((uint32_t) internal_index);
667 }
668 
669 void mesh_store_app_key(mesh_transport_key_t * app_key){
670     mesh_persistent_app_key_t data;
671     printf("Store AppKey: internal index 0x%x, AppKey Index 0x%06x, AID %02x: ", app_key->internal_index, app_key->appkey_index, app_key->aid);
672     printf_hexdump(app_key->key, 16);
673     uint32_t tag = mesh_transport_key_tag_for_internal_index(app_key->internal_index);
674     data.netkey_index = app_key->netkey_index;
675     data.appkey_index = app_key->appkey_index;
676     data.aid = app_key->aid;
677     data.version = app_key->version;
678     memcpy(data.key, app_key->key, 16);
679     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
680 }
681 
682 void mesh_delete_app_key(uint16_t internal_index){
683     uint32_t tag = mesh_transport_key_tag_for_internal_index(internal_index);
684     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
685 }
686 
687 void mesh_load_app_keys(void){
688     printf("Load App Keys\n");
689     uint16_t internal_index;
690     for (internal_index = 0; internal_index < MAX_NR_MESH_TRANSPORT_KEYS; internal_index++){
691         mesh_persistent_app_key_t data;
692         uint32_t tag = mesh_transport_key_tag_for_internal_index(internal_index);
693         int app_key_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &data, sizeof(data));
694         if (app_key_len == 0) continue;
695 
696         mesh_transport_key_t * key = btstack_memory_mesh_transport_key_get();
697         if (key == NULL) return;
698 
699         key->internal_index = internal_index;
700         key->appkey_index = data.appkey_index;
701         key->netkey_index = data.netkey_index;
702         key->aid          = data.aid;
703         key->akf          = 1;
704         key->version      = data.version;
705         memcpy(key->key, data.key, 16);
706         mesh_transport_key_add(key);
707         printf("- internal index 0x%x, AppKey Index 0x%06x, AID %02x: ", key->internal_index, key->appkey_index, key->aid);
708         printf_hexdump(key->key, 16);
709 
710         // dump into packet log
711         mesh_log_key("mesh-appkey",  key->appkey_index, key->key);
712     }
713 }
714 
715 void mesh_delete_app_keys(void){
716     printf("Delete App Keys\n");
717 
718     uint16_t internal_index;
719     for (internal_index = 0; internal_index < MAX_NR_MESH_TRANSPORT_KEYS; internal_index++){
720         mesh_delete_app_key(internal_index);
721     }
722 }
723 
724 
725 // Model to Appkey List
726 
727 static uint32_t mesh_model_tag_for_index(uint16_t internal_model_id){
728     return ((uint32_t) 'M' << 24) | ((uint32_t) 'B' << 16) | ((uint32_t) internal_model_id);
729 }
730 
731 static void mesh_load_appkey_list(mesh_model_t * model){
732     uint32_t tag = mesh_model_tag_for_index(model->mid);
733     btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &model->appkey_indices, sizeof(model->appkey_indices));
734 }
735 
736 static void mesh_store_appkey_list(mesh_model_t * model){
737     uint32_t tag = mesh_model_tag_for_index(model->mid);
738     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, tag, (uint8_t *) &model->appkey_indices, sizeof(model->appkey_indices));
739 }
740 
741 static void mesh_delete_appkey_list(mesh_model_t * model){
742     uint32_t tag = mesh_model_tag_for_index(model->mid);
743     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, tag);
744 }
745 
746 void mesh_load_appkey_lists(void){
747     printf("Load Appkey Lists\n");
748     // iterate over elements and models
749     mesh_element_iterator_t element_it;
750     mesh_element_iterator_init(&element_it);
751     while (mesh_element_iterator_has_next(&element_it)){
752         mesh_element_t * element = mesh_element_iterator_next(&element_it);
753         mesh_model_iterator_t model_it;
754         mesh_model_iterator_init(&model_it, element);
755         while (mesh_model_iterator_has_next(&model_it)){
756             mesh_model_t * model = mesh_model_iterator_next(&model_it);
757             mesh_load_appkey_list(model);
758         }
759     }
760 }
761 
762 void mesh_delete_appkey_lists(void){
763     printf("Delete Appkey Lists\n");
764     // iterate over elements and models
765     mesh_element_iterator_t element_it;
766     mesh_element_iterator_init(&element_it);
767     while (mesh_element_iterator_has_next(&element_it)){
768         mesh_element_t * element = mesh_element_iterator_next(&element_it);
769         mesh_model_iterator_t model_it;
770         mesh_model_iterator_init(&model_it, element);
771         while (mesh_model_iterator_has_next(&model_it)){
772             mesh_model_t * model = mesh_model_iterator_next(&model_it);
773             mesh_delete_appkey_list(model);
774         }
775     }
776 }
777 
778 uint8_t mesh_model_bind_appkey(mesh_model_t * mesh_model, uint16_t appkey_index){
779     uint16_t i;
780     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
781         if (mesh_model->appkey_indices[i] == appkey_index) return MESH_FOUNDATION_STATUS_SUCCESS;
782     }
783     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
784         if (mesh_model->appkey_indices[i] == MESH_APPKEY_INVALID) {
785             mesh_model->appkey_indices[i] = appkey_index;
786             mesh_store_appkey_list(mesh_model);
787             return MESH_FOUNDATION_STATUS_SUCCESS;
788         }
789     }
790     return MESH_FOUNDATION_STATUS_INSUFFICIENT_RESOURCES;
791 }
792 
793 void mesh_model_unbind_appkey(mesh_model_t * mesh_model, uint16_t appkey_index){
794     uint16_t i;
795     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
796         if (mesh_model->appkey_indices[i] == appkey_index) {
797             mesh_model->appkey_indices[i] = MESH_APPKEY_INVALID;
798             mesh_store_appkey_list(mesh_model);
799         }
800     }
801 }
802 
803 int mesh_model_contains_appkey(mesh_model_t * mesh_model, uint16_t appkey_index){
804     uint16_t i;
805     for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
806         if (mesh_model->appkey_indices[i] == appkey_index) return 1;
807     }
808     return 0;
809 }
810 
811 void mesh_access_netkey_finalize(mesh_network_key_t * network_key){
812     mesh_network_key_remove(network_key);
813     mesh_delete_network_key(network_key->internal_index);
814     btstack_memory_mesh_network_key_free(network_key);
815 }
816 
817 void mesh_access_appkey_finalize(mesh_transport_key_t * transport_key){
818     mesh_transport_key_remove(transport_key);
819     mesh_delete_app_key(transport_key->appkey_index);
820     btstack_memory_mesh_transport_key_free(transport_key);
821 }
822 
823 void mesh_access_key_refresh_revoke_keys(mesh_subnet_t * subnet){
824     // delete old netkey index
825     mesh_access_netkey_finalize(subnet->old_key);
826     subnet->old_key = subnet->new_key;
827     subnet->new_key = NULL;
828 
829     // delete old appkeys, if any
830     mesh_transport_key_iterator_t it;
831     mesh_transport_key_iterator_init(&it, subnet->netkey_index);
832     while (mesh_transport_key_iterator_has_more(&it)){
833         mesh_transport_key_t * transport_key = mesh_transport_key_iterator_get_next(&it);
834         if (transport_key->old_key == 0) continue;
835         mesh_access_appkey_finalize(transport_key);
836     }
837 }
838 
839 // Mesh IV Index
840 static const uint32_t mesh_tag_for_iv_index_and_seq_number = ((uint32_t) 'M' << 24) | ((uint32_t) 'F' << 16) | ((uint32_t) 'I' << 9) | ((uint32_t) 'S');
841 
842 static int mesh_load_iv_index_and_sequence_number(uint32_t * iv_index, uint32_t * sequence_number){
843     iv_index_and_sequence_number_t data;
844     uint32_t len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, mesh_tag_for_iv_index_and_seq_number, (uint8_t *) &data, sizeof(data));
845     if (len == sizeof(iv_index_and_sequence_number_t)){
846         *iv_index = data.iv_index;
847         *sequence_number = data.seq_number;
848         return 1;
849     }
850     return 0;
851 }
852 
853 static void mesh_store_iv_index_and_sequence_number(uint32_t iv_index, uint32_t sequence_number){
854     iv_index_and_sequence_number_t data;
855     data.iv_index   = iv_index;
856     data.seq_number = sequence_number;
857     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, mesh_tag_for_iv_index_and_seq_number, (uint8_t *) &data, sizeof(data));
858 
859     sequence_number_last_stored = data.seq_number;
860     sequence_number_storage_trigger = sequence_number_last_stored + MESH_SEQUENCE_NUMBER_STORAGE_INTERVAL;
861 }
862 
863 static void mesh_persist_iv_index_and_sequence_number(void){
864     mesh_store_iv_index_and_sequence_number(mesh_get_iv_index(), mesh_sequence_number_peek());
865 }
866 
867 
868 // higher layer - only store if sequence number is higher than trigger
869 static void mesh_persist_iv_index_and_sequence_number_if_needed(void){
870     if (mesh_sequence_number_peek() >= sequence_number_storage_trigger){
871         mesh_persist_iv_index_and_sequence_number();
872     }
873 }
874 
875 static void mesh_access_secure_network_beacon_handler(uint8_t packet_type, uint16_t channel, uint8_t * packet, uint16_t size){
876     UNUSED(channel);
877     UNUSED(size);
878 
879     if (packet_type != MESH_BEACON_PACKET) return;
880 
881     // lookup subnet and netkey by network id
882     uint8_t * beacon_network_id = &packet[2];
883     mesh_subnet_iterator_t it;
884     mesh_subnet_iterator_init(&it);
885     mesh_subnet_t * subnet = NULL;
886     uint8_t new_key = 0;
887     while (mesh_subnet_iterator_has_more(&it)){
888         mesh_subnet_t * item = mesh_subnet_iterator_get_next(&it);
889         if (memcmp(item->old_key->network_id, beacon_network_id, 8) == 0 ) {
890             subnet = item;
891         }
892         if (item->new_key != NULL && memcmp(item->new_key->network_id, beacon_network_id, 8) == 0 ) {
893             subnet = item;
894             new_key = 1;
895         }
896         break;
897     }
898     if (subnet == NULL) return;
899 
900     uint8_t flags = packet[1];
901 
902     // Key refresh via secure network beacons that are authenticated with new netkey
903     if (new_key){
904         // either first or second phase (in phase 0, new key is not set)
905         int key_refresh_flag = flags & 1;
906         if (key_refresh_flag){
907             //  transition to phase 3 from either phase 1 or 2
908             switch (subnet->key_refresh){
909                 case MESH_KEY_REFRESH_FIRST_PHASE:
910                 case MESH_KEY_REFRESH_SECOND_PHASE:
911                     mesh_access_key_refresh_revoke_keys(subnet);
912                     subnet->key_refresh = MESH_KEY_REFRESH_NOT_ACTIVE;
913                     break;
914                 default:
915                     break;
916             }
917         } else {
918             //  transition to phase 2 from either phase 1
919             switch (subnet->key_refresh){
920                 case MESH_KEY_REFRESH_FIRST_PHASE:
921                     // -- update state
922                     subnet->key_refresh = MESH_KEY_REFRESH_SECOND_PHASE;
923                     break;
924                 default:
925                     break;
926             }
927         }
928     }
929 
930     // IV Update
931 
932     int     beacon_iv_update_active = flags & 2;
933     int     local_iv_update_active = mesh_iv_update_active();
934     uint32_t beacon_iv_index = big_endian_read_32(packet, 10);
935     uint32_t local_iv_index = mesh_get_iv_index();
936 
937     int32_t iv_index_delta = (int32_t)(beacon_iv_index - local_iv_index);
938 
939     // "If a node in Normal Operation receives a Secure Network beacon with an IV index less than the last known IV Index or greater than
940     //  the last known IV Index + 42, the Secure Network beacon shall be ignored."
941     if (iv_index_delta < 0 || iv_index_delta > 42){
942         return;
943     }
944 
945     // "If a node in Normal Operation receives a Secure Network beacon with an IV index equal to the last known IV index+1 and
946     //  the IV Update Flag set to 0, the node may update its IV without going to the IV Update in Progress state, or it may initiate
947     //  an IV Index Recovery procedure (Section 3.10.6), or it may ignore the Secure Network beacon. The node makes the choice depending
948     //  on the time since last IV update and the likelihood that the node has missed the Secure Network beacons with the IV update Flag set to 1.""
949     if (local_iv_update_active == 0 && beacon_iv_update_active == 0 && iv_index_delta == 1){
950         // instant iv update
951         mesh_set_iv_index( beacon_iv_index );
952         // store updated iv index
953         mesh_persist_iv_index_and_sequence_number();
954         return;
955     }
956 
957     // "If this node is a member of a primary subnet and receives a Secure Network beacon on a secondary subnet with an IV Index greater than
958     //  the last known IV Index of the primary subnet, the Secure Network beacon shall be ignored."
959     int member_of_primary_subnet = mesh_subnet_get_by_netkey_index(0) != NULL;
960     int beacon_on_secondary_subnet = subnet->netkey_index != 0;
961     if (member_of_primary_subnet && beacon_on_secondary_subnet && iv_index_delta > 0){
962         return;
963     }
964 
965     // "If a node in Normal Operation receives a Secure Network beacon with an IV index greater than the last known IV Index + 1..."
966     // "... it may initiate an IV Index Recovery procedure, see Section 3.10.6."
967     if (local_iv_update_active == 0 && iv_index_delta > 1){
968         // "Upon receiving and successfully authenticating a Secure Network beacon for a primary subnet... "
969         int beacon_on_primary_subnet = subnet->netkey_index == 0;
970         if (!beacon_on_primary_subnet) return;
971         // "... whose IV Index is 1 or more higher than the current known IV Index, the node shall "
972         // " set its current IV Index and its current IV Update procedure state from the values in this Secure Network beacon."
973         mesh_iv_index_recovered(beacon_iv_update_active, beacon_iv_index);
974         // store updated iv index if in normal mode
975         if (beacon_iv_update_active == 0){
976             mesh_persist_iv_index_and_sequence_number();
977         }
978         return;
979     }
980 
981     if (local_iv_update_active == 0){
982         if (beacon_iv_update_active){
983             mesh_trigger_iv_update();
984         }
985     } else {
986         if (beacon_iv_update_active == 0){
987             // " At the point of transition, the node shall reset the sequence number to 0x000000."
988             mesh_sequence_number_set(0);
989             mesh_iv_update_completed();
990             // store updated iv index
991             mesh_persist_iv_index_and_sequence_number();
992         }
993     }
994 }
995 
996 static const uint32_t mesh_tag_for_prov_data = ((uint32_t) 'P' << 24) | ((uint32_t) 'R' << 16) | ((uint32_t) 'O' <<  8) | (uint32_t)'V';
997 
998 void mesh_node_reset(void){
999     // PROV
1000     btstack_tlv_singleton_impl->delete_tag(btstack_tlv_singleton_context, mesh_tag_for_prov_data);
1001     // everything else
1002     mesh_delete_network_keys();
1003     mesh_delete_app_keys();
1004     mesh_delete_appkey_lists();
1005     mesh_delete_virtual_addresses();
1006     mesh_delete_subscriptions();
1007     mesh_delete_publications();
1008 }
1009 
1010 typedef struct {
1011     uint16_t unicast_address;
1012     uint8_t  flags;
1013     uint8_t  device_key[16];
1014 
1015 } mesh_persistent_provisioning_data_t;
1016 
1017 static void mesh_node_store_provisioning_data(mesh_provisioning_data_t * provisioning_data){
1018 
1019     // fill persistent prov data
1020     mesh_persistent_provisioning_data_t persistent_provisioning_data;
1021 
1022     persistent_provisioning_data.unicast_address = provisioning_data->unicast_address;
1023     persistent_provisioning_data.flags = provisioning_data->flags;
1024     memcpy(persistent_provisioning_data.device_key, provisioning_data->device_key, 16);
1025 
1026     // store in tlv
1027     btstack_tlv_get_instance(&btstack_tlv_singleton_impl, &btstack_tlv_singleton_context);
1028     btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, mesh_tag_for_prov_data, (uint8_t *) &persistent_provisioning_data, sizeof(mesh_persistent_provisioning_data_t));
1029 
1030     // store IV Index and sequence number
1031     mesh_store_iv_index_and_sequence_number(provisioning_data->iv_index, 0);
1032 
1033     // store primary network key
1034     mesh_store_network_key(provisioning_data->network_key);
1035 }
1036 
1037 static void mesh_access_setup_unprovisioned_device(const uint8_t * device_uuid){
1038 #ifdef ENABLE_MESH_PB_ADV
1039     // PB-ADV
1040     beacon_unprovisioned_device_start(device_uuid, 0);
1041 #else
1042     UNUSED(device_uuid);;
1043 #endif
1044 #ifdef ENABLE_MESH_PB_GATT
1045     mesh_proxy_start_advertising_unprovisioned_device();
1046 #endif
1047 }
1048 
1049 static void mesh_access_setup_without_provisiong_data_random(void * arg){
1050     UNUSED(arg);
1051     // set random value
1052     mesh_node_set_device_uuid(random_device_uuid);
1053     mesh_access_setup_unprovisioned_device(random_device_uuid);
1054 }
1055 
1056 static void mesh_access_setup_with_provisiong_data_random(void * arg){
1057     UNUSED(arg);
1058     // set random value
1059     mesh_node_set_device_uuid(random_device_uuid);
1060 }
1061 
1062 static int mesh_node_startup_from_tlv(void){
1063 
1064     mesh_persistent_provisioning_data_t persistent_provisioning_data;
1065     btstack_tlv_get_instance(&btstack_tlv_singleton_impl, &btstack_tlv_singleton_context);
1066 
1067     // load provisioning data
1068     uint32_t prov_len = btstack_tlv_singleton_impl->get_tag(btstack_tlv_singleton_context, mesh_tag_for_prov_data, (uint8_t *) &persistent_provisioning_data, sizeof(mesh_persistent_provisioning_data_t));
1069     printf("Provisioning data available: %u\n", prov_len ? 1 : 0);
1070     int prov_data_valid = prov_len == sizeof(mesh_persistent_provisioning_data_t);
1071     if (prov_data_valid){
1072 
1073         // copy into mesh_provisioning_data
1074         mesh_provisioning_data_t provisioning_data;
1075         memcpy(provisioning_data.device_key, persistent_provisioning_data.device_key, 16);
1076         provisioning_data.unicast_address = persistent_provisioning_data.unicast_address;
1077         provisioning_data.flags = persistent_provisioning_data.flags;
1078         provisioning_data.network_key = NULL;
1079         printf("Provisioning Data: Flags %x, unicast_address %04x\n", persistent_provisioning_data.flags, provisioning_data.unicast_address);
1080 
1081         // try load iv index and sequence number
1082         uint32_t iv_index        = 0;
1083         uint32_t sequence_number = 0;
1084         (void) mesh_load_iv_index_and_sequence_number(&iv_index, &sequence_number);
1085 
1086         // bump sequence number to account for interval updates
1087         sequence_number += MESH_SEQUENCE_NUMBER_STORAGE_INTERVAL;
1088         mesh_store_iv_index_and_sequence_number(iv_index, sequence_number);
1089 
1090         mesh_set_iv_index(iv_index);
1091         mesh_sequence_number_set(sequence_number);
1092         provisioning_data.iv_index = iv_index;
1093         printf("IV Index: %08x, Sequence Number %08x\n", (int) iv_index, (int) sequence_number);
1094 
1095         // setup iv update, node address, device key ...
1096         mesh_setup_from_provisioning_data(&provisioning_data);
1097 
1098         // load network keys
1099         mesh_load_network_keys();
1100 
1101         // load app keys
1102         mesh_load_app_keys();
1103 
1104         // load foundation state
1105         mesh_foundation_state_load();
1106 
1107         // load model to appkey bindings
1108         mesh_load_appkey_lists();
1109 
1110         // load virtual addresses
1111         mesh_load_virtual_addresses();
1112 
1113         // load model subscriptions
1114         mesh_load_subscriptions();
1115 
1116         // load model publications
1117         mesh_load_publications();
1118 
1119 #if defined(ENABLE_MESH_ADV_BEARER) || defined(ENABLE_MESH_PB_ADV)
1120         // start sending Secure Network Beacon
1121         mesh_subnet_t * subnet = mesh_subnet_get_by_netkey_index(0);
1122         if (subnet){
1123             beacon_secure_network_start(subnet);
1124         }
1125 #endif
1126         // create random uuid if not already set
1127         if (mesh_node_get_device_uuid() == NULL){
1128             btstack_crypto_random_generate(&mesh_access_crypto_random, random_device_uuid, 16, &mesh_access_setup_with_provisiong_data_random, NULL);
1129         }
1130 
1131         // dump into packet log
1132         hci_dump_log(HCI_DUMP_LOG_LEVEL_INFO, "mesh-iv-index: %08x",  iv_index);
1133         mesh_log_key("mesh-devkey",  0xffff, persistent_provisioning_data.device_key);
1134 
1135     } else {
1136 
1137         const uint8_t * device_uuid = mesh_node_get_device_uuid();
1138         if (device_uuid){
1139             mesh_access_setup_unprovisioned_device(device_uuid);
1140         } else{
1141             btstack_crypto_random_generate(&mesh_access_crypto_random, random_device_uuid, 16, &mesh_access_setup_without_provisiong_data_random, NULL);
1142         }
1143 
1144     }
1145 
1146     return prov_data_valid;
1147 }
1148 
1149 static void mesh_control_message_handler(mesh_pdu_t * pdu){
1150     // get opcode
1151     uint8_t opcode = mesh_pdu_control_opcode(pdu);
1152     printf("Opcode: 0x%02x\n", opcode);
1153 
1154     uint8_t init_ttl;
1155     uint8_t hops = 0;
1156     uint16_t features = 0;
1157     switch(opcode){
1158         case 0x0a:
1159             // read params
1160             init_ttl = (*mesh_pdu_data(pdu)) & 0x7fu;
1161             features = big_endian_read_16(mesh_pdu_data(pdu), 1);
1162             // calculates hops
1163             hops     = init_ttl - mesh_pdu_ttl(pdu) + 1;
1164             // process heartbeat info
1165             mesh_configuration_server_process_heartbeat(&mesh_configuration_server_model, mesh_pdu_src(pdu), mesh_pdu_dst(pdu), hops, features);
1166             break;
1167         default:
1168             break;
1169     }
1170     mesh_upper_transport_message_processed_by_higher_layer(pdu);
1171 }
1172 
1173 static void mesh_node_setup_default_models(void){
1174     // configure Config Server
1175     mesh_configuration_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_CONFIGURATION_SERVER);
1176     mesh_configuration_server_model.model_data       = &mesh_configuration_server_model_context;
1177     mesh_configuration_server_model.operations       = mesh_configuration_server_get_operations();
1178     mesh_element_add_model(mesh_node_get_primary_element(), &mesh_configuration_server_model);
1179 
1180     // Config Health Server
1181     mesh_health_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_HEALTH_SERVER);
1182     mesh_health_server_model.model_data       = &mesh_health_server_model_context;
1183     mesh_health_server_model.operations       = mesh_health_server_get_operations();
1184     mesh_health_server_model.publication_model = &mesh_health_server_publication;
1185     mesh_element_add_model(mesh_node_get_primary_element(), &mesh_health_server_model);
1186     mesh_health_server_set_publication_model(&mesh_health_server_model, &mesh_health_server_publication);
1187 }
1188 
1189 void mesh_init(void){
1190 
1191     // register for HCI events
1192     hci_event_callback_registration.callback = &hci_packet_handler;
1193     hci_add_event_handler(&hci_event_callback_registration);
1194 
1195     // ADV Bearer also used for GATT Proxy Advertisements and PB-GATT
1196     adv_bearer_init();
1197 
1198 #ifdef ENABLE_MESH_GATT_BEARER
1199     // Setup GATT bearer
1200     gatt_bearer_init();
1201 #endif
1202 
1203 #ifdef ENABLE_MESH_ADV_BEARER
1204     // Setup Unprovisioned Device Beacon
1205     beacon_init();
1206 #endif
1207 
1208     provisioning_device_init();
1209     provisioning_device_register_packet_handler(&mesh_provisioning_message_handler);
1210 
1211     // Node Configuration
1212     mesh_node_init();
1213 
1214     // Network layer
1215     mesh_network_init();
1216 
1217     // Transport layers (lower + upper))
1218     mesh_lower_transport_init();
1219     mesh_upper_transport_init();
1220 
1221     // Access layer
1222     mesh_access_init();
1223 
1224     // Add mandatory models: Config Server and Health Server
1225     mesh_node_setup_default_models();
1226 
1227     // register for secure network beacons
1228     beacon_register_for_secure_network_beacons(&mesh_access_secure_network_beacon_handler);
1229 
1230     // register for seq number updates
1231     mesh_sequence_number_set_update_callback(&mesh_persist_iv_index_and_sequence_number_if_needed);
1232 
1233     // register for control messages
1234     mesh_upper_transport_register_control_message_handler(&mesh_control_message_handler);
1235 }
1236 
1237 /**
1238  * Register for Mesh Provisioning Device events
1239  * @param packet_handler
1240  */
1241 void mesh_register_provisioning_device_packet_handler(btstack_packet_handler_t packet_handler){
1242     provisioning_device_packet_handler = packet_handler;
1243 }
1244