diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 24cb52c16be..1c3d0885f96 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -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) diff --git a/subsys/bluetooth/controller/include/ll.h b/subsys/bluetooth/controller/include/ll.h index 8008e49e0d3..392a08b84fb 100644 --- a/subsys/bluetooth/controller/include/ll.h +++ b/subsys/bluetooth/controller/include/ll.h @@ -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); diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.c b/subsys/bluetooth/controller/ll_sw/ctrl.c index 15b14243052..913b5c2828d 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.c +++ b/subsys/bluetooth/controller/ll_sw/ctrl.c @@ -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) { diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.h b/subsys/bluetooth/controller/ll_sw/ctrl.h index 72519edb4ac..c1f5f6f212f 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.h +++ b/subsys/bluetooth/controller/ll_sw/ctrl.h @@ -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, diff --git a/subsys/bluetooth/controller/ll_sw/ll_adv.c b/subsys/bluetooth/controller/ll_sw/ll_adv.c index de3eb2dc9af..47b05f7469b 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_adv.c +++ b/subsys/bluetooth/controller/ll_sw/ll_adv.c @@ -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)