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