Skip to content

Commit a1bbfc5

Browse files
committed
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 Chettimada <vinayak.kariappa.chettimada@nordicsemi.no>
1 parent caad338 commit a1bbfc5

File tree

5 files changed

+156
-31
lines changed

5 files changed

+156
-31
lines changed

subsys/bluetooth/controller/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,17 @@ config BLUETOOTH_CONTROLLER_ADV_INDICATION
266266
help
267267
Generate events indicating on air advertisement events.
268268

269+
config BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY
270+
bool "Scan Request Notifications"
271+
help
272+
Generate events notifying the on air scan requests received.
273+
274+
config BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI
275+
bool "Measure Scan Request RSSI"
276+
depends on BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY
277+
help
278+
Measure RSSI of the on air scan requests received.
279+
269280
endmenu
270281

271282
comment "BLE Controller debug configuration"

subsys/bluetooth/controller/hci/hci.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,45 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b,
11141114

11151115
}
11161116

1117+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
1118+
static void le_scan_req_received(struct pdu_data *pdu_data, u8_t *b,
1119+
struct net_buf *buf)
1120+
{
1121+
struct pdu_adv *adv = (struct pdu_adv *)pdu_data;
1122+
struct bt_hci_evt_le_scan_req_received *sep;
1123+
1124+
/* TODO: fill handle when Adv Ext. feature is implemented. */
1125+
1126+
if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) ||
1127+
!(le_event_mask & BT_EVT_MASK_LE_SCAN_REQ_RECEIVED)) {
1128+
char addr_str[BT_ADDR_LE_STR_LEN];
1129+
bt_addr_le_t addr;
1130+
u8_t handle;
1131+
u8_t rssi;
1132+
1133+
handle = 0;
1134+
addr.type = adv->tx_addr;
1135+
memcpy(&addr.a.val[0], &adv->payload.scan_req.scan_addr[0],
1136+
sizeof(bt_addr_t));
1137+
rssi = b[offsetof(struct radio_pdu_node_rx, pdu_data) +
1138+
offsetof(struct pdu_adv, payload) + adv->len];
1139+
1140+
bt_addr_le_to_str(&addr, addr_str, sizeof(addr_str));
1141+
1142+
BT_WARN("handle: %d, addr: %s, rssi: -%d dB.",
1143+
handle, addr_str, rssi);
1144+
1145+
return;
1146+
}
1147+
1148+
sep = meta_evt(buf, BT_HCI_EVT_LE_SCAN_REQ_RECEIVED, sizeof(*sep));
1149+
sep->handle = 0;
1150+
sep->addr.type = adv->tx_addr;
1151+
memcpy(&sep->addr.a.val[0], &adv->payload.scan_req.scan_addr[0],
1152+
sizeof(bt_addr_t));
1153+
}
1154+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
1155+
11171156
static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle,
11181157
struct net_buf *buf)
11191158
{
@@ -1244,6 +1283,12 @@ static void encode_control(struct radio_pdu_node_rx *node_rx,
12441283
le_advertising_report(pdu_data, b, buf);
12451284
break;
12461285

1286+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
1287+
case NODE_RX_TYPE_SCAN_REQ:
1288+
le_scan_req_received(pdu_data, b, buf);
1289+
break;
1290+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
1291+
12471292
case NODE_RX_TYPE_CONNECTION:
12481293
le_conn_complete(pdu_data, handle, buf);
12491294
break;

subsys/bluetooth/controller/ll_sw/ctrl.c

Lines changed: 93 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,11 @@ static inline void isr_radio_state_tx(void)
529529
}
530530

531531
radio_tmr_end_capture();
532+
533+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI)
534+
radio_rssi_measure();
535+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI */
536+
532537
break;
533538

534539
case ROLE_OBS:
@@ -576,6 +581,37 @@ static inline void isr_radio_state_tx(void)
576581
}
577582
}
578583

584+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
585+
static u32_t isr_rx_adv_sr_report(struct pdu_adv *pdu_adv_rx, u8_t rssi_ready)
586+
{
587+
struct radio_pdu_node_rx *radio_pdu_node_rx;
588+
struct pdu_adv *pdu_adv;
589+
u8_t pdu_len;
590+
591+
radio_pdu_node_rx = packet_rx_reserve_get(3);
592+
if (radio_pdu_node_rx == 0) {
593+
return 1;
594+
}
595+
596+
/* Prepare the report (scan req) */
597+
radio_pdu_node_rx->hdr.handle = 0xffff;
598+
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_SCAN_REQ;
599+
600+
/* Make a copy of PDU into Rx node (as the received PDU is in the
601+
* scratch buffer), and save the RSSI value.
602+
*/
603+
pdu_adv = (struct pdu_adv *)radio_pdu_node_rx->pdu_data;
604+
pdu_len = offsetof(struct pdu_adv, payload) + pdu_adv_rx->len;
605+
memcpy(pdu_adv, pdu_adv_rx, pdu_len);
606+
((u8_t *)pdu_adv)[pdu_len] =
607+
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
608+
609+
packet_rx_enqueue();
610+
611+
return 0;
612+
}
613+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
614+
579615
static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok,
580616
u8_t irkmatch_id, u8_t rssi_ready)
581617
{
@@ -589,13 +625,22 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok,
589625
(((_radio.advertiser.filter_policy & 0x01) == 0) ||
590626
(devmatch_ok) || (irkmatch_ok)) &&
591627
(1 /** @todo own addr match check */)) {
628+
629+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
630+
u32_t err;
631+
632+
/* Generate the scan request event */
633+
err = isr_rx_adv_sr_report(pdu_adv, rssi_ready);
634+
if (err) {
635+
/* Scan Response will not be transmitted */
636+
return err;
637+
}
638+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
639+
592640
_radio.state = STATE_CLOSE;
593641

594642
radio_switch_complete_and_disable();
595643

596-
/* TODO use rssi_ready to generate proprietary scan_req event */
597-
ARG_UNUSED(rssi_ready);
598-
599644
/* use the latest scan data, if any */
600645
if (_radio.advertiser.scan_data.first != _radio.
601646
advertiser.scan_data.last) {
@@ -827,6 +872,31 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok,
827872
return 1;
828873
}
829874

875+
static u32_t isr_rx_obs_report(u8_t rssi_ready)
876+
{
877+
struct radio_pdu_node_rx *radio_pdu_node_rx;
878+
struct pdu_adv *pdu_adv_rx;
879+
880+
radio_pdu_node_rx = packet_rx_reserve_get(3);
881+
if (radio_pdu_node_rx == 0) {
882+
return 1;
883+
}
884+
885+
/* Prepare the report (adv or scan resp) */
886+
radio_pdu_node_rx->hdr.handle = 0xffff;
887+
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
888+
889+
/* save the RSSI value */
890+
pdu_adv_rx = (struct pdu_adv *)radio_pdu_node_rx->pdu_data;
891+
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
892+
pdu_adv_rx->len] =
893+
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
894+
895+
packet_rx_enqueue();
896+
897+
return 0;
898+
}
899+
830900
static inline u32_t isr_rx_obs(u8_t irkmatch_id, u8_t rssi_ready)
831901
{
832902
struct pdu_adv *pdu_adv_rx;
@@ -1082,23 +1152,14 @@ static inline u32_t isr_rx_obs(u8_t irkmatch_id, u8_t rssi_ready)
10821152
(pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
10831153
(_radio.observer.scan_type != 0) &&
10841154
(_radio.observer.conn == 0)) {
1085-
struct radio_pdu_node_rx *radio_pdu_node_rx;
10861155
struct pdu_adv *pdu_adv_tx;
1087-
1088-
radio_pdu_node_rx = packet_rx_reserve_get(3);
1089-
if (radio_pdu_node_rx == 0) {
1090-
return 1;
1091-
}
1092-
1093-
/* save the RSSI value */
1094-
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
1095-
pdu_adv_rx->len] =
1096-
(rssi_ready) ? (radio_rssi_get() & 0x7F) : 0x7F;
1156+
u32_t err;
10971157

10981158
/* save the adv packet */
1099-
radio_pdu_node_rx->hdr.handle = 0xffff;
1100-
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
1101-
packet_rx_enqueue();
1159+
err = isr_rx_obs_report(rssi_ready);
1160+
if (err) {
1161+
return err;
1162+
}
11021163

11031164
/* prepare the scan request packet */
11041165
pdu_adv_tx = (struct pdu_adv *)radio_pkt_scratch_get();
@@ -1140,22 +1201,13 @@ static inline u32_t isr_rx_obs(u8_t irkmatch_id, u8_t rssi_ready)
11401201
((pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_RSP) &&
11411202
(_radio.observer.scan_state != 0))) &&
11421203
(pdu_adv_rx->len != 0) && (!_radio.observer.conn)) {
1143-
struct radio_pdu_node_rx *radio_pdu_node_rx;
1144-
1145-
radio_pdu_node_rx = packet_rx_reserve_get(3);
1146-
if (radio_pdu_node_rx == 0) {
1147-
return 1;
1148-
}
1149-
1150-
/* save the RSSI value */
1151-
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
1152-
pdu_adv_rx->len] =
1153-
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
1204+
u32_t err;
11541205

11551206
/* save the scan response packet */
1156-
radio_pdu_node_rx->hdr.handle = 0xffff;
1157-
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
1158-
packet_rx_enqueue();
1207+
err = isr_rx_obs_report(rssi_ready);
1208+
if (err) {
1209+
return err;
1210+
}
11591211
}
11601212
/* invalid PDU */
11611213
else {
@@ -8188,6 +8240,11 @@ void radio_rx_dequeue(void)
81888240
switch (radio_pdu_node_rx->hdr.type) {
81898241
case NODE_RX_TYPE_DC_PDU:
81908242
case NODE_RX_TYPE_REPORT:
8243+
8244+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
8245+
case NODE_RX_TYPE_SCAN_REQ:
8246+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
8247+
81918248
case NODE_RX_TYPE_CONNECTION:
81928249
case NODE_RX_TYPE_CONN_UPDATE:
81938250
case NODE_RX_TYPE_ENC_REFRESH:
@@ -8242,6 +8299,11 @@ void radio_rx_mem_release(struct radio_pdu_node_rx **radio_pdu_node_rx)
82428299
switch (_radio_pdu_node_rx_free->hdr.type) {
82438300
case NODE_RX_TYPE_DC_PDU:
82448301
case NODE_RX_TYPE_REPORT:
8302+
8303+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
8304+
case NODE_RX_TYPE_SCAN_REQ:
8305+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
8306+
82458307
case NODE_RX_TYPE_CONNECTION:
82468308
case NODE_RX_TYPE_CONN_UPDATE:
82478309
case NODE_RX_TYPE_ENC_REFRESH:

subsys/bluetooth/controller/ll_sw/ctrl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ enum radio_pdu_node_rx_type {
199199
NODE_RX_TYPE_NONE,
200200
NODE_RX_TYPE_DC_PDU,
201201
NODE_RX_TYPE_REPORT,
202+
203+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
204+
NODE_RX_TYPE_SCAN_REQ,
205+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
206+
202207
NODE_RX_TYPE_CONNECTION,
203208
NODE_RX_TYPE_TERMINATE,
204209
NODE_RX_TYPE_CONN_UPDATE,

tests/bluetooth/init/prj_controller_dbg.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ CONFIG_BLUETOOTH_CONTROLLER_XTAL_ADVANCED=n
66
CONFIG_BLUETOOTH_CONTROLLER_SCHED_ADVANCED=n
77
CONFIG_BLUETOOTH_CONTROLLER_CONN_RSSI=y
88
CONFIG_BLUETOOTH_CONTROLLER_ADV_INDICATION=y
9+
CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY=y
10+
CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI=y
911
CONFIG_BLUETOOTH_CONTROLLER_PROFILE_ISR=y
1012
CONFIG_BLUETOOTH_PERIPHERAL=y
1113
CONFIG_BLUETOOTH_CENTRAL=y

0 commit comments

Comments
 (0)