Bluetooth: Controller: Vendor Specific: support for Scan Request Reports

Add support for vendor specific Set Scan Request Reports command and
Scan Request Received Event, available for legacy advertising.

Signed-off-by: Giancarlo Stasi <giancarlo.stasi.co@gmail.com>
This commit is contained in:
Giancarlo Stasi 2024-02-06 16:00:02 +01:00 committed by Fabio Baltieri
commit 95851583b8
4 changed files with 86 additions and 2 deletions

View file

@ -4802,6 +4802,10 @@ static void vs_read_supported_commands(struct net_buf *buf,
rp->commands[0] |= BIT(5) | BIT(7);
/* Read Static Addresses, Read Key Hierarchy Roots */
rp->commands[1] |= BIT(0) | BIT(1);
#if defined(CONFIG_BT_CTLR_VS_SCAN_REQ_RX)
/* Set Scan Request Reports */
rp->commands[1] |= BIT(4);
#endif /* CONFIG_BT_CTLR_VS_SCAN_REQ_RX */
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
/* Write Tx Power, Read Tx Power */
rp->commands[1] |= BIT(5) | BIT(6);
@ -4908,6 +4912,20 @@ static void vs_set_min_used_chans(struct net_buf *buf, struct net_buf **evt)
}
#endif /* CONFIG_BT_CTLR_MIN_USED_CHAN && CONFIG_BT_PERIPHERAL */
#if defined(CONFIG_BT_CTLR_VS_SCAN_REQ_RX)
static void vs_set_scan_req_reports(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_cp_vs_set_scan_req_reports *cmd = (void *)buf->data;
if (cmd->enable) {
vs_events_mask |= BT_EVT_MASK_VS_SCAN_REQ_RX;
} else {
vs_events_mask &= ~BT_EVT_MASK_VS_SCAN_REQ_RX;
}
*evt = cmd_complete_status(0x00);
}
#endif /* CONFIG_BT_CTLR_VS_SCAN_REQ_RX */
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
static void vs_write_tx_power_level(struct net_buf *buf, struct net_buf **evt)
{
@ -5470,6 +5488,12 @@ int hci_vendor_cmd_handle_common(uint16_t ocf, struct net_buf *cmd,
vs_read_key_hierarchy_roots(cmd, evt);
break;
#if defined(CONFIG_BT_CTLR_VS_SCAN_REQ_RX)
case BT_OCF(BT_HCI_OP_VS_SET_SCAN_REQ_REPORTS):
vs_set_scan_req_reports(cmd, evt);
break;
#endif /* CONFIG_BT_CTLR_VS_SCAN_REQ_RX */
#if defined(CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL)
case BT_OCF(BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL):
vs_write_tx_power_level(cmd, evt);
@ -7942,6 +7966,7 @@ static void le_big_terminate(struct pdu_data *pdu,
#endif /* CONFIG_BT_BROADCASTER */
#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
static void le_scan_req_received(struct pdu_data *pdu_data,
struct node_rx_pdu *node_rx,
struct net_buf *buf)
@ -7995,6 +8020,50 @@ static void le_scan_req_received(struct pdu_data *pdu_data,
sizeof(bt_addr_t));
}
}
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#if defined(CONFIG_BT_CTLR_VS_SCAN_REQ_RX)
static void le_vs_scan_req_received(struct pdu_data *pdu,
struct node_rx_pdu *node_rx,
struct net_buf *buf)
{
struct pdu_adv *adv = (void *)pdu;
struct bt_hci_evt_vs_scan_req_rx *sep;
#if defined(CONFIG_BT_CTLR_PRIVACY)
uint8_t rl_idx;
#endif
if (!(vs_events_mask & BT_EVT_MASK_VS_SCAN_REQ_RX)) {
return;
}
sep = vs_event(buf, BT_HCI_EVT_VS_SCAN_REQ_RX, sizeof(*sep));
sep->addr.type = adv->tx_addr;
memcpy(&sep->addr.a.val[0], &adv->scan_req.scan_addr[0],
sizeof(bt_addr_t));
#if defined(CONFIG_BT_CTLR_PRIVACY)
rl_idx = node_rx->hdr.rx_ftr.rl_idx;
if (rl_idx < ll_rl_size_get()) {
/* Store identity address */
ll_rl_id_addr_get(rl_idx, &sep->addr.type,
&sep->addr.a.val[0]);
/* Mark it as identity address from RPA (0x02, 0x03) */
sep->addr.type += 2U;
} else {
#else
if (1) {
#endif
sep->addr.type = adv->tx_addr;
memcpy(&sep->addr.a.val[0], &adv->adv_ind.addr[0],
sizeof(bt_addr_t));
}
/* The Link Layer currently returns RSSI as an absolute value */
sep->rssi = -(node_rx->hdr.rx_ftr.rssi);
}
#endif /* CONFIG_BT_CTLR_VS_SCAN_REQ_RX */
#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */
#if defined(CONFIG_BT_CONN)
@ -8371,7 +8440,13 @@ static void encode_control(struct node_rx_pdu *node_rx,
#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
case NODE_RX_TYPE_SCAN_REQ:
#if defined(CONFIG_BT_CTLR_ADV_EXT)
le_scan_req_received(pdu_data, node_rx, buf);
#elif defined(CONFIG_BT_CTLR_VS_SCAN_REQ_RX)
le_vs_scan_req_received(pdu_data, node_rx, buf);
#else
LL_ASSERT(0);
#endif /* CONFIG_BT_CTLR_ADV_EXT */
break;
#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */