From bedbd7fdee840f47ac6929328fb093306adc45c1 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 7 Jun 2017 13:11:47 +0200 Subject: [PATCH] Bluetooth: controller: Extended scan for nconn nscan w/o aux Update scanner implementation to receive ADV_EXT_IND PDUs. Jira: ZEP-2238 Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/hci/hci.c | 86 +++++++++++++++++++++ subsys/bluetooth/controller/ll_sw/ctrl.c | 53 ++++++++++++- subsys/bluetooth/controller/ll_sw/ctrl.h | 5 ++ subsys/bluetooth/controller/ll_sw/ll_scan.c | 18 +++++ 4 files changed, 160 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 501fa241f13..8ed72cc9e44 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -1357,6 +1357,78 @@ fill_report: } +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) +static void le_adv_ext_report(struct pdu_data *pdu_data, u8_t *b, + struct net_buf *buf, u8_t phy) +{ + struct pdu_adv *adv = (struct pdu_adv *)pdu_data; + u8_t rssi; + + rssi = b[offsetof(struct radio_pdu_node_rx, pdu_data) + + offsetof(struct pdu_adv, payload) + adv->len]; + + BT_WARN("phy= 0x%x, type= 0x%x, len= %u, tat= %u, rat= %u, rssi=-%u dB", + phy, adv->type, adv->len, adv->tx_addr, adv->rx_addr, rssi); + + if ((adv->type == PDU_ADV_TYPE_EXT_IND) && adv->len) { + struct pdu_adv_payload_com_ext_adv *p; + struct ext_adv_hdr *h; + u8_t *ptr; + + p = (void *)&adv->payload.adv_ext_ind; + h = (void *)p->ext_hdr_adi_adv_data; + ptr = (u8_t *)h + sizeof(*h); + + BT_WARN("Ext. adv mode= 0x%x, hdr len= %u", p->adv_mode, + p->ext_hdr_len); + + if (!p->ext_hdr_len) { + goto no_ext_hdr; + } + + if (h->adv_addr) { + char addr_str[BT_ADDR_LE_STR_LEN]; + bt_addr_le_t addr; + + addr.type = adv->tx_addr; + memcpy(&addr.a.val[0], ptr, sizeof(bt_addr_t)); + ptr += BDADDR_SIZE; + + bt_addr_le_to_str(&addr, addr_str, sizeof(addr_str)); + + BT_WARN("AdvA: %s", addr_str); + + } + + if (h->tx_pwr) { + s8_t tx_pwr; + + tx_pwr = *(s8_t *)ptr; + ptr++; + + BT_WARN("Tx pwr= %d dB", tx_pwr); + } + + /* TODO: length check? */ + } + +no_ext_hdr: + return; +} + +static void le_adv_ext_1M_report(struct pdu_data *pdu_data, u8_t *b, + struct net_buf *buf) +{ + le_adv_ext_report(pdu_data, b, buf, BIT(0)); +} + +static void le_adv_ext_coded_report(struct pdu_data *pdu_data, u8_t *b, + struct net_buf *buf) +{ + le_adv_ext_report(pdu_data, b, buf, BIT(2)); +} +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + #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) @@ -1562,6 +1634,16 @@ static void encode_control(struct radio_pdu_node_rx *node_rx, le_advertising_report(pdu_data, b, buf); break; +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + case NODE_RX_TYPE_EXT_1M_REPORT: + le_adv_ext_1M_report(pdu_data, b, buf); + break; + + case NODE_RX_TYPE_EXT_CODED_REPORT: + le_adv_ext_coded_report(pdu_data, b, buf); + break; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + #if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY) case NODE_RX_TYPE_SCAN_REQ: le_scan_req_received(pdu_data, b, buf); @@ -1917,6 +1999,10 @@ 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_ADV_EXT) + case NODE_RX_TYPE_EXT_1M_REPORT: + case NODE_RX_TYPE_EXT_CODED_REPORT: +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ #if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY) case NODE_RX_TYPE_SCAN_REQ: #endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */ diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.c b/subsys/bluetooth/controller/ll_sw/ctrl.c index 784c2c1d871..14dd40981da 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.c +++ b/subsys/bluetooth/controller/ll_sw/ctrl.c @@ -100,6 +100,11 @@ struct scanner { u8_t is_enabled:1; u8_t state:1; u8_t chan:2; + u8_t rfu:4; + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + u8_t phy:3; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ u8_t type:1; u8_t filter_policy:2; u8_t adv_addr_type:1; @@ -958,7 +963,28 @@ static u32_t isr_rx_scan_report(u8_t rssi_ready) /* Prepare the report (adv or scan resp) */ radio_pdu_node_rx->hdr.handle = 0xffff; - radio_pdu_node_rx->hdr.type = NODE_RX_TYPE_REPORT; + if (0) { +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + } else if (_radio.scanner.phy) { + switch (_radio.scanner.phy) { + case BIT(0): + radio_pdu_node_rx->hdr.type = + NODE_RX_TYPE_EXT_1M_REPORT; + break; + + case BIT(2): + radio_pdu_node_rx->hdr.type = + NODE_RX_TYPE_EXT_CODED_REPORT; + break; + + default: + LL_ASSERT(0); + break; + } +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + } else { + 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; @@ -1276,6 +1302,10 @@ static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready) ((pdu_adv_rx->payload.direct_ind.tgt_addr[5] & 0xc0) == 0x40)))) || (pdu_adv_rx->type == PDU_ADV_TYPE_NONCONN_IND) || (pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND) || +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + ((pdu_adv_rx->type == PDU_ADV_TYPE_EXT_IND) && + (_radio.scanner.phy)) || +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ ((pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_RSP) && (_radio.scanner.state != 0))) && (pdu_adv_rx->len != 0) && (!_radio.scanner.conn)) { @@ -4975,7 +5005,11 @@ static void event_scan(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, _radio.ticks_anchor = ticks_at_expire; _radio.scanner.state = 0; - adv_scan_configure(0, 0); /* TODO: Advertisement PHY */ +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + adv_scan_configure(_radio.scanner.phy, 1); /* if coded then use S8. */ +#else /* !CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + adv_scan_configure(0, 0); +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ chan_set(37 + _radio.scanner.chan++); if (_radio.scanner.chan == 3) { @@ -8289,6 +8323,11 @@ u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr, } _radio.scanner.type = type; + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + _radio.scanner.phy = type >> 1; +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + _radio.scanner.init_addr_type = init_addr_type; memcpy(&_radio.scanner.init_addr[0], init_addr, BDADDR_SIZE); _radio.scanner.ticks_window = @@ -9016,6 +9055,11 @@ void radio_rx_dequeue(void) case NODE_RX_TYPE_DC_PDU: case NODE_RX_TYPE_REPORT: +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + case NODE_RX_TYPE_EXT_1M_REPORT: + case NODE_RX_TYPE_EXT_CODED_REPORT: +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + #if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY) case NODE_RX_TYPE_SCAN_REQ: #endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */ @@ -9079,6 +9123,11 @@ void radio_rx_mem_release(struct radio_pdu_node_rx **radio_pdu_node_rx) case NODE_RX_TYPE_DC_PDU: case NODE_RX_TYPE_REPORT: +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + case NODE_RX_TYPE_EXT_1M_REPORT: + case NODE_RX_TYPE_EXT_CODED_REPORT: +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + #if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY) case NODE_RX_TYPE_SCAN_REQ: #endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */ diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.h b/subsys/bluetooth/controller/ll_sw/ctrl.h index 83963e56a27..a7af99cedc9 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.h +++ b/subsys/bluetooth/controller/ll_sw/ctrl.h @@ -222,6 +222,11 @@ enum radio_pdu_node_rx_type { NODE_RX_TYPE_DC_PDU, NODE_RX_TYPE_REPORT, +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + NODE_RX_TYPE_EXT_1M_REPORT, + NODE_RX_TYPE_EXT_CODED_REPORT, +#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + #if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY) NODE_RX_TYPE_SCAN_REQ, #endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */ diff --git a/subsys/bluetooth/controller/ll_sw/ll_scan.c b/subsys/bluetooth/controller/ll_sw/ll_scan.c index 7dadb985f4e..5d6a197efef 100644 --- a/subsys/bluetooth/controller/ll_sw/ll_scan.c +++ b/subsys/bluetooth/controller/ll_sw/ll_scan.c @@ -17,7 +17,13 @@ static struct { u16_t interval; u16_t window; + +#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) + u8_t type:4; +#else /* !CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ u8_t type:1; +#endif /* !CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */ + u8_t tx_addr:1; u8_t filter_policy:1; } ll_scan; @@ -29,6 +35,18 @@ u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window, return 0x0C; /* Command Disallowed */ } + /* type value: + * 0000b - legacy 1M passive + * 0001b - legacy 1M active + * 0010b - Ext. 1M passive + * 0011b - Ext. 1M active + * 0100b - invalid + * 0101b - invalid + * 0110b - invalid + * 0111b - invalid + * 1000b - Ext. Coded passive + * 1001b - Ext. Coded active + */ ll_scan.type = type; ll_scan.interval = interval; ll_scan.window = window;