From 85ef2c0fd5ff9ef5c9ada5703d29ade8f3bd668b Mon Sep 17 00:00:00 2001 From: iranl Date: Wed, 24 Jul 2024 21:54:02 +0200 Subject: [PATCH] BLE fixes --- .gitmodules | 2 +- README.md | 4 +- lib/BleScanner/src/BleScanner.cpp | 6 ++ lib/BleScanner/src/BleScanner.h | 8 ++ lib/esp-nimble-cpp/src/NimBLEClient.cpp | 2 - lib/nuki_ble | 2 +- platformio.ini | 113 +++++++++++++----------- sdkconfig.defaults | 3 +- src/NukiOpenerWrapper.cpp | 3 +- src/NukiWrapper.cpp | 3 +- src/WebCfgServer.cpp | 2 +- src/main.cpp | 17 +++- updater/platformio.ini | 2 +- 13 files changed, 102 insertions(+), 65 deletions(-) diff --git a/.gitmodules b/.gitmodules index 789cb4f6..fab84694 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "lib/nuki_ble"] path = lib/nuki_ble - url = https://github.com/I-Connect/NukiBleEsp32 + url = https://github.com/iranl/NukiBleEsp32 diff --git a/README.md b/README.md index 4748ec2e..ab7a6bf0 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ Feel free to join us on Discord: https://discord.gg/9nPq85bP4p Supported ESP32 devices: - Nuki Hub is compiled against all ESP32 models with Wi-Fi and Bluetooh Low Energy (BLE) which are supported by ESP-IDF 5.1.4 and Arduino Core 3.0.1. - Tested stable builds are provided for the ESP32, ESP32-S3 and ESP32-C3. -- Support for the ESP32-C6 is ***HIGHLY*** experimental. Expect frequent crashes, especially when running Nuki Hub paired as an app (when not using in Hybrid mode). Pairing is also not supported yet and needs to be done manually on the /advanced page of the web configurator. -- The ESP32-Solo1 is not supported by ESP-IDF 5.1 and as such can't be build using Arduino Core 3 and ESP-IDF 5.1. Untested build against Arduino Core 2.0.14 and ESP-IDF 4.4 are provided. +- Support for the ESP32-C6 is experimental. There could be more frequent crashes than on other ESP32 devices and connections with the Nuki device are created more slowly than on other ESP32 devices. Pairing is also not supported yet and needs to be done manually on the /advanced page of the web configurator by copying the pairing information of another already paired ESP32(-S3/-C3) device running Nuki Hub. +- The ESP32-Solo1 is not supported by ESP-IDF 5.1 and as such can't be build using Arduino Core 3 and ESP-IDF 5.1. Untested builds against Arduino Core 2.0.14 and ESP-IDF 4.4 are provided. Not supported ESP32 devices: - The ESP32-S2 has no BLE and as such can't run Nuki Hub. diff --git a/lib/BleScanner/src/BleScanner.cpp b/lib/BleScanner/src/BleScanner.cpp index 4ad6ab73..ff4eca4c 100644 --- a/lib/BleScanner/src/BleScanner.cpp +++ b/lib/BleScanner/src/BleScanner.cpp @@ -30,6 +30,7 @@ void Scanner::initialize(const std::string& deviceName, const bool wantDuplicate } BLEDevice::init(deviceName); } + bleScan = BLEDevice::getScan(); #ifndef BLESCANNER_USE_LATEST_NIMBLE @@ -98,4 +99,9 @@ void Scanner::onResult(NimBLEAdvertisedDevice* advertisedDevice) { } } +void Scanner::whitelist(BLEAddress bleAddress) { + BLEDevice::whiteListAdd(bleAddress); + bleScan->setFilterPolicy(BLE_HCI_SCAN_FILT_USE_WL); +} + } // namespace BleScanner \ No newline at end of file diff --git a/lib/BleScanner/src/BleScanner.h b/lib/BleScanner/src/BleScanner.h index c7b0bcbe..4942bc04 100644 --- a/lib/BleScanner/src/BleScanner.h +++ b/lib/BleScanner/src/BleScanner.h @@ -84,6 +84,14 @@ class Scanner : public Publisher, BLEAdvertisedDeviceCallbacks { * @param advertisedDevice */ void onResult(NimBLEAdvertisedDevice* advertisedDevice) override; + + /** + * @brief Whitelist a specific BLE Address + * + * @param whiteListBleAddress + */ + void whitelist(BLEAddress bleAddress); + private: uint32_t scanDuration = 0; //default indefinite scanning time diff --git a/lib/esp-nimble-cpp/src/NimBLEClient.cpp b/lib/esp-nimble-cpp/src/NimBLEClient.cpp index b524a2dd..a0a01312 100644 --- a/lib/esp-nimble-cpp/src/NimBLEClient.cpp +++ b/lib/esp-nimble-cpp/src/NimBLEClient.cpp @@ -295,8 +295,6 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttributes) if(isConnected()) { NIMBLE_LOGE(LOG_TAG, "Connect timeout - no response"); disconnect(); - NIMBLE_LOGE(LOG_TAG, "Connect timeout - cancelling"); - ble_gap_conn_cancel(); } else { // workaround; if the controller doesn't cancel the connection // at the timeout, cancel it here. diff --git a/lib/nuki_ble b/lib/nuki_ble index 9116261c..9dd3f29a 160000 --- a/lib/nuki_ble +++ b/lib/nuki_ble @@ -1 +1 @@ -Subproject commit 9116261c791d64d77238e093780d64cbeac32256 +Subproject commit 9dd3f29a8fff86f2068c9ea9cece7d1d1765cef4 diff --git a/platformio.ini b/platformio.ini index e2a0a68b..a96de731 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ default_envs = esp32dev boards_dir = boards [env] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.06.11/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.07.11/platform-espressif32.zip platform_packages = framework = arduino, espidf build_type = release @@ -25,13 +25,13 @@ build_unflags = -Werror=all -Wall build_flags = - -fexceptions - -DTLS_CA_MAX_SIZE=2200 - -DTLS_CERT_MAX_SIZE=1500 - -DTLS_KEY_MAX_SIZE=1800 - -DESP_PLATFORM - -DESP32 - -DARDUINO_ARCH_ESP32 + -fexceptions + -DTLS_CA_MAX_SIZE=2200 + -DTLS_CERT_MAX_SIZE=1500 + -DTLS_KEY_MAX_SIZE=1800 + -DESP_PLATFORM + -DESP32 + -DARDUINO_ARCH_ESP32 -DCONFIG_BTDM_BLE_SCAN_DUPL=y -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 -DCONFIG_ASYNC_TCP_PRIORITY=10 @@ -61,14 +61,15 @@ monitor_filters = board = esp32dev extra_scripts = post:pio_package.py build_flags = - ${env.build_flags} + ${env.build_flags} + -DNUKI_ALT_CONNECT -DBLESCANNER_USE_LATEST_NIMBLE -DNUKI_USE_LATEST_NIMBLE -DNUKI_NO_WDT_RESET -DNUKI_MUTEX_RECURSIVE -DNUKI_64BIT_TIME -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 -DCONFIG_BT_NIMBLE_LOG_LEVEL=0 [env:esp32-c3] @@ -89,11 +90,12 @@ framework = arduino board = esp32-solo1 extra_scripts = post:pio_package.py build_flags = - ${env.build_flags} - -DFRAMEWORK_ARDUINO_SOLO1 + ${env.build_flags} + -DFRAMEWORK_ARDUINO_SOLO1 -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 -DCONFIG_BT_NIMBLE_LOG_LEVEL=0 + -DNUKI_ALT_CONNECT -DNUKI_64BIT_TIME lib_deps = BleScanner=symlink://lib/BleScanner @@ -107,99 +109,104 @@ lib_ignore = extends = env:esp32dev custom_build = debug build_flags = - ${env.build_flags} + ${env.build_flags} -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 -DCONFIG_BT_NIMBLE_LOG_LEVEL=0 + -DNUKI_ALT_CONNECT -DBLESCANNER_USE_LATEST_NIMBLE -DNUKI_USE_LATEST_NIMBLE -DNUKI_NO_WDT_RESET -DNUKI_MUTEX_RECURSIVE -DNUKI_64BIT_TIME -DDEBUG_NUKIHUB - -DDEBUG_SENSE_NUKI - -DDEBUG_NUKI_COMMAND - -DDEBUG_NUKI_CONNECT - -DDEBUG_NUKI_COMMUNICATION - ;-DDEBUG_NUKI_HEX_DATA - -DDEBUG_NUKI_READABLE_DATA + -DDEBUG_SENSE_NUKI + -DDEBUG_NUKI_COMMAND + -DDEBUG_NUKI_CONNECT + -DDEBUG_NUKI_COMMUNICATION + ;-DDEBUG_NUKI_HEX_DATA + -DDEBUG_NUKI_READABLE_DATA [env:esp32-c3_dbg] extends = env:esp32-c3 custom_build = debug build_flags = - ${env.build_flags} + ${env.build_flags} -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 -DCONFIG_BT_NIMBLE_LOG_LEVEL=0 + -DNUKI_ALT_CONNECT -DBLESCANNER_USE_LATEST_NIMBLE -DNUKI_USE_LATEST_NIMBLE -DNUKI_NO_WDT_RESET -DNUKI_MUTEX_RECURSIVE -DNUKI_64BIT_TIME -DDEBUG_NUKIHUB - -DDEBUG_SENSE_NUKI - -DDEBUG_NUKI_COMMAND - -DDEBUG_NUKI_CONNECT - -DDEBUG_NUKI_COMMUNICATION - ;-DDEBUG_NUKI_HEX_DATA - -DDEBUG_NUKI_READABLE_DATA + -DDEBUG_SENSE_NUKI + -DDEBUG_NUKI_COMMAND + -DDEBUG_NUKI_CONNECT + -DDEBUG_NUKI_COMMUNICATION + ;-DDEBUG_NUKI_HEX_DATA + -DDEBUG_NUKI_READABLE_DATA [env:esp32-c6_dbg] extends = env:esp32-c6 custom_build = debug build_flags = - ${env.build_flags} + ${env.build_flags} -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 -DCONFIG_BT_NIMBLE_LOG_LEVEL=0 + -DNUKI_ALT_CONNECT -DBLESCANNER_USE_LATEST_NIMBLE -DNUKI_USE_LATEST_NIMBLE -DNUKI_NO_WDT_RESET -DNUKI_MUTEX_RECURSIVE -DNUKI_64BIT_TIME -DDEBUG_NUKIHUB - -DDEBUG_SENSE_NUKI - -DDEBUG_NUKI_COMMAND - -DDEBUG_NUKI_CONNECT - -DDEBUG_NUKI_COMMUNICATION - ;-DDEBUG_NUKI_HEX_DATA - -DDEBUG_NUKI_READABLE_DATA + -DDEBUG_SENSE_NUKI + -DDEBUG_NUKI_COMMAND + -DDEBUG_NUKI_CONNECT + -DDEBUG_NUKI_COMMUNICATION + ;-DDEBUG_NUKI_HEX_DATA + -DDEBUG_NUKI_READABLE_DATA [env:esp32-s3_dbg] extends = env:esp32-s3 custom_build = debug build_flags = - ${env.build_flags} + ${env.build_flags} -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 -DCONFIG_BT_NIMBLE_LOG_LEVEL=0 + -DNUKI_ALT_CONNECT -DBLESCANNER_USE_LATEST_NIMBLE -DNUKI_USE_LATEST_NIMBLE -DNUKI_NO_WDT_RESET -DNUKI_MUTEX_RECURSIVE -DNUKI_64BIT_TIME -DDEBUG_NUKIHUB - -DDEBUG_SENSE_NUKI - -DDEBUG_NUKI_COMMAND - -DDEBUG_NUKI_CONNECT - -DDEBUG_NUKI_COMMUNICATION - ;-DDEBUG_NUKI_HEX_DATA - -DDEBUG_NUKI_READABLE_DATA + -DDEBUG_SENSE_NUKI + -DDEBUG_NUKI_COMMAND + -DDEBUG_NUKI_CONNECT + -DDEBUG_NUKI_COMMUNICATION + ;-DDEBUG_NUKI_HEX_DATA + -DDEBUG_NUKI_READABLE_DATA [env:esp32solo1_dbg] extends = env:esp32solo1 custom_build = debug build_flags = - ${env.build_flags} + ${env.build_flags} -DFRAMEWORK_ARDUINO_SOLO1 -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + -DNUKI_ALT_CONNECT -DNUKI_64BIT_TIME -DDEBUG_NUKIHUB - -DDEBUG_SENSE_NUKI - -DDEBUG_NUKI_COMMAND - -DDEBUG_NUKI_CONNECT - -DDEBUG_NUKI_COMMUNICATION - ;-DDEBUG_NUKI_HEX_DATA - -DDEBUG_NUKI_READABLE_DATA \ No newline at end of file + -DDEBUG_SENSE_NUKI + -DDEBUG_NUKI_COMMAND + -DDEBUG_NUKI_CONNECT + -DDEBUG_NUKI_COMMUNICATION + ;-DDEBUG_NUKI_HEX_DATA + -DDEBUG_NUKI_READABLE_DATA \ No newline at end of file diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 4e3f25bf..77e9d490 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -64,4 +64,5 @@ CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n CONFIG_IEEE802154_ENABLED=n CONFIG_ARDUINO_SELECTIVE_COMPILATION=y CONFIG_ARDUINO_SELECTIVE_HTTPClient=n -CONFIG_ARDUINO_SELECTIVE_WebServer=n \ No newline at end of file +CONFIG_ARDUINO_SELECTIVE_WebServer=n +CONFIG_HEAP_TASK_TRACKING=n \ No newline at end of file diff --git a/src/NukiOpenerWrapper.cpp b/src/NukiOpenerWrapper.cpp index a02b5582..083e4ac5 100644 --- a/src/NukiOpenerWrapper.cpp +++ b/src/NukiOpenerWrapper.cpp @@ -103,7 +103,8 @@ void NukiOpenerWrapper::initialize() } _nukiOpener.setEventHandler(this); - _nukiOpener.setDisonnectTimeout(5000); + _nukiOpener.setConnectTimeout(3); + _nukiOpener.setDisconnectTimeout(5000); Log->print(F("Lock state interval: ")); Log->print(_intervalLockstate); diff --git a/src/NukiWrapper.cpp b/src/NukiWrapper.cpp index 9771418d..5386a27c 100644 --- a/src/NukiWrapper.cpp +++ b/src/NukiWrapper.cpp @@ -173,7 +173,8 @@ void NukiWrapper::initialize(const bool& firstStart) } _nukiLock.setEventHandler(this); - _nukiLock.setDisonnectTimeout(5000); + _nukiLock.setConnectTimeout(3); + _nukiLock.setDisconnectTimeout(5000); Log->print(F("Lock state interval: ")); Log->print(_intervalLockstate); diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp index 98b5272b..036a47ee 100644 --- a/src/WebCfgServer.cpp +++ b/src/WebCfgServer.cpp @@ -762,7 +762,7 @@ void WebCfgServer::sendSettings() } } - if(pairing && _preferences->getBool(preference_show_secrets)) + if(pairing) { if(_nuki != nullptr) { diff --git a/src/main.cpp b/src/main.cpp index 15e6e16e..0c79a33f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,6 +116,7 @@ void networkTask(void *pvParameters) void nukiTask(void *pvParameters) { int64_t nukiLoopTs = 0; + bool whiteListed = false; while(true) { @@ -128,6 +129,20 @@ void nukiTask(void *pvParameters) { delay(5000); } + #ifndef PRESENCE_DETECTION_ENABLED + else if (!whiteListed) + { + whiteListed = true; + if(lockEnabled) + { + bleScanner->whitelist(nuki->getBleAddress()); + } + if(openerEnabled) + { + bleScanner->whitelist(nukiOpener->getBleAddress()); + } + } + #endif if(lockEnabled) { @@ -393,7 +408,7 @@ void setup() // Scan interval and window according to Nuki recommendations: // https://developer.nuki.io/t/bluetooth-specification-questions/1109/27 bleScanner->initialize("NukiHub", true, 40, 40); - bleScanner->setScanDuration(10); + bleScanner->setScanDuration(0); #if PRESENCE_DETECTION_ENABLED if(preferences->getInt(preference_presence_detection_timeout) >= 0) diff --git a/updater/platformio.ini b/updater/platformio.ini index 9e810298..afdaa1ca 100644 --- a/updater/platformio.ini +++ b/updater/platformio.ini @@ -13,7 +13,7 @@ default_envs = updater_esp32dev boards_dir = ../boards [env] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.06.11/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.07.11/platform-espressif32.zip platform_packages = framework = arduino, espidf build_type = release