From 8d6cc495057dd5aa1b5e3d3029ec82bac0289123 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Thu, 25 May 2023 15:42:45 +0200 Subject: [PATCH] nimble/host: Add BIGInfo report event This allows to receive BIGInfo reports in periodic advertisement sync callback function --- nimble/controller/syscfg.yml | 2 +- nimble/host/include/host/ble_gap.h | 49 ++++++++++++++++++++++++++++++ nimble/host/src/ble_gap.c | 41 +++++++++++++++++++++++++ nimble/host/src/ble_gap_priv.h | 3 ++ nimble/host/src/ble_hs_hci_evt.c | 23 ++++++++++++++ nimble/host/src/ble_hs_startup.c | 10 ++++++ nimble/syscfg.yml | 8 ++++- 7 files changed, 134 insertions(+), 2 deletions(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index bff7b966e..55c20cf1f 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -367,7 +367,7 @@ syscfg.defs: description: > This option is used to enable/disable support for handling BIGInfo data - value: 0 + value: MYNEWT_VAL(BLE_BIGINFO_REPORTS) BLE_LL_SCAN_AUX_SEGMENT_CNT: description: > diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index a5dadfbdf..09139994c 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -141,6 +141,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_PARING_COMPLETE 27 #define BLE_GAP_EVENT_SUBRATE_CHANGE 28 #define BLE_GAP_EVENT_VS_HCI 29 +#define BLE_GAP_EVENT_BIGINFO_REPORT 30 /*** Reason codes for the subscribe GAP event. */ @@ -982,6 +983,54 @@ struct ble_gap_event { } periodic_transfer; #endif +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) + /** + * Represents a periodic advertising sync transfer received. Valid for + * the following event types: + * o BLE_GAP_EVENT_BIGINFO_REPORT + */ + struct { + /** Synchronization handle */ + uint16_t sync_handle; + + /** Number of present BISes */ + uint8_t bis_cnt; + + /** Number of SubEvents */ + uint8_t nse; + + /** ISO Interval */ + uint16_t iso_interval; + + /** Burst Number */ + uint8_t bn; + + /** Pre-Transmission Offset */ + uint8_t pto; + + /** Immediate Repetition Count */ + uint8_t irc; + + /** Maximum PDU size */ + uint16_t max_pdu; + + /** Maximum SDU size */ + uint16_t max_sdu; + + /** Service Data Unit Interval */ + uint32_t sdu_interval; + + /** BIG PHY */ + uint8_t phy; + + /** Framing of BIS Data PDUs */ + uint8_t framing : 1; + + /** Encryption */ + uint8_t encryption : 1; + } biginfo_report; +#endif + #if MYNEWT_VAL(BLE_POWER_CONTROL) /** * Represents a change in either local transmit power or remote transmit diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index add9ea529..92023a491 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1849,6 +1849,47 @@ ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_ ble_hs_unlock(); + cb(&event, cb_arg); +} +#endif + +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +void +ble_gap_rx_biginfo_adv_rpt(const struct ble_hci_ev_le_subev_biginfo_adv_report *ev) +{ + struct ble_hs_periodic_sync *psync; + struct ble_gap_event event; + ble_gap_event_fn *cb; + void *cb_arg; + + cb = NULL; + cb_arg = NULL; + + ble_hs_lock(); + psync = ble_hs_periodic_sync_find_by_handle(le16toh(ev->sync_handle)); + if (psync) { + cb = psync->cb; + cb_arg = psync->cb_arg; + } + ble_hs_unlock(); + + memset(&event, 0, sizeof event); + + event.type = BLE_GAP_EVENT_BIGINFO_REPORT; + event.biginfo_report.sync_handle = ev->sync_handle; + event.biginfo_report.bis_cnt = ev->bis_cnt; + event.biginfo_report.nse = ev->nse; + event.biginfo_report.iso_interval = ev->iso_interval; + event.biginfo_report.bn = ev->bn; + event.biginfo_report.pto = ev->pto; + event.biginfo_report.irc = ev->irc; + event.biginfo_report.max_pdu = ev->max_pdu; + event.biginfo_report.sdu_interval = get_le24(&ev->sdu_interval[0]); + event.biginfo_report.max_sdu = ev->max_sdu; + event.biginfo_report.phy = ev->phy; + event.biginfo_report.framing = ev->framing; + event.biginfo_report.encryption = ev->encryption; + ble_gap_event_listener_call(&event); if (cb) { cb(&event, cb_arg); diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 1c3f92b74..d7fb76094 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -88,6 +88,9 @@ void ble_gap_rx_periodic_adv_rpt(const struct ble_hci_ev_le_subev_periodic_adv_r void ble_gap_rx_periodic_adv_sync_lost(const struct ble_hci_ev_le_subev_periodic_adv_sync_lost *ev); void ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_adv_sync_transfer *ev); #endif +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +void ble_gap_rx_biginfo_adv_rpt(const struct ble_hci_ev_le_subev_biginfo_adv_report *ev); +#endif void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev); #endif void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc); diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 1699c645b..b91e771c0 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -63,6 +63,9 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_biginfo_adv_report; +#endif #if MYNEWT_VAL(BLE_POWER_CONTROL) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_pathloss_threshold; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_transmit_power_report; @@ -128,6 +131,9 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED] = ble_hs_hci_evt_le_adv_set_terminated, [BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD] = ble_hs_hci_evt_le_scan_req_rcvd, [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) + [BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT] = ble_hs_hci_evt_le_biginfo_adv_report, +#endif #if MYNEWT_VAL(BLE_POWER_CONTROL) [BLE_HCI_LE_SUBEV_PATH_LOSS_THRESHOLD] = ble_hs_hci_evt_le_pathloss_threshold, [BLE_HCI_LE_SUBEV_TRANSMIT_POWER_REPORT] = ble_hs_hci_evt_le_transmit_power_report, @@ -723,6 +729,23 @@ ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, return 0; } +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +static int +ble_hs_hci_evt_le_biginfo_adv_report(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_biginfo_adv_report *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_EBADDATA; + } + + ble_gap_rx_biginfo_adv_rpt(ev); + + return 0; +} +#endif + static int ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, const void *data, unsigned int len) diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 7509fd5e4..15e50bf06 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -261,6 +261,16 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) + if (version >= BLE_HCI_VER_BCS_5_2) { + /** + * Enable the following LE events: + * 0x0000000200000000 LE BIGInfo Advertising Report event + */ + mask |= 0x0000000200000000; + } +#endif + cmd.event_mask = htole64(mask); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index a50bc89e6..17caf410c 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -68,7 +68,13 @@ syscfg.defs: restrictions: - 'BLE_PERIODIC_ADV if 1' - '(BLE_ROLE_CENTRAL || BLE_ROLE_PERIPHERAL) if 1' - + BLE_BIGINFO_REPORTS: + description: > + This enables BIGInfo reports. + value: 0 + restrictions: + - 'BLE_PERIODIC_ADV if 1' + - '(BLE_VERSION >= 52) if 1' BLE_EXT_ADV_MAX_SIZE: description: > This allows to configure maximum size of advertising data and