xref: /btstack/src/mesh/beacon.c (revision 046b44372d25c7bd6fe78e5cf6e5176a1979f437)
1 /*
2  * Copyright (C) 2017 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__ "beacon.c"
39 
40 #include "mesh/beacon.h"
41 
42 #include <string.h>
43 
44 #include "ble/core.h"
45 #include "bluetooth.h"
46 #include "bluetooth_data_types.h"
47 #include "btstack_debug.h"
48 #include "btstack_event.h"
49 #include "btstack_run_loop.h"
50 #include "btstack_util.h"
51 #include "gap.h"
52 
53 #include "mesh/adv_bearer.h"
54 #include "mesh/gatt_bearer.h"
55 #include "mesh/mesh_foundation.h"
56 #include "mesh/mesh_iv_index_seq_number.h"
57 #include "mesh/mesh_keys.h"
58 
59 #define BEACON_TYPE_UNPROVISIONED_DEVICE 0
60 #define BEACON_TYPE_SECURE_NETWORK 1
61 
62 #define UNPROVISIONED_BEACON_INTERVAL_MS 5000
63 #define UNPROVISIONED_BEACON_LEN      23
64 
65 #define SECURE_NETWORK_BEACON_INTERVAL_MIN_MS  10000
66 #define SECURE_NETWORK_BEACON_INTERVAL_MAX_MS 600000
67 #define SECURE_NETWORK_BEACON_LEN                 22
68 
69 // prototypes
70 static void mesh_secure_network_beacon_run(btstack_timer_source_t * ts);
71 
72 // bearers
73 #ifdef ENABLE_MESH_GATT_BEARER
74 static hci_con_handle_t gatt_bearer_con_handle;
75 #endif
76 
77 // beacon
78 static uint8_t mesh_beacon_data[29];
79 static uint8_t mesh_beacon_len;
80 static btstack_timer_source_t   beacon_timer;
81 
82 // unprovisioned device beacon
83 #ifdef ENABLE_MESH_ADV_BEARER
84 static const uint8_t * beacon_device_uuid;
85 static       uint16_t  beacon_oob_information;
86 static       uint32_t  beacon_uri_hash;
87 static int             beacon_send_device_beacon;
88 #endif
89 
90 static btstack_packet_handler_t unprovisioned_device_beacon_handler;
91 
92 // secure network beacon
93 static btstack_crypto_aes128_cmac_t        mesh_secure_network_beacon_cmac_request;
94 static uint8_t                             mesh_secure_network_beacon_auth_value[16];
95 static btstack_packet_handler_t            mesh_secure_network_beacon_handler;
96 static int                                 mesh_secure_network_beacon_active;
97 #ifdef ENABLE_MESH_ADV_BEARER
98 static uint8_t                             mesh_secure_network_beacon_validate_buffer[SECURE_NETWORK_BEACON_LEN];
99 #endif
100 
101 #ifdef ENABLE_MESH_ADV_BEARER
102 static void beacon_timer_handler(btstack_timer_source_t * ts){
103     // restart timer
104     btstack_run_loop_set_timer(ts, UNPROVISIONED_BEACON_INTERVAL_MS);
105     btstack_run_loop_add_timer(ts);
106 
107     // setup beacon
108     mesh_beacon_len = UNPROVISIONED_BEACON_LEN;
109     mesh_beacon_data[0] = BEACON_TYPE_UNPROVISIONED_DEVICE;
110     memcpy(&mesh_beacon_data[1], beacon_device_uuid, 16);
111     big_endian_store_16(mesh_beacon_data, 17, beacon_oob_information);
112     big_endian_store_32(mesh_beacon_data, 19, beacon_uri_hash);
113 
114     // request to send
115     beacon_send_device_beacon = 1;
116     adv_bearer_request_can_send_now_for_beacon();
117 }
118 #endif
119 
120 static void mesh_secure_network_beacon_auth_value_calculated(void * arg){
121     mesh_subnet_t * mesh_subnet = (mesh_subnet_t *) arg;
122 
123     memcpy(&mesh_beacon_data[14], mesh_secure_network_beacon_auth_value, 8);
124     mesh_beacon_len = SECURE_NETWORK_BEACON_LEN;
125 
126     printf("Secure Network Beacon\n");
127     printf("- ");
128     printf_hexdump(mesh_beacon_data, mesh_beacon_len);
129 
130     mesh_secure_network_beacon_active = 0;
131     mesh_subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_AUTH_VALUE;
132 
133     mesh_secure_network_beacon_run(NULL);
134 }
135 
136 static uint8_t mesh_secure_network_beacon_get_flags(mesh_subnet_t * mesh_subnet){
137     uint8_t mesh_flags = 0;
138     if (mesh_subnet->key_refresh != MESH_KEY_REFRESH_NOT_ACTIVE){
139         mesh_flags |= 1;
140     }
141     if (mesh_iv_update_active()){
142         mesh_flags |= 2;
143     }
144 
145     return mesh_flags;
146 }
147 
148 static void mesh_secure_network_beacon_setup(mesh_subnet_t * mesh_subnet){
149     mesh_beacon_data[0] = BEACON_TYPE_SECURE_NETWORK;
150     mesh_beacon_data[1] = mesh_secure_network_beacon_get_flags(mesh_subnet);
151     // TODO: pick correct key based on key refresh phase
152 
153     memcpy(&mesh_beacon_data[2], mesh_subnet->old_key->network_id, 8);
154     big_endian_store_32(mesh_beacon_data, 10, mesh_get_iv_index());
155     mesh_network_key_t * network_key = mesh_subnet_get_outgoing_network_key(mesh_subnet);
156     btstack_crypto_aes128_cmac_message(&mesh_secure_network_beacon_cmac_request, network_key->beacon_key, 13,
157         &mesh_beacon_data[1], mesh_secure_network_beacon_auth_value, &mesh_secure_network_beacon_auth_value_calculated, mesh_subnet);
158 }
159 
160 static void mesh_secure_network_beacon_update_interval(mesh_subnet_t * subnet){
161     uint32_t min_observation_period_ms = 2 * subnet->beacon_interval_ms;
162     uint32_t actual_observation_period = btstack_time_delta(btstack_run_loop_get_time_ms(), subnet->beacon_observation_start_ms);
163 
164     // The Observation Period in seconds should typically be double the typical Beacon Interval.
165     if (actual_observation_period < min_observation_period_ms) return;
166 
167     // Expected Number of Beacons (1 beacon per 10 seconds)
168     uint16_t expected_number_of_beacons = actual_observation_period / SECURE_NETWORK_BEACON_INTERVAL_MIN_MS;
169 
170     // Beacon Interval = Observation Period * (Observed Number of Beacons + 1) / Expected Number of Beacons
171     uint32_t new_beacon_interval  =  actual_observation_period * (subnet->beacon_observation_counter + 1) / expected_number_of_beacons;
172 
173     if (new_beacon_interval > SECURE_NETWORK_BEACON_INTERVAL_MAX_MS){
174         new_beacon_interval = SECURE_NETWORK_BEACON_INTERVAL_MAX_MS;
175     }
176     else if (new_beacon_interval < SECURE_NETWORK_BEACON_INTERVAL_MIN_MS){
177         new_beacon_interval = SECURE_NETWORK_BEACON_INTERVAL_MAX_MS;
178     }
179     subnet->beacon_interval_ms = new_beacon_interval;
180     log_info("New beacon interval %u seconds", (int) (subnet->beacon_interval_ms / 1000));
181 }
182 
183 static void mesh_secure_network_beacon_run(btstack_timer_source_t * ts){
184     UNUSED(ts);
185 
186     uint32_t next_timeout_ms = 0;
187 
188     // iterate over all networks
189     mesh_subnet_iterator_t it;
190     mesh_subnet_iterator_init(&it);
191     while (mesh_subnet_iterator_has_more(&it)){
192         mesh_subnet_t * subnet = mesh_subnet_iterator_get_next(&it);
193         switch (subnet->beacon_state){
194             case MESH_SECURE_NETWORK_BEACON_W4_INTERVAL:
195                 // update beacon interval
196                 mesh_secure_network_beacon_update_interval(subnet);
197 
198                 if (mesh_foundation_beacon_get() == 0){
199                     // beacon off, continue observing
200                     if (next_timeout_ms == 0 || next_timeout_ms > subnet->beacon_interval_ms){
201                         next_timeout_ms = subnet->beacon_interval_ms;
202                     }
203                     break;
204                 }
205 
206                 // send new beacon
207                 subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_W2_AUTH_VALUE;
208 
209                 /** Explict Fall-through */
210 
211             case MESH_SECURE_NETWORK_BEACON_W2_AUTH_VALUE:
212                 if (mesh_secure_network_beacon_active){
213                     // just try again in 10 ms
214                     next_timeout_ms = 10;
215                     break;
216                 }
217                 subnet->beacon_state  = MESH_SECURE_NETWORK_BEACON_W4_AUTH_VALUE;
218                 mesh_secure_network_beacon_active = 1;
219                 mesh_secure_network_beacon_setup(subnet);
220                 break;
221 
222             case MESH_SECURE_NETWORK_BEACON_AUTH_VALUE:
223 
224 #ifdef ENABLE_MESH_ADV_BEARER
225                 subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_W2_SEND_ADV;
226                 adv_bearer_request_can_send_now_for_beacon();
227                 break;
228 #endif
229                 subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_ADV_SENT;
230 
231                 /** Explict Fall-through */
232 
233             case MESH_SECURE_NETWORK_BEACON_ADV_SENT:
234 
235 #ifdef ENABLE_MESH_GATT_BEARER
236                 if (gatt_bearer_con_handle != HCI_CON_HANDLE_INVALID && mesh_foundation_gatt_proxy_get() != 0){
237                     subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_W2_SEND_GATT;
238                     gatt_bearer_request_can_send_now_for_beacon();
239                     break;
240                 }
241 #endif
242                 subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_GATT_SENT;
243 
244                 /** Explict Fall-through */
245 
246             case MESH_SECURE_NETWORK_BEACON_GATT_SENT:
247                 // now, start listening for beacons
248                 subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_W4_INTERVAL;
249                 // and request timeout
250                 if (next_timeout_ms == 0 || next_timeout_ms > subnet->beacon_interval_ms){
251                     next_timeout_ms = subnet->beacon_interval_ms;
252                 }
253                 break;
254 
255             default:
256                 break;
257         }
258     }
259 
260     // setup next run
261     if (next_timeout_ms == 0) return;
262 
263     btstack_run_loop_set_timer(&beacon_timer, next_timeout_ms);
264     btstack_run_loop_set_timer_handler(&beacon_timer, mesh_secure_network_beacon_run);
265     btstack_run_loop_add_timer(&beacon_timer);
266 }
267 
268 #ifdef ENABLE_MESH_ADV_BEARER
269 static void beacon_handle_secure_beacon_auth_value_calculated(void * arg){
270     UNUSED(arg);
271 
272     // pass on, if auth value checks out
273     if (memcmp(&mesh_secure_network_beacon_validate_buffer[14], mesh_secure_network_beacon_auth_value, 8) == 0) {
274         if (mesh_secure_network_beacon_handler){
275             (*mesh_secure_network_beacon_handler)(MESH_BEACON_PACKET, 0, mesh_secure_network_beacon_validate_buffer, SECURE_NETWORK_BEACON_LEN);
276         }
277     }
278 
279     // done
280     mesh_secure_network_beacon_active = 0;
281     mesh_secure_network_beacon_run(NULL);
282 }
283 
284 static void beacon_handle_secure_beacon(uint8_t * packet, uint16_t size){
285     if (size != SECURE_NETWORK_BEACON_LEN) return;
286 
287     // lookup subnet and netkey by network id
288     uint8_t * beacon_network_id = &packet[2];
289     mesh_subnet_iterator_t it;
290     mesh_subnet_iterator_init(&it);
291     mesh_subnet_t * subnet = NULL;
292     mesh_network_key_t * network_key = NULL;
293     while (mesh_subnet_iterator_has_more(&it)){
294         mesh_subnet_t * item = mesh_subnet_iterator_get_next(&it);
295         if (memcmp(item->old_key->network_id, beacon_network_id, 8) == 0 ) {
296             subnet = item;
297             network_key = item->old_key;
298         }
299         if (item->new_key != NULL && memcmp(item->new_key->network_id, beacon_network_id, 8) == 0 ) {
300             subnet = item;
301             network_key = item->new_key;
302         }
303         break;
304     }
305     if (subnet == NULL) return;
306 
307     // count beacon
308     subnet->beacon_observation_counter++;
309 
310     // check if new flags are set
311     uint8_t current_flags = mesh_secure_network_beacon_get_flags(subnet);
312     uint8_t new_flags = packet[1] & (~current_flags);
313 
314     if (new_flags == 0) return;
315 
316     // validate beacon - if crytpo ready
317     if (mesh_secure_network_beacon_active) return;
318 
319     mesh_secure_network_beacon_active = 1;
320     memcpy(mesh_secure_network_beacon_validate_buffer, &packet[0], SECURE_NETWORK_BEACON_LEN);
321 
322     btstack_crypto_aes128_cmac_message(&mesh_secure_network_beacon_cmac_request, network_key->beacon_key, 13,
323         &mesh_secure_network_beacon_validate_buffer[1], mesh_secure_network_beacon_auth_value, &beacon_handle_secure_beacon_auth_value_calculated, subnet);
324 }
325 
326 static void beacon_handle_beacon_packet(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
327     log_info("beacon type %u", packet[0]);
328     switch (packet[0]){
329         case BEACON_TYPE_UNPROVISIONED_DEVICE:
330             if (unprovisioned_device_beacon_handler){
331                 (*unprovisioned_device_beacon_handler)(packet_type, channel, packet, size);
332             }
333             break;
334         case BEACON_TYPE_SECURE_NETWORK:
335             beacon_handle_secure_beacon(packet, size);
336             break;
337         default:
338             break;
339     }
340 }
341 
342 static void beacon_adv_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
343     mesh_subnet_iterator_t it;
344     switch (packet_type){
345         case HCI_EVENT_PACKET:
346             switch(packet[0]){
347                 case HCI_EVENT_MESH_META:
348                     switch(packet[2]){
349                         case MESH_SUBEVENT_CAN_SEND_NOW:
350                             if (beacon_send_device_beacon){
351                                 beacon_send_device_beacon = 0;
352                                 adv_bearer_send_beacon(mesh_beacon_data, mesh_beacon_len);
353                                 break;
354                             }
355                             // secure beacon state machine
356                             mesh_subnet_iterator_init(&it);
357                             while (mesh_subnet_iterator_has_more(&it)){
358                                 mesh_subnet_t * subnet = mesh_subnet_iterator_get_next(&it);
359                                 switch (subnet->beacon_state){
360                                     case MESH_SECURE_NETWORK_BEACON_W2_SEND_ADV:
361                                         adv_bearer_send_beacon(mesh_beacon_data, mesh_beacon_len);
362                                         subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_ADV_SENT;
363                                         mesh_secure_network_beacon_run(NULL);
364                                         break;
365                                     default:
366                                         break;
367                                 }
368                             }
369                             break;
370                         default:
371                             break;
372                     }
373                     break;
374                 default:
375                     break;
376             }
377             break;
378         case MESH_BEACON_PACKET:
379             beacon_handle_beacon_packet(packet_type, channel, packet, size);
380             break;
381         default:
382             break;
383     }
384 }
385 #endif
386 
387 #ifdef ENABLE_MESH_GATT_BEARER
388 // handle MESH_SUBEVENT_PROXY_DISCONNECTED and MESH_SUBEVENT_CAN_SEND_NOW
389 static void beacon_gatt_handle_mesh_event(uint8_t mesh_subevent){
390     mesh_subnet_iterator_t it;
391     mesh_subnet_iterator_init(&it);
392     while (mesh_subnet_iterator_has_more(&it)){
393         mesh_subnet_t * subnet = mesh_subnet_iterator_get_next(&it);
394         switch (subnet->beacon_state){
395             case MESH_SECURE_NETWORK_BEACON_W2_SEND_GATT:
396                 // skip send on MESH_SUBEVENT_PROXY_DISCONNECTED
397                 if (mesh_subevent == MESH_SUBEVENT_CAN_SEND_NOW){
398                     gatt_bearer_send_beacon(mesh_beacon_data, mesh_beacon_len);
399                 }
400                 subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_GATT_SENT;
401                 mesh_secure_network_beacon_run(NULL);
402                 break;
403             default:
404                 break;
405         }
406     }
407 
408 }
409 
410 static void beacon_gatt_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
411     uint8_t mesh_subevent;
412     switch (packet_type){
413         case HCI_EVENT_PACKET:
414             switch(packet[0]){
415                 case HCI_EVENT_MESH_META:
416                     mesh_subevent = packet[2];
417                     switch(mesh_subevent){
418                         case MESH_SUBEVENT_PROXY_CONNECTED:
419                             gatt_bearer_con_handle = mesh_subevent_proxy_connected_get_con_handle(packet);
420                             break;
421                         case MESH_SUBEVENT_PROXY_DISCONNECTED:
422                             gatt_bearer_con_handle = HCI_CON_HANDLE_INVALID;
423                             beacon_gatt_handle_mesh_event(mesh_subevent);
424                             break;
425                         case MESH_SUBEVENT_CAN_SEND_NOW:
426                             beacon_gatt_handle_mesh_event(mesh_subevent);
427                             break;
428                         default:
429                             break;
430                     }
431                     break;
432                 default:
433                     break;
434             }
435             break;
436         case MESH_BEACON_PACKET:
437             beacon_handle_beacon_packet(packet_type, channel, packet, size);
438             break;
439         default:
440             break;
441     }
442 }
443 #endif
444 
445 void beacon_init(void){
446 #ifdef ENABLE_MESH_ADV_BEARER
447     adv_bearer_register_for_beacon(&beacon_adv_packet_handler);
448 #endif
449 #ifdef ENABLE_MESH_GATT_BEARER
450     gatt_bearer_con_handle = HCI_CON_HANDLE_INVALID;
451     gatt_bearer_register_for_beacon(&beacon_gatt_packet_handler);
452 #endif
453 }
454 
455 /**
456  * Start Unprovisioned Device Beacon
457  */
458 void beacon_unprovisioned_device_start(const uint8_t * device_uuid, uint16_t oob_information){
459 #ifdef ENABLE_MESH_ADV_BEARER
460     beacon_oob_information = oob_information;
461     if (device_uuid){
462         beacon_device_uuid = device_uuid;
463         beacon_timer.process = &beacon_timer_handler;
464         beacon_timer_handler(&beacon_timer);
465     }
466 #endif
467 }
468 
469 /**
470  * Stop Unprovisioned Device Beacon
471  */
472 void beacon_unprovisioned_device_stop(void){
473 #ifdef ENABLE_MESH_ADV_BEARER
474     btstack_run_loop_remove_timer(&beacon_timer);
475 #endif
476 }
477 
478 // secure network beacons
479 
480 void beacon_secure_network_start(mesh_subnet_t * mesh_subnet){
481     // default interval
482     mesh_subnet->beacon_interval_ms = SECURE_NETWORK_BEACON_INTERVAL_MIN_MS;
483     mesh_subnet->beacon_observation_start_ms = btstack_run_loop_get_time_ms();
484     mesh_subnet->beacon_observation_counter = 0;
485     if (mesh_foundation_beacon_get()){
486         mesh_subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_W2_AUTH_VALUE;
487     } else {
488         mesh_subnet->beacon_state = MESH_SECURE_NETWORK_BEACON_GATT_SENT;
489     }
490 
491     // start sending
492     mesh_secure_network_beacon_run(NULL);
493 }
494 
495 // register handler
496 void beacon_register_for_unprovisioned_device_beacons(btstack_packet_handler_t packet_handler){
497     unprovisioned_device_beacon_handler = packet_handler;
498 }
499 
500 void beacon_register_for_secure_network_beacons(btstack_packet_handler_t packet_handler){
501     mesh_secure_network_beacon_handler = packet_handler;
502 }
503