From ebd6bb8031e59847e66895f45335ed764a89348b Mon Sep 17 00:00:00 2001 From: Csiki Date: Wed, 3 Mar 2021 00:13:14 +0100 Subject: [PATCH] Bt discovery fix (#880) * launchDiscovery fix for esp32 (sending the discovery mqtt messages on the main core) --- main/ZgatewayBT.ino | 62 ++++++++++++++++++++++++++++++----------- main/ZmqttDiscovery.ino | 2 +- main/config_BT.h | 2 ++ main/main.ino | 4 +++ 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index 58f28c124c..977db2871f 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -82,7 +82,8 @@ struct decompose { bool reverse; }; -vector devices; +vector devices; +int newDevices = 0; static BLEdevice NO_DEVICE_FOUND = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false, false, false, UNKNOWN_MODEL}; static bool oneWhite = false; @@ -194,9 +195,9 @@ void createOrUpdateDevice(const char* mac, uint8_t flags, ble_sensor_model model BLEdevice* getDeviceByMac(const char* mac) { Log.trace(F("getDeviceByMac %s" CR), mac); - for (vector::iterator p = devices.begin(); p != devices.end(); ++p) { - if ((strcmp(p->macAdr, mac) == 0)) { - return &(*p); + for (vector::iterator it = devices.begin(); it != devices.end(); ++it) { + if ((strcmp((*it)->macAdr, mac) == 0)) { + return *it; } } return &NO_DEVICE_FOUND; @@ -234,7 +235,8 @@ void createOrUpdateDevice(const char* mac, uint8_t flags, ble_sensor_model model device->isWhtL = flags & device_flags_isWhiteL; device->isBlkL = flags & device_flags_isBlackL; if (model != UNKNOWN_MODEL) device->sensorModel = model; - devices.push_back(*device); + devices.push_back(device); + newDevices++; } else { Log.trace(F("update %s" CR), mac); @@ -263,7 +265,8 @@ void createOrUpdateDevice(const char* mac, uint8_t flags, ble_sensor_model model # define isDiscovered(device) device->isDisc void dumpDevices() { - for (vector::iterator p = devices.begin(); p != devices.end(); ++p) { + for (vector::iterator it = devices.begin(); it != devices.end(); ++it) { + BLEdevice* p = *it; Log.trace(F("macAdr %s" CR), p->macAdr); Log.trace(F("isDisc %d" CR), p->isDisc); Log.trace(F("isWhtL %d" CR), p->isWhtL); @@ -625,7 +628,8 @@ void notifyCB( JsonObject& BLEdata = getBTJsonObject(); String mac_adress = pBLERemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress().toString().c_str(); mac_adress.toUpperCase(); - for (vector::iterator p = devices.begin(); p != devices.end(); ++p) { + for (vector::iterator it = devices.begin(); it != devices.end(); ++it) { + BLEdevice* p = *it; if ((strcmp(p->macAdr, (char*)mac_adress.c_str()) == 0)) { if (p->sensorModel == LYWSD03MMC) BLEdata.set("model", "LYWSD03MMC"); @@ -657,7 +661,8 @@ void notifyCB( void BLEconnect() { Log.notice(F("BLE Connect begin" CR)); BLEDevice::init(""); - for (vector::iterator p = devices.begin(); p != devices.end(); ++p) { + for (vector::iterator it = devices.begin(); it != devices.end(); ++it) { + BLEdevice* p = *it; if (p->sensorModel == LYWSD03MMC || p->sensorModel == MHO_C401) { Log.trace(F("Model to connect found" CR)); NimBLEClient* pClient; @@ -730,10 +735,6 @@ void coreTask(void* pvParameters) { // Launching a connect every BLEscanBeforeConnect if (!(scanCount % BLEscanBeforeConnect) || scanCount == 1) BLEconnect(); -# ifdef ZmqttDiscovery - if (disc) - launchDiscovery(); -# endif dumpDevices(); } if (lowpowermode) { @@ -961,8 +962,22 @@ boolean valid_service_data(const char* data) { return false; } -void launchDiscovery() { - for (vector::iterator p = devices.begin(); p != devices.end(); ++p) { +// This function always should be called from the main core as it generates direct mqtt messages +void launchBTDiscovery() { + if (newDevices == 0) + return; +# ifdef ESP32 + if (!semaphoreCreateOrUpdateDevice.take(1000, "launchBTDiscovery")) + return; + newDevices = 0; + vector localDevices = devices; + semaphoreCreateOrUpdateDevice.give(); + for (vector::iterator it = localDevices.begin(); it != localDevices.end(); ++it) { +# else + newDevices = 0; + for (vector::iterator it = devices.begin(); it != devices.end(); ++it) { +# endif + BLEdevice* p = *it; if (p->sensorModel != UNKNOWN_MODEL && !isDiscovered(p)) { String macWOdots = String(p->macAdr); macWOdots.replace(":", ""); @@ -983,9 +998,14 @@ void launchDiscovery() { if (p->sensorModel == LYWSD03MMC || p->sensorModel == LYWSD03MMC_ATC) LYWSD03MMCDiscovery((char*)macWOdots.c_str(), "LYWSD03MMC"); if (p->sensorModel == MHO_C401) MHO_C401Discovery((char*)macWOdots.c_str(), "MHO_C401"); if (p->sensorModel == INODE_EM) INodeEMDiscovery((char*)macWOdots.c_str(), "INODE_EM"); - createOrUpdateDevice(p->macAdr, device_flags_isDisc, p->sensorModel); + p->isDisc = true; // we don't need the semaphore and all the search magic via createOrUpdateDevice } else { - Log.trace(F("Device already discovered or UNKNOWN_MODEL" CR)); + if (!isDiscovered(p)) { + Log.trace(F("Device UNKNOWN_MODEL %s" CR), p->macAdr); + p->isDisc = true; + } else { + Log.trace(F("Device already discovered %s" CR), p->macAdr); + } } } } @@ -1416,8 +1436,16 @@ void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding WorBupdated |= updateWorB(BTdata, true); WorBupdated |= updateWorB(BTdata, false); - if (WorBupdated) + if (WorBupdated) { +# ifdef ESP32 + if (!semaphoreCreateOrUpdateDevice.take(1000, "dumpDevices")) { + dumpDevices(); + semaphoreCreateOrUpdateDevice.give(); + } +# else dumpDevices(); +# endif + } // Scan interval set if (BTdata.containsKey("interval")) { diff --git a/main/ZmqttDiscovery.ino b/main/ZmqttDiscovery.ino index 667183666f..74a385459d 100644 --- a/main/ZmqttDiscovery.ino +++ b/main/ZmqttDiscovery.ino @@ -137,7 +137,7 @@ void createDiscovery(char* sensor_type, deviceid[12] = '\0'; StaticJsonBuffer jsonDeviceBuffer; JsonObject& device = jsonDeviceBuffer.createObject(); - if (device_mac != "") { + if (device_mac[0] != 0) { JsonArray& connections = device.createNestedArray("connections"); JsonArray& connection_mac = connections.createNestedArray(); connection_mac.add("mac"); diff --git a/main/config_BT.h b/main/config_BT.h index 474f030dbc..d7e210b863 100644 --- a/main/config_BT.h +++ b/main/config_BT.h @@ -29,6 +29,8 @@ extern void setupBT(); extern bool BTtoMQTT(); extern void MQTTtoBT(char* topicOri, JsonObject& RFdata); +extern void emptyBTQueue(); +extern void launchBTDiscovery(); #ifdef ESP32 extern int btQueueBlocked; diff --git a/main/main.ino b/main/main.ino index cab2c4535e..69a084f22d 100644 --- a/main/main.ino +++ b/main/main.ino @@ -1319,6 +1319,10 @@ void loop() { PilighttoMQTT(); #endif #ifdef ZgatewayBT +# ifdef ZmqttDiscovery + if (disc) + launchBTDiscovery(); +# endif # ifndef ESP32 if (BTtoMQTT()) Log.trace(F("BTtoMQTT OK" CR));