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