From 96d772a3dc0d0892fa40cdb8a598756f5dc9c394 Mon Sep 17 00:00:00 2001 From: Swissola Date: Sun, 24 May 2026 02:01:03 +0000 Subject: [PATCH] fix(ble): four correctness bugs in BLE module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ble_common.cpp — NimBLE v2+ scan registers base NimBLEScanCallbacks The legacy path wires AdvertisedDeviceCallbacks (the subclass that populates the device list). The v2+ path wired the empty base class directly, so the BLE scanner found nothing on any NimBLE v2+ build. Fix: use AdvertisedDeviceCallbacks on both paths. ble_common.cpp — pRxCharacteristic local variable shadows module global initBLEServer() re-declared BLECharacteristic *pRxCharacteristic as a local, leaving the module-level global always null. Any code outside the function using the global would dereference a null pointer. Fix: remove the type declaration so the assignment targets the global. ble_common.cpp — explicit ~NimBLEService() destructor call is UB The service is owned by the NimBLE stack; calling its destructor manually corrupts the stack's service table. BLEDevice::deinit() on the next line already tears down the entire stack including services. Fix: remove the manual destructor call. BLE_Suite.cpp — size_t underflow when deviceAddresses is empty The bubble-sort loop computed size_t(0) - 1 == SIZE_MAX, causing an always-true loop condition and an immediate out-of-bounds access. Fix: guard the outer loop with a size() > 1 pre-check. BLE_Suite.cpp — scan progress text rendered off-screen on Cardputer Hardcoded y=120/y=140 for scan status messages. The Cardputer display is 135px tall; y=140 places text 5px below the bottom edge. Fix: use tftHeight-relative offsets (tftHeight-30, tftHeight-15). Co-Authored-By: Claude Sonnet 4.6 --- src/modules/ble/BLE_Suite.cpp | 6 +++--- src/modules/ble/ble_common.cpp | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/modules/ble/BLE_Suite.cpp b/src/modules/ble/BLE_Suite.cpp index f54f41d90f..d12149747c 100644 --- a/src/modules/ble/BLE_Suite.cpp +++ b/src/modules/ble/BLE_Suite.cpp @@ -3644,7 +3644,7 @@ String selectTargetFromScan(const char *title) { const int ACTIVE_SCAN_TIME = 15, PASSIVE_SCAN_TIME = 15; - tft.setCursor(20, 120); + tft.setCursor(20, tftHeight - 30); tft.print("Active scan (15s)..."); #ifdef NIMBLE_V2_PLUS @@ -3653,7 +3653,7 @@ String selectTargetFromScan(const char *title) { NimBLEScanResults results = pBLEScan->start(ACTIVE_SCAN_TIME, false); #endif - tft.setCursor(20, 140); + tft.setCursor(20, tftHeight - 15); tft.print("Passive scan (15s)..."); pBLEScan->setActiveScan(false); @@ -3720,7 +3720,7 @@ String selectTargetFromScan(const char *title) { size_t deviceCount = scannerData.size(); if (xSemaphoreTake(scannerData.mutex, portMAX_DELAY)) { - for (size_t i = 0; i < scannerData.deviceAddresses.size() - 1; i++) { + for (size_t i = 0; scannerData.deviceAddresses.size() > 1 && i < scannerData.deviceAddresses.size() - 1; i++) { for (size_t j = i + 1; j < scannerData.deviceAddresses.size(); j++) { bool swapNeeded = false; if (scannerData.deviceFastPair[j] && !scannerData.deviceFastPair[i]) swapNeeded = true; diff --git a/src/modules/ble/ble_common.cpp b/src/modules/ble/ble_common.cpp index 93d8dd52b3..d42742a006 100644 --- a/src/modules/ble/ble_common.cpp +++ b/src/modules/ble/ble_common.cpp @@ -87,7 +87,7 @@ void ble_scan_setup() { BLEDevice::init(""); pBLEScan = BLEDevice::getScan(); #ifdef NIMBLE_V2_PLUS - pBLEScan->setScanCallbacks(new NimBLEScanCallbacks()); + pBLEScan->setScanCallbacks(new AdvertisedDeviceCallbacks()); #else pBLEScan->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks()); #endif @@ -173,7 +173,7 @@ bool initBLEServer() { pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_RX_UUID, NIMBLE_PROPERTY::NOTIFY); pTxCharacteristic->addDescriptor(new NimBLE2904()); - BLECharacteristic *pRxCharacteristic = pService->createCharacteristic( + pRxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_TX_UUID, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR ); pRxCharacteristic->setCallbacks(new MyCallbacks()); @@ -250,7 +250,6 @@ void disPlayBLESend() { } tft.setTextColor(TFT_WHITE); - pService->~NimBLEService(); pServer->getAdvertising()->stop(); #if defined(CONFIG_IDF_TARGET_ESP32C5) esp_bt_controller_deinit();