Skip to content

fix(ble): NimBLE v2 scan broken, pRxCharacteristic null, destructor UB, size_t underflow, Cardputer display offset#2465

Open
Swissola wants to merge 1 commit into
BruceDevices:devfrom
Swissola:fix/ble-bugs
Open

fix(ble): NimBLE v2 scan broken, pRxCharacteristic null, destructor UB, size_t underflow, Cardputer display offset#2465
Swissola wants to merge 1 commit into
BruceDevices:devfrom
Swissola:fix/ble-bugs

Conversation

@Swissola

Copy link
Copy Markdown

Five bugs in the BLE module, all found by reading the source. PRs against dev as per contributing guidelines.

1. NimBLE v2+ scan always finds nothing

ble_scan_setup() registered the base NimBLEScanCallbacks class on the v2+ path instead of the AdvertisedDeviceCallbacks subclass. The base class has an empty onResult(), so no devices are ever added to options. The BLE scanner menu shows only "Back" on any NimBLE v2+ build.

2. pRxCharacteristic local variable shadows module global

initBLEServer() declared BLECharacteristic *pRxCharacteristic = ... as a local, shadowing the module-level global on line 21. The global stays nullptr for the lifetime of the program. Any code that uses the global after initBLEServer() returns dereferences null.

3. Explicit ~NimBLEService() destructor call is undefined behaviour

disPlayBLESend() called pService->~NimBLEService() directly. The service is owned by the NimBLE stack; manual destructor invocation corrupts the stack's internal service table without freeing memory. BLEDevice::deinit() on the next line already performs a full teardown — the explicit call is both wrong and redundant.

4. size_t underflow crashes sort when device list is empty

The bubble-sort in selectTargetFromScan() computed scannerData.deviceAddresses.size() - 1 as size_t. When the vector is empty, size_t(0) - 1 wraps to SIZE_MAX, making the loop condition always true and immediately causing an out-of-bounds vector access.

5. Scan progress text rendered off-screen on Cardputer (135 px tall display)

setCursor(20, 140) for "Passive scan (15s)..." places text 5 px below the bottom of the Cardputer's 135 px landscape display. Changed to tftHeight-relative offsets, which are already used throughout the rest of the file.

Files changed

  • src/modules/ble/ble_common.cpp — bugs 1, 2, 3
  • src/modules/ble/BLE_Suite.cpp — bugs 4, 5

🤖 Generated with Claude Code

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 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant