Bluetooth: controller: Fix advertiser context corruption
Under invalid host behavior, trying to start advertising while already active would corrupt the advertiser context. This is fixed by having an explicit flag to check whether advertiser is already running. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
d577d3c450
commit
8eb9c8cea0
5 changed files with 40 additions and 17 deletions
|
@ -572,16 +572,17 @@ static void le_set_adv_param(struct net_buf *buf, struct net_buf **evt)
|
|||
struct bt_hci_cp_le_set_adv_param *cmd = (void *)buf->data;
|
||||
struct bt_hci_evt_cc_status *ccst;
|
||||
u16_t min_interval;
|
||||
u32_t status;
|
||||
|
||||
min_interval = sys_le16_to_cpu(cmd->min_interval);
|
||||
|
||||
ll_adv_params_set(min_interval, cmd->type,
|
||||
cmd->own_addr_type, cmd->direct_addr.type,
|
||||
&cmd->direct_addr.a.val[0], cmd->channel_map,
|
||||
cmd->filter_policy);
|
||||
status = ll_adv_params_set(min_interval, cmd->type, cmd->own_addr_type,
|
||||
cmd->direct_addr.type,
|
||||
&cmd->direct_addr.a.val[0], cmd->channel_map,
|
||||
cmd->filter_policy);
|
||||
|
||||
ccst = cmd_complete(evt, sizeof(*ccst));
|
||||
ccst->status = 0x00;
|
||||
ccst->status = (!status) ? 0x00 : BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
static void le_read_adv_chan_tx_power(struct net_buf *buf, struct net_buf **evt)
|
||||
|
|
|
@ -12,10 +12,10 @@ int ll_init(struct k_sem *sem_rx);
|
|||
void ll_reset(void);
|
||||
u8_t *ll_addr_get(u8_t addr_type, u8_t *p_bdaddr);
|
||||
void ll_addr_set(u8_t addr_type, u8_t const *const p_bdaddr);
|
||||
void ll_adv_params_set(u16_t interval, u8_t adv_type,
|
||||
u8_t own_addr_type, u8_t direct_addr_type,
|
||||
u8_t const *const p_direct_addr, u8_t chl_map,
|
||||
u8_t filter_policy);
|
||||
u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
|
||||
u8_t own_addr_type, u8_t direct_addr_type,
|
||||
u8_t const *const p_direct_addr, u8_t chl_map,
|
||||
u8_t filter_policy);
|
||||
void ll_adv_data_set(u8_t len, u8_t const *const p_data);
|
||||
void ll_scan_data_set(u8_t len, u8_t const *const p_data);
|
||||
u32_t ll_adv_enable(u8_t enable);
|
||||
|
|
|
@ -75,6 +75,7 @@ enum state {
|
|||
struct advertiser {
|
||||
struct shdr hdr;
|
||||
|
||||
u8_t is_enabled:1;
|
||||
u8_t chl_map:3;
|
||||
u8_t chl_map_current:3;
|
||||
u8_t filter_policy:2;
|
||||
|
@ -444,6 +445,7 @@ void ll_reset(void)
|
|||
/* reset controller context members */
|
||||
_radio.filter_enable_bitmask = 0;
|
||||
_radio.nirk = 0;
|
||||
_radio.advertiser.is_enabled = 0;
|
||||
_radio.advertiser.conn = NULL;
|
||||
_radio.scanner.is_enabled = 0;
|
||||
_radio.scanner.conn = NULL;
|
||||
|
@ -760,6 +762,10 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok,
|
|||
conn = _radio.advertiser.conn;
|
||||
_radio.advertiser.conn = NULL;
|
||||
|
||||
/* Advertiser transitions to Slave role */
|
||||
LL_ASSERT(_radio.advertiser.is_enabled);
|
||||
_radio.advertiser.is_enabled = 0;
|
||||
|
||||
/* Populate the slave context */
|
||||
conn->handle = mem_index_get(conn, _radio.conn_pool,
|
||||
CONNECTION_T_SIZE);
|
||||
|
@ -8056,6 +8062,10 @@ u32_t radio_adv_enable(u16_t interval, u8_t chl_map, u8_t filter_policy)
|
|||
struct pdu_adv *pdu_adv;
|
||||
u32_t ret;
|
||||
|
||||
if (_radio.advertiser.is_enabled) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pdu_adv = (struct pdu_adv *)
|
||||
&_radio.advertiser.adv_data.data[_radio.advertiser.adv_data.last][0];
|
||||
|
||||
|
@ -8246,6 +8256,8 @@ u32_t radio_adv_enable(u16_t interval, u8_t chl_map, u8_t filter_policy)
|
|||
}
|
||||
|
||||
if (ret_cb == TICKER_STATUS_SUCCESS) {
|
||||
_radio.advertiser.is_enabled = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -8269,6 +8281,8 @@ u32_t radio_adv_disable(void)
|
|||
if (!status) {
|
||||
struct connection *conn;
|
||||
|
||||
_radio.advertiser.is_enabled = 0;
|
||||
|
||||
conn = _radio.advertiser.conn;
|
||||
if (conn) {
|
||||
_radio.advertiser.conn = NULL;
|
||||
|
@ -8282,6 +8296,11 @@ u32_t radio_adv_disable(void)
|
|||
return status;
|
||||
}
|
||||
|
||||
u32_t radio_adv_is_enabled(void)
|
||||
{
|
||||
return _radio.advertiser.is_enabled;
|
||||
}
|
||||
|
||||
u32_t radio_scan_enable(u8_t scan_type, u8_t init_addr_type, u8_t *init_addr,
|
||||
u16_t interval, u16_t window, u8_t filter_policy)
|
||||
{
|
||||
|
|
|
@ -312,11 +312,13 @@ u32_t radio_init(void *hf_clock, u8_t sca, u8_t connection_count_max,
|
|||
u16_t packet_tx_data_size, u8_t *mem_radio,
|
||||
u16_t mem_size);
|
||||
void radio_ticks_active_to_start_set(u32_t ticks_active_to_start);
|
||||
/* Downstream - Advertiser */
|
||||
struct radio_adv_data *radio_adv_data_get(void);
|
||||
struct radio_adv_data *radio_scan_data_get(void);
|
||||
u32_t radio_adv_enable(u16_t interval, u8_t chl_map,
|
||||
u8_t filter_policy);
|
||||
u32_t radio_adv_disable(void);
|
||||
u32_t radio_adv_is_enabled(void);
|
||||
/* Downstream - Scanner */
|
||||
u32_t radio_scan_enable(u8_t scan_type, u8_t init_addr_type,
|
||||
u8_t *init_addr, u16_t interval,
|
||||
|
|
|
@ -26,10 +26,10 @@ static struct {
|
|||
u8_t direct_addr[BDADDR_SIZE];
|
||||
} ll_adv;
|
||||
|
||||
void ll_adv_params_set(u16_t interval, u8_t adv_type,
|
||||
u8_t own_addr_type, u8_t direct_addr_type,
|
||||
u8_t const *const direct_addr, u8_t chl_map,
|
||||
u8_t filter_policy)
|
||||
u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
|
||||
u8_t own_addr_type, u8_t direct_addr_type,
|
||||
u8_t const *const direct_addr, u8_t chl_map,
|
||||
u8_t filter_policy)
|
||||
{
|
||||
u8_t const pdu_adv_type[] = {PDU_ADV_TYPE_ADV_IND,
|
||||
PDU_ADV_TYPE_DIRECT_IND,
|
||||
|
@ -39,10 +39,9 @@ void ll_adv_params_set(u16_t interval, u8_t adv_type,
|
|||
struct radio_adv_data *radio_adv_data;
|
||||
struct pdu_adv *pdu;
|
||||
|
||||
/* TODO: check and fail if adv state active else
|
||||
* update (implemented below) current index elements for
|
||||
* both adv and scan data.
|
||||
*/
|
||||
if (radio_adv_is_enabled()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* remember params so that set adv/scan data and adv enable
|
||||
* interface can correctly update adv/scan data in the
|
||||
|
@ -97,6 +96,8 @@ void ll_adv_params_set(u16_t interval, u8_t adv_type,
|
|||
if (pdu->len == 0) {
|
||||
pdu->len = BDADDR_SIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ll_adv_data_set(u8_t len, u8_t const *const data)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue