[Bugfix] Extended advertisements not reporting full data.

Extended advertisement reports would be truncated incorrectly as the handler was not checking the data status.

Correct advertisement length and set status on update.
This commit is contained in:
h2zero
2025-09-05 08:55:10 -06:00
parent e8f7147ac5
commit 1ffd013794
3 changed files with 37 additions and 5 deletions

View File

@@ -38,6 +38,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice(const ble_gap_event* event, uint8
m_callbackSent{0},
m_advLength{event->ext_disc.length_data},
m_isLegacyAdv{!!(event->ext_disc.props & BLE_HCI_ADV_LEGACY_MASK)},
m_dataStatus{event->ext_disc.data_status},
m_sid{event->ext_disc.sid},
m_primPhy{event->ext_disc.prim_phy},
m_secPhy{event->ext_disc.sec_phy},
@@ -60,6 +61,15 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice(const ble_gap_event* event, uint8
void NimBLEAdvertisedDevice::update(const ble_gap_event* event, uint8_t eventType) {
# if MYNEWT_VAL(BLE_EXT_ADV)
const auto& disc = event->ext_disc;
if (m_dataStatus == BLE_GAP_EXT_ADV_DATA_STATUS_INCOMPLETE) {
m_payload.reserve(m_advLength + disc.length_data);
m_payload.insert(m_payload.end(), disc.data, disc.data + disc.length_data);
m_dataStatus = disc.data_status;
m_advLength = m_payload.size();
return;
}
m_dataStatus = disc.data_status;
m_isLegacyAdv = disc.props & BLE_HCI_ADV_LEGACY_MASK;
# else
const auto& disc = event->disc;
@@ -617,6 +627,18 @@ uint8_t NimBLEAdvertisedDevice::getSecondaryPhy() const {
uint16_t NimBLEAdvertisedDevice::getPeriodicInterval() const {
return m_periodicItvl;
} // getPeriodicInterval
/**
* @brief Get the advertisement data status.
* @return The advertisement data status.
* One of:
* * BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE (0) - Complete extended advertising data
* * BLE_GAP_EXT_ADV_DATA_STATUS_INCOMPLETE (1) - Incomplete extended advertising data, more to come
* * BLE_GAP_EXT_ADV_DATA_STATUS_TRUNCATED (2) - Incomplete extended advertising data, no more to come
*/
uint8_t NimBLEAdvertisedDevice::getDataStatus() const {
return m_dataStatus;
} // getDataStatus
# endif
uint8_t NimBLEAdvertisedDevice::findAdvField(uint8_t type, uint8_t index, size_t* data_loc) const {

View File

@@ -92,6 +92,7 @@ class NimBLEAdvertisedDevice {
uint8_t getPrimaryPhy() const;
uint8_t getSecondaryPhy() const;
uint16_t getPeriodicInterval() const;
uint8_t getDataStatus() const;
# endif
operator NimBLEAddress() const;
@@ -165,6 +166,7 @@ class NimBLEAdvertisedDevice {
# if MYNEWT_VAL(BLE_EXT_ADV)
bool m_isLegacyAdv{};
uint8_t m_dataStatus{};
uint8_t m_sid{};
uint8_t m_primPhy{};
uint8_t m_secPhy{};

View File

@@ -115,14 +115,22 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
advertisedDevice = new NimBLEAdvertisedDevice(event, event_type);
pScan->m_scanResults.m_deviceVec.push_back(advertisedDevice);
NIMBLE_LOGI(LOG_TAG, "New advertiser: %s", advertisedAddress.toString().c_str());
#if MYNEWT_VAL(BLE_EXT_ADV)
if (advertisedDevice->getDataStatus() == BLE_GAP_EXT_ADV_DATA_STATUS_INCOMPLETE) {
NIMBLE_LOGI(LOG_TAG, " EXT ADV data incomplete, waiting for more...");
return 0;
}
#endif
} else {
advertisedDevice->update(event, event_type);
if (isLegacyAdv && event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
if (isLegacyAdv) {
if (event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
NIMBLE_LOGI(LOG_TAG, "Scan response from: %s", advertisedAddress.toString().c_str());
} else {
NIMBLE_LOGI(LOG_TAG, "Duplicate; updated: %s", advertisedAddress.toString().c_str());
}
}
}
if (!advertisedDevice->m_callbackSent) {
advertisedDevice->m_callbackSent++;