andrzej-kaczmarek closed pull request #794: nimble: Fixes for extended scanner
URL: https://github.com/apache/mynewt-core/pull/794
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/net/nimble/controller/include/controller/ble_ll.h
b/net/nimble/controller/include/controller/ble_ll.h
index 97338dc68..f8a85fd66 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -259,7 +259,6 @@ struct ble_dev_addr
#define BLE_ADV_PDU_HDR_CHSEL_MASK (0x20)
#define BLE_ADV_PDU_HDR_TXADD_MASK (0x40)
#define BLE_ADV_PDU_HDR_RXADD_MASK (0x80)
-#define BLE_ADV_PDU_HDR_LEN_MASK (0x3F)
/* Advertising channel PDU types */
#define BLE_ADV_PDU_TYPE_ADV_IND (0)
diff --git a/net/nimble/controller/include/controller/ble_ll_scan.h
b/net/nimble/controller/include/controller/ble_ll_scan.h
index 95e9727a2..8a4cee537 100644
--- a/net/nimble/controller/include/controller/ble_ll_scan.h
+++ b/net/nimble/controller/include/controller/ble_ll_scan.h
@@ -226,7 +226,7 @@ int ble_ll_scan_ext_initiator_start(struct
hci_ext_create_conn *hcc,
/* Called to parse extended advertising*/
struct ble_ll_ext_adv;
-int ble_ll_scan_parse_ext_adv(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr,
+int ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr,
struct ble_ll_ext_adv *parsed_evt);
void ble_ll_scan_aux_data_free(struct ble_ll_aux_data *aux_scan);
diff --git a/net/nimble/controller/src/ble_ll.c
b/net/nimble/controller/src/ble_ll.c
index 649a59cc8..23d8d78de 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -935,7 +935,7 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
/* Get advertising PDU type and length */
pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
- len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
+ len = rxbuf[1];
/* If the CRC checks, make sure lengths check! */
badpkt = 0;
diff --git a/net/nimble/controller/src/ble_ll_conn.c
b/net/nimble/controller/src/ble_ll_conn.c
index 4c93391cd..d4d95566e 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -3107,7 +3107,7 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
rc = -1;
pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
- pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
+ pyld_len = rxbuf[1];
if (!crcok) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
diff --git a/net/nimble/controller/src/ble_ll_scan.c
b/net/nimble/controller/src/ble_ll_scan.c
index f1935d2c1..5aa984b9c 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -544,7 +544,7 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd)
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static struct ble_ll_ext_adv *
-ble_ll_scan_init_ext_adv(void)
+ble_ll_scan_init_ext_adv(struct ble_ll_ext_adv *copy_from)
{
struct ble_ll_ext_adv *evt;
@@ -554,20 +554,24 @@ ble_ll_scan_init_ext_adv(void)
return NULL;
}
- memset(evt, 0, sizeof(*evt));
-
- evt->event_meta = BLE_HCI_EVCODE_LE_META;
- evt->subevt = BLE_HCI_LE_SUBEV_EXT_ADV_RPT;
- /* We support only one report per event now */
- evt->num_reports = 1;
- /* Init TX Power with "Not available" which is 127 */
- evt->tx_power = 127;
- /* Init RSSI with "Not available" which is 127 */
- evt->rssi = 127;
- /* Init SID with "Not available" which is 0xFF */
- evt->sid = 0xFF;
- /* Init address type with "anonymous" which is 0xFF */
- evt->addr_type = 0xFF;
+ if (copy_from) {
+ memcpy(evt, copy_from, sizeof(*evt));
+ } else {
+ memset(evt, 0, sizeof(*evt));
+
+ evt->event_meta = BLE_HCI_EVCODE_LE_META;
+ evt->subevt = BLE_HCI_LE_SUBEV_EXT_ADV_RPT;
+ /* We support only one report per event now */
+ evt->num_reports = 1;
+ /* Init TX Power with "Not available" which is 127 */
+ evt->tx_power = 127;
+ /* Init RSSI with "Not available" which is 127 */
+ evt->rssi = 127;
+ /* Init SID with "Not available" which is 0xFF */
+ evt->sid = 0xFF;
+ /* Init address type with "anonymous" which is 0xFF */
+ evt->addr_type = 0xFF;
+ }
return evt;
}
@@ -591,7 +595,7 @@ ble_ll_hci_send_legacy_ext_adv_report(uint8_t evtype,
return -1;
}
- evt = ble_ll_scan_init_ext_adv();
+ evt = ble_ll_scan_init_ext_adv(NULL);
if (!evt) {
return 0;
}
@@ -745,7 +749,7 @@ ble_ll_scan_send_adv_report(uint8_t pdu_type, uint8_t
txadd, struct os_mbuf *om,
} else {
evtype = BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP;
}
- adv_data_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
+ adv_data_len = rxbuf[1];
adv_data_len -= BLE_DEV_ADDR_LEN;
event_len = BLE_HCI_LE_ADV_RPT_MIN_LEN + adv_data_len;
os_mbuf_adj(om, BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN);
@@ -1704,11 +1708,11 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
*
* @return int
* < 0 Error
- * == 0: Success.
+ * >= 0: Success (number of bytes left in PDU)
*
*/
int
-ble_ll_scan_parse_ext_adv(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr,
+ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr,
struct ble_ll_ext_adv *out_evt)
{
uint8_t pdu_len;
@@ -1796,22 +1800,6 @@ ble_ll_scan_parse_ext_adv(struct os_mbuf *om, struct
ble_mbuf_hdr *ble_hdr,
/* Skip ADAC if it is there */
i = ext_hdr_len;
- /* Adjust for advertising data */
- os_mbuf_adj(om, i);
-
- if ((pdu_len - i - 1 > 0)) {
- out_evt->adv_data_len = pdu_len - i - 1;
-
- /* XXX Drop packet if it does not fit into event buffer for now.*/
- if ((sizeof(*out_evt) + out_evt->adv_data_len) + 1 >
- MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) {
- STATS_INC(ble_ll_stats, adv_evt_dropped);
- return -1;
- }
-
- os_mbuf_copydata(om, 0, out_evt->adv_data_len, out_evt->adv_data);
- }
-
/* In the event we need information on primary and secondary PHY used
during
* advertising.
*/
@@ -1823,20 +1811,15 @@ ble_ll_scan_parse_ext_adv(struct os_mbuf *om, struct
ble_mbuf_hdr *ble_hdr,
out_evt->sec_phy = aux_data->aux_phy;
out_evt->prim_phy = aux_data->aux_primary_phy;
- /* Set event type */
- if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) {
- out_evt->evt_type |= (BLE_HCI_ADV_INCOMPLETE << 8);
- } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT))
{
- out_evt->evt_type |= (BLE_HCI_ADV_CORRUPTED << 8);
- }
-
if (BLE_MBUF_HDR_SCAN_RSP_RCV(ble_hdr)) {
out_evt->evt_type |= BLE_HCI_ADV_SCAN_RSP_MASK;
}
-done:
+ /* Adjust mbuf to contain advertising data only */
+ os_mbuf_adj(om, i);
- return 0;
+done:
+ return pdu_len - i - 1;
}
static int
@@ -2271,29 +2254,70 @@ static void
ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om,
struct ble_mbuf_hdr *hdr)
{
+ struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data;
struct ble_ll_ext_adv *evt;
- int rc;
+ struct ble_ll_ext_adv *next_evt;
+ int offset;
+ int datalen;
if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) {
return;
}
- evt = ble_ll_scan_init_ext_adv();
+ evt = ble_ll_scan_init_ext_adv(NULL);
if (!evt) {
return;
}
- rc = ble_ll_scan_parse_ext_adv(om, hdr, evt);
- if (rc) {
-
+ datalen = ble_ll_scan_parse_ext_hdr(om, hdr, evt);
+ if (datalen < 0) {
ble_hci_trans_buf_free((uint8_t *)evt);
return;
}
- evt->event_len = sizeof(struct ble_ll_ext_adv) + evt->adv_data_len;
- evt->rssi = hdr->rxinfo.rssi;
+ offset = 0;
+
+ do {
+ next_evt = NULL;
+
+ evt->adv_data_len = min(BLE_LL_MAX_EVT_LEN - sizeof(*evt),
+ datalen - offset);
+ os_mbuf_copydata(om, offset, evt->adv_data_len, evt->adv_data);
+
+ offset += evt->adv_data_len;
+
+ if (offset < datalen) {
+ /*
+ * We need to fragment this PDU as it does not fit in single HCI
+ * event. Subsequent event will have exactly the same header data.
+ * If we cannot allocate another HCI event from pool, just mark
+ * data as truncated.
+ */
+ next_evt = ble_ll_scan_init_ext_adv(evt);
+
+ if (next_evt) {
+ evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE);
+ } else {
+ evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED);
+ }
+ } else {
+ if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) {
+ evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE);
+ } else if (BLE_LL_CHECK_AUX_FLAG(aux_data,
BLE_LL_AUX_INCOMPLETE_ERR_BIT)) {
+ evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED);
+ }
+ }
+
+ evt->event_len = (sizeof(*evt) - BLE_HCI_EVENT_HDR_LEN) +
+ evt->adv_data_len;
+ evt->rssi = hdr->rxinfo.rssi;
+
+ ble_ll_hci_event_send((uint8_t *)evt);
+
+ evt = next_evt;
+ } while (evt);
- ble_ll_hci_event_send((uint8_t *)evt);
+ assert(offset <= datalen);
}
#endif
/**
diff --git a/net/nimble/include/nimble/hci_common.h
b/net/nimble/include/nimble/hci_common.h
index 482889d7f..52a676e0c 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -241,9 +241,10 @@ extern "C" {
#define BLE_HCI_ADV_SCAN_RSP_MASK (0x0008)
#define BLE_HCI_ADV_LEGACY_MASK (0x0010)
-#define BLE_HCI_ADV_COMPLETED (0x00)
-#define BLE_HCI_ADV_INCOMPLETE (0x01)
-#define BLE_HCI_ADV_CORRUPTED (0x10)
+#define BLE_HCI_ADV_DATA_STATUS_COMPLETE (0x0000)
+#define BLE_HCI_ADV_DATA_STATUS_INCOMPLETE (0x0020)
+#define BLE_HCI_ADV_DATA_STATUS_TRUNCATED (0x0040)
+#define BLE_HCI_ADV_DATA_STATUS_MASK (0x0060)
/* Own address types */
#define BLE_HCI_ADV_OWN_ADDR_PUBLIC (0)
diff --git a/net/nimble/transport/ram/syscfg.yml
b/net/nimble/transport/ram/syscfg.yml
index 60060771a..0323ace6c 100644
--- a/net/nimble/transport/ram/syscfg.yml
+++ b/net/nimble/transport/ram/syscfg.yml
@@ -40,6 +40,3 @@ syscfg.defs:
This is the maximum size of the data portion of HCI ACL data
packets. It does not include the HCI data header (of 4 bytes).
value: 255
-
-syscfg.vals.BLE_EXT_ADV:
- BLE_HCI_EVT_BUF_SIZE: 274
diff --git a/net/nimble/transport/socket/syscfg.yml
b/net/nimble/transport/socket/syscfg.yml
index bbb35f383..530850064 100644
--- a/net/nimble/transport/socket/syscfg.yml
+++ b/net/nimble/transport/socket/syscfg.yml
@@ -71,6 +71,3 @@ syscfg.defs:
BLE_SOCK_STACK_SIZE:
description: 'Size of the HCI socket stack (units=words).'
value: 80
-
-syscfg.vals.BLE_EXT_ADV:
- BLE_HCI_EVT_BUF_SIZE: 274
diff --git a/net/nimble/transport/uart/syscfg.yml
b/net/nimble/transport/uart/syscfg.yml
index 0ffa1da35..81b47f373 100644
--- a/net/nimble/transport/uart/syscfg.yml
+++ b/net/nimble/transport/uart/syscfg.yml
@@ -66,6 +66,3 @@ syscfg.defs:
BLE_HCI_UART_FLOW_CTRL:
description: 'Flow control used for HCI uart interface'
value: HAL_UART_FLOW_CTL_RTS_CTS
-
-syscfg.vals.BLE_EXT_ADV:
- BLE_HCI_EVT_BUF_SIZE: 274
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services