mesh: allow to provide list of connectable advertisements in adv_bearer

This commit is contained in:
Matthias Ringwald 2019-06-03 15:37:51 +02:00
parent 7535d2caf6
commit 94a4ac9a13
3 changed files with 82 additions and 43 deletions

View File

@ -103,8 +103,6 @@ static uint8_t adv_bearer_count;
static uint16_t adv_bearer_interval;
// gap advertising
static uint8_t gap_advertising_data_length;
static uint8_t * gap_advertising_data;
static int gap_advertising_enabled;
static uint16_t gap_adv_int_min = 0x30;
static uint16_t gap_adv_int_ms;
@ -115,6 +113,8 @@ static bd_addr_t gap_direct_address;
static uint8_t gap_channel_map = 0x07;
static uint8_t gap_filter_policy = 0;
static btstack_linked_list_t gap_connectable_advertisements;
// dispatch advertising events
static void adv_bearer_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
const uint8_t * data;
@ -240,13 +240,18 @@ static void adv_bearer_run(void){
case STATE_IDLE:
if (gap_advertising_enabled){
if ((int32_t)(now - gap_adv_next_ms) >= 0){
// time to advertise again
log_debug("Start GAP ADV");
gap_advertisements_set_params(ADVERTISING_INTERVAL_CONNECTABLE_MIN, ADVERTISING_INTERVAL_CONNECTABLE_MIN, gap_adv_type, gap_direct_address_typ, gap_direct_address, gap_channel_map, gap_filter_policy);
gap_advertisements_set_data(gap_advertising_data_length, gap_advertising_data);
gap_advertisements_enable(1);
adv_bearer_set_timeout(ADVERTISING_INTERVAL_CONNECTABLE_MIN_MS);
adv_bearer_state = STATE_GAP;
adv_bearer_connectable_advertisement_data_item_t * item = (adv_bearer_connectable_advertisement_data_item_t *) btstack_linked_list_pop(&gap_connectable_advertisements);
if (item != NULL){
// queue again
btstack_linked_list_add_tail(&gap_connectable_advertisements, (void*) item);
// time to advertise again
log_debug("Start GAP ADV, %p", item);
gap_advertisements_set_params(ADVERTISING_INTERVAL_CONNECTABLE_MIN, ADVERTISING_INTERVAL_CONNECTABLE_MIN, gap_adv_type, gap_direct_address_typ, gap_direct_address, gap_channel_map, gap_filter_policy);
gap_advertisements_set_data(item->adv_length, item->adv_data);
gap_advertisements_enable(1);
adv_bearer_set_timeout(ADVERTISING_INTERVAL_CONNECTABLE_MIN_MS);
adv_bearer_state = STATE_GAP;
}
break;
}
}
@ -353,9 +358,12 @@ void adv_bearer_advertisements_enable(int enabled){
adv_bearer_run();
}
void adv_bearer_advertisements_set_data(uint8_t advertising_data_length, uint8_t * advertising_data){
gap_advertising_data_length = advertising_data_length;
gap_advertising_data = advertising_data;
void adv_bearer_advertisements_add_item(adv_bearer_connectable_advertisement_data_item_t * item){
btstack_linked_list_add(&gap_connectable_advertisements, (void*) item);
}
void adv_bearer_advertisements_remove_item(adv_bearer_connectable_advertisement_data_item_t * item){
btstack_linked_list_remove(&gap_connectable_advertisements, (void*) item);
}
void adv_bearer_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type,

View File

@ -47,6 +47,12 @@
extern "C" {
#endif
typedef struct {
void * next;
uint8_t adv_length;
uint8_t adv_data[31];
} adv_bearer_connectable_advertisement_data_item_t;
/**
* Initialize Advertising Bearer
*/
@ -58,14 +64,20 @@ void adv_bearer_init(void);
// Advertisements are interleaved with ADV Bearer Messages
/**
* Set Advertisement Data
*
* @param advertising_data_length
* @param advertising_data (max 31 octets)
* @note data is not copied, pointer has to stay valid
* Add Connectable Advertisement Data Item
* @param item
* @note item is not copied, pointer has to stay valid
* @note '00:00:00:00:00:00' in advertising_data will be replaced with actual bd addr
*/
void adv_bearer_advertisements_set_data(uint8_t advertising_data_length, uint8_t * advertising_data);
void adv_bearer_advertisements_add_item(adv_bearer_connectable_advertisement_data_item_t * item);
/**
* Remove Connectable Advertisement Data Item
* @param item
* @note item is not copied, pointer has to stay valid
* @note '00:00:00:00:00:00' in advertising_data will be replaced with actual bd addr
*/
void adv_bearer_advertisements_remove_item(adv_bearer_connectable_advertisement_data_item_t * item);
/**
* @brief Set Advertisement Paramters

View File

@ -82,7 +82,7 @@ static void show_usage(void);
const static uint8_t device_uuid[] = { 0x00, 0x1B, 0xDC, 0x08, 0x10, 0x21, 0x0B, 0x0E, 0x0A, 0x0C, 0x00, 0x0B, 0x0E, 0x0A, 0x0C, 0x00 };
// Mesh Provisioning
static uint8_t adv_data[] = {
static uint8_t adv_data_unprovisioned[] = {
// Flags general discoverable, BR/EDR not supported
0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06,
// 16-bit Service UUIDs
@ -94,6 +94,7 @@ static uint8_t adv_data[] = {
// OOB information
0x00, 0x00
};
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;
@ -134,8 +135,7 @@ static uint8_t adv_data_with_network_id[] = {
const uint8_t adv_data_with_network_id_len = sizeof(adv_data_with_network_id);
#endif
const uint8_t adv_data_len = sizeof(adv_data);
static adv_bearer_connectable_advertisement_data_item_t connectable_advertisement_item;
static btstack_packet_callback_registration_t hci_event_callback_registration;
@ -179,6 +179,12 @@ static void mesh_proxy_handle_get_aes128(void * arg){
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
bd_addr_t null_addr;
memset(null_addr, 0, 6);
@ -186,7 +192,7 @@ static void mesh_proxy_handle_get_aes128(void * arg){
uint16_t adv_int_min = 0x0030;
uint16_t adv_int_max = 0x0030;
adv_bearer_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00);
adv_bearer_advertisements_set_data(adv_data_with_node_identity_len, (uint8_t*) adv_data_with_node_identity);
adv_bearer_advertisements_add_item(&connectable_advertisement_item);
adv_bearer_advertisements_enable(1);
}
@ -208,16 +214,16 @@ static void mesh_proxy_handle_get_random(void * arg){
#ifdef USE_ADVERTISING_WITH_NETWORK_ID
static void setup_advertising_with_network_id(const mesh_provisioning_data_t * prov_data){
static void setup_advertising_with_network_id(void){
// dynamically store network ID into adv data
memcpy(&adv_data_with_network_id[12], prov_data->network_id, sizeof(prov_data->network_id));
// copy beacon key and network id
memcpy(beacon_key, prov_data->beacon_key, 16);
memcpy(network_id, prov_data->network_id, 8);
printf_hexdump(prov_data->network_id, 8);
mesh_flags = prov_data->flags;
memcpy(&adv_data_with_network_id[12], network_id, sizeof(network_id));
// store in advertisement item
memset(&connectable_advertisement_item, 0, sizeof(connectable_advertisement_item));
connectable_advertisement_item.adv_length = adv_data_with_network_id_len;
memcpy(connectable_advertisement_item.adv_data, (uint8_t*) adv_data_with_network_id, adv_data_with_network_id_len);
// setup advertisements
bd_addr_t null_addr;
memset(null_addr, 0, 6);
@ -225,7 +231,7 @@ static void setup_advertising_with_network_id(const mesh_provisioning_data_t * p
uint16_t adv_int_min = 0x0030;
uint16_t adv_int_max = 0x0030;
adv_bearer_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00);
adv_bearer_advertisements_set_data(adv_data_with_network_id_len, (uint8_t*) adv_data_with_network_id);
adv_bearer_advertisements_add_item(&connectable_advertisement_item);
adv_bearer_advertisements_enable(1);
}
#endif
@ -264,11 +270,11 @@ static void mesh_setup_from_provisioning_data(const mesh_provisioning_data_t * p
mesh_flags = provisioning_data->flags;
// dump data
mesh_provisioning_dump(provisioning_data);
// Mesh Proxy
#ifdef USE_ADVERTISING_WITH_NETWORK_ID
printf("Advertise Mesh Proxy Service with Network ID\n");
setup_advertising_with_network_id(provisioning_data);
setup_advertising_with_network_id();
#endif
#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY
printf("Advertise Mesh Proxy Service with Node Identity\n");
@ -280,7 +286,11 @@ static void mesh_setup_from_provisioning_data(const mesh_provisioning_data_t * p
static void setup_advertising_unprovisioned(void) {
printf("Advertise Mesh Provisioning Service\n");
// dynamically store device uuid into adv data
memcpy(&adv_data[11], device_uuid, sizeof(device_uuid));
memcpy(&adv_data_unprovisioned[11], device_uuid, sizeof(device_uuid));
// store in advertisement item
memset(&connectable_advertisement_item, 0, sizeof(connectable_advertisement_item));
connectable_advertisement_item.adv_length = adv_data_unprovisioned_len;
memcpy(connectable_advertisement_item.adv_data, (uint8_t*) adv_data_unprovisioned, adv_data_unprovisioned_len);
// setup advertisements
uint8_t adv_type = 0; // ADV_IND
@ -289,7 +299,7 @@ static void setup_advertising_unprovisioned(void) {
bd_addr_t null_addr;
memset(null_addr, 0, 6);
adv_bearer_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00);
adv_bearer_advertisements_set_data(adv_data_len, (uint8_t*) adv_data);
adv_bearer_advertisements_add_item(&connectable_advertisement_item);
adv_bearer_advertisements_enable(1);
}
#endif
@ -420,19 +430,23 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
// enable PB_GATT
if (provisioned == 0){
setup_advertising_unprovisioned();
} else {
#ifdef USE_ADVERTISING_WITH_NETWORK_ID
printf("Advertise Mesh Proxy Service with Network ID\n");
setup_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
}
break;
case HCI_EVENT_LE_META:
if (hci_event_le_meta_get_subevent_code(packet) != HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
// disable PB_GATT
if (provisioned){
printf("Connected, disabling GATT Proxy advertising\n");
adv_bearer_advertisements_enable(0);
} else {
printf("Connected, disabling PB_GATT advertising\n");
adv_bearer_advertisements_enable(0);
}
printf("Connected, stop advertising gatt service\n");
adv_bearer_advertisements_remove_item(&connectable_advertisement_item);
break;
default:
break;
@ -483,6 +497,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);
break;
default: