From 7706f5a6b203fcf75326aae31ad6f69c4b3cc7f9 Mon Sep 17 00:00:00 2001 From: h2zero Date: Fri, 5 Sep 2025 14:11:27 -0600 Subject: [PATCH] Support up to 1650 bytes of advertisement with extended advertising. --- src/NimBLEAdvertisedDevice.cpp | 2 +- src/NimBLEAdvertisedDevice.h | 4 ++-- src/NimBLEExtAdvertising.cpp | 21 ++++++++++++++++++++- src/NimBLEScan.cpp | 13 +++++++------ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/NimBLEAdvertisedDevice.cpp b/src/NimBLEAdvertisedDevice.cpp index 476b0e4..c4db793 100644 --- a/src/NimBLEAdvertisedDevice.cpp +++ b/src/NimBLEAdvertisedDevice.cpp @@ -752,7 +752,7 @@ std::string NimBLEAdvertisedDevice::toString() const { * @brief Get the length of the advertisement data in the payload. * @return The number of bytes in the payload that is from the advertisement. */ -uint8_t NimBLEAdvertisedDevice::getAdvLength() const { +uint16_t NimBLEAdvertisedDevice::getAdvLength() const { return m_advLength; } diff --git a/src/NimBLEAdvertisedDevice.h b/src/NimBLEAdvertisedDevice.h index f775a99..246692c 100644 --- a/src/NimBLEAdvertisedDevice.h +++ b/src/NimBLEAdvertisedDevice.h @@ -69,7 +69,7 @@ class NimBLEAdvertisedDevice { NimBLEAddress getTargetAddress(uint8_t index = 0) const; uint8_t getTargetAddressCount() const; int8_t getTXPower() const; - uint8_t getAdvLength() const; + uint16_t getAdvLength() const; uint8_t getAddressType() const; bool isAdvertisingService(const NimBLEUUID& uuid) const; bool haveAppearance() const; @@ -162,7 +162,7 @@ class NimBLEAdvertisedDevice { uint8_t m_advType{}; int8_t m_rssi{}; uint8_t m_callbackSent{}; - uint8_t m_advLength{}; + uint16_t m_advLength{}; # if MYNEWT_VAL(BLE_EXT_ADV) bool m_isLegacyAdv{}; diff --git a/src/NimBLEExtAdvertising.cpp b/src/NimBLEExtAdvertising.cpp index 3e0062a..d3f78c3 100644 --- a/src/NimBLEExtAdvertising.cpp +++ b/src/NimBLEExtAdvertising.cpp @@ -616,6 +616,11 @@ bool NimBLEExtAdvertisement::setFlags(uint8_t flag) { * @return True if successful. */ bool NimBLEExtAdvertisement::setManufacturerData(const uint8_t* data, size_t length) { + if (length > 0xFF - 1) { + NIMBLE_LOGE(LOG_TAG, "Manufacturer data too long!"); + return false; + } + uint8_t header[2]; header[0] = length + 1; header[1] = BLE_HS_ADV_TYPE_MFG_DATA; @@ -652,6 +657,11 @@ bool NimBLEExtAdvertisement::setManufacturerData(const std::vector& dat * @return True if successful. */ bool NimBLEExtAdvertisement::setURI(const std::string& uri) { + if (uri.length() > 0xFF - 1) { + NIMBLE_LOGE(LOG_TAG, "URI too long!"); + return false; + } + uint8_t header[2]; header[0] = uri.length() + 1; header[1] = BLE_HS_ADV_TYPE_URI; @@ -670,6 +680,11 @@ bool NimBLEExtAdvertisement::setURI(const std::string& uri) { * @return True if successful. */ bool NimBLEExtAdvertisement::setName(const std::string& name, bool isComplete) { + if (name.length() > 0xFF - 1) { + NIMBLE_LOGE(LOG_TAG, "Name too long!"); + return false; + } + uint8_t header[2]; header[0] = name.length() + 1; header[1] = isComplete ? BLE_HS_ADV_TYPE_COMP_NAME : BLE_HS_ADV_TYPE_INCOMP_NAME; @@ -917,8 +932,12 @@ bool NimBLEExtAdvertisement::setServices(bool complete, uint8_t size, const std: */ bool NimBLEExtAdvertisement::setServiceData(const NimBLEUUID& uuid, const uint8_t* data, size_t length) { uint8_t uuidBytes = uuid.bitSize() / 8; - uint8_t sDataLen = 2 + uuidBytes + length; + if (length + uuidBytes + 2 > 0xFF) { + NIMBLE_LOGE(LOG_TAG, "Service data too long!"); + return false; + } + uint8_t sDataLen = 2 + uuidBytes + length; if (m_payload.size() + sDataLen > MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)) { return false; } diff --git a/src/NimBLEScan.cpp b/src/NimBLEScan.cpp index d8fc151..d8a12a0 100644 --- a/src/NimBLEScan.cpp +++ b/src/NimBLEScan.cpp @@ -115,12 +115,6 @@ 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) { @@ -132,6 +126,13 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) { } } +#if MYNEWT_VAL(BLE_EXT_ADV) + if (advertisedDevice->getDataStatus() == BLE_GAP_EXT_ADV_DATA_STATUS_INCOMPLETE) { + NIMBLE_LOGD(LOG_TAG, "EXT ADV data incomplete, waiting for more"); + return 0; + } +# endif + if (!advertisedDevice->m_callbackSent) { advertisedDevice->m_callbackSent++; pScan->m_pScanCallbacks->onDiscovered(advertisedDevice);