Bluetooth: Controller: Initial support for Periodic Sync Receive enable
Initial support for Periodic Advertising Synchronization Receive Enable command. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
1686551395
commit
64eaa52e41
3 changed files with 68 additions and 21 deletions
|
@ -3551,6 +3551,22 @@ static void le_per_adv_recv_enable(struct net_buf *buf, struct net_buf **evt)
|
||||||
|
|
||||||
status = ll_sync_recv_enable(handle, cmd->enable);
|
status = ll_sync_recv_enable(handle, cmd->enable);
|
||||||
|
|
||||||
|
#if CONFIG_BT_CTLR_DUP_FILTER_LEN > 0
|
||||||
|
if (!status) {
|
||||||
|
if (cmd->enable &
|
||||||
|
BT_HCI_LE_SET_PER_ADV_RECV_ENABLE_FILTER_DUPLICATE) {
|
||||||
|
if (!dup_scan || (dup_count < 0)) {
|
||||||
|
dup_count = 0;
|
||||||
|
dup_curr = 0U;
|
||||||
|
} else {
|
||||||
|
/* FIXME: Invalidate dup_ext_adv_mode array entries */
|
||||||
|
}
|
||||||
|
} else if (!dup_scan) {
|
||||||
|
dup_count = DUP_FILTER_DISABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ccst = hci_cmd_complete(evt, sizeof(*ccst));
|
ccst = hci_cmd_complete(evt, sizeof(*ccst));
|
||||||
ccst->status = status;
|
ccst->status = status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -619,6 +619,7 @@ static void isr_aux_setup(void *param)
|
||||||
static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8_t rssi_ready,
|
static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8_t rssi_ready,
|
||||||
enum sync_status status)
|
enum sync_status status)
|
||||||
{
|
{
|
||||||
|
uint8_t sched = 0U;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Check CRC and generate Periodic Advertising Report */
|
/* Check CRC and generate Periodic Advertising Report */
|
||||||
|
@ -626,7 +627,8 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8
|
||||||
struct node_rx_pdu *node_rx;
|
struct node_rx_pdu *node_rx;
|
||||||
|
|
||||||
node_rx = ull_pdu_rx_alloc_peek(3);
|
node_rx = ull_pdu_rx_alloc_peek(3);
|
||||||
if (node_rx) {
|
if (node_rx &&
|
||||||
|
(lll->is_rx_enabled || (node_type == NODE_RX_TYPE_SYNC))) {
|
||||||
struct node_rx_ftr *ftr;
|
struct node_rx_ftr *ftr;
|
||||||
struct pdu_adv *pdu;
|
struct pdu_adv *pdu;
|
||||||
|
|
||||||
|
@ -660,25 +662,31 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, uint8
|
||||||
|
|
||||||
ull_rx_put(node_rx->hdr.link, node_rx);
|
ull_rx_put(node_rx->hdr.link, node_rx);
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
|
sched = 1U;
|
||||||
(void)create_iq_report(lll, rssi_ready,
|
|
||||||
BT_HCI_LE_CTE_CRC_OK);
|
|
||||||
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
|
|
||||||
|
|
||||||
ull_rx_sched();
|
|
||||||
} else {
|
} else {
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
|
||||||
|
(void)create_iq_report(lll, rssi_ready, BT_HCI_LE_CTE_CRC_OK);
|
||||||
|
sched = 1U;
|
||||||
|
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
#if defined(CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC)
|
#if defined(CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC)
|
||||||
err = create_iq_report(lll, rssi_ready, BT_HCI_LE_CTE_CRC_ERR_CTE_BASED_TIME);
|
err = create_iq_report(lll, rssi_ready, BT_HCI_LE_CTE_CRC_ERR_CTE_BASED_TIME);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
ull_rx_sched();
|
sched = 1U;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC */
|
#endif /* CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC */
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sched) {
|
||||||
|
ull_rx_sched();
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_type,
|
||||||
lll_sync->filter_policy = scan->per_scan.filter_policy;
|
lll_sync->filter_policy = scan->per_scan.filter_policy;
|
||||||
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
|
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
|
||||||
|
|
||||||
/* TODO: Add support for reporting initially enabled/disabled */
|
/* Reporting initially enabled/disabled */
|
||||||
lll_sync->is_rx_enabled =
|
lll_sync->is_rx_enabled =
|
||||||
!(options & BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_REPORTS_DISABLED);
|
!(options & BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_REPORTS_DISABLED);
|
||||||
|
|
||||||
|
@ -361,8 +361,27 @@ uint8_t ll_sync_terminate(uint16_t handle)
|
||||||
|
|
||||||
uint8_t ll_sync_recv_enable(uint16_t handle, uint8_t enable)
|
uint8_t ll_sync_recv_enable(uint16_t handle, uint8_t enable)
|
||||||
{
|
{
|
||||||
/* TODO: Add support for reporting enable/disable */
|
struct ll_sync_set *sync;
|
||||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
struct lll_sync *lll;
|
||||||
|
|
||||||
|
sync = ull_sync_is_enabled_get(handle);
|
||||||
|
if (!sync) {
|
||||||
|
return BT_HCI_ERR_UNKNOWN_ADV_IDENTIFIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reporting enabled/disabled */
|
||||||
|
lll = &sync->lll;
|
||||||
|
lll->is_rx_enabled = (enable &
|
||||||
|
BT_HCI_LE_SET_PER_ADV_RECV_ENABLE_ENABLE) ?
|
||||||
|
1U : 0U;
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_ADI_SUPPORT)
|
||||||
|
sync->nodups = (enable &
|
||||||
|
BT_HCI_LE_SET_PER_ADV_RECV_ENABLE_FILTER_DUPLICATE) ?
|
||||||
|
1U : 0U;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ull_sync_init(void)
|
int ull_sync_init(void)
|
||||||
|
@ -716,6 +735,7 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
|
||||||
struct lll_sync *lll;
|
struct lll_sync *lll;
|
||||||
|
|
||||||
ftr = &rx->rx_ftr;
|
ftr = &rx->rx_ftr;
|
||||||
|
lll = ftr->param;
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING)
|
#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING)
|
||||||
enum sync_status sync_status;
|
enum sync_status sync_status;
|
||||||
|
@ -725,8 +745,6 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
|
||||||
#else
|
#else
|
||||||
struct pdu_cte_info *rx_cte_info;
|
struct pdu_cte_info *rx_cte_info;
|
||||||
|
|
||||||
lll = ftr->param;
|
|
||||||
|
|
||||||
rx_cte_info = pdu_cte_info_get((struct pdu_adv *)((struct node_rx_pdu *)rx)->pdu);
|
rx_cte_info = pdu_cte_info_get((struct pdu_adv *)((struct node_rx_pdu *)rx)->pdu);
|
||||||
if (rx_cte_info != NULL) {
|
if (rx_cte_info != NULL) {
|
||||||
sync_status = lll_sync_cte_is_allowed(lll->cte_type, lll->filter_policy,
|
sync_status = lll_sync_cte_is_allowed(lll->cte_type, lll->filter_policy,
|
||||||
|
@ -741,14 +759,14 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
|
||||||
* or the CTE type is incorrect and filter policy doesn't allow to continue scanning.
|
* or the CTE type is incorrect and filter policy doesn't allow to continue scanning.
|
||||||
*/
|
*/
|
||||||
if (sync_status != SYNC_STAT_READY_OR_CONT_SCAN) {
|
if (sync_status != SYNC_STAT_READY_OR_CONT_SCAN) {
|
||||||
#else
|
#else /* !CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
|
||||||
|
|
||||||
if (1) {
|
if (1) {
|
||||||
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
|
#endif /* !CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
|
||||||
|
|
||||||
/* Set the sync handle corresponding to the LLL context passed in the node rx
|
/* Set the sync handle corresponding to the LLL context passed in the node rx
|
||||||
* footer field.
|
* footer field.
|
||||||
*/
|
*/
|
||||||
lll = ftr->param;
|
|
||||||
ull_sync = HDR_LLL2ULL(lll);
|
ull_sync = HDR_LLL2ULL(lll);
|
||||||
|
|
||||||
/* Prepare and dispatch sync notification */
|
/* Prepare and dispatch sync notification */
|
||||||
|
@ -783,15 +801,20 @@ void ull_sync_established_report(memq_link_t *link, struct node_rx_hdr *rx)
|
||||||
* scanning is terminated due to wrong CTE type.
|
* scanning is terminated due to wrong CTE type.
|
||||||
*/
|
*/
|
||||||
if (sync_status != SYNC_STAT_TERM) {
|
if (sync_status != SYNC_STAT_TERM) {
|
||||||
#else
|
#else /* !CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
|
||||||
|
|
||||||
if (1) {
|
if (1) {
|
||||||
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
|
#endif /* !CONFIG_BT_CTLR_SYNC_PERIODIC_CTE_TYPE_FILTERING */
|
||||||
/* Switch sync event prepare function to one reposnsible for regular PDUs receive */
|
/* Switch sync event prepare function to one reposnsible for regular PDUs receive */
|
||||||
mfy_lll_prepare.fp = lll_sync_prepare;
|
mfy_lll_prepare.fp = lll_sync_prepare;
|
||||||
|
|
||||||
/* Change node type to appropriately handle periodic advertising PDU report */
|
if (lll->is_rx_enabled) {
|
||||||
rx->type = NODE_RX_TYPE_SYNC_REPORT;
|
/* Change node type to appropriately handle periodic
|
||||||
ull_scan_aux_setup(link, rx);
|
* advertising PDU report.
|
||||||
|
*/
|
||||||
|
rx->type = NODE_RX_TYPE_SYNC_REPORT;
|
||||||
|
ull_scan_aux_setup(link, rx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue