diff --git a/firmware/esp32/xterra-controller/bms.cpp b/firmware/esp32/xterra-controller/bms.cpp index ff1054c..3986ac7 100644 --- a/firmware/esp32/xterra-controller/bms.cpp +++ b/firmware/esp32/xterra-controller/bms.cpp @@ -68,6 +68,58 @@ static void handleNotify( } + +class BleScanCallbacks : public NimBLEScanCallbacks { + void onResult(const NimBLEAdvertisedDevice* device) override { + if (bleScanResultCount >= MAX_BLE_SCAN_RESULTS) { + return; + } + + String address = device->getAddress().toString().c_str(); + + for (int i = 0; i < bleScanResultCount; i++) { + if (bleScanResults[i].address == address) { + bleScanResults[i].rssi = device->getRSSI(); + + if (bleScanResults[i].name.length() == 0 && device->haveName()) { + bleScanResults[i].name = device->getName().c_str(); + } + + return; + } + } + + String name = ""; + if (device->haveName()) { + name = device->getName().c_str(); + } + + bleScanResults[bleScanResultCount].address = address; + bleScanResults[bleScanResultCount].name = name; + bleScanResults[bleScanResultCount].rssi = device->getRSSI(); + + Serial.print(logTimestamp()); + Serial.print(" BLE: found "); + Serial.print(bleScanResultCount + 1); + Serial.print(") "); + + if (name.length() > 0) { + Serial.print(name); + } else { + Serial.print("(no name)"); + } + + Serial.print(" | "); + Serial.print(address); + Serial.print(" | RSSI "); + Serial.println(device->getRSSI()); + + bleScanResultCount++; + } +}; + +static BleScanCallbacks bleScanCallbacks; + void pauseBmsReconnect(uint32_t pauseMs) { bmsReconnectPausedUntil = millis() + pauseMs; } @@ -103,17 +155,24 @@ int scanBleDevices(uint32_t scanSeconds) { bleScanResultCount = 0; NimBLEScan* scan = NimBLEDevice::getScan(); + scan->setScanCallbacks(&bleScanCallbacks, false); scan->setActiveScan(true); scan->setInterval(100); scan->setWindow(99); scan->clearResults(); Serial.print(logTimestamp()); - Serial.print(" BLE: Starting continuous scan for "); + Serial.print(" BLE: Scanning for "); Serial.print(scanSeconds); Serial.println(" seconds..."); - scan->start(scanSeconds, false, false); + bool started = scan->start(scanSeconds, false, false); + + if (!started) { + Serial.print(logTimestamp()); + Serial.println(" BLE: scan failed to start"); + return 0; + } unsigned long startMs = millis(); unsigned long durationMs = scanSeconds * 1000UL; @@ -130,50 +189,14 @@ int scanBleDevices(uint32_t scanSeconds) { Serial.print(elapsed / 1000); Serial.print("/"); Serial.print(scanSeconds); - Serial.println(" sec"); + Serial.print(" sec, devices "); + Serial.println(bleScanResultCount); } delay(50); } scan->stop(); - - NimBLEScanResults results = scan->getResults(); - int resultCount = results.getCount(); - - Serial.print(logTimestamp()); - Serial.print(" BLE: Raw devices seen: "); - Serial.println(resultCount); - - for (int i = 0; i < resultCount && bleScanResultCount < MAX_BLE_SCAN_RESULTS; i++) { - const NimBLEAdvertisedDevice* device = results.getDevice(i); - - String address = device->getAddress().toString().c_str(); - bool alreadySeen = false; - - for (int existing = 0; existing < bleScanResultCount; existing++) { - if (bleScanResults[existing].address == address) { - alreadySeen = true; - break; - } - } - - if (alreadySeen) { - continue; - } - - String name = ""; - if (device->haveName()) { - name = device->getName().c_str(); - } - - bleScanResults[bleScanResultCount].address = address; - bleScanResults[bleScanResultCount].name = name; - bleScanResults[bleScanResultCount].rssi = device->getRSSI(); - - bleScanResultCount++; - } - scan->clearResults(); Serial.print(logTimestamp()); @@ -181,6 +204,7 @@ int scanBleDevices(uint32_t scanSeconds) { Serial.println(bleScanResultCount); if (bleScanResultCount == 0) { + Serial.println("No BLE devices found."); return bleScanResultCount; }