diff --git a/ble/gap_le.h b/ble/gap_le.h index 6db5956ee..ae1a6a56e 100644 --- a/ble/gap_le.h +++ b/ble/gap_le.h @@ -76,15 +76,16 @@ gap_random_address_type_t gap_random_address_get_mode(void); * @param supervision_timeout (unit: 10ms) * @returns 0 if ok */ -void gap_update_connection_parameters(hci_con_handle_t con_handle, uint16_t conn_interval_min, +int gap_update_connection_parameters(hci_con_handle_t con_handle, uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout); -/** - * @brief Set Advertisement Data - * @param advertisement date (31 octets) +/** + * @brief Set Advertisement Data + * @param advertising_data_length + * @param advertising_data (max 31 octets) * @note data is not copied, pointer has to stay valid */ -void gap_advertisements_set_data(uint8_t * adv_data); +void gap_advertisements_set_data(uint8_t advertising_data_length, uint8_t * advertising_data); /** * @brief Set Advertisement Paramters diff --git a/ble/sm.c b/ble/sm.c index 444d2d063..d7214ea3b 100644 --- a/ble/sm.c +++ b/ble/sm.c @@ -350,6 +350,7 @@ static void gap_random_address_update_stop(void){ run_loop_remove_timer(&gap_random_address_update_timer); } + static void sm_random_start(sm_connection_t * sm_conn){ sm_random_connection_source = sm_conn; hci_send_cmd(&hci_le_rand); @@ -2203,3 +2204,22 @@ void gap_random_address_set_update_period(int period_ms){ gap_random_address_update_stop(); gap_random_address_update_start(); } + +/** + * @brief Set Advertisement Paramters + * @param adv_int_min + * @param adv_int_max + * @param adv_type + * @param direct_address_type + * @param direct_address + * @param channel_map + * @param filter_policy + * + * @note own_address_type is used from gap_random_address_set_mode + */ +void gap_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, + uint8_t direct_address_typ, bd_addr_t direct_address, uint8_t channel_map, uint8_t filter_policy){ + hci_le_advertisements_set_params(adv_int_min, adv_int_max, adv_type, gap_random_adress_type, + direct_address_typ, direct_address, channel_map, filter_policy); +} + diff --git a/src/hci.c b/src/hci.c index 373326be1..fda2b50d5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -47,6 +47,10 @@ #include "hci.h" #include "gap.h" +#ifdef HAVE_BLE +#include "gap_le.h" +#endif + #include #include #include @@ -2091,8 +2095,8 @@ void hci_run(void){ } #ifdef HAVE_BLE - // handle le scan if (hci_stack->state == HCI_STATE_WORKING){ + // handle le scan switch(hci_stack->le_scanning_state){ case LE_START_SCAN: hci_stack->le_scanning_state = LE_SCANNING; @@ -2113,6 +2117,36 @@ void hci_run(void){ hci_send_cmd(&hci_le_set_scan_parameters, scan_type, hci_stack->le_scan_interval, hci_stack->le_scan_window, hci_stack->adv_addr_type, 0); return; } + // le advertisement control + if (hci_stack->le_advertisements_todo & LE_ADVERTISEMENT_TASKS_DISABLE){ + hci_stack->le_advertisements_todo &= ~LE_ADVERTISEMENT_TASKS_DISABLE; + hci_send_cmd(&hci_le_set_advertise_enable, 0); + return; + } + if (hci_stack->le_advertisements_todo & LE_ADVERTISEMENT_TASKS_SET_PARAMS){ + hci_stack->le_advertisements_todo &= ~LE_ADVERTISEMENT_TASKS_SET_PARAMS; + hci_send_cmd(&hci_le_set_advertising_parameters, + hci_stack->le_advertisements_interval_min, + hci_stack->le_advertisements_interval_max, + hci_stack->le_advertisements_type, + hci_stack->le_advertisements_own_address_type, + hci_stack->le_advertisements_direct_address_type, + hci_stack->le_advertisements_direct_address, + hci_stack->le_advertisements_channel_map, + hci_stack->le_advertisements_filter_policy); + return; + } + if (hci_stack->le_advertisements_todo & LE_ADVERTISEMENT_TASKS_SET_DATA){ + hci_stack->le_advertisements_todo &= ~LE_ADVERTISEMENT_TASKS_SET_DATA; + hci_send_cmd(&hci_le_set_advertising_data, hci_stack->le_advertisements_data_len, + hci_stack->le_advertisements_data); + return; + } + if (hci_stack->le_advertisements_todo & LE_ADVERTISEMENT_TASKS_ENABLE){ + hci_stack->le_advertisements_todo &= ~LE_ADVERTISEMENT_TASKS_ENABLE; + hci_send_cmd(&hci_le_set_advertise_enable, 1); + return; + } } #endif @@ -2926,6 +2960,70 @@ int gap_update_connection_parameters(hci_con_handle_t con_handle, uint16_t conn_ return 0; } +/** + * @brief Set Advertisement Data + * @param advertising_data_length + * @param advertising_data (max 31 octets) + * @note data is not copied, pointer has to stay valid + */ +void gap_advertisements_set_data(uint8_t advertising_data_length, uint8_t * advertising_data){ + hci_stack->le_advertisements_data_len = advertising_data_length; + hci_stack->le_advertisements_data = advertising_data; + hci_stack->le_advertisements_todo |= LE_ADVERTISEMENT_TASKS_SET_DATA; + // disable advertisements before setting data + if (hci_stack->le_advertisements_enabled){ + hci_stack->le_advertisements_todo |= LE_ADVERTISEMENT_TASKS_DISABLE | LE_ADVERTISEMENT_TASKS_ENABLE; + } +} + +/** + * @brief Set Advertisement Parameters + * @param adv_int_min + * @param adv_int_max + * @param adv_type + * @param own_address_type + * @param direct_address_type + * @param direct_address + * @param channel_map + * @param filter_policy + * + * @note internal use. use gap_advertisements_set_params from gap_le.h instead. + */ + void hci_le_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, + uint8_t own_address_type, uint8_t direct_address_typ, bd_addr_t direct_address, + uint8_t channel_map, uint8_t filter_policy) { + + hci_stack->le_advertisements_interval_min = adv_int_min; + hci_stack->le_advertisements_interval_max = adv_int_max; + hci_stack->le_advertisements_type = adv_type; + hci_stack->le_advertisements_own_address_type = own_address_type; + hci_stack->le_advertisements_direct_address_type = direct_address_typ; + hci_stack->le_advertisements_channel_map = channel_map; + hci_stack->le_advertisements_filter_policy = filter_policy; + memcpy(hci_stack->le_advertisements_direct_address, direct_address, 6); + + hci_stack->le_advertisements_todo |= LE_ADVERTISEMENT_TASKS_SET_PARAMS; + // disable advertisements before changing params + if (hci_stack->le_advertisements_enabled){ + hci_stack->le_advertisements_todo |= LE_ADVERTISEMENT_TASKS_DISABLE | LE_ADVERTISEMENT_TASKS_ENABLE; + } + } + +/** + * @brief Enable/Disable Advertisements + * @param enabled + */ +void gap_advertisements_enable(int enabled){ + hci_stack->le_advertisements_enabled = enabled; + if (enabled && !hci_stack->le_advertisements_active){ + hci_stack->le_advertisements_todo |= LE_ADVERTISEMENT_TASKS_ENABLE; + } + if (!enabled && hci_stack->le_advertisements_active){ + hci_stack->le_advertisements_todo |= LE_ADVERTISEMENT_TASKS_DISABLE; + } +} + + le_command_status_t gap_disconnect(hci_con_handle_t handle){ hci_connection_t * conn = hci_connection_for_handle(handle); if (!conn){ diff --git a/src/hci.h b/src/hci.h index 905702108..7000cc1ca 100644 --- a/src/hci.h +++ b/src/hci.h @@ -587,6 +587,12 @@ typedef enum hci_init_state{ } hci_substate_t; +enum { + LE_ADVERTISEMENT_TASKS_DISABLE = 1 << 0, + LE_ADVERTISEMENT_TASKS_SET_DATA = 1 << 1, + LE_ADVERTISEMENT_TASKS_SET_PARAMS = 1 << 2, + LE_ADVERTISEMENT_TASKS_ENABLE = 1 << 0, +}; /** * main data structure @@ -682,7 +688,21 @@ typedef struct { le_connection_parameter_range_t le_connection_parameter_range; + uint8_t * le_advertisements_data; + uint8_t le_advertisements_data_len; + uint8_t le_advertisements_active; + uint8_t le_advertisements_enabled; + uint8_t le_advertisements_todo; + + uint16_t le_advertisements_interval_min; + uint16_t le_advertisements_interval_max; + uint8_t le_advertisements_type; + uint8_t le_advertisements_own_address_type; + uint8_t le_advertisements_direct_address_type; + uint8_t le_advertisements_channel_map; + uint8_t le_advertisements_filter_policy; + bd_addr_t le_advertisements_direct_address; // custom BD ADDR bd_addr_t custom_bd_addr; @@ -874,6 +894,23 @@ void hci_set_hardware_error_callback(void (*fn)(void)); /* API_END */ +/** + * @brief Set Advertisement Parameters + * @param adv_int_min + * @param adv_int_max + * @param adv_type + * @param own_address_type + * @param direct_address_type + * @param direct_address + * @param channel_map + * @param filter_policy + * + * @note internal use. use gap_advertisements_set_params from gap_le.h instead. + */ +void hci_le_advertisements_set_params(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, + uint8_t own_address_type, uint8_t direct_address_typ, bd_addr_t direct_address, + uint8_t channel_map, uint8_t filter_policy); + #if defined __cplusplus } #endif