This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 06bc61ee35103c9bccf4e1515f47887de691fc63
Author: Michal Gorecki <michal.gore...@codecoup.pl>
AuthorDate: Thu May 25 15:39:20 2023 +0200

    nimble/ll: Add HCI events for BIGInfo reports
---
 nimble/controller/include/controller/ble_ll.h |  1 +
 nimble/controller/src/ble_ll_sync.c           | 92 ++++++++++++++++++++++++++-
 nimble/controller/syscfg.yml                  |  6 ++
 3 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll.h 
b/nimble/controller/include/controller/ble_ll.h
index 35b562a9..c4e70e6e 100644
--- a/nimble/controller/include/controller/ble_ll.h
+++ b/nimble/controller/include/controller/ble_ll.h
@@ -475,6 +475,7 @@ struct ble_dev_addr
 
 /* ACAD data types */
 #define BLE_LL_ACAD_CHANNEL_MAP_UPDATE_IND 0x28
+#define BLE_LL_ACAD_BIGINFO                0x2C
 
 struct ble_ll_acad_channel_map_update_ind {
     uint8_t map[5];
diff --git a/nimble/controller/src/ble_ll_sync.c 
b/nimble/controller/src/ble_ll_sync.c
index f06f87c1..f10a5993 100644
--- a/nimble/controller/src/ble_ll_sync.c
+++ b/nimble/controller/src/ble_ll_sync.c
@@ -66,6 +66,9 @@
 
 #define BLE_LL_SYNC_ITVL_USECS              1250
 
+#define BLE_LL_SYNC_BIGINFO_LEN             33
+#define BLE_LL_SYNC_BIGINFO_LEN_ENC         57
+
 struct ble_ll_sync_sm {
     uint16_t flags;
 
@@ -661,6 +664,70 @@ ble_ll_sync_send_truncated_per_adv_rpt(struct 
ble_ll_sync_sm *sm, uint8_t *evbuf
     ble_ll_hci_event_send(hci_ev);
 }
 
+#if MYNEWT_VAL(BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS)
+static void
+ble_ll_sync_parse_biginfo_to_ev(struct ble_hci_ev_le_subev_biginfo_adv_report 
*ev,
+                                const uint8_t *biginfo, uint8_t biginfo_len)
+{
+    uint32_t fields_buf;
+
+    fields_buf = get_le32(&biginfo[0]);
+    ev->iso_interval = (fields_buf >> 15) & 0x0FFF;
+    ev->bis_cnt = (fields_buf >> 27) & 0x1F;
+
+    fields_buf = get_le32(&biginfo[4]);
+    ev->nse = fields_buf & 0x1F;
+    ev->bn = (fields_buf >> 5) & 0x07;
+    ev->pto = (fields_buf >> 28) & 0x0F;
+
+    fields_buf = get_le32(&biginfo[8]);
+    ev->irc = (fields_buf >> 20) & 0x0F;
+    ev->max_pdu = (fields_buf >> 24) & 0xFF;
+
+    fields_buf = get_le32(&biginfo[17]);
+    ev->sdu_interval[0] = fields_buf & 0xFF;
+    ev->sdu_interval[1] = (fields_buf >> 8) & 0xFF;
+    ev->sdu_interval[2] = (fields_buf >> 16) & 0x0F;
+    ev->max_sdu = (fields_buf >> 20) & 0x0FFF;
+
+    ev->phy = (biginfo[27] >> 5) & 0x07;
+
+    ev->framing = (biginfo[32] >> 7) & 0x01;
+
+    if (biginfo_len == BLE_LL_SYNC_BIGINFO_LEN_ENC) {
+        ev->encryption = 1;
+    } else {
+        ev->encryption = 0;
+    }
+}
+
+static void
+ble_ll_sync_send_biginfo_adv_rpt(struct ble_ll_sync_sm *sm, const uint8_t 
*biginfo, uint8_t biginfo_len)
+{
+    struct ble_hci_ev_le_subev_biginfo_adv_report *ev;
+    struct ble_hci_ev *hci_ev;
+
+    if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT)) {
+        return;
+    }
+
+    hci_ev = ble_transport_alloc_evt(1);
+    if (!hci_ev) {
+        return;
+    }
+
+    hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
+    hci_ev->length = sizeof(*ev);
+    ev = (void *) hci_ev->data;
+
+    ev->subev_code = BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT;
+    ev->sync_handle = htole16(ble_ll_sync_get_handle(sm));
+    ble_ll_sync_parse_biginfo_to_ev(ev, biginfo, biginfo_len);
+
+    ble_ll_hci_event_send(hci_ev);
+}
+#endif
+
 static void
 ble_ll_sync_send_per_adv_rpt(struct ble_ll_sync_sm *sm, struct os_mbuf *rxpdu,
                              int8_t rssi, int8_t tx_power, int datalen,
@@ -963,7 +1030,8 @@ ble_ll_sync_check_failed(struct ble_ll_sync_sm *sm)
 
 static bool
 ble_ll_sync_check_acad(struct ble_ll_sync_sm *sm,
-                       const uint8_t *acad, uint8_t acad_len)
+                       const uint8_t *acad, uint8_t acad_len,
+                       const uint8_t **biginfo, uint8_t *biginfo_len)
 {
     const struct ble_ll_acad_channel_map_update_ind *chmu;
     unsigned int ad_len;
@@ -1009,6 +1077,18 @@ ble_ll_sync_check_acad(struct ble_ll_sync_sm *sm,
             sm->chan_map_new_instant = le16toh(chmu->instant);
             sm->flags |= BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP;
             break;
+
+#if MYNEWT_VAL(BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS)
+        case BLE_LL_ACAD_BIGINFO:
+            if ((ad_len - 1 == BLE_LL_SYNC_BIGINFO_LEN) || (ad_len - 1 == 
BLE_LL_SYNC_BIGINFO_LEN_ENC)) {
+                *biginfo = &acad[2];
+                *biginfo_len = ad_len - 1;
+            } else {
+                return false;
+            }
+            break;
+#endif
+
         default:
             break;
         }
@@ -1034,6 +1114,8 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct 
ble_mbuf_hdr *hdr)
     uint8_t *aux = NULL;
     uint8_t *acad = NULL;
     uint8_t acad_len;
+    const uint8_t *biginfo = NULL;
+    uint8_t biginfo_len = 0;
     int datalen;
     bool reports_enabled;
 
@@ -1099,7 +1181,7 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct 
ble_mbuf_hdr *hdr)
     }
 
     /* check ACAD, needs to be done before rxpdu is adjusted for ADV data  */
-    if (acad && !ble_ll_sync_check_acad(sm, acad, acad_len)) {
+    if (acad && !ble_ll_sync_check_acad(sm, acad, acad_len, &biginfo, 
&biginfo_len)) {
         /* we got bad packet (bad ACAD data), end event */
         goto end_event;
     }
@@ -1117,6 +1199,12 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct 
ble_mbuf_hdr *hdr)
         /* send reports from this PDU */
         ble_ll_sync_send_per_adv_rpt(sm, rxpdu, hdr->rxinfo.rssi, tx_power,
                                      datalen, aux, aux_scheduled);
+
+#if MYNEWT_VAL(BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS)
+        if (biginfo) {
+            ble_ll_sync_send_biginfo_adv_rpt(sm, biginfo, biginfo_len);
+        }
+#endif
     }
 
     /* if chain was scheduled we don't end event yet */
diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml
index 34039bb0..bff7b966 100644
--- a/nimble/controller/syscfg.yml
+++ b/nimble/controller/syscfg.yml
@@ -363,6 +363,12 @@ syscfg.defs:
         restrictions:
             - 'BLE_LL_CFG_FEAT_LL_ISO if 1'
 
+    BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS:
+        description: >
+            This option is used to enable/disable support for
+            handling BIGInfo data
+        value: 0
+
     BLE_LL_SCAN_AUX_SEGMENT_CNT:
          description: >
             Number of auxiliary advertising segments that can be scanned

Reply via email to