Bluetooth: controller: Fix BIG Sync Terminate command
Fix BIG Sync Terminate Command to generate Sync Established event if Sync initiation is in progress. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
eaa0215c74
commit
abcee4dc2b
4 changed files with 61 additions and 23 deletions
|
@ -1524,12 +1524,13 @@ static void le_big_create_sync(struct net_buf *buf, struct net_buf **evt)
|
|||
}
|
||||
|
||||
|
||||
static void le_big_terminate_sync(struct net_buf *buf, struct net_buf **evt)
|
||||
static void le_big_terminate_sync(struct net_buf *buf, struct net_buf **evt,
|
||||
void **node_rx)
|
||||
{
|
||||
struct bt_hci_cp_le_big_terminate_sync *cmd = (void *)buf->data;
|
||||
uint8_t status;
|
||||
|
||||
status = ll_big_sync_terminate(cmd->big_handle);
|
||||
status = ll_big_sync_terminate(cmd->big_handle, node_rx);
|
||||
|
||||
*evt = cmd_complete_status(status);
|
||||
}
|
||||
|
@ -3243,7 +3244,7 @@ static int controller_cmd_handle(uint16_t ocf, struct net_buf *cmd,
|
|||
break;
|
||||
|
||||
case BT_OCF(BT_HCI_OP_LE_BIG_TERMINATE_SYNC):
|
||||
le_big_terminate_sync(cmd, evt);
|
||||
le_big_terminate_sync(cmd, evt, node_rx);
|
||||
break;
|
||||
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
|
||||
#endif /* CONFIG_BT_OBSERVER */
|
||||
|
|
|
@ -147,7 +147,7 @@ uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
|
|||
uint8_t encryption, uint8_t *bcode, uint8_t mse,
|
||||
uint16_t sync_timeout, uint8_t num_bis,
|
||||
uint8_t *bis);
|
||||
uint8_t ll_big_sync_terminate(uint8_t big_handle);
|
||||
uint8_t ll_big_sync_terminate(uint8_t big_handle, void **rx);
|
||||
#else /* !CONFIG_BT_CTLR_ADV_EXT */
|
||||
uint8_t ll_scan_enable(uint8_t enable);
|
||||
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
|
||||
|
|
|
@ -114,11 +114,13 @@ uint8_t ll_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
|
|||
return BT_HCI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t ll_big_sync_terminate(uint8_t big_handle)
|
||||
uint8_t ll_big_sync_terminate(uint8_t big_handle, void **rx)
|
||||
{
|
||||
memq_link_t *big_sync_estab;
|
||||
memq_link_t *big_sync_lost;
|
||||
struct ll_sync_iso *sync_iso;
|
||||
struct node_rx_pdu *node_rx;
|
||||
memq_link_t *link_sync_estab;
|
||||
memq_link_t *link_sync_lost;
|
||||
struct ll_sync_set *sync;
|
||||
int err;
|
||||
|
||||
sync_iso = ull_sync_iso_get(big_handle);
|
||||
|
@ -126,19 +128,53 @@ uint8_t ll_big_sync_terminate(uint8_t big_handle)
|
|||
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
|
||||
}
|
||||
|
||||
err = ull_ticker_stop_with_mark(
|
||||
TICKER_ID_SCAN_SYNC_ISO_BASE + big_handle,
|
||||
sync_iso, &sync_iso->lll);
|
||||
sync = sync_iso->sync;
|
||||
if (sync) {
|
||||
struct node_rx_sync_iso *se;
|
||||
|
||||
if (sync->iso.sync_iso != sync_iso) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
sync->iso.sync_iso = NULL;
|
||||
sync_iso->sync = NULL;
|
||||
|
||||
node_rx = (void *)sync->iso.node_rx_estab;
|
||||
link_sync_estab = node_rx->hdr.link;
|
||||
link_sync_lost = sync_iso->node_rx_lost.hdr.link;
|
||||
|
||||
ll_rx_link_release(link_sync_lost);
|
||||
ll_rx_link_release(link_sync_estab);
|
||||
ll_rx_release(node_rx);
|
||||
|
||||
node_rx = (void *)&sync_iso->node_rx_lost;
|
||||
node_rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
|
||||
node_rx->hdr.handle = 0xffff;
|
||||
|
||||
/* NOTE: struct node_rx_lost has uint8_t member following the
|
||||
* struct node_rx_hdr to store the reason.
|
||||
*/
|
||||
se = (void *)node_rx->pdu;
|
||||
se->status = BT_HCI_ERR_OP_CANCELLED_BY_HOST;
|
||||
|
||||
/* NOTE: Since NODE_RX_TYPE_SYNC_ISO is only generated from ULL
|
||||
* context, pass ULL context as parameter.
|
||||
*/
|
||||
node_rx->hdr.rx_ftr.param = sync_iso;
|
||||
|
||||
*rx = node_rx;
|
||||
|
||||
return BT_HCI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
err = ull_ticker_stop_with_mark((TICKER_ID_SCAN_SYNC_ISO_BASE +
|
||||
big_handle), sync_iso, &sync_iso->lll);
|
||||
LL_ASSERT(err == 0 || err == -EALREADY);
|
||||
if (err) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
big_sync_lost = sync_iso->node_rx_lost.link;
|
||||
ll_rx_link_release(big_sync_lost);
|
||||
|
||||
big_sync_estab = sync_iso->node_rx_estab.link;
|
||||
ll_rx_link_release(big_sync_estab);
|
||||
link_sync_lost = sync_iso->node_rx_lost.hdr.link;
|
||||
ll_rx_link_release(link_sync_lost);
|
||||
|
||||
ull_sync_iso_release(sync_iso);
|
||||
|
||||
|
@ -198,17 +234,17 @@ void ull_sync_iso_setup(struct ll_sync_iso *sync_iso,
|
|||
struct node_rx_hdr *node_rx,
|
||||
struct pdu_biginfo *biginfo)
|
||||
{
|
||||
uint16_t handle;
|
||||
struct node_rx_sync_iso *se;
|
||||
uint16_t interval;
|
||||
uint32_t interval_us;
|
||||
uint32_t ticks_slot_overhead;
|
||||
struct node_rx_sync_iso *se;
|
||||
uint32_t ticks_slot_offset;
|
||||
uint32_t ret;
|
||||
struct lll_sync_iso *lll;
|
||||
struct node_rx_ftr *ftr;
|
||||
uint32_t sync_offset_us;
|
||||
struct node_rx_pdu *rx;
|
||||
struct lll_sync_iso *lll;
|
||||
uint32_t interval_us;
|
||||
uint16_t interval;
|
||||
uint16_t handle;
|
||||
uint32_t ret;
|
||||
|
||||
lll = &sync_iso->lll;
|
||||
handle = ull_sync_iso_handle_get(sync_iso);
|
||||
|
@ -218,7 +254,7 @@ void ull_sync_iso_setup(struct ll_sync_iso *sync_iso,
|
|||
|
||||
/* TODO: Populate LLL with information from the BIGINFO */
|
||||
|
||||
rx = (void *)sync_iso->node_rx_estab.link;
|
||||
rx = (void *)sync_iso->sync->iso.node_rx_estab;
|
||||
rx->hdr.type = NODE_RX_TYPE_SYNC_ISO;
|
||||
rx->hdr.handle = handle;
|
||||
rx->hdr.rx_ftr.param = sync_iso;
|
||||
|
|
|
@ -294,6 +294,7 @@ static void test_iso_recv_main(void)
|
|||
uint8_t encryption = 0;
|
||||
uint8_t bcode[16] = { 0 };
|
||||
uint16_t sync_timeout = 0;
|
||||
struct node_rx_hdr *node_rx;
|
||||
|
||||
printk("Creating BIG...\n");
|
||||
err = ll_big_sync_create(big_handle, sync->handle, encryption, bcode,
|
||||
|
@ -307,7 +308,7 @@ static void test_iso_recv_main(void)
|
|||
k_sleep(K_MSEC(5000));
|
||||
|
||||
printk("Terminating BIG...\n");
|
||||
err = ll_big_sync_terminate(big_handle);
|
||||
err = ll_big_sync_terminate(big_handle, (void **)&node_rx);
|
||||
if (err) {
|
||||
FAIL("Could not terminate BIG sync: %d\n", err);
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue