mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-09 21:45:54 +00:00
mesh: allow to provide list of connectable advertisements in adv_bearer
This commit is contained in:
parent
7535d2caf6
commit
94a4ac9a13
@ -103,8 +103,6 @@ static uint8_t adv_bearer_count;
|
|||||||
static uint16_t adv_bearer_interval;
|
static uint16_t adv_bearer_interval;
|
||||||
|
|
||||||
// gap advertising
|
// gap advertising
|
||||||
static uint8_t gap_advertising_data_length;
|
|
||||||
static uint8_t * gap_advertising_data;
|
|
||||||
static int gap_advertising_enabled;
|
static int gap_advertising_enabled;
|
||||||
static uint16_t gap_adv_int_min = 0x30;
|
static uint16_t gap_adv_int_min = 0x30;
|
||||||
static uint16_t gap_adv_int_ms;
|
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_channel_map = 0x07;
|
||||||
static uint8_t gap_filter_policy = 0;
|
static uint8_t gap_filter_policy = 0;
|
||||||
|
|
||||||
|
static btstack_linked_list_t gap_connectable_advertisements;
|
||||||
|
|
||||||
// dispatch advertising events
|
// dispatch advertising events
|
||||||
static void adv_bearer_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
static void adv_bearer_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||||
const uint8_t * data;
|
const uint8_t * data;
|
||||||
@ -240,13 +240,18 @@ static void adv_bearer_run(void){
|
|||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
if (gap_advertising_enabled){
|
if (gap_advertising_enabled){
|
||||||
if ((int32_t)(now - gap_adv_next_ms) >= 0){
|
if ((int32_t)(now - gap_adv_next_ms) >= 0){
|
||||||
// time to advertise again
|
adv_bearer_connectable_advertisement_data_item_t * item = (adv_bearer_connectable_advertisement_data_item_t *) btstack_linked_list_pop(&gap_connectable_advertisements);
|
||||||
log_debug("Start GAP ADV");
|
if (item != NULL){
|
||||||
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);
|
// queue again
|
||||||
gap_advertisements_set_data(gap_advertising_data_length, gap_advertising_data);
|
btstack_linked_list_add_tail(&gap_connectable_advertisements, (void*) item);
|
||||||
gap_advertisements_enable(1);
|
// time to advertise again
|
||||||
adv_bearer_set_timeout(ADVERTISING_INTERVAL_CONNECTABLE_MIN_MS);
|
log_debug("Start GAP ADV, %p", item);
|
||||||
adv_bearer_state = STATE_GAP;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -353,9 +358,12 @@ void adv_bearer_advertisements_enable(int enabled){
|
|||||||
adv_bearer_run();
|
adv_bearer_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
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){
|
||||||
gap_advertising_data_length = advertising_data_length;
|
btstack_linked_list_add(&gap_connectable_advertisements, (void*) item);
|
||||||
gap_advertising_data = advertising_data;
|
}
|
||||||
|
|
||||||
|
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,
|
void adv_bearer_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type,
|
||||||
|
@ -47,6 +47,12 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void * next;
|
||||||
|
uint8_t adv_length;
|
||||||
|
uint8_t adv_data[31];
|
||||||
|
} adv_bearer_connectable_advertisement_data_item_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize Advertising Bearer
|
* Initialize Advertising Bearer
|
||||||
*/
|
*/
|
||||||
@ -58,14 +64,20 @@ void adv_bearer_init(void);
|
|||||||
// Advertisements are interleaved with ADV Bearer Messages
|
// Advertisements are interleaved with ADV Bearer Messages
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Advertisement Data
|
* Add Connectable Advertisement Data Item
|
||||||
*
|
* @param item
|
||||||
* @param advertising_data_length
|
* @note item is not copied, pointer has to stay valid
|
||||||
* @param advertising_data (max 31 octets)
|
|
||||||
* @note data 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
|
* @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
|
* @brief Set Advertisement Paramters
|
||||||
|
@ -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 };
|
const static uint8_t device_uuid[] = { 0x00, 0x1B, 0xDC, 0x08, 0x10, 0x21, 0x0B, 0x0E, 0x0A, 0x0C, 0x00, 0x0B, 0x0E, 0x0A, 0x0C, 0x00 };
|
||||||
|
|
||||||
// Mesh Provisioning
|
// Mesh Provisioning
|
||||||
static uint8_t adv_data[] = {
|
static uint8_t adv_data_unprovisioned[] = {
|
||||||
// Flags general discoverable, BR/EDR not supported
|
// Flags general discoverable, BR/EDR not supported
|
||||||
0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06,
|
0x02, BLUETOOTH_DATA_TYPE_FLAGS, 0x06,
|
||||||
// 16-bit Service UUIDs
|
// 16-bit Service UUIDs
|
||||||
@ -94,6 +94,7 @@ static uint8_t adv_data[] = {
|
|||||||
// OOB information
|
// OOB information
|
||||||
0x00, 0x00
|
0x00, 0x00
|
||||||
};
|
};
|
||||||
|
const uint8_t adv_data_unprovisioned_len = sizeof(adv_data_unprovisioned);
|
||||||
|
|
||||||
#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY
|
#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY
|
||||||
static btstack_crypto_random_t crypto_request_random;
|
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);
|
const uint8_t adv_data_with_network_id_len = sizeof(adv_data_with_network_id);
|
||||||
#endif
|
#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;
|
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("\nUSE_ADVERTISING_WITH_NODE_IDENTITY:\n");
|
||||||
printf_hexdump(adv_data_with_node_identity, sizeof(adv_data_with_node_identity));
|
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
|
// setup advertisements
|
||||||
bd_addr_t null_addr;
|
bd_addr_t null_addr;
|
||||||
memset(null_addr, 0, 6);
|
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_min = 0x0030;
|
||||||
uint16_t adv_int_max = 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_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);
|
adv_bearer_advertisements_enable(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,16 +214,16 @@ static void mesh_proxy_handle_get_random(void * arg){
|
|||||||
|
|
||||||
|
|
||||||
#ifdef USE_ADVERTISING_WITH_NETWORK_ID
|
#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
|
// dynamically store network ID into adv data
|
||||||
memcpy(&adv_data_with_network_id[12], prov_data->network_id, sizeof(prov_data->network_id));
|
memcpy(&adv_data_with_network_id[12], network_id, sizeof(network_id));
|
||||||
// copy beacon key and network id
|
|
||||||
memcpy(beacon_key, prov_data->beacon_key, 16);
|
// store in advertisement item
|
||||||
memcpy(network_id, prov_data->network_id, 8);
|
memset(&connectable_advertisement_item, 0, sizeof(connectable_advertisement_item));
|
||||||
|
connectable_advertisement_item.adv_length = adv_data_with_network_id_len;
|
||||||
printf_hexdump(prov_data->network_id, 8);
|
memcpy(connectable_advertisement_item.adv_data, (uint8_t*) adv_data_with_network_id, adv_data_with_network_id_len);
|
||||||
mesh_flags = prov_data->flags;
|
|
||||||
|
|
||||||
// setup advertisements
|
// setup advertisements
|
||||||
bd_addr_t null_addr;
|
bd_addr_t null_addr;
|
||||||
memset(null_addr, 0, 6);
|
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_min = 0x0030;
|
||||||
uint16_t adv_int_max = 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_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);
|
adv_bearer_advertisements_enable(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -264,11 +270,11 @@ static void mesh_setup_from_provisioning_data(const mesh_provisioning_data_t * p
|
|||||||
mesh_flags = provisioning_data->flags;
|
mesh_flags = provisioning_data->flags;
|
||||||
// dump data
|
// dump data
|
||||||
mesh_provisioning_dump(provisioning_data);
|
mesh_provisioning_dump(provisioning_data);
|
||||||
|
|
||||||
// Mesh Proxy
|
// Mesh Proxy
|
||||||
#ifdef USE_ADVERTISING_WITH_NETWORK_ID
|
#ifdef USE_ADVERTISING_WITH_NETWORK_ID
|
||||||
printf("Advertise Mesh Proxy Service with Network ID\n");
|
printf("Advertise Mesh Proxy Service with Network ID\n");
|
||||||
setup_advertising_with_network_id(provisioning_data);
|
setup_advertising_with_network_id();
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY
|
#ifdef USE_ADVERTISING_WITH_NODE_IDENTITY
|
||||||
printf("Advertise Mesh Proxy Service with Node Identity\n");
|
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) {
|
static void setup_advertising_unprovisioned(void) {
|
||||||
printf("Advertise Mesh Provisioning Service\n");
|
printf("Advertise Mesh Provisioning Service\n");
|
||||||
// dynamically store device uuid into adv data
|
// 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
|
// setup advertisements
|
||||||
uint8_t adv_type = 0; // ADV_IND
|
uint8_t adv_type = 0; // ADV_IND
|
||||||
@ -289,7 +299,7 @@ static void setup_advertising_unprovisioned(void) {
|
|||||||
bd_addr_t null_addr;
|
bd_addr_t null_addr;
|
||||||
memset(null_addr, 0, 6);
|
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_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);
|
adv_bearer_advertisements_enable(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -420,19 +430,23 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
|||||||
// enable PB_GATT
|
// enable PB_GATT
|
||||||
if (provisioned == 0){
|
if (provisioned == 0){
|
||||||
setup_advertising_unprovisioned();
|
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;
|
break;
|
||||||
|
|
||||||
case HCI_EVENT_LE_META:
|
case HCI_EVENT_LE_META:
|
||||||
if (hci_event_le_meta_get_subevent_code(packet) != HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
|
if (hci_event_le_meta_get_subevent_code(packet) != HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break;
|
||||||
// disable PB_GATT
|
// disable PB_GATT
|
||||||
if (provisioned){
|
printf("Connected, stop advertising gatt service\n");
|
||||||
printf("Connected, disabling GATT Proxy advertising\n");
|
adv_bearer_advertisements_remove_item(&connectable_advertisement_item);
|
||||||
adv_bearer_advertisements_enable(0);
|
|
||||||
} else {
|
|
||||||
printf("Connected, disabling PB_GATT advertising\n");
|
|
||||||
adv_bearer_advertisements_enable(0);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -483,6 +497,11 @@ static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t cha
|
|||||||
|
|
||||||
// store in TLV
|
// store in TLV
|
||||||
btstack_tlv_singleton_impl->store_tag(btstack_tlv_singleton_context, 'PROV', (uint8_t *) &provisioning_data, sizeof(mesh_provisioning_data_t));
|
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);
|
mesh_setup_from_provisioning_data(&provisioning_data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user