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;
|
struct bt_hci_cp_le_big_terminate_sync *cmd = (void *)buf->data;
|
||||||
uint8_t status;
|
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);
|
*evt = cmd_complete_status(status);
|
||||||
}
|
}
|
||||||
|
@ -3243,7 +3244,7 @@ static int controller_cmd_handle(uint16_t ocf, struct net_buf *cmd,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BT_OCF(BT_HCI_OP_LE_BIG_TERMINATE_SYNC):
|
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;
|
break;
|
||||||
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
|
#endif /* CONFIG_BT_CTLR_SYNC_ISO */
|
||||||
#endif /* CONFIG_BT_OBSERVER */
|
#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,
|
uint8_t encryption, uint8_t *bcode, uint8_t mse,
|
||||||
uint16_t sync_timeout, uint8_t num_bis,
|
uint16_t sync_timeout, uint8_t num_bis,
|
||||||
uint8_t *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 */
|
#else /* !CONFIG_BT_CTLR_ADV_EXT */
|
||||||
uint8_t ll_scan_enable(uint8_t enable);
|
uint8_t ll_scan_enable(uint8_t enable);
|
||||||
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
|
#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;
|
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 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;
|
int err;
|
||||||
|
|
||||||
sync_iso = ull_sync_iso_get(big_handle);
|
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;
|
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ull_ticker_stop_with_mark(
|
sync = sync_iso->sync;
|
||||||
TICKER_ID_SCAN_SYNC_ISO_BASE + big_handle,
|
if (sync) {
|
||||||
sync_iso, &sync_iso->lll);
|
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);
|
LL_ASSERT(err == 0 || err == -EALREADY);
|
||||||
if (err) {
|
if (err) {
|
||||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
big_sync_lost = sync_iso->node_rx_lost.link;
|
link_sync_lost = sync_iso->node_rx_lost.hdr.link;
|
||||||
ll_rx_link_release(big_sync_lost);
|
ll_rx_link_release(link_sync_lost);
|
||||||
|
|
||||||
big_sync_estab = sync_iso->node_rx_estab.link;
|
|
||||||
ll_rx_link_release(big_sync_estab);
|
|
||||||
|
|
||||||
ull_sync_iso_release(sync_iso);
|
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 node_rx_hdr *node_rx,
|
||||||
struct pdu_biginfo *biginfo)
|
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;
|
uint32_t ticks_slot_overhead;
|
||||||
|
struct node_rx_sync_iso *se;
|
||||||
uint32_t ticks_slot_offset;
|
uint32_t ticks_slot_offset;
|
||||||
uint32_t ret;
|
struct lll_sync_iso *lll;
|
||||||
struct node_rx_ftr *ftr;
|
struct node_rx_ftr *ftr;
|
||||||
uint32_t sync_offset_us;
|
uint32_t sync_offset_us;
|
||||||
struct node_rx_pdu *rx;
|
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;
|
lll = &sync_iso->lll;
|
||||||
handle = ull_sync_iso_handle_get(sync_iso);
|
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 */
|
/* 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.type = NODE_RX_TYPE_SYNC_ISO;
|
||||||
rx->hdr.handle = handle;
|
rx->hdr.handle = handle;
|
||||||
rx->hdr.rx_ftr.param = sync_iso;
|
rx->hdr.rx_ftr.param = sync_iso;
|
||||||
|
|
|
@ -294,6 +294,7 @@ static void test_iso_recv_main(void)
|
||||||
uint8_t encryption = 0;
|
uint8_t encryption = 0;
|
||||||
uint8_t bcode[16] = { 0 };
|
uint8_t bcode[16] = { 0 };
|
||||||
uint16_t sync_timeout = 0;
|
uint16_t sync_timeout = 0;
|
||||||
|
struct node_rx_hdr *node_rx;
|
||||||
|
|
||||||
printk("Creating BIG...\n");
|
printk("Creating BIG...\n");
|
||||||
err = ll_big_sync_create(big_handle, sync->handle, encryption, bcode,
|
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));
|
k_sleep(K_MSEC(5000));
|
||||||
|
|
||||||
printk("Terminating BIG...\n");
|
printk("Terminating BIG...\n");
|
||||||
err = ll_big_sync_terminate(big_handle);
|
err = ll_big_sync_terminate(big_handle, (void **)&node_rx);
|
||||||
if (err) {
|
if (err) {
|
||||||
FAIL("Could not terminate BIG sync: %d\n", err);
|
FAIL("Could not terminate BIG sync: %d\n", err);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue