Bluetooth: controller: Scan Request Notifications
Implement the framework for LE Scan Request Received Event. The feature is available under the Controller's advanced features and will be selected implcitly when Bluetooth v5.0 LE Advertising Extensions feature is implemented. Jira: ZEP-2073 Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
a9a72f7bea
commit
fc6d8d1bc4
5 changed files with 159 additions and 31 deletions
|
@ -262,6 +262,17 @@ config BLUETOOTH_CONTROLLER_ADV_INDICATION
|
|||
help
|
||||
Generate events indicating on air advertisement events.
|
||||
|
||||
config BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY
|
||||
bool "Scan Request Notifications"
|
||||
help
|
||||
Generate events notifying the on air scan requests received.
|
||||
|
||||
config BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI
|
||||
bool "Measure Scan Request RSSI"
|
||||
depends on BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY
|
||||
help
|
||||
Measure RSSI of the on air scan requests received.
|
||||
|
||||
endmenu
|
||||
|
||||
comment "BLE Controller debug configuration"
|
||||
|
|
|
@ -1236,6 +1236,45 @@ fill_report:
|
|||
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||
static void le_scan_req_received(struct pdu_data *pdu_data, u8_t *b,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
struct pdu_adv *adv = (struct pdu_adv *)pdu_data;
|
||||
struct bt_hci_evt_le_scan_req_received *sep;
|
||||
|
||||
/* TODO: fill handle when Adv Ext. feature is implemented. */
|
||||
|
||||
if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) ||
|
||||
!(le_event_mask & BT_EVT_MASK_LE_SCAN_REQ_RECEIVED)) {
|
||||
char addr_str[BT_ADDR_LE_STR_LEN];
|
||||
bt_addr_le_t addr;
|
||||
u8_t handle;
|
||||
u8_t rssi;
|
||||
|
||||
handle = 0;
|
||||
addr.type = adv->tx_addr;
|
||||
memcpy(&addr.a.val[0], &adv->payload.scan_req.scan_addr[0],
|
||||
sizeof(bt_addr_t));
|
||||
rssi = b[offsetof(struct radio_pdu_node_rx, pdu_data) +
|
||||
offsetof(struct pdu_adv, payload) + adv->len];
|
||||
|
||||
bt_addr_le_to_str(&addr, addr_str, sizeof(addr_str));
|
||||
|
||||
BT_WARN("handle: %d, addr: %s, rssi: -%d dB.",
|
||||
handle, addr_str, rssi);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sep = meta_evt(buf, BT_HCI_EVT_LE_SCAN_REQ_RECEIVED, sizeof(*sep));
|
||||
sep->handle = 0;
|
||||
sep->addr.type = adv->tx_addr;
|
||||
memcpy(&sep->addr.a.val[0], &adv->payload.scan_req.scan_addr[0],
|
||||
sizeof(bt_addr_t));
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle,
|
||||
struct net_buf *buf)
|
||||
|
@ -1372,6 +1411,12 @@ static void encode_control(struct radio_pdu_node_rx *node_rx,
|
|||
le_advertising_report(pdu_data, b, buf);
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||
case NODE_RX_TYPE_SCAN_REQ:
|
||||
le_scan_req_received(pdu_data, b, buf);
|
||||
break;
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
case NODE_RX_TYPE_CONNECTION:
|
||||
le_conn_complete(pdu_data, handle, buf);
|
||||
|
@ -1706,6 +1751,9 @@ s8_t hci_get_class(struct radio_pdu_node_rx *node_rx)
|
|||
|
||||
switch (node_rx->hdr.type) {
|
||||
case NODE_RX_TYPE_REPORT:
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||
case NODE_RX_TYPE_SCAN_REQ:
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_INDICATION)
|
||||
case NODE_RX_TYPE_ADV_INDICATION:
|
||||
#endif
|
||||
|
|
|
@ -531,6 +531,11 @@ static inline void isr_radio_state_tx(void)
|
|||
}
|
||||
|
||||
radio_tmr_end_capture();
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI)
|
||||
radio_rssi_measure();
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI */
|
||||
|
||||
break;
|
||||
|
||||
case ROLE_OBS:
|
||||
|
@ -578,6 +583,37 @@ static inline void isr_radio_state_tx(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||
static u32_t isr_rx_adv_sr_report(struct pdu_adv *pdu_adv_rx, u8_t rssi_ready)
|
||||
{
|
||||
struct radio_pdu_node_rx *radio_pdu_node_rx;
|
||||
struct pdu_adv *pdu_adv;
|
||||
u8_t pdu_len;
|
||||
|
||||
radio_pdu_node_rx = packet_rx_reserve_get(3);
|
||||
if (radio_pdu_node_rx == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Prepare the report (scan req) */
|
||||
radio_pdu_node_rx->hdr.handle = 0xffff;
|
||||
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_SCAN_REQ;
|
||||
|
||||
/* Make a copy of PDU into Rx node (as the received PDU is in the
|
||||
* scratch buffer), and save the RSSI value.
|
||||
*/
|
||||
pdu_adv = (struct pdu_adv *)radio_pdu_node_rx->pdu_data;
|
||||
pdu_len = offsetof(struct pdu_adv, payload) + pdu_adv_rx->len;
|
||||
memcpy(pdu_adv, pdu_adv_rx, pdu_len);
|
||||
((u8_t *)pdu_adv)[pdu_len] =
|
||||
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
|
||||
|
||||
packet_rx_enqueue();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||
|
||||
static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok,
|
||||
u8_t irkmatch_id, u8_t rssi_ready)
|
||||
{
|
||||
|
@ -591,13 +627,22 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok,
|
|||
(((_radio.advertiser.filter_policy & 0x01) == 0) ||
|
||||
(devmatch_ok) || (irkmatch_ok)) &&
|
||||
(1 /** @todo own addr match check */)) {
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||
u32_t err;
|
||||
|
||||
/* Generate the scan request event */
|
||||
err = isr_rx_adv_sr_report(pdu_adv, rssi_ready);
|
||||
if (err) {
|
||||
/* Scan Response will not be transmitted */
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||
|
||||
_radio.state = STATE_CLOSE;
|
||||
|
||||
radio_switch_complete_and_disable();
|
||||
|
||||
/* TODO use rssi_ready to generate proprietary scan_req event */
|
||||
ARG_UNUSED(rssi_ready);
|
||||
|
||||
/* use the latest scan data, if any */
|
||||
if (_radio.advertiser.scan_data.first != _radio.
|
||||
advertiser.scan_data.last) {
|
||||
|
@ -829,6 +874,31 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static u32_t isr_rx_obs_report(u8_t rssi_ready)
|
||||
{
|
||||
struct radio_pdu_node_rx *radio_pdu_node_rx;
|
||||
struct pdu_adv *pdu_adv_rx;
|
||||
|
||||
radio_pdu_node_rx = packet_rx_reserve_get(3);
|
||||
if (radio_pdu_node_rx == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Prepare the report (adv or scan resp) */
|
||||
radio_pdu_node_rx->hdr.handle = 0xffff;
|
||||
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
|
||||
|
||||
/* save the RSSI value */
|
||||
pdu_adv_rx = (struct pdu_adv *)radio_pdu_node_rx->pdu_data;
|
||||
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
|
||||
pdu_adv_rx->len] =
|
||||
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
|
||||
|
||||
packet_rx_enqueue();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32_t isr_rx_obs(u8_t irkmatch_id, u8_t rssi_ready)
|
||||
{
|
||||
struct pdu_adv *pdu_adv_rx;
|
||||
|
@ -1084,23 +1154,14 @@ static inline u32_t isr_rx_obs(u8_t irkmatch_id, u8_t rssi_ready)
|
|||
(pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
|
||||
(_radio.observer.scan_type != 0) &&
|
||||
(_radio.observer.conn == 0)) {
|
||||
struct radio_pdu_node_rx *radio_pdu_node_rx;
|
||||
struct pdu_adv *pdu_adv_tx;
|
||||
|
||||
radio_pdu_node_rx = packet_rx_reserve_get(3);
|
||||
if (radio_pdu_node_rx == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* save the RSSI value */
|
||||
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
|
||||
pdu_adv_rx->len] =
|
||||
(rssi_ready) ? (radio_rssi_get() & 0x7F) : 0x7F;
|
||||
u32_t err;
|
||||
|
||||
/* save the adv packet */
|
||||
radio_pdu_node_rx->hdr.handle = 0xffff;
|
||||
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
|
||||
packet_rx_enqueue();
|
||||
err = isr_rx_obs_report(rssi_ready);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* prepare the scan request packet */
|
||||
pdu_adv_tx = (struct pdu_adv *)radio_pkt_scratch_get();
|
||||
|
@ -1143,22 +1204,13 @@ static inline u32_t isr_rx_obs(u8_t irkmatch_id, u8_t rssi_ready)
|
|||
((pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_RSP) &&
|
||||
(_radio.observer.scan_state != 0))) &&
|
||||
(pdu_adv_rx->len != 0) && (!_radio.observer.conn)) {
|
||||
struct radio_pdu_node_rx *radio_pdu_node_rx;
|
||||
|
||||
radio_pdu_node_rx = packet_rx_reserve_get(3);
|
||||
if (radio_pdu_node_rx == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* save the RSSI value */
|
||||
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
|
||||
pdu_adv_rx->len] =
|
||||
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
|
||||
u32_t err;
|
||||
|
||||
/* save the scan response packet */
|
||||
radio_pdu_node_rx->hdr.handle = 0xffff;
|
||||
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
|
||||
packet_rx_enqueue();
|
||||
err = isr_rx_obs_report(rssi_ready);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
/* invalid PDU */
|
||||
else {
|
||||
|
@ -8196,6 +8248,11 @@ void radio_rx_dequeue(void)
|
|||
switch (radio_pdu_node_rx->hdr.type) {
|
||||
case NODE_RX_TYPE_DC_PDU:
|
||||
case NODE_RX_TYPE_REPORT:
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||
case NODE_RX_TYPE_SCAN_REQ:
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||
|
||||
case NODE_RX_TYPE_CONNECTION:
|
||||
case NODE_RX_TYPE_CONN_UPDATE:
|
||||
case NODE_RX_TYPE_ENC_REFRESH:
|
||||
|
@ -8250,6 +8307,11 @@ void radio_rx_mem_release(struct radio_pdu_node_rx **radio_pdu_node_rx)
|
|||
switch (_radio_pdu_node_rx_free->hdr.type) {
|
||||
case NODE_RX_TYPE_DC_PDU:
|
||||
case NODE_RX_TYPE_REPORT:
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||
case NODE_RX_TYPE_SCAN_REQ:
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||
|
||||
case NODE_RX_TYPE_CONNECTION:
|
||||
case NODE_RX_TYPE_CONN_UPDATE:
|
||||
case NODE_RX_TYPE_ENC_REFRESH:
|
||||
|
|
|
@ -199,6 +199,11 @@ enum radio_pdu_node_rx_type {
|
|||
NODE_RX_TYPE_NONE,
|
||||
NODE_RX_TYPE_DC_PDU,
|
||||
NODE_RX_TYPE_REPORT,
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||
NODE_RX_TYPE_SCAN_REQ,
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||
|
||||
NODE_RX_TYPE_CONNECTION,
|
||||
NODE_RX_TYPE_TERMINATE,
|
||||
NODE_RX_TYPE_CONN_UPDATE,
|
||||
|
|
|
@ -6,6 +6,8 @@ CONFIG_BLUETOOTH_CONTROLLER_XTAL_ADVANCED=n
|
|||
CONFIG_BLUETOOTH_CONTROLLER_SCHED_ADVANCED=n
|
||||
CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI=y
|
||||
CONFIG_BLUETOOTH_CONTROLLER_ADV_INDICATION=y
|
||||
CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY=y
|
||||
CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI=y
|
||||
CONFIG_BLUETOOTH_CONTROLLER_PROFILE_ISR=y
|
||||
CONFIG_BLUETOOTH_PERIPHERAL=y
|
||||
CONFIG_BLUETOOTH_CENTRAL=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue