Bluetooth: controller: Reworked adv set terminate event
Reworked the implementation of Advertising Set Terminate event. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
46a622837d
commit
cd0e72a91e
6 changed files with 174 additions and 102 deletions
|
@ -3604,12 +3604,12 @@ static void le_adv_ext_terminate(struct pdu_data *pdu_data,
|
|||
}
|
||||
|
||||
sep = meta_evt(buf, BT_HCI_EVT_LE_ADV_SET_TERMINATED, sizeof(*sep));
|
||||
sep->num_completed_ext_adv_evts =
|
||||
(uint8_t)((uint32_t)node_rx->hdr.rx_ftr.extra & 0xff);
|
||||
sep->status = ((uint32_t)node_rx->hdr.rx_ftr.extra >> 8) & 0xff;
|
||||
sep->adv_handle = (node_rx->hdr.handle & 0xff);
|
||||
sep->conn_handle = sys_cpu_to_le16
|
||||
(*(uint16_t *)((uint32_t)node_rx->hdr.rx_ftr.extra >> 16));
|
||||
sep->adv_handle = node_rx->hdr.handle & 0xff;
|
||||
sep->conn_handle =
|
||||
sys_cpu_to_le16((uint32_t)node_rx->hdr.rx_ftr.param & 0xffff);
|
||||
sep->num_completed_ext_adv_evts =
|
||||
(uint32_t)node_rx->hdr.rx_ftr.extra & 0xff;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
#endif /* CONFIG_BT_OBSERVER */
|
||||
|
@ -4326,7 +4326,6 @@ uint8_t hci_get_class(struct node_rx_pdu *node_rx)
|
|||
case NODE_RX_TYPE_EXT_1M_REPORT:
|
||||
case NODE_RX_TYPE_EXT_2M_REPORT:
|
||||
case NODE_RX_TYPE_EXT_CODED_REPORT:
|
||||
case NODE_RX_TYPE_EXT_ADV_TERMINATE:
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
#endif /* CONFIG_BT_OBSERVER */
|
||||
|
||||
|
@ -4354,6 +4353,11 @@ uint8_t hci_get_class(struct node_rx_pdu *node_rx)
|
|||
case NODE_RX_TYPE_MESH_REPORT:
|
||||
#endif /* CONFIG_BT_HCI_MESH_EXT */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
/* fallthrough */
|
||||
case NODE_RX_TYPE_EXT_ADV_TERMINATE:
|
||||
return HCI_CLASS_EVT_REQUIRED;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
case NODE_RX_TYPE_CONNECTION:
|
||||
|
|
|
@ -448,9 +448,6 @@ static void isr_done(void *param)
|
|||
{
|
||||
struct node_rx_hdr *node_rx;
|
||||
struct lll_adv *lll = param;
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
struct event_done_extra *e;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
/* Clear radio status and events */
|
||||
lll_isr_status_reset();
|
||||
|
@ -558,9 +555,12 @@ static void isr_done(void *param)
|
|||
#endif /* !CONFIG_BT_CTLR_ADV_INDICATION */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
e = ull_event_done_extra_get();
|
||||
LL_ASSERT(e);
|
||||
e->type = EVENT_DONE_EXTRA_TYPE_ADV;
|
||||
struct event_done_extra *extra;
|
||||
|
||||
extra = ull_event_done_extra_get();
|
||||
LL_ASSERT(extra);
|
||||
|
||||
extra->type = EVENT_DONE_EXTRA_TYPE_ADV;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
lll_isr_cleanup(param);
|
||||
|
|
|
@ -280,10 +280,6 @@ static inline void rx_demux_event_done(memq_link_t *link,
|
|||
static inline void ll_rx_link_inc_quota(int8_t delta);
|
||||
static void disabled_cb(void *param);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_BROADCASTER)
|
||||
static void term_evt_disable(struct ull_hdr *ull_hdr);
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_BROADCASTER */
|
||||
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
static uint8_t tx_cmplt_get(uint16_t *handle, uint8_t *first, uint8_t last);
|
||||
#endif /* CONFIG_BT_CONN */
|
||||
|
@ -601,8 +597,39 @@ void ll_rx_dequeue(void)
|
|||
break;
|
||||
|
||||
case NODE_RX_TYPE_EXT_ADV_TERMINATE:
|
||||
break;
|
||||
{
|
||||
struct lll_conn *lll_conn;
|
||||
struct ll_adv_set *adv;
|
||||
struct ll_conn *conn;
|
||||
memq_link_t *link;
|
||||
|
||||
adv = ull_adv_set_get(rx->handle);
|
||||
|
||||
lll_conn = adv->lll.conn;
|
||||
if (!lll_conn) {
|
||||
adv->is_enabled = 0U;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
LL_ASSERT(!lll_conn->link_tx_free);
|
||||
link = memq_deinit(&lll_conn->memq_tx.head,
|
||||
&lll_conn->memq_tx.tail);
|
||||
LL_ASSERT(link);
|
||||
lll_conn->link_tx_free = link;
|
||||
|
||||
conn = (void *)HDR_LLL2EVT(lll_conn);
|
||||
ll_conn_release(conn);
|
||||
adv->lll.conn = NULL;
|
||||
|
||||
ll_rx_release(adv->node_rx_cc_free);
|
||||
adv->node_rx_cc_free = NULL;
|
||||
ll_rx_link_release(adv->link_cc_free);
|
||||
adv->link_cc_free = NULL;
|
||||
|
||||
adv->is_enabled = 0U;
|
||||
}
|
||||
break;
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
|
@ -668,7 +695,7 @@ void ll_rx_dequeue(void)
|
|||
* enabled status bitmask
|
||||
*/
|
||||
bm = (IS_ENABLED(CONFIG_BT_OBSERVER) &&
|
||||
ull_scan_is_enabled(0) << 1) |
|
||||
(ull_scan_is_enabled(0) << 1)) |
|
||||
(IS_ENABLED(CONFIG_BT_BROADCASTER) &&
|
||||
ull_adv_is_enabled(0));
|
||||
|
||||
|
@ -1745,28 +1772,6 @@ static inline int rx_demux_rx(memq_link_t *link, struct node_rx_hdr *rx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_BROADCASTER)
|
||||
static void term_evt_disable(struct ull_hdr *ull_hdr)
|
||||
{
|
||||
struct lll_adv *lll;
|
||||
struct ll_adv_set *adv;
|
||||
uint8_t handle;
|
||||
uint32_t ret;
|
||||
|
||||
lll = (struct lll_adv *)HDR_ULL2LLL(ull_hdr);
|
||||
adv = (void *)HDR_LLL2EVT(lll);
|
||||
|
||||
handle = ull_adv_handle_get(adv);
|
||||
LL_ASSERT(handle < BT_CTLR_ADV_SET);
|
||||
|
||||
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
|
||||
TICKER_ID_ADV_BASE + handle, NULL, adv);
|
||||
|
||||
LL_ASSERT((ret == TICKER_STATUS_SUCCESS)
|
||||
|| (ret == TICKER_STATUS_BUSY));
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_BROADCASTER */
|
||||
|
||||
static inline void rx_demux_event_done(memq_link_t *link,
|
||||
struct node_rx_hdr *rx)
|
||||
{
|
||||
|
@ -1788,53 +1793,8 @@ static inline void rx_demux_event_done(memq_link_t *link,
|
|||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_BROADCASTER)
|
||||
case EVENT_DONE_EXTRA_TYPE_ADV:
|
||||
{
|
||||
struct lll_adv *lll;
|
||||
struct ll_adv_set *adv;
|
||||
bool send_term_evt = false;
|
||||
|
||||
lll = (struct lll_adv *)HDR_ULL2LLL(ull_hdr);
|
||||
adv = (void *)HDR_LLL2EVT(lll);
|
||||
|
||||
if ((adv->max_events > 0) &&
|
||||
(adv->event_counter >= adv->max_events)) {
|
||||
adv->max_events = 0;
|
||||
send_term_evt = true;
|
||||
|
||||
lll->node_rx_adv_term->rx_ftr.extra = (void *)
|
||||
((uint32_t)adv->event_counter & 0xff);
|
||||
}
|
||||
|
||||
if (adv->ticks_remain_duration &&
|
||||
(adv->ticks_remain_duration <
|
||||
HAL_TICKER_US_TO_TICKS((uint64_t)adv->interval * 625U))) {
|
||||
adv->ticks_remain_duration = 0;
|
||||
send_term_evt = true;
|
||||
|
||||
lll->node_rx_adv_term->rx_ftr.extra = (void *)
|
||||
(((uint32_t)adv->event_counter & 0xff)
|
||||
| (BT_HCI_ERR_ADV_TIMEOUT << 8));
|
||||
}
|
||||
|
||||
if (send_term_evt) {
|
||||
lll->node_rx_adv_term->rx_ftr.extra =
|
||||
(void *)lll->node_rx_adv_term->rx_ftr.extra;
|
||||
lll->node_rx_adv_term->type =
|
||||
NODE_RX_TYPE_EXT_ADV_TERMINATE;
|
||||
lll->node_rx_adv_term->handle =
|
||||
(uint16_t)ull_adv_handle_get(adv);
|
||||
lll->node_rx_adv_term->rx_ftr.param = (void *)lll;
|
||||
|
||||
rx = lll->node_rx_adv_term;
|
||||
link = rx->link;
|
||||
|
||||
ll_rx_put(link, rx);
|
||||
ll_rx_sched();
|
||||
|
||||
term_evt_disable(ull_hdr);
|
||||
}
|
||||
ull_adv_done(done);
|
||||
break;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_BROADCASTER */
|
||||
|
||||
#if defined(CONFIG_BT_OBSERVER)
|
||||
|
|
|
@ -67,6 +67,11 @@ static void disabled_cb(void *param);
|
|||
static void conn_release(struct ll_adv_set *adv);
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
static void ticker_op_ext_stop_cb(uint32_t status, void *param);
|
||||
static void ext_disabled_cb(void *param);
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
static inline uint8_t disable(uint8_t handle);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_SET)
|
||||
|
@ -825,23 +830,32 @@ uint8_t ll_adv_enable(uint8_t enable)
|
|||
/* The alloc here used for ext adv termination event */
|
||||
link_adv_term = ll_rx_link_alloc();
|
||||
if (!link_adv_term) {
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
if (adv->lll.conn) {
|
||||
conn_release(adv);
|
||||
}
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
||||
/* TODO: figure out right return value */
|
||||
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
|
||||
}
|
||||
|
||||
node_rx_adv_term = ll_rx_alloc();
|
||||
if (!node_rx_adv_term) {
|
||||
#if defined(CONFIG_BT_PERIPHERAL)
|
||||
if (adv->lll.conn) {
|
||||
conn_release(adv);
|
||||
}
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
||||
ll_rx_link_release(link_adv_term);
|
||||
|
||||
/* TODO: figure out right return value */
|
||||
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
|
||||
}
|
||||
|
||||
node_rx_adv_term->hdr.link =
|
||||
(memq_link_t *)link_adv_term;
|
||||
|
||||
adv->lll.node_rx_adv_term =
|
||||
(struct node_rx_hdr *)node_rx_adv_term;
|
||||
node_rx_adv_term->hdr.link = (void *)link_adv_term;
|
||||
adv->lll.node_rx_adv_term = (void *)node_rx_adv_term;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
@ -1378,6 +1392,51 @@ uint8_t ull_scan_rsp_set(struct ll_adv_set *adv, uint8_t len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
void ull_adv_done(struct node_rx_event_done *done)
|
||||
{
|
||||
struct lll_adv *lll = (void *)HDR_ULL2LLL(done->param);
|
||||
struct ll_adv_set *adv = (void *)HDR_LLL2EVT(lll);
|
||||
uint8_t handle;
|
||||
uint32_t ret;
|
||||
|
||||
if (adv->max_events && (adv->event_counter >= adv->max_events)) {
|
||||
adv->max_events = 0;
|
||||
|
||||
lll->node_rx_adv_term->rx_ftr.extra =
|
||||
(void *)(((uint32_t)adv->event_counter & 0xff) |
|
||||
(BT_HCI_ERR_LIMIT_REACHED << 8));
|
||||
|
||||
goto ext_adv_disable;
|
||||
}
|
||||
|
||||
if (adv->ticks_remain_duration &&
|
||||
(adv->ticks_remain_duration <
|
||||
HAL_TICKER_US_TO_TICKS((uint64_t)adv->interval * 625U))) {
|
||||
adv->ticks_remain_duration = 0;
|
||||
|
||||
lll->node_rx_adv_term->rx_ftr.extra =
|
||||
(void *)(((uint32_t)adv->event_counter & 0xff) |
|
||||
(BT_HCI_ERR_ADV_TIMEOUT << 8));
|
||||
|
||||
goto ext_adv_disable;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
ext_adv_disable:
|
||||
handle = ull_adv_handle_get(adv);
|
||||
LL_ASSERT(handle < BT_CTLR_ADV_SET);
|
||||
|
||||
ret = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH,
|
||||
(TICKER_ID_ADV_BASE + handle), ticker_op_ext_stop_cb,
|
||||
adv);
|
||||
|
||||
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
||||
(ret == TICKER_STATUS_BUSY));
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
static int init_reset(void)
|
||||
{
|
||||
return 0;
|
||||
|
@ -1450,6 +1509,7 @@ static void ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t laz
|
|||
ticker_op_update_cb, adv);
|
||||
LL_ASSERT((ret == TICKER_STATUS_SUCCESS) ||
|
||||
(ret == TICKER_STATUS_BUSY));
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
adv->event_counter += (lazy + 1);
|
||||
|
||||
|
@ -1611,6 +1671,49 @@ static void conn_release(struct ll_adv_set *adv)
|
|||
}
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
static void ticker_op_ext_stop_cb(uint32_t status, void *param)
|
||||
{
|
||||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, NULL};
|
||||
struct ll_adv_set *adv;
|
||||
uint32_t ret;
|
||||
|
||||
/* Ignore if race between thread and ULL */
|
||||
if (status != TICKER_STATUS_SUCCESS) {
|
||||
/* TODO: detect race */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
adv = param;
|
||||
mfy.fp = ext_disabled_cb;
|
||||
mfy.param = &adv->lll;
|
||||
ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW, TICKER_USER_ID_ULL_HIGH, 0,
|
||||
&mfy);
|
||||
LL_ASSERT(!ret);
|
||||
}
|
||||
|
||||
static void ext_disabled_cb(void *param)
|
||||
{
|
||||
struct lll_adv *lll = (void *)param;
|
||||
struct node_rx_hdr *rx_hdr = (void *)lll->node_rx_adv_term;
|
||||
|
||||
/* Under race condition, if a connection has been established then
|
||||
* node_rx is already utilized to send terminate event on connection */
|
||||
if (!rx_hdr) {
|
||||
return;
|
||||
}
|
||||
|
||||
rx_hdr->type = NODE_RX_TYPE_EXT_ADV_TERMINATE;
|
||||
|
||||
/* NOTE: parameters are already populated on disable, just enqueue here
|
||||
*/
|
||||
ll_rx_put(rx_hdr->link, rx_hdr);
|
||||
ll_rx_sched();
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
static inline uint8_t disable(uint8_t handle)
|
||||
{
|
||||
uint32_t volatile ret_cb;
|
||||
|
@ -1683,14 +1786,16 @@ static inline uint8_t disable(uint8_t handle)
|
|||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
struct node_rx_pdu *node_rx_adv_term;
|
||||
struct lll_adv *lll = &adv->lll;
|
||||
|
||||
if (lll->node_rx_adv_term) {
|
||||
node_rx_adv_term = (struct node_rx_pdu *)lll->node_rx_adv_term;
|
||||
struct node_rx_pdu *node_rx_adv_term =
|
||||
(void *)lll->node_rx_adv_term;
|
||||
|
||||
lll->node_rx_adv_term = NULL;
|
||||
|
||||
ll_rx_link_release(node_rx_adv_term->hdr.link);
|
||||
ll_rx_release(node_rx_adv_term);
|
||||
lll->node_rx_adv_term = NULL;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
||||
|
|
|
@ -46,6 +46,10 @@ uint8_t ull_scan_rsp_set(struct ll_adv_set *adv, uint8_t len,
|
|||
uint8_t const *const data);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
|
||||
/* helper function to handle adv done events */
|
||||
void ull_adv_done(struct node_rx_event_done *done);
|
||||
|
||||
/* Helper functions to initialise and reset ull_adv_aux module */
|
||||
int ull_adv_aux_init(void);
|
||||
int ull_adv_aux_reset(void);
|
||||
|
|
|
@ -216,10 +216,7 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
|
|||
|
||||
#if defined(CONFIG_BT_CTLR_ADV_EXT)
|
||||
if (adv->is_created & ULL_ADV_CREATED_BITMASK_EXTENDED) {
|
||||
struct ull_hdr *ull;
|
||||
|
||||
ull = &adv->ull;
|
||||
|
||||
/* Enqueue connection or CSA event */
|
||||
ll_rx_put(link, rx);
|
||||
|
||||
/* use reserved link and node_rx to prepare
|
||||
|
@ -227,9 +224,11 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
|
|||
*/
|
||||
rx = adv->lll.node_rx_adv_term;
|
||||
link = rx->link;
|
||||
|
||||
rx->handle = ull_adv_handle_get(adv);
|
||||
rx->type = NODE_RX_TYPE_EXT_ADV_TERMINATE;
|
||||
rx->rx_ftr.extra = (void *)((uint32_t)lll->handle << 16);
|
||||
rx->rx_ftr.param = (void *)(uint32_t)lll->handle;
|
||||
rx->rx_ftr.extra = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue