From fb56b85482a9e516dfffcdc34cb20d50f09f3996 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Tue, 4 Jun 2019 11:44:15 +0200 Subject: [PATCH] mesh: re-write advertising with node identity --- test/mesh/mesh.c | 154 ++++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 76 deletions(-) diff --git a/test/mesh/mesh.c b/test/mesh/mesh.c index 97f58d81e..ebb81538b 100644 --- a/test/mesh/mesh.c +++ b/test/mesh/mesh.c @@ -63,17 +63,6 @@ #define ENABLE_MESH_PB_GATT -#define USE_ADVERTISING_WITH_NETWORK_ID -// #define USE_ADVERTISING_WITH_NODE_IDENTITY - -#if defined(USE_ADVERTISING_WITH_NETWORK_ID) && defined(USE_ADVERTISING_WITH_NODE_IDENTITY) -#error "USE_ADVERTISING_WITH_NETWORK_ID and USE_ADVERTISING_WITH_NODE_IDENTITY cannot be defined at the same time" -#endif - -#if !defined(USE_ADVERTISING_WITH_NETWORK_ID) && !defined(USE_ADVERTISING_WITH_NODE_IDENTITY) -#error "USE_ADVERTISING_WITH_NETWORK_ID or USE_ADVERTISING_WITH_NODE_IDENTITY must be defined" -#endif - #define BEACON_TYPE_SECURE_NETWORK 1 #define PTS_DEFAULT_TTL 10 @@ -96,29 +85,7 @@ static uint8_t adv_data_unprovisioned[] = { }; const uint8_t adv_data_unprovisioned_len = sizeof(adv_data_unprovisioned); -#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY -static btstack_crypto_random_t crypto_request_random; -static btstack_crypto_aes128_t crypto_request_aes128; -static uint8_t plaintext[16]; -static uint8_t hash[16]; -static uint8_t random_value[8]; -static uint8_t adv_data_with_node_identity[] = { - // Flags general discoverable, BR/EDR not supported - 0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06, - // 16-bit Service UUIDs - 0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS, ORG_BLUETOOTH_SERVICE_MESH_PROXY & 0xff, ORG_BLUETOOTH_SERVICE_MESH_PROXY >> 8, - // Service Data - 0x14, BLUETOOTH_DATA_TYPE_SERVICE_DATA, ORG_BLUETOOTH_SERVICE_MESH_PROXY & 0xff, ORG_BLUETOOTH_SERVICE_MESH_PROXY >> 8, - // MESH_IDENTIFICATION_NODE_IDENTIFY_TYPE - MESH_IDENTIFICATION_NODE_IDENTIFY_TYPE, - // Hash - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Random - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -const uint8_t adv_data_with_node_identity_len = sizeof(adv_data_with_node_identity); -#endif - +// Mesh Proxy, advertise with node id static adv_bearer_connectable_advertisement_data_item_t connectable_advertisement_item; static btstack_packet_callback_registration_t hci_event_callback_registration; @@ -154,59 +121,106 @@ static void mesh_print_hex(const char * name, const uint8_t * data, uint16_t len // } #ifdef ENABLE_MESH_PROXY_SERVER -static mesh_proxy_start_advertising_with_network_id(void){ + +// we only support a single active node id advertisement. when new one is started, an active one is stopped + +#define MESH_PROXY_NODE_ID_ADVERTISEMENT_TIMEOUT_MS 60000 + +static adv_bearer_connectable_advertisement_data_item_t mesh_proxy_node_id_advertisement_item; +static btstack_timer_source_t mesh_proxy_node_id_timer; +static btstack_crypto_random_t mesh_proxy_node_id_crypto_request_random; +static btstack_crypto_aes128_t mesh_proxy_node_id_crypto_request_aes128; +static uint8_t mesh_proxy_node_id_plaintext[16]; +static uint8_t mesh_proxy_node_id_hash[16]; +static uint8_t mesh_proxy_node_id_random_value[8]; + +static const uint8_t adv_data_with_node_identity_template[] = { + // Flags general discoverable, BR/EDR not supported + 0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06, + // 16-bit Service UUIDs + 0x03, BLUETOOTH_DATA_TYPE_COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS, ORG_BLUETOOTH_SERVICE_MESH_PROXY & 0xff, ORG_BLUETOOTH_SERVICE_MESH_PROXY >> 8, + // Service Data + 0x14, BLUETOOTH_DATA_TYPE_SERVICE_DATA, ORG_BLUETOOTH_SERVICE_MESH_PROXY & 0xff, ORG_BLUETOOTH_SERVICE_MESH_PROXY >> 8, + // MESH_IDENTIFICATION_NODE_IDENTIFY_TYPE + MESH_IDENTIFICATION_NODE_IDENTIFY_TYPE, + // Hash - 8 bytes + // Random - 8 bytes +}; + + +static void mesh_proxy_start_advertising_with_network_id(void){ mesh_network_key_iterator_t it; mesh_network_key_iterator_init(&it); while (mesh_network_key_iterator_has_more(&it)){ mesh_network_key_t * network_key = mesh_network_key_iterator_get_next(&it); + log_info("Proxy start advertising with network id, netkey index %04x", network_key->netkey_index); adv_bearer_advertisements_add_item(&network_key->advertisement_with_network_id); } } -static mesh_proxy_stop_advertising_with_network_id(void){ +static void mesh_proxy_stop_advertising_with_network_id(void){ mesh_network_key_iterator_t it; mesh_network_key_iterator_init(&it); while (mesh_network_key_iterator_has_more(&it)){ mesh_network_key_t * network_key = mesh_network_key_iterator_get_next(&it); + log_info("Proxy stop advertising with network id, netkey index %04x", network_key->netkey_index); adv_bearer_advertisements_remove_item(&network_key->advertisement_with_network_id); } } -#endif -#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY -static void mesh_proxy_handle_get_aes128(void * arg){ +static void mesh_proxy_stop_all_advertising_with_node_id(void){ + mesh_network_key_iterator_t it; + mesh_network_key_iterator_init(&it); + while (mesh_network_key_iterator_has_more(&it)){ + mesh_network_key_t * network_key = mesh_network_key_iterator_get_next(&it); + if (network_key->node_id_advertisement_running != 0){ + adv_bearer_advertisements_remove_item(&network_key->advertisement_with_network_id); + btstack_run_loop_remove_timer(&mesh_proxy_node_id_timer); + network_key->node_id_advertisement_running = 0; + } + } +} + +static void mesh_proxy_node_id_timeout_handler(btstack_timer_source_t * ts){ + UNUSED(ts); + mesh_proxy_stop_all_advertising_with_node_id(); +} + +static void mesh_proxy_node_id_handle_get_aes128(void * arg){ UNUSED(arg); - memcpy(&adv_data_with_node_identity[12], &hash[8], 8); - memcpy(&adv_data_with_node_identity[20], random_value, 8); - printf("Calculated Hash\n"); - printf_hexdump(hash, sizeof(hash)); + memcpy(connectable_advertisement_item.adv_data, adv_data_with_node_identity_template, 12); + memcpy(&connectable_advertisement_item.adv_data[12], &mesh_proxy_node_id_hash[8], 8); + memcpy(&connectable_advertisement_item.adv_data[20], mesh_proxy_node_id_random_value, 8); - printf("\nUSE_ADVERTISING_WITH_NODE_IDENTITY:\n"); - printf_hexdump(adv_data_with_node_identity, sizeof(adv_data_with_node_identity)); - - // store in advertisement item - memset(connectable_advertisement_item, 0, sizeof(connectable_advertisement_item)); - connectable_advertisement_item.adv_length = adv_data_with_node_identity_len; - memcpy(connectable_advertisement_item.adv_data, (uint8_t*) adv_data_with_node_identity, adv_data_with_node_identity_len); - // setup advertisements adv_bearer_advertisements_add_item(&connectable_advertisement_item); adv_bearer_advertisements_enable(1); + + // set timer + btstack_run_loop_set_timer_handler(&mesh_proxy_node_id_timer, mesh_proxy_node_id_timeout_handler); + btstack_run_loop_set_timer(&mesh_proxy_node_id_timer, MESH_PROXY_NODE_ID_ADVERTISEMENT_TIMEOUT_MS); + btstack_run_loop_add_timer(&mesh_proxy_node_id_timer); } -static void setup_advertising_with_node_identity(void){ +static void mesh_proxy_node_id_handle_random(void * arg){ // Hash = e(IdentityKey, Padding | Random | Address) mod 2^64 - memset(plaintext, 0, sizeof(plaintext)); - memcpy(&plaintext[6] , random_value, 8); - big_endian_store_16(plaintext, 14, primary_element_address); - btstack_crypto_aes128_encrypt(&crypto_request_aes128,identity_key, plaintext, hash, mesh_proxy_handle_get_aes128, NULL); + memset(mesh_proxy_node_id_plaintext, 0, sizeof(mesh_proxy_node_id_plaintext)); + memcpy(&mesh_proxy_node_id_plaintext[6] , mesh_proxy_node_id_random_value, 8); + big_endian_store_16(mesh_proxy_node_id_plaintext, 14, primary_element_address); + btstack_crypto_aes128_encrypt(&mesh_proxy_node_id_crypto_request_aes128,identity_key, mesh_proxy_node_id_plaintext, mesh_proxy_node_id_hash, mesh_proxy_node_id_handle_get_aes128, NULL); } -static void mesh_proxy_handle_get_random(void * arg){ - UNUSED(arg); - printf("Received random value\n"); - printf_hexdump(random_value, sizeof(random_value)); - setup_advertising_with_node_identity(); +static void mesh_proxy_start_advertising_with_node_id(uint16_t netkey_index){ + mesh_proxy_stop_all_advertising_with_node_id(); + log_info("Proxy start advertising with node id, netkey index %04x", netkey_index); + // setup node id + btstack_crypto_random_generate(&mesh_proxy_node_id_crypto_request_random, mesh_proxy_node_id_random_value, sizeof(mesh_proxy_node_id_random_value), mesh_proxy_node_id_handle_random, NULL); +} + +static void mesh_proxy_stop_advertising_with_node_id(uint16_t netkey_index){ + UNUSED(netkey_index); + log_info("Proxy stop advertising with node id, netkey index %04x", netkey_index); + mesh_proxy_stop_all_advertising_with_node_id(); } #endif @@ -284,15 +298,9 @@ static void mesh_setup_from_provisioning_data(const mesh_provisioning_data_t * p // Mesh Proxy #ifdef ENABLE_MESH_PROXY_SERVER -#ifdef USE_ADVERTISING_WITH_NETWORK_ID printf("Advertise Mesh Proxy Service with Network ID\n"); mesh_proxy_start_advertising_with_network_id(); #endif -#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY - printf("Advertise Mesh Proxy Service with Node Identity\n"); - btstack_crypto_random_generate(&crypto_request_random, random_value, sizeof(random_value), mesh_proxy_handle_get_random, NULL); -#endif -#endif } #ifdef ENABLE_MESH_PB_GATT @@ -439,14 +447,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack setup_advertising_unprovisioned(); } else { #ifdef ENABLE_MESH_PROXY_SERVER -#ifdef USE_ADVERTISING_WITH_NETWORK_ID printf("Advertise Mesh Proxy Service with Network ID\n"); mesh_proxy_start_advertising_with_network_id(); -#endif -#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY - printf("Advertise Mesh Proxy Service with Node Identity\n"); - btstack_crypto_random_generate(&crypto_request_random, random_value, sizeof(random_value), mesh_proxy_handle_get_random, NULL); -#endif #endif } break; @@ -507,11 +509,11 @@ static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t cha // store in TLV btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, 'PROV', (uint8_t *) &provisioning_data, sizeof(mesh_provisioning_data_t)); - // stop adv using adv data - adv_bearer_advertisements_remove_item(&connectable_advertisement_item); - // setup after provisioned mesh_setup_from_provisioning_data(&provisioning_data); + + // start advertising with node id after provisioning + mesh_proxy_start_advertising_with_node_id(network_key->netkey_index); break; default: break;