From da3bbf3658a1d7fad80b9109d8ef55a5a385edb7 Mon Sep 17 00:00:00 2001 From: SteWers <42718143+SteWers@users.noreply.github.com> Date: Mon, 7 Sep 2026 11:00:02 +0200 Subject: [PATCH] Add BLE pairing to support newer EQ3 TRV firmware (#25008) * Add BLE pairing to support newer EQ3 TRV firmware * Verify fwrite result when saving BLE data --- .../tasmota_xdrv_driver/xdrv_79_esp32_ble.ino | 175 +++++++++++++++- .../xdrv_85_esp32_ble_eq3_trv.ino | 187 ++---------------- 2 files changed, 190 insertions(+), 172 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino index 7c29faa16..464c1dfbb 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino @@ -230,6 +230,7 @@ namespace BLE_ESP32 { #define BLE_ESP32_MAXNAMELEN 32 #define BLE_ESP32_MAXALIASLEN 32 +#define BLE_STORE_DIR "/.blestore" #define MAX_BLE_DATA_LEN 100 struct generic_sensor_t { @@ -387,6 +388,7 @@ static void BLEStartOperationTask(); // these are only run from the run task static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOperation, NimBLEClient **ppClient); static void BLETaskRunTaskDoneOperation(BLE_ESP32::generic_sensor_t** op, NimBLEClient **ppClient); +static void BLEDoPairing(NimBLEClient **ppClient); int BLETaskStartScan(int time); @@ -508,7 +510,7 @@ int minRSSI = -100; #define D_CMND_BLE "BLE" const char kBLE_Commands[] PROGMEM = D_CMND_BLE "|" - "Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved|FilterNames|MinRssiLevel"; + "Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved|FilterNames|MinRssiLevel|Pair"; static void CmndBLEPeriod(void); static void CmndBLEAdv(void); @@ -525,6 +527,7 @@ static void CmndBLEAddrFilter(void); static void CmndBLEEnableUnsaved(void); static void CmndBleFilterNames(void); static void CmndSetMinRSSI(void); +static void CmndPair(void); void (*const BLE_Commands[])(void) PROGMEM = { &BLE_ESP32::CmndBLEPeriod, @@ -541,7 +544,8 @@ void (*const BLE_Commands[])(void) PROGMEM = { &BLE_ESP32::CmndBLEAddrFilter, &BLE_ESP32::CmndBLEEnableUnsaved, &BLE_ESP32::CmndBleFilterNames, - &BLE_ESP32::CmndSetMinRSSI + &BLE_ESP32::CmndSetMinRSSI, + &BLE_ESP32::CmndPair }; const char *successStates[] PROGMEM = { @@ -614,6 +618,12 @@ enum { //BLE_ADV_ALL = 2, // driver sends every advert with full data to MQTT } BLEADVERTMODE; +enum BLE_PAIRING_STATES : uint8_t { + PAIRING_NONE = 0, + PAIRING_REQUESTED, + PAIRING_CONNECTED, + PAIRING_KEY_SENT +}; uint8_t BLEMode = BLEModeRegularScan; //uint8_t BLEMode = BLEModeScanByCommand; @@ -621,6 +631,10 @@ uint8_t BLETriggerScan = 0; uint8_t BLEAdvertMode = BLE_ADV_TELE; uint8_t BLEdeviceLimitReached = 0; +uint8_t pairingState = PAIRING_NONE; +uint32_t pairingPIN = 0; +NimBLEAddress pairingAddress; + uint8_t BLEStop = 0; uint64_t BLEStopAt = 0; @@ -638,6 +652,64 @@ const char *BLE_RESTART_BLE_REASON_CONN_LIMIT = PSTR("connect failed with connec const char *BLE_RESTART_BLE_REASON_CONN_EXISTS = PSTR("connect failed with connection exists"); const char *BLERestartBLEReason = nullptr; +// Global native hook: Filepath +static void ble_get_bond_filepath(const uint8_t* val, int type, char* out_buf, size_t buf_len) { + // Format: BLE_STORE_DIR/AABBCCDDEEFF.TYPE + snprintf(out_buf, buf_len, BLE_STORE_DIR "/%02X%02X%02X%02X%02X%02X.%03d", + val[5], val[4], val[3], val[2], val[1], val[0], type); +} + +// Global native hook: Read stored BLE data +int ble_local_store_read(int type, const union ble_store_key* key, union ble_store_value* value) { + if (type != BLE_STORE_OBJ_TYPE_PEER_SEC) return BLE_HS_ENOENT; // Only that is needed at the moment + char filepath[sizeof(BLE_STORE_DIR) + 20]; + + // Pass the raw 6-byte MAC array pointer from the internal union struct + ble_get_bond_filepath(key->sec.peer_addr.val, type, filepath, sizeof(filepath)); + + FILE* file = fopen(filepath, "r"); + if (file) { + if (fread(&value->sec, 1, sizeof(ble_store_value_sec), file) == sizeof(ble_store_value_sec)) { + fclose(file); + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: BLE data loaded from %s", filepath); + return 0; // 0 = Success for the NimBLE controller + } + fclose(file); + } + return BLE_HS_ENOENT; // Key not found, falls back to normal pairing workflow +} + +// Global native hook: Write BLE data +int ble_local_store_write(int type, const union ble_store_value* value) { + if (type != BLE_STORE_OBJ_TYPE_PEER_SEC) return BLE_HS_ENOMEM; // Only that is needed at the moment + char filepath[sizeof(BLE_STORE_DIR) + 20]; + + // Pass the raw 6-byte MAC array pointer from the internal union struct + ble_get_bond_filepath(value->sec.peer_addr.val, type, filepath, sizeof(filepath)); + + FILE* file = fopen(filepath, "w"); + if (file) { + size_t written = fwrite(&value->sec, 1, sizeof(ble_store_value_sec), file); + fclose(file); + if (written == sizeof(ble_store_value_sec)) { + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: BLE data saved in %s", filepath); + return 0; // 0 = Success + } + } + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: Save BLE data failed"); + return BLE_HS_ENOMEM; // Write failed +} + +// Global API: Delete dynamic storage file +void ble_local_store_delete(const uint8_t* mac_addr) { + if (!mac_addr) return; + char filepath[sizeof(BLE_STORE_DIR) + 20]; + + // Only delete files of BLE_STORE_OBJ_TYPE_PEER_SEC as no others are needed at the moment + ble_get_bond_filepath(mac_addr, BLE_STORE_OBJ_TYPE_PEER_SEC, filepath, sizeof(filepath)); + unlink(filepath); + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: Deleted BLE data file %s", filepath); +} /*********************************************************************************************\ * log of all devices present @@ -1331,17 +1403,17 @@ void postAdvertismentDetails(){ class BLESensorCallback : public NimBLEClientCallbacks { void onConnect(NimBLEClient* pClient) { #ifdef BLE_ESP32_DEBUG - AddLog(BLELogLevel[LOG_LEVEL_DEBUG], PSTR("BLE: onConnect %s"), ((std::string)pClient->getPeerAddress()).c_str()); + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: onConnect %s", pClient->getPeerAddress().toString().c_str()); #endif } void onDisconnect(NimBLEClient* pClient, int reason) { #ifdef BLE_ESP32_DEBUG - AddLog(BLELogLevel[LOG_LEVEL_DEBUG], PSTR("BLE: onDisconnect %s"), ((std::string)pClient->getPeerAddress()).c_str()); + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: onDisconnect %s, reason: 0x%04X", pClient->getPeerAddress().toString().c_str(), reason); #endif } bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) { #ifdef BLE_ESP32_DEBUG - AddLog(BLELogLevel[LOG_LEVEL_DEBUG], PSTR("BLE: onConnParamsUpdateRequest %s"), ((std::string)pClient->getPeerAddress()).c_str()); + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: onConnParamsUpdateRequest %s", pClient->getPeerAddress().toString().c_str()); #endif // if(params->itvl_min < 24) { /** 1.25ms units */ @@ -1371,6 +1443,33 @@ class BLESensorCallback : public NimBLEClientCallbacks { return false; } + void onPassKeyEntry(NimBLEConnInfo& connInfo) override { +#ifdef BLE_ESP32_DEBUG + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: onPassKeyEntry %s", connInfo.getAddress().toString().c_str()); +#endif + if (pairingState == PAIRING_CONNECTED && connInfo.getAddress() == pairingAddress) { + NimBLEDevice::injectPassKey(connInfo, pairingPIN); + AddLog(LOG_LEVEL_INFO, "BLE: PIN %06u sent to %s", pairingPIN, connInfo.getAddress().toString().c_str()); + pairingState = PAIRING_KEY_SENT; + } + } + void onAuthenticationComplete(NimBLEConnInfo& connInfo) override { +#ifdef BLE_ESP32_DEBUG + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: onAuthenticationComplete %s", connInfo.getAddress().toString().c_str()); +#endif + NimBLEClient* pActiveClient = NimBLEDevice::getClientByPeerAddress(connInfo.getAddress()); + if (pActiveClient && pActiveClient->isConnected()) { + if (pairingState == PAIRING_KEY_SENT && connInfo.getAddress() == pairingAddress) { + if (connInfo.isEncrypted()) { + AddLog(LOG_LEVEL_INFO, "BLE: Pairing %s successful.", connInfo.getAddress().toString().c_str()); + } else { + AddLog(LOG_LEVEL_ERROR, "BLE: Pairing %s failed!", connInfo.getAddress().toString().c_str()); + } + pActiveClient->disconnect(); + pairingState = PAIRING_NONE; + } + } + } }; static BLESensorCallback clientCB; @@ -1742,6 +1841,17 @@ static void BLETaskStopStartNimBLE(NimBLEClient **ppClient, bool start = true){ AddLog(LOG_LEVEL_INFO, PSTR("BLE: BLETask: Starting NimBLE")); NimBLEDevice::init("BLE_ESP32"); + // --- NEUTRAL ADVANCED STORAGE ROUTING LAYER --- + // Create the physical folder BLE_STORE_DIR in the flash memory + mkdir(BLE_STORE_DIR, 0777); + // Hook the dynamic directory filesystem into the native Apache MyNewT config + ble_hs_cfg.store_read_cb = ble_local_store_read; + ble_hs_cfg.store_write_cb = ble_local_store_write; + + // Set default global security capabilities for the Bluetooth stack + NimBLEDevice::setSecurityAuth(BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM | BLE_SM_PAIR_AUTHREQ_SC); + NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY); + *ppClient = NimBLEDevice::createClient(); (*ppClient)->setClientCallbacks(&clientCB, false); /** Set initial connection parameters: These settings are 15ms interval, 0 latency, 120ms timout. @@ -1808,6 +1918,33 @@ int BLETaskStartScan(int time){ return 0; } +static void BLEDoPairing(NimBLEClient **ppClient) { + if (pairingState != PAIRING_REQUESTED) return; + AddLog(BLELogLevel[LOG_LEVEL_DEBUG], "BLE: Pairing requested. PIN: %u", pairingPIN); + + NimBLEClient *pClient = *ppClient; + + BLERunningScan = 0; + // Delete old bonding + ble_local_store_delete(pairingAddress.getBase()->val); + NimBLEDevice::deleteBond(pairingAddress); // Must be executed after ble_local_store_delete + + if (pClient->connect(pairingAddress, false, false, false)) { + AddLog(LOG_LEVEL_DEBUG, "BLE: Connected for pairing. Starting crypto handshake..."); + pairingState = PAIRING_CONNECTED; + // secureConnection will rise onPassKeyEntry for transmitting the PairingPIN. + // Abort the pairing prozess, when sending fails. + if (!pClient->secureConnection()) { + pClient->disconnect(); + pairingState = PAIRING_NONE; + } + } else { + AddLog(LOG_LEVEL_ERROR, "BLE: Connect for pairing failed."); + pairingState = PAIRING_NONE; + } +} + + // this runs one operation // if the passed pointer is empty, it tries to get a next one. static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOperation, NimBLEClient **ppClient){ @@ -2243,6 +2380,8 @@ static void BLEOperationTask(void *pvParameters){ BLELastLoopTime = esp_timer_get_time(); BLELoopCount++; + BLE_ESP32::BLEDoPairing(&pClient); + BLE_ESP32::BLETaskRunCurrentOperation(¤tOperation, &pClient); // start a scan if possible @@ -3074,6 +3213,32 @@ void CmndBLEName(void) { return; } + void CmndPair(void) { + // "BLEPair " + + if (!XdrvMailbox.data_len) { + ResponseCmndError(); + return; + } + + // Find the separator space between and to replace it with '\0' + char* space_ptr = strchr(XdrvMailbox.data, ' '); + if (!space_ptr) { + ResponseCmndError(); + return; + } + *space_ptr = '\0'; + pairingPIN = atoi(space_ptr + 1); + + uint8_t addrbin[7]; + if (!getAddr(addrbin, XdrvMailbox.data)) { + ResponseCmndError(); + return; + } + pairingAddress = NimBLEAddress(addrbin, addrbin[6]); + pairingState = PAIRING_REQUESTED; + Response_P("{\"%s\":\"started\",\"MAC\":\"%s\",\"PIN\":\"%06u\"}", XdrvMailbox.command, pairingAddress.toString().c_str(), pairingPIN); + }; ////////////////////////////////////////////////////////////////////////// diff --git a/tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino b/tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino index d623cfc6e..8aaf906ab 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino @@ -299,7 +299,6 @@ struct eq3_device_t { uint8_t ValvePos; // 1 Byte uint8_t Mode; // 1 Byte uint8_t lastStatusLen; // 1 Byte - bool pairing; // 1 Byte bool Battery; // 1 Byte uint8_t addr[6]; // 6 Bytes uint8_t lastStatus[16]; // 16 Bytes @@ -312,12 +311,8 @@ int retries = 0; // allow 240s before timeout of sa device - based on that we restart BLE if we don't see adverts for 120s #define EQ3_TIMEOUT 240L -uint8_t pairingaddr[6] = {}; -char pairingserial[20] = {}; -bool pairing = false; - #define EQ3_NUM_DEVICESLOTS 16 -eq3_device_t EQ3Devices[EQ3_NUM_DEVICESLOTS]; +eq3_device_t EQ3Devices[EQ3_NUM_DEVICESLOTS] = {}; SemaphoreHandle_t EQ3mutex = nullptr; uint16_t EQ3Period = 300; @@ -655,7 +650,7 @@ int EQ3GenericOpCompleteFn(BLE_ESP32::generic_sensor_t* op) { retries--; if (EQ3Operation(addrev, op->dataToWrite, op->writelen, (int)context)) { - AddLog(LOG_LEVEL_INFO, "EQ3: %s: Operation 1/%u \"%s\" failed - retries left: %d/%d - State: %d", addrStr(addrev), opQueue.size(), IdxToTrvCmd(context & 0x7f), retries, EQ3Retries, op->state); + AddLog(LOG_LEVEL_INFO, "EQ3: %s: Operation 1/%u \"%s\" failed - retries left: %d/%d - State: %s (%d)", addrStr(addrev), opQueue.size(), IdxToTrvCmd(context & 0x7f), retries, EQ3Retries, BLE_ESP32::getStateString(op->state), op->state); opInProgress = true; return 0; } @@ -663,7 +658,7 @@ int EQ3GenericOpCompleteFn(BLE_ESP32::generic_sensor_t* op) { } if (is_failed) { - AddLog(LOG_LEVEL_ERROR, "EQ3: %s: Operation 1/%u \"%s\" final fail - State: %d", addrStr(addrev), opQueue.size(), IdxToTrvCmd(context & 0x7f), op->state); + AddLog(LOG_LEVEL_ERROR, "EQ3: %s: Operation 1/%u \"%s\" final fail - State: %s (%d)", addrStr(addrev), opQueue.size(), IdxToTrvCmd(context & 0x7f), BLE_ESP32::getStateString(op->state), op->state); } else { AddLog(LOG_LEVEL_DEBUG, "EQ3: %s: Operation 1/%u \"%s\" done", addrStr(addrev), opQueue.size(), IdxToTrvCmd(context & 0x7f)); } @@ -682,130 +677,13 @@ int EQ3GenericOpCompleteFn(BLE_ESP32::generic_sensor_t* op) { } /*********************************************************************************************\ - * Functons actualy called from within the BLE task + * Functions actualy called from within the BLE task \*********************************************************************************************/ -int ispairing2(const uint8_t* payload, int len, char* name, int nameLen, char* serial, int serialLen) { - while (len) { - int l = *payload; - //BLE_ESP32::dump(temp, 40, payload, l+1); - //AddLog(LOG_LEVEL_ERROR, PSTR("EQ3: %s"), temp); - - payload++; - len--; - if (len < l) { - //AddLog(LOG_LEVEL_ERROR, PSTR("EQ3: part len er %d<%d"),len, l); - return 0; - } - switch (*payload) { - case 0xff: {// parse the EQ3 advert payload looking for nnFF01ssssssss - payload++; - len--; - l--; - if (*payload == 1) { - payload++; - len--; - l--; - //char serialstr[20]; - //strncpy(serialstr, (const char*)payload, l); - //AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3: adv part FF01 detected %s"), serialstr); - // we don;t use these, but that's what they seem to be.... - strncpy(serial, (const char*)payload, tmin(l, serialLen)); - serial[serialLen - 1] = 0; - payload += l; - len -= l; - return 1; - } else { - payload += l; - len -= l; - } - } break; - case 0x09: { - payload++; - len--; - l--; - if (*payload == 1) { - payload++; - len--; - l--; - //char serialstr[20]; - //strncpy(serialstr, (const char*)payload, l); - //AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3: adv part FF01 detected %s"), serialstr); - // we don;t use these, but that's what they seem to be.... - strncpy(serial, (const char*)payload, tmin(l, serialLen)); - name[nameLen - 1] = 0; - payload += l; - len -= l; - //return 1; - } else { - payload += l; - len -= l; - } - } break; - default:{ - payload += l; - len -= l; - } break; - } - } - return 0; -} - -int ispairing(const uint8_t* payload, int len) { - //char temp[40]; - //BLE_ESP32::dump(temp, 40, payload, len); - //AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3: pair%d %s"), len, temp); - while (len) { - int l = *payload; - //BLE_ESP32::dump(temp, 40, payload, l+1); - //AddLog(LOG_LEVEL_ERROR, PSTR("EQ3: %s"), temp); - - payload++; - len--; - if (len < l) { - //AddLog(LOG_LEVEL_ERROR, PSTR("EQ3: part len er %d<%d"),len, l); - return 0; - } - if (*payload == 0xff) { - payload++; - len--; - l--; - if (*payload == 1) { - payload++; - len--; - l--; - //char serialstr[20]; - //strncpy(serialstr, (const char*)payload, l); - //AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3: adv part FF01 detected %s"), serialstr); - // we don;t use these, but that's what they seem to be.... - const uint8_t* serial = payload; - uint8_t serialLen = l; - payload += l; - len -= l; - return 1; - } else { - payload += l; - len -= l; - } - } else { - payload += l; - len -= l; - } - } - return 0; -} - -void TaskEQ3AddDevice(int8_t RSSI, const uint8_t* addr, char* serial) { +void TaskEQ3AddDevice(int8_t RSSI, const uint8_t* addr) { eq3_device_t* targetDevice = nullptr; eq3_device_t* firstFreeSlot = nullptr; - if (serial && *serial && !pairing) { - memcpy(pairingaddr, addr, 6); - strncpy(pairingserial, serial, sizeof(pairingserial)); - pairingserial[sizeof(pairingserial) - 1] = 0; - pairing = true; - } - for (auto& device : EQ3Devices) { if (!memcmp(addr, device.addr, 6)) { targetDevice = &device; @@ -830,7 +708,6 @@ void TaskEQ3AddDevice(int8_t RSSI, const uint8_t* addr, char* serial) { targetDevice->timeoutTime = esp_timer_get_time() + 1000000ULL * EQ3_TIMEOUT; memcpy(targetDevice->addr, addr, 6); targetDevice->RSSI = RSSI; - targetDevice->pairing = (serial && *serial); } int TaskEQ3advertismentCallback(BLE_ESP32::ble_advertisment_t* pStruct) @@ -869,17 +746,9 @@ int TaskEQ3advertismentCallback(BLE_ESP32::ble_advertisment_t* pStruct) AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Device seen", addrStr(addr)); #endif - uint8_t* payload = (uint8_t*)advertisedDevice->getPayload().data(); - size_t payloadlen = advertisedDevice->getPayload().size(); - - char name[20] {}; - char serial[20] {}; - // bool pairing = false; // Is not used below, so removing should be no problem - ispairing2(payload, payloadlen, name, sizeof(name), serial, sizeof(serial)); - // this will take and keep the mutex until the function is over TasAutoMutex localmutex(&EQ3mutex); - TaskEQ3AddDevice(RSSI, addr, serial); + TaskEQ3AddDevice(RSSI, addr); return 0; } @@ -898,8 +767,6 @@ void EQ3Init(void) { #endif EQ3Period = tmax(Settings->tele_period, EQ3_NUM_DEVICESLOTS); - - return; } /***********************************************************************\ @@ -913,16 +780,6 @@ void EQ3Init(void) { void EQ3EverySecond(void) { -/// Handle pairing //// - if (pairing) { - Response_P("{\"pairing\":\"%s\",\"serial\":\"%s\"}", addrStr(pairingaddr), pairingserial); - char addrstr[4 + 8 * 2 + 2] = "EQ3/"; - BLE_ESP32::dump(&addrstr[4], 8 * 2 + 2, pairingaddr, 6); - char* topic = topicPrefix((int)STAT, pairingaddr, true); - MqttPublish(topic, false); - pairing = false; - } - /// Check for timeout and cleanup devices //// for (auto& device : EQ3Devices) { if (device.timeoutTime && (device.timeoutTime < esp_timer_get_time() || !Settings->flag5.mi32_enable)) { @@ -933,7 +790,7 @@ void EQ3EverySecond(void) { /// Handle polling //// if (NextPollSeconds) NextPollSeconds--; - if (!NextPollSeconds && EQ3Period && opQueue.empty() && !opInProgress && !pairing) { + if (!NextPollSeconds && EQ3Period && opQueue.empty() && !opInProgress) { uint8_t activeDevices = 0; for (const auto& dev : EQ3Devices) { if (dev.timeoutTime) activeDevices++; @@ -962,7 +819,7 @@ void EQ3EverySecond(void) { //// Simulation //// #ifdef EQ3_SIMULATION - TaskEQ3AddDevice(-RtcTime.second - 30, TESTADDR1, nullptr); + TaskEQ3AddDevice(-RtcTime.second - 30, TESTADDR1); if (TasmotaGlobal.uptime < 120) { for (auto& dev : EQ3Devices) { if (!memcmp(dev.addr, TESTADDR1, 6)) dev.lastStatusTime = UtcTime(); @@ -1365,23 +1222,19 @@ uint8_t CmndTrvNext(char* data) { // only allow one command in progress //if (retries) return TRV_IGNOREDBUSY; - bool useAlias = false; - uint8_t addrbin[6]; - int addrres = BLE_ESP32::getAddr(addrbin, p); - if (addrres) { - if (addrres == 2) { - AddLog(LOG_LEVEL_DEBUG, "EQ3: addr used alias: %s", p); - useAlias = true; - } - NimBLEAddress addr(addrbin, addrbin[6]); - -#ifdef EQ3_DEBUG - //AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_INFO], PSTR("EQ3: cmd addr: %s -> %s"), p, addr.toString().c_str()); -#endif - } else { - AddLog(LOG_LEVEL_ERROR, "EQ3: addr invalid: %s", p); + uint8_t addrbin[7]; // Must be 7, because addrbin[6] contains the type + int addrResult = BLE_ESP32::getAddr(addrbin, p); + if (!addrResult) { + AddLog(LOG_LEVEL_ERROR, "EQ3: Address invalid: %s", p); return TRV_INVADDR; } + bool useAlias = (addrResult == 2); + if (useAlias) AddLog(LOG_LEVEL_DEBUG, "EQ3: %s: Used alias: %s", addrStr(addrbin), p); +// NimBLEAddress addr(addrbin, addrbin[6]); // Object addr not used, only addrbin. Maybe we use it in future. + +#ifdef EQ3_DEBUG + //AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_INFO], PSTR("EQ3: cmd addr: %s -> %s"), p, addrStr(addrbin)); +#endif // get index of next part of cmd char* cmd = strtok(nullptr, " "); @@ -1527,7 +1380,7 @@ bool mqtt_direct() { int remains = 120; memset(tmp, 0, sizeof(tmp)); p = tmp; - uint8_t addr[6]; + uint8_t addr[7]; // Must be 7, because addr[6] contains the type uint8_t res = TRV_INVADDR; // invalid address/alias // if address or alias valid