Switching BLE client (ios/android) on the same ESP ... and can't reconnect without re-bonding
Hello
I have a large project with ESP-DF (4.4.1) and Ardunio (2.0.3). I use Nimble-Arduino (1.4.0).
My ESP32 act as server and clients (phones) alternativly connect on the ESP32.
Currently, once android is the last peered device (then disconnected), the iphone will never be able to reconnect (his ble stack says "Peer removed pairing information"). The user has to manualy remove it from ios peered devices... not very user friendly.
I've found some posts about "BLE_HOST_BASED_PRIVACY" option. But it seems it's forced to '1' in my ESP-IDF configuration.
esp_nimble_cfg.h
#if CONFIG_IDF_TARGET_ESP32
#define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (1)
#else
#ifndef MYNEWT_VAL_BLE_HOST_BASED_PRIVACY
#define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (CONFIG_BT_NIMBLE_HOST_BASED_PRIVACY)
#endif
#endif
Is there any solution ? found nothing in the documentation.
Thanks !
My init sequence is this :
NimBLEDevice::init(bleName);
NimBLEDevice::setMTU(BLE_MTU);
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
/////
NimBLEDevice::setSecurityAuth(true, true, true);
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
// NimBLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
NimBLEDevice::setSecurityCallbacks(new BLESecurityCallback());
/////
int mtu = BLEDevice::getMTU();
Serial.print(F("BLH - MTU : "));
Serial.println(mtu);
// Serial.printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__);
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new BLEServerCallback());
...
NimBLEDevice::setSecurityPasskey(pinCode);
pSecurity->setStaticPIN(pinCode);
pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
Host based privacy is required for the esp32 to support bonding with phones, this is not the issue you're having.
It sounds like what you need is to increase the number of bonds that can be stored. You can set this with CONFIG_BT_NIMBLE_MAX_BONDS by default it is set to 3.
ok thanks. i'll try right now 👍 3 in not enought for a 2 client devices competition ?
nope ... same issue.
by the way, I tried many solutions to increease nimble log levels, but it's not working : -DBLE_HS_LOG_LVL=0 -DMYNEWT_VAL_BLE_HS_LOG_LVL=0 -DCONFIG_BT_NIMBLE_LOG_LEVEL=0
Please try erasing the esp32 flash before uploading and try again.
same same. I erased the flash, and reflashed all.
I've set with build flags : -DCONFIG_BT_NIMBLE_MAX_BONDS=7 -DMYNEWT_VAL_BLE_STORE_MAX_BONDS=7
confirmed to be taken into account by log traces
my test : 1/ remove peering from ios & android phone 2/ launch android app, peering (with pin code), read datas, disconnect => all good 3/ launch ios app, peering (with pin code), read datas, disconnect => all good 4/ launch android app, it request for a new peering, disconnect => wrong 5/ launch ios app, it fails at connection => "peer removed" ios bt stack trace
if I manually remove the peering from ios, then I can peer it again and it works. but very dirty
Thanks, I'm not sure what is happening in the case.
Could you try with the secure server example and let me know if you have the issue? I will need to reproduce this to debug so it would be helpful to confirm with common code.
not so easy (flash encryption, lot of scripts, have to replicate a part of the phone apps), but I'll try.
it works with the example with the same envrionnement (same IDF, arduino, lib ...). I've posted most of my code above for the BLE. what could be wrong. I also scan almost continously. could it be related ?
Thanks for checking that. So if it works fine with the example code there must be something else going on in your code or environment that is different, There isn't much I can suggest as the code you've provided does not present any obvious faults.
I would recommend however to remove the use of NimBLESecurity class in your code, this might (shouldn't) be part of the issue, however, it has been deprecated for some time and now removed in the master branch and will not be in the next releases.
ok, thanks for the advise & help. I close the issue ;)
still trying to test the example and understand. it seems as soon I increase the number of characteristics on my services, the issue happen.
1 service with 6 chrac + 1 service with 1 charac => OK 1 service with 14 chrac + 1 service with 1 charac => KO !
Here is the full test code.
#include <Arduino.h>
#include <NimBLEDevice.h>
#define ENABLE_ALL_CHARAC 0
#define ENABLE_ALL_SERVICE_AND_CHARAC 1
#define SERVICE_MAIN_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define SERVICE_FIRMWARE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914c"
#define SERVICE_SETTINGS_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914d"
#define SERVICE_VESC_UUID "6e400001-b5a3-f393-e0a9-e50e24dcca9e"
#define MEASUREMENTS_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a0"
#define MEASUREMENTS2_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a1"
#define FIRMWARE_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a3"
#define COMMANDS_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a5"
#define BTLOCK_STATUS_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a6"
#define ERROR_HISTORY1_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a7"
#define CALIB_ORDER_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26ad"
#define SWITCH_TO_OTA_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26ae"
#define LOGS_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26af"
#define DISTANCE_RST_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26b5"
#define ADC_DAC_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26b6"
#define ACTION_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26fe"
#define SETTINGS_DATA_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26ff"
#define SETTINGS_VERSION_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26fc"
#define DATE_TIME_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26b7"
#define TPMS_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define VESC_CHARACTERISTIC_UUID_RX_UUID "6e400002-b5a3-f393-e0a9-e50e24dcca9e"
#define VESC_CHARACTERISTIC_UUID_TX_UUID "6e400003-b5a3-f393-e0a9-e50e24dcca9e"
NimBLECharacteristic *pCharacteristicMeasurements;
NimBLECharacteristic *pCharacteristicMeasurements2;
NimBLECharacteristic *pCharacteristicBtlockStatus;
NimBLECharacteristic *pCharacteristicErrorHistory1;
NimBLECharacteristic *pCharacteristicCalibOrder;
NimBLECharacteristic *pCharacteristicOtaSwitch;
NimBLECharacteristic *pCharacteristicLogs;
NimBLECharacteristic *pCharacteristicDistanceRst;
NimBLECharacteristic *pCharacteristicCommands;
NimBLECharacteristic *pCharacteristicAdcDac;
NimBLECharacteristic *pCharacteristicSettingsVersion;
NimBLECharacteristic *pCharacteristicVescTx;
NimBLECharacteristic *pCharacteristicVescRx;
NimBLECharacteristic *pCharacteristicDateTime;
NimBLECharacteristic *pCharacteristicTpms;
NimBLECharacteristic *pCharacteristicSettingsGen;
NimBLECharacteristic *pCharacteristicSettingsAction;
NimBLECharacteristic *pCharacteristicFirmware;
void setup()
{
Serial.begin(921600);
Serial.println("\nBoot");
NimBLEDevice::init("Smart-00");
#ifdef ESP_PLATFORM
NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */
#else
NimBLEDevice::setPower(9); /** +9db */
#endif
NimBLEDevice::setSecurityAuth(true, true, true);
NimBLEDevice::setSecurityPasskey(147258);
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
NimBLEServer *pServer = NimBLEDevice::createServer();
BLEService *pServiceMain = pServer->createService(BLEUUID(SERVICE_MAIN_UUID));
BLEService *pServiceFirmware = pServer->createService(BLEUUID(SERVICE_FIRMWARE_UUID));
#if ENABLE_ALL_SERVICE_AND_CHARAC
BLEService *pServiceSettings = pServer->createService(BLEUUID(SERVICE_SETTINGS_UUID));
BLEService *pServiceVesc = pServer->createService(BLEUUID(SERVICE_VESC_UUID));
#endif
// Create a BLE Characteristic
//-------------------
// services firmware
pCharacteristicFirmware = pServiceFirmware->createCharacteristic(
FIRMWARE_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
//-------------------
// services main
pCharacteristicCommands = pServiceMain->createCharacteristic(
COMMANDS_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN |
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
pCharacteristicBtlockStatus = pServiceMain->createCharacteristic(
BTLOCK_STATUS_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN |
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
pCharacteristicDateTime = pServiceMain->createCharacteristic(
DATE_TIME_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN);
pCharacteristicErrorHistory1 = pServiceMain->createCharacteristic(
ERROR_HISTORY1_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
pCharacteristicSettingsVersion = pServiceMain->createCharacteristic(
SETTINGS_VERSION_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
pCharacteristicTpms = pServiceMain->createCharacteristic(
TPMS_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
#if ENABLE_ALL_CHARAC
pCharacteristicMeasurements = pServiceMain->createCharacteristic(
MEASUREMENTS_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
pCharacteristicMeasurements2 = pServiceMain->createCharacteristic(
MEASUREMENTS2_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
pCharacteristicCalibOrder = pServiceMain->createCharacteristic(
CALIB_ORDER_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN);
pCharacteristicOtaSwitch = pServiceMain->createCharacteristic(
SWITCH_TO_OTA_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN);
pCharacteristicLogs = pServiceMain->createCharacteristic(
LOGS_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN);
pCharacteristicDistanceRst = pServiceMain->createCharacteristic(
DISTANCE_RST_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN);
pCharacteristicAdcDac = pServiceMain->createCharacteristic(
ADC_DAC_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN |
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
#endif
//-------------------
// VESC settings
#if ENABLE_ALL_SERVICE_AND_CHARAC
// Create a BLE Characteristic for VESC TX
pCharacteristicVescTx = pServiceVesc->createCharacteristic(
VESC_CHARACTERISTIC_UUID_TX_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN);
// Create a BLE Characteristic for VESC RX
pCharacteristicVescRx = pServiceVesc->createCharacteristic(
VESC_CHARACTERISTIC_UUID_RX_UUID,
NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::READ_ENC |
NIMBLE_PROPERTY::READ_AUTHEN |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN);
//-------------------
// services settings
pCharacteristicSettingsGen = pServiceSettings->createCharacteristic(
SETTINGS_DATA_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::INDICATE |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN);
pCharacteristicSettingsAction = pServiceSettings->createCharacteristic(
ACTION_CHARACTERISTIC_UUID,
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::INDICATE |
NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::WRITE_ENC |
NIMBLE_PROPERTY::WRITE_AUTHEN);
#endif
pServiceMain->start();
pServiceFirmware->start();
#if ENABLE_ALL_SERVICE_AND_CHARAC
pServiceVesc->start();
pServiceSettings->start();
#endif
pCharacteristicFirmware->setValue("sd_vesc_35v2");
uint8_t data[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
pCharacteristicCommands->setValue(data);
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_MAIN_UUID);
pAdvertising->addServiceUUID(SERVICE_FIRMWARE_UUID);
#if ENABLE_ALL_SERVICE_AND_CHARAC
pAdvertising->addServiceUUID(SERVICE_VESC_UUID);
pAdvertising->addServiceUUID(SERVICE_SETTINGS_UUID);
#endif
pAdvertising->start();
}
void loop()
{
vTaskDelay(10 / portTICK_PERIOD_MS);
}
if I set ENABLE_ALL_CHARAC to 1, it doesn't work anymore.
platformio config :
[env]
platform = https://github.com/tasmota/platform-espressif32/releases/download/v.2.0.3/platform-espressif32-v.2.0.3.zip
framework = arduino, espidf
board = esp32dev
lib_deps =
h2zero/[email protected]
board_build.partitions = partition6.csv
board_upload.offset_address = 0xb000
build_flags =
-DESP32=1
-DARDUINO_ARCH_ESP32=1
-DARDUINO=100
-Wformat-contains-nul
-Wno-format-overflow
-Wno-error=format-truncation
-Wno-cast-function-type
-Wno-misleading-indentation
-Wignored-qualifiers
-ftrack-macro-expansion=0
-DUSE_PGM=1
-DCONFIG_BT_NIMBLE_MAX_BONDS=7
-DMYNEWT_VAL_BLE_STORE_MAX_BONDS=7
;-fno-diagnostics-show-caret
;-std=c++17
; only use C++17 now not GNU++17. This is an either-or relation.
-std=gnu++17
build_unflags =
-Werror=all
-std=gnu++11
partition6.csv
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0xC000, 0x5000
otadata, data, ota, 0x11000, 0x2000
spiffs, data, spiffs, 0x13000, 0x2D000
ota_0, app, ota_0, 0x40000, 0x1D8000
ota_1, app, ota_1, 0x220000, 0x1D8000
# nvs_key, data, nvs_keys, , 0x1000
firmware / partitions encryption is enabled
1 service with 8 chrac + 1 service with 1 charac => fail
same issue with : 1 service with 1 charac
- 1 service with 6 charac
- 1 service with 2 charac
- 1 service with 2 charac
==> so i doesn't seems related to the numbers of characteristics per service but more to a global number of characteristics. could it be related to NVS storage size ?
holly crap ! I increase the nuber of stored CCCDs... and it works now ! -DMYNEWT_VAL_BLE_STORE_MAX_CCCDS=20
I could be interesting to add a bit more of documentation on build options ;)
I was just about to respond when you typed that, but yes that is certainly the issue. Glad you figured it out :smile:, yes more documentation around these is certainly a good idea, though it is documented here: https://h2zero.github.io/NimBLE-Arduino/md__command_line_config.html
CONFIG_BT_NIMBLE_MAX_CCCDS
Sets the maximum number of CCCD subscriptions to store
Default value is 8