Skip to content

Commit a8e1d1b

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 Kariappa Chettimada <[email protected]>
1 parent b031d76 commit a8e1d1b

File tree

5 files changed

+156
-31
lines changed

5 files changed

+156
-31
lines changed

subsys/bluetooth/controller/Kconfig

+11
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,17 @@ config BLUETOOTH_CONTROLLER_ADV_INDICATION
262262
help
263263
Generate events indicating on air advertisement events.
264264

265+
config BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY
266+
bool "Scan Request Notifications"
267+
help
268+
Generate events notifying the on air scan requests received.
269+
270+
config BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI
271+
bool "Measure Scan Request RSSI"
272+
depends on BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY
273+
help
274+
Measure RSSI of the on air scan requests received.
275+
265276
endmenu
266277

267278
comment "BLE Controller debug configuration"

subsys/bluetooth/controller/hci/hci.c

+45
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,45 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b,
12361236

12371237
}
12381238

1239+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
1240+
static void le_scan_req_received(struct pdu_data *pdu_data, u8_t *b,
1241+
struct net_buf *buf)
1242+
{
1243+
struct pdu_adv *adv = (struct pdu_adv *)pdu_data;
1244+
struct bt_hci_evt_le_scan_req_received *sep;
1245+
1246+
/* TODO: fill handle when Adv Ext. feature is implemented. */
1247+
1248+
if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) ||
1249+
!(le_event_mask & BT_EVT_MASK_LE_SCAN_REQ_RECEIVED)) {
1250+
char addr_str[BT_ADDR_LE_STR_LEN];
1251+
bt_addr_le_t addr;
1252+
u8_t handle;
1253+
u8_t rssi;
1254+
1255+
handle = 0;
1256+
addr.type = adv->tx_addr;
1257+
memcpy(&addr.a.val[0], &adv->payload.scan_req.scan_addr[0],
1258+
sizeof(bt_addr_t));
1259+
rssi = b[offsetof(struct radio_pdu_node_rx, pdu_data) +
1260+
offsetof(struct pdu_adv, payload) + adv->len];
1261+
1262+
bt_addr_le_to_str(&addr, addr_str, sizeof(addr_str));
1263+
1264+
BT_WARN("handle: %d, addr: %s, rssi: -%d dB.",
1265+
handle, addr_str, rssi);
1266+
1267+
return;
1268+
}
1269+
1270+
sep = meta_evt(buf, BT_HCI_EVT_LE_SCAN_REQ_RECEIVED, sizeof(*sep));
1271+
sep->handle = 0;
1272+
sep->addr.type = adv->tx_addr;
1273+
memcpy(&sep->addr.a.val[0], &adv->payload.scan_req.scan_addr[0],
1274+
sizeof(bt_addr_t));
1275+
}
1276+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
1277+
12391278
#if defined(CONFIG_BLUETOOTH_CONN)
12401279
static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle,
12411280
struct net_buf *buf)
@@ -1372,6 +1411,12 @@ static void encode_control(struct radio_pdu_node_rx *node_rx,
13721411
le_advertising_report(pdu_data, b, buf);
13731412
break;
13741413

1414+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
1415+
case NODE_RX_TYPE_SCAN_REQ:
1416+
le_scan_req_received(pdu_data, b, buf);
1417+
break;
1418+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
1419+
13751420
#if defined(CONFIG_BLUETOOTH_CONN)
13761421
case NODE_RX_TYPE_CONNECTION:
13771422
le_conn_complete(pdu_data, handle, buf);

subsys/bluetooth/controller/ll_sw/ctrl.c

+93-31
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,11 @@ static inline void isr_radio_state_tx(void)
531531
}
532532

533533
radio_tmr_end_capture();
534+
535+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI)
536+
radio_rssi_measure();
537+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_RSSI */
538+
534539
break;
535540

536541
case ROLE_OBS:
@@ -578,6 +583,37 @@ static inline void isr_radio_state_tx(void)
578583
}
579584
}
580585

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

596644
radio_switch_complete_and_disable();
597645

598-
/* TODO use rssi_ready to generate proprietary scan_req event */
599-
ARG_UNUSED(rssi_ready);
600-
601646
/* use the latest scan data, if any */
602647
if (_radio.advertiser.scan_data.first != _radio.
603648
advertiser.scan_data.last) {
@@ -829,6 +874,31 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t irkmatch_ok,
829874
return 1;
830875
}
831876

877+
static u32_t isr_rx_obs_report(u8_t rssi_ready)
878+
{
879+
struct radio_pdu_node_rx *radio_pdu_node_rx;
880+
struct pdu_adv *pdu_adv_rx;
881+
882+
radio_pdu_node_rx = packet_rx_reserve_get(3);
883+
if (radio_pdu_node_rx == 0) {
884+
return 1;
885+
}
886+
887+
/* Prepare the report (adv or scan resp) */
888+
radio_pdu_node_rx->hdr.handle = 0xffff;
889+
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
890+
891+
/* save the RSSI value */
892+
pdu_adv_rx = (struct pdu_adv *)radio_pdu_node_rx->pdu_data;
893+
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
894+
pdu_adv_rx->len] =
895+
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
896+
897+
packet_rx_enqueue();
898+
899+
return 0;
900+
}
901+
832902
static inline u32_t isr_rx_obs(u8_t irkmatch_id, u8_t rssi_ready)
833903
{
834904
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)
10841154
(pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND)) &&
10851155
(_radio.observer.scan_type != 0) &&
10861156
(_radio.observer.conn == 0)) {
1087-
struct radio_pdu_node_rx *radio_pdu_node_rx;
10881157
struct pdu_adv *pdu_adv_tx;
1089-
1090-
radio_pdu_node_rx = packet_rx_reserve_get(3);
1091-
if (radio_pdu_node_rx == 0) {
1092-
return 1;
1093-
}
1094-
1095-
/* save the RSSI value */
1096-
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
1097-
pdu_adv_rx->len] =
1098-
(rssi_ready) ? (radio_rssi_get() & 0x7F) : 0x7F;
1158+
u32_t err;
10991159

11001160
/* save the adv packet */
1101-
radio_pdu_node_rx->hdr.handle = 0xffff;
1102-
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
1103-
packet_rx_enqueue();
1161+
err = isr_rx_obs_report(rssi_ready);
1162+
if (err) {
1163+
return err;
1164+
}
11041165

11051166
/* prepare the scan request packet */
11061167
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)
11431204
((pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_RSP) &&
11441205
(_radio.observer.scan_state != 0))) &&
11451206
(pdu_adv_rx->len != 0) && (!_radio.observer.conn)) {
1146-
struct radio_pdu_node_rx *radio_pdu_node_rx;
1147-
1148-
radio_pdu_node_rx = packet_rx_reserve_get(3);
1149-
if (radio_pdu_node_rx == 0) {
1150-
return 1;
1151-
}
1152-
1153-
/* save the RSSI value */
1154-
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
1155-
pdu_adv_rx->len] =
1156-
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
1207+
u32_t err;
11571208

11581209
/* save the scan response packet */
1159-
radio_pdu_node_rx->hdr.handle = 0xffff;
1160-
radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT;
1161-
packet_rx_enqueue();
1210+
err = isr_rx_obs_report(rssi_ready);
1211+
if (err) {
1212+
return err;
1213+
}
11621214
}
11631215
/* invalid PDU */
11641216
else {
@@ -8196,6 +8248,11 @@ void radio_rx_dequeue(void)
81968248
switch (radio_pdu_node_rx->hdr.type) {
81978249
case NODE_RX_TYPE_DC_PDU:
81988250
case NODE_RX_TYPE_REPORT:
8251+
8252+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
8253+
case NODE_RX_TYPE_SCAN_REQ:
8254+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
8255+
81998256
case NODE_RX_TYPE_CONNECTION:
82008257
case NODE_RX_TYPE_CONN_UPDATE:
82018258
case NODE_RX_TYPE_ENC_REFRESH:
@@ -8250,6 +8307,11 @@ void radio_rx_mem_release(struct radio_pdu_node_rx **radio_pdu_node_rx)
82508307
switch (_radio_pdu_node_rx_free->hdr.type) {
82518308
case NODE_RX_TYPE_DC_PDU:
82528309
case NODE_RX_TYPE_REPORT:
8310+
8311+
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
8312+
case NODE_RX_TYPE_SCAN_REQ:
8313+
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
8314+
82538315
case NODE_RX_TYPE_CONNECTION:
82548316
case NODE_RX_TYPE_CONN_UPDATE:
82558317
case NODE_RX_TYPE_ENC_REFRESH:

subsys/bluetooth/controller/ll_sw/ctrl.h

+5
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

+2
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)