From a51936f81964212e1bf46e28dbe29d420b918c62 Mon Sep 17 00:00:00 2001 From: eddy Date: Tue, 4 Aug 2026 00:31:38 +0200 Subject: [PATCH] feat(client): scan+connect statemachine replaces hardcoded MAC --- src/client.cpp | 98 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index b302c20..22ae341 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -97,6 +97,7 @@ class MyClientCallbacks : public NimBLEClientCallbacks { } void onDisconnect(NimBLEClient *client, int reason) override { connected = false; + disconnectTime = millis(); relay1SendState = false; relay2SendState = false; pCmdChar = nullptr; @@ -359,25 +360,37 @@ void setup() { if (allProvisioned) { NimBLEDevice::init("SylDa_Client"); bleReady = true; - ESP_LOGI(TAG, "BLE: initialized, connecting..."); - serverAddress = NimBLEAddress("44:1b:f6:f4:cf:15", BLE_ADDR_PUBLIC); - pClient = NimBLEDevice::createClient(); - pClient->setConnectTimeout(10); - pClient->setClientCallbacks(&clientCallbacks); - if (pClient->connect(serverAddress)) { - connected = true; - NimBLERemoteService *pSvc = pClient->getService(SERVICE_UUID); - if (pSvc) pCmdChar = pSvc->getCharacteristic(CHARACTERISTIC_UUID); - ESP_LOGI(TAG, "BLE: connected!"); - } else { - ESP_LOGE(TAG, "BLE: connect failed"); + preferences.begin(NVS_NAMESPACE, true); + uint8_t addrBuf[6]; + size_t addrLen = preferences.getBytes(NVS_ADDR_NAME, addrBuf, 6); + preferences.end(); + if (addrLen == 6) { + storedServerAddr = NimBLEAddress(addrBuf, BLE_ADDR_RANDOM); + serverAddrStored = true; + ESP_LOGI(TAG, "BLE: stored server address %s", storedServerAddr.toString().c_str()); } + + ESP_LOGI(TAG, "BLE: initialized, will scan for server"); } ESP_LOGI(TAG, "Setup done."); } +static void startScan() { + if (scanning) return; + NimBLEScan *pScan = NimBLEDevice::getScan(); + pScan->setScanCallbacks(new MyScanCallbacks()); + pScan->setActiveScan(true); + pScan->setInterval(32); + pScan->setWindow(16); + serverFound = false; + scanning = true; + scanStarted = millis(); + pScan->start(SCAN_DURATION_MS / 100, false); + ESP_LOGI(TAG, "BLE: scanning started"); +} + void loop() { if (Serial.available()) { static String serialBuf; @@ -551,32 +564,63 @@ void loop() { } } - static uint32_t lastConnectAttempt = 0; + static uint32_t lastScanAttempt = 0; static uint32_t statusLog = 0; if (bleReady && millis() - statusLog > 2000) { - ESP_LOGI(TAG, "BLE: connected=%d, pClient=%p, isConn=%d", - connected, (void*)pClient, pClient ? pClient->isConnected() : 0); + ESP_LOGI(TAG, "BLE: connected=%d scanning=%d ecdh=%d serverFound=%d", + connected, scanning, ecdhReady, serverFound); statusLog = millis(); } if (!connected && bleReady) { - if (millis() - lastConnectAttempt > SCAN_INTERVAL_MS) { - ESP_LOGI(TAG, "BLE: connecting to server..."); - if (pClient == nullptr) { + if (!scanning) { + if (millis() - lastScanAttempt > SCAN_INTERVAL_MS) { + if (serverAddrStored) { + ESP_LOGI(TAG, "BLE: trying stored address %s", storedServerAddr.toString().c_str()); + serverAddress = storedServerAddr; + if (connectToServer()) { + connected = true; + ESP_LOGI(TAG, "BLE: connected via stored address"); + } else { + ESP_LOGI(TAG, "BLE: stored address failed, starting scan"); + serverAddrStored = false; + startScan(); + } + } else { + startScan(); + } + 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) { + NimBLEDevice::getScan()->stop(); + scanning = false; + ESP_LOGI(TAG, "BLE: scan timeout, no server found"); } - if (pClient->connect(serverAddress)) { - connected = true; - NimBLERemoteService *pSvc = pClient->getService(SERVICE_UUID); - if (pSvc) pCmdChar = pSvc->getCharacteristic(CHARACTERISTIC_UUID); - ESP_LOGI(TAG, "BLE: connected!"); - } else { - ESP_LOGW(TAG, "BLE: connect failed"); - } - lastConnectAttempt = millis(); } }