fix(client): connectTimeout in ms, NVS addr byte order, onScanEnd callback
All checks were successful
CI / build (push) Successful in 1m14s

- setConnectTimeout(5000ms) instead of 10ms (NimBLE-Arduino v2 uses ms)
- Fix NVS stored address: use ble_addr_t struct constructor to avoid
  double byte-reversal, and correct type BLE_ADDR_PUBLIC
- Use onScanEnd callback to defer connect until scan fully terminated
- Separate foundAddr to avoid race between scan callback and loop
This commit is contained in:
eddy 2026-08-04 01:00:35 +02:00
commit 3c87990a9c
3 changed files with 433 additions and 32 deletions

View file

@ -66,6 +66,7 @@ bool otaEnded = false;
static bool bleReady = false;
static bool serverFound = false;
static NimBLEAddress serverAddress;
static NimBLEAddress foundAddr;
static bool scanning = false;
static uint32_t scanStarted = 0;
static uint32_t disconnectTime = 0;
@ -78,16 +79,19 @@ class MyScanCallbacks : public NimBLEScanCallbacks {
void onResult(const NimBLEAdvertisedDevice *advertisedDevice) override {
if (scanning && advertisedDevice->isAdvertisingService(NimBLEUUID(SERVICE_UUID))) {
std::string mfgData = advertisedDevice->getManufacturerData();
if (mfgData.length() >= 4) {
if (memcmp(mfgData.data(), deviceUuid, 4) == 0) {
serverAddress = advertisedDevice->getAddress();
if (mfgData.length() >= 6) {
if (memcmp(mfgData.data() + 2, serverUuid, 4) == 0) {
foundAddr = advertisedDevice->getAddress();
serverFound = true;
ESP_LOGI(TAG, "BLE: server found at %s", serverAddress.toString().c_str());
NimBLEDevice::getScan()->stop();
ESP_LOGI(TAG, "BLE: server found at %s", foundAddr.toString().c_str());
}
}
}
}
void onScanEnd(const NimBLEScanResults &results, int reason) override {
scanning = false;
ESP_LOGI(TAG, "BLE: scan ended (reason=%d, found=%d)", reason, serverFound);
}
};
class MyClientCallbacks : public NimBLEClientCallbacks {
@ -253,7 +257,7 @@ static bool performEcdhHandshake(NimBLERemoteService *pSvc) {
static bool connectToServer() {
if (pClient == nullptr) {
pClient = NimBLEDevice::createClient();
pClient->setConnectTimeout(10);
pClient->setConnectTimeout(5000);
pClient->setClientCallbacks(&clientCallbacks);
}
@ -366,7 +370,10 @@ void setup() {
size_t addrLen = preferences.getBytes(NVS_ADDR_NAME, addrBuf, 6);
preferences.end();
if (addrLen == 6) {
storedServerAddr = NimBLEAddress(addrBuf, BLE_ADDR_RANDOM);
ble_addr_t addr;
addr.type = BLE_ADDR_PUBLIC;
memcpy(addr.val, addrBuf, 6);
storedServerAddr = NimBLEAddress(addr);
serverAddrStored = true;
ESP_LOGI(TAG, "BLE: stored server address %s", storedServerAddr.toString().c_str());
}
@ -574,7 +581,24 @@ void loop() {
}
if (!connected && bleReady) {
if (!scanning) {
if (serverFound && !scanning) {
serverFound = false;
serverAddress = foundAddr;
ESP_LOGI(TAG, "BLE: connecting to %s type=%d", serverAddress.toString().c_str(), serverAddress.getType());
if (connectToServer()) {
connected = true;
uint8_t addrBuf[6];
memcpy(addrBuf, serverAddress.getVal(), 6);
preferences.begin(NVS_NAMESPACE, false);
preferences.putBytes(NVS_ADDR_NAME, addrBuf, 6);
preferences.end();
storedServerAddr = serverAddress;
serverAddrStored = true;
ESP_LOGI(TAG, "BLE: server address stored in NVS");
} else {
ESP_LOGW(TAG, "BLE: connectToServer failed");
}
} else if (!scanning) {
if (millis() - lastScanAttempt > SCAN_INTERVAL_MS) {
if (serverAddrStored) {
ESP_LOGI(TAG, "BLE: trying stored address %s", storedServerAddr.toString().c_str());
@ -593,30 +617,7 @@ void loop() {
lastScanAttempt = millis();
}
} else {
if (serverFound) {
scanning = false;
ESP_LOGI(TAG, "BLE: connecting to found server at %s", serverAddress.toString().c_str());
if (pClient != nullptr && pClient->isConnected()) {
pClient->disconnect();
delay(100);
}
pClient = NimBLEDevice::createClient();
pClient->setConnectTimeout(10);
pClient->setClientCallbacks(&clientCallbacks);
if (connectToServer()) {
connected = true;
uint8_t addrBuf[6];
memcpy(addrBuf, serverAddress.getVal(), 6);
preferences.begin(NVS_NAMESPACE, false);
preferences.putBytes(NVS_ADDR_NAME, addrBuf, 6);
preferences.end();
storedServerAddr = serverAddress;
serverAddrStored = true;
ESP_LOGI(TAG, "BLE: server address stored in NVS");
} else {
ESP_LOGW(TAG, "BLE: connectToServer failed");
}
} else if (millis() - scanStarted > SCAN_DURATION_MS) {
if (millis() - scanStarted > SCAN_DURATION_MS) {
NimBLEDevice::getScan()->stop();
scanning = false;
ESP_LOGI(TAG, "BLE: scan timeout, no server found");