esp-idf
esp-idf copied to clipboard
ASSERT_PARAM(-218959118 0), in arch_main.c at line 365 while using BLE (IDFGH-12768)
Answers checklist.
- [X] I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- [X] I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- [X] I have searched the issue tracker for a similar issue and not found a similar issue.
General issue report
Environment
Development Kit: none (this is a custom board, but could reproduce the issue with a ESP32-WROOM-based board too)
Module or chip used: ESP32-D0WD
IDF version: v4.4.4 from Tasmota 2023.06.02
Build System: Platformio/Make
Compiler version: xtensa-esp32-elf-gcc (crosstool-NG esp-2021r2-patch5) 8.4.0
Operating System: Windows
Power Supply: external 5V or USB
Problem Description
My software uses BLE, Wifi (disabled during this test, but enable in sdkconfig), TWAI, UART, SPI, U2C and UART...
It scans for BLE beacons every second while it is connected in BLE to a 1 smartphone, and it reports the detected devices belonging to a custom filtered list with custom BLE characteristics.
Advertising is enabled while the smartphone is connected. It uses NimBLE.
I crash after 5 to 8h if a smartphone remains connected. I don't see any crash if the smartphone isn't connected.
I've tried many many configurations following similar previous BLE stack errors reported on this github :
- customize bt controller adv report
- disable bt controller sleep
- remove _btdm_sleep_check_duration callback from bt.c
- increase watchdog timeout
- change scan strategies and filtering
- enabling BLE queue congestion check
Without success ...
Monitoring memory every 1h, I don't see any leak over time.
My sdkconfig : https://pastebin.com/2TzT7sTC
I can't move to higher IDF without a large impact on my software... which is not possible considering we are launching the production soon. I tried IDF 4.4.5, but it crashes too (I didn't note the exception/backtrace)
Any help please ?
Expected Behaviour
The BLE stack should not panic when scanning.
Actual Behaviour
The application will panic after seemingly non-deterministic intervals, generally during BLE scans.
Steps to reproduce
N/A considering the complexity of the application.
Debug Logs
ASSERT_PARAM(-218959118 0), in arch_main.c at line 365
Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x40090b88: 000000f0 00004136 f01d0000
Core 0 register dump:
PC : 0x40090b8f PS : 0x00060734 A0 : 0x80086505 A1 : 0x3ffb6020
A2 : 0x00000000 A3 : 0xf2f2f2f2 A4 : 0x00000000 A5 : 0x3f43627e
A6 : 0x0000016d A7 : 0xfffffffc A8 : 0x8000814b A9 : 0x3ffb5f90
A10 : 0x00000000 A11 : 0x3ffb5fb3 A12 : 0x3ffb5f5f A13 : 0x00000035
A14 : 0x00000000 A15 : 0x3ffb5f64 SAR : 0x00000004 EXCCAUSE: 0x00000000
EXCVADDR: 0x00000000 LBEG : 0x4008640d LEND : 0x40086415 LCOUNT : 0x00000000
Backtrace: 0x40090b8c:0x3ffb6020 0x40086502:0x3ffb6040 0x401a1691:0x3ffb6060 0x40019fb5:0x3ffb6080 0x4001a1f2:0x3ffb60b0 0x401afe5a:0x3ffb60d0 0x401b15e1:0x3ffb6140 0x401ae5ff:0x3ffb6190 0x401ab7d2:0x3ffb61e0 0x40019d11:0x3ffb6220 0x40055b4d:0x3ffb6240 0x401a1a83:0x3ffb6260 0x401a20e5:0x3ffb6280 0x40096cad:0x3ffb62b0
Decoded stack trace :
r_assert at C:\Users\koxx3\.platformio\packages\framework-espidf\components\bt\controller\esp32/bt.c:1862
r_assert_param at ??:?
r_platform_reset at ??:?
?? ??:0
?? ??:0
r_llm_le_adv_report_ind at ??:?
r_llm_pdu_defer at ??:?
r_lld_pdu_check at ??:?
r_lld_evt_deffered_elt_handler at ??:?
?? ??:0
?? ??:0
r_rw_schedule at ??:?
btdm_controller_task at ??:?
vPortTaskWrapper at C:\Users\koxx3\.platformio\packages\framework-espidf\components\freertos\port\xtensa/port.c:142
Memory left after boot :
MEM left = 75468
idle = 5064
tft = 2188
wifi = 4492
btn = 2440
canrx = 1572
cantx = 1760
sound = 188
serial = 4488
btCntr = 1580
btHost = 4932
CAN_WD_BI = 1536
CAN_LORX = 3524
Tmr = 1384
esp_timer = 3140
loopTask = 4200
ipc0 = 860
ipc1 = 992
sys_evt = 4200
arduino_events = 4200
CPU usage :
loopTask 94881202 9%
taskButtons 12519417 1%
taskWifi 7381082 <1%
taskSerial 7324840 <1%
taskCanRx 28419565 2%
IDLE 976617190 94%
IDLE 806747117 77%
taskSound 4433369 <1%
taskTFT 100563690 9%
CAN_WD_BI 83969 <1%
Tmr Svc 103468 <1%
taskCanTx 4063407 <1%
CAN_RX 36 <1%
ipc1 105205 <1%
CAN_LORX 4447391 <1%
nimble_host 6326191 <1%
btController 18189015 1%
ipc0 4655381 <1%
esp_timer 23 <1%
Tasks informations:
taskCanTx | Core ID: 0 | Priority: 0 | Stack High Water Mark: 1760
taskCanRx | Core ID: 0 | Priority: 0 | Stack High Water Mark: 1652
Tmr Svc | Core ID: 0 | Priority: 1 | Stack High Water Mark: 1384
nimble_host | Core ID: 0 | Priority: 21 | Stack High Water Mark: 4932
btController | Core ID: 0 | Priority: 23 | Stack High Water Mark: 1580
esp_timer | Core ID: 0 | Priority: 22 | Stack High Water Mark: 3140
ipc0 | Core ID: 0 | Priority: 1 | Stack High Water Mark: 764
IDLE | Core ID: 0 | Priority: 0 | Stack High Water Mark: 1116
loopTask | Core ID: 1 | Priority: 1 | Stack High Water Mark: 4488
taskSound | Core ID: 1 | Priority: 0 | Stack High Water Mark: 220
taskButtons | Core ID: 1 | Priority: 0 | Stack High Water Mark: 2440
taskWifi | Core ID: 1 | Priority: 0 | Stack High Water Mark: 4492
taskSerial | Core ID: 1 | Priority: 0 | Stack High Water Mark: 4488
taskTFT | Core ID: 1 | Priority: 0 | Stack High Water Mark: 2188
CAN_WD_BI | Core ID: 1 | Priority: 10 | Stack High Water Mark: 1536
CAN_LORX | Core ID: 1 | Priority: 19 | Stack High Water Mark: 3524
CAN_RX | Core ID: 2147483647 | Priority: 15 | Stack High Water Mark: 7704
ipc1 | Core ID: 1 | Priority: 1 | Stack High Water Mark: 992
IDLE | Core ID: 1 | Priority: 0 | Stack High Water Mark: 1104
Thank you for reporting the issue. It seems to be related to the BLE controller's memory. The reason for this issue is that the controller failed to allocate memory. We will attempt to replicate the problem. Could you provide a demo that reproduces this issue? This would be helpful in resolving the problem.
The BLE controller allocates a block of memory during initialization, which is exclusively for the controller's use. There's no way to determine from the outside whether there has been a memory leak in the memory allocated for the controller.
thanks a lot for the answer. I've spent a lot of time tracking this issue...
I switch to IDF 4.4.5, but no improvement.
I'll try to patch IDF-4.4.5 BT controller with 4.4.7 BT controller to ensure this issue isn't already fixed in the latest version.
Some questions : 1/ is it possible to observe the memory leak from outside of the BT controller ? 2/ do you think disconnecting the client can release the memory ? 3/ would is possible to allocate more memory to this module by any mean ? 4/ considering it seems to be "r_llm_le_adv_report_ind" the issue, is there any way to prevent it ? with advertising configuration, scan configuration, reducing MTU (255 bytes negociated by the IOS client in my case), sdk configuration or anything else ?
A said in the first post, it will be very complicated to release a test module if other software parts are involved, but I'll try during next weeks.
1-Is it possible to observe memory leaks from outside of the BT controller? Answer: Currently, it's not possible to detect memory leaks externally. The memory allocation for the controller is predetermined, and there's no API available for external monitoring of its memory usage. However, for debugging purposes, I can provide you with a new library and internal interfaces to access the controller's memory usage.Do you require access to this interface? 2-Do you think disconnecting the client can release the memory? Answer: When there are no connections, a portion of the memory is indeed released. This is because the memory size is fixed after the controller's initialization. 3-Is it possible to allocate more memory to this module by any means? Answer: The memory size allocated during controller initialization is calculated based on factors such as duplicate list size and maximum connection count. In theory, there should not be any assertion errors as sufficient memory is already allocated. Currently, there's no external interface to adjust memory allocation size, but internal adjustments can be made. 4-Considering "r_llm_le_adv_report_ind" seems to be the issue, is there any way to prevent it? Whether through advertising configuration, scan configuration, reducing MTU (255 bytes negotiated by the iOS client in my case), SDK configuration, or anything else? Answer: The consumption of memory decreases when there are no established connections, and it also reduces when there are fewer devices in the air (due to duplicate list reasons). Other scenarios require further assessment. 5-As mentioned in the first post, it might be challenging to release a test module if other software components are involved, but I'll attempt it in the next few weeks. Answer: Currently, it seems that this issue is solely related to BLE and not connected to other components. I'm still attempting to replicate the problem here. If you can replicate the issue using BLE, it would greatly aid in resolving the problem.
ok, thanks again. I'll keep you updated of the 4.4.5/4.4.7 patch tests. if it fails, yes, it would be really interesting to have few APIs to monitor the memory and debug.
d166426.zip(based on e8bdaf91986a41678adc6be13888fc037b1acb68 tag: v4.4.4) Please replace the esp-idf/components/bt/controller/lib_esp32/esp32/libbtdm_app.a file. In the new lib file, I've added a new API that can retrieve the memory usage of the controller. Below is an example and the printed log. When the BT controller compile version is printed as [d166426], it indicates successful application.
I (586) BTDM_INIT: BT controller compile version [d166426]
code:
extern uint16_t ke_get_heap_free_size(void);
uint16_t free_size;
while (1) {
free_size = ke_get_heap_free_size();
printf("free size %d byte\n",free_size);
vTaskDelay(10000 / portTICK_PERIOD_MS);
}
log:
I (29) boot: ESP-IDF v4.4.4-dirty 2nd stage bootloader
I (29) boot: compile time 20:28:41
I (29) boot: chip revision: v3.1
I (33) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (40) boot.esp32: SPI Speed : 40MHz
I (44) boot.esp32: SPI Mode : DIO
I (49) boot.esp32: SPI Flash Size : 2MB
I (53) boot: Enabling RNG early entropy source...
I (59) boot: Partition Table:
I (62) boot: ## Label Usage Type ST Offset Length
I (70) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (77) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (85) boot: 2 factory factory app 00 00 00010000 00100000
I (92) boot: End of partition table
I (96) boot_comm: chip revision: 3, min. application chip revision: 0
I (103) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=1d050h (118864) map
I (155) esp_image: segment 1: paddr=0002d078 vaddr=3ffbdb60 size=02fa0h ( 12192) load
I (160) esp_image: segment 2: paddr=00030020 vaddr=400d0020 size=7ca74h (510580) map
I (346) esp_image: segment 3: paddr=000aca9c vaddr=3ffc0b00 size=017f8h ( 6136) load
I (348) esp_image: segment 4: paddr=000ae29c vaddr=40080000 size=17658h ( 95832) load
I (402) boot: Loaded app from partition at offset 0x10000
I (402) boot: Disabling RNG early entropy source...
I (414) cpu_start: Pro cpu up.
I (414) cpu_start: Starting app cpu, entry point is 0x400811d8
0x400811d8: call_start_cpu1 at /home/zhanghaipeng/esp_v4/esp-idf/components/esp_system/port/cpu_start.c:148
I (0) cpu_start: App cpu up.
I (430) cpu_start: Pro cpu start user code
I (430) cpu_start: cpu freq: 160000000
I (431) cpu_start: Application information:
I (435) cpu_start: Project name: gatt_client_demo
I (441) cpu_start: App version: v4.4.4-dirty
I (446) cpu_start: Compile time: May 7 2024 20:28:36
I (452) cpu_start: ELF file SHA256: c3c24db549fa719a...
I (458) cpu_start: ESP-IDF: v4.4.4-dirty
I (464) heap_init: Initializing. RAM available for dynamic allocation:
I (471) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (477) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (483) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (489) heap_init: At 3FFC8AC8 len 00017538 (93 KiB): DRAM
I (495) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (502) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (508) heap_init: At 40097658 len 000089A8 (34 KiB): IRAM
I (516) spi_flash: detected chip: generic
I (519) spi_flash: flash io: dio
W (523) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (537) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (586) BTDM_INIT: BT controller compile version [d166426]
I (586) system_api: Base MAC address is not set
I (586) system_api: read default base MAC address from EFUSE
I (596) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
I (1016) GATTC_DEMO: REG_EVT
free size 9556 byte
I (1016) GATTC_DEMO: scan start success
free size 9364 byte
free size 9364 byte
free size 9364 byte
free size 9540 byte
ok. I am currently trying with IDF 4.4.7 version. I'll be out of the office for few days, I'll be back in few days to continue tests. If it's not too much to ask, can you generate it for IDF 4.4.5 and 4.4.7 please ?
ok, let's go for a test in IDF 4.4.4 + libbtdm_app.a patch before the long weekend.
compilation test :
15:29:32.558 > I (216) BTDM_INIT: BT controller compile version [d166426]
15:29:32.558 > ESP_ERROR_CHECK failed: esp_err_t 0x101 (ESP_ERR_NO_MEM) at 0x40092ab0
15:29:32.559 > file: ".pio/libdeps/smartdisplay_vesc_35v2_pcb210/nimble/src/NimBLEDevice.cpp" line 879
15:29:32.560 > func: static void NimBLEDevice::init(const string&)
15:29:32.560 > expression: esp_bt_controller_init(&bt_cfg)
15:29:32.561 >
15:29:32.561 > abort() was called at PC 0x40092ab3 on core 1
15:29:32.561 >
15:29:32.561 >
15:29:32.561 > Backtrace: 0x40083842:0x3ffd93c0 0x40092abd:0x3ffd93e0 0x400991da:0x3ffd9400 0x40092ab3:0x3ffd9470 0x40115622:0x3ffd9490 0x400d8517:0x3ffd94e0 0x4010726f:0x3ffd96c0 0x401471da:0x3ffd97c0 0x40096a69:0x3ffd97e0
15:29:32.564 >
15:29:32.564 >
15:29:32.564 >
15:29:32.564 >
15:29:32.564 > ELF file SHA256: 22f76682b73e94f5
15:29:32.564 >
15:29:32.564 > Rebooting...
NimBle function at this line :
void NimBLEDevice::init(const std::string &deviceName) {
if(!initialized){
int rc=0;
#ifdef ESP_PLATFORM
esp_err_t errRc = ESP_OK;
#ifdef CONFIG_ENABLE_ARDUINO_DEPENDS
// make sure the linker includes esp32-hal-bt.c so Arduino init doesn't release BLE memory.
btStarted();
#endif
errRc = nvs_flash_init();
if (errRc == ESP_ERR_NVS_NO_FREE_PAGES || errRc == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
errRc = nvs_flash_init();
}
ESP_ERROR_CHECK(errRc);
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
#if defined (CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)
bt_cfg.bluetooth_mode = ESP_BT_MODE_BLE;
#else
bt_cfg.mode = ESP_BT_MODE_BLE;
bt_cfg.ble_max_conn = CONFIG_BT_NIMBLE_MAX_CONNECTIONS;
#endif
bt_cfg.normal_adv_size = m_scanDuplicateSize;
bt_cfg.scan_duplicate_type = m_scanFilterMode;
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));
ESP_ERROR_CHECK(esp_nimble_hci_init());
#endif
nimble_port_init();
// Setup callbacks for host events
ble_hs_cfg.reset_cb = NimBLEDevice::onReset;
ble_hs_cfg.sync_cb = NimBLEDevice::onSync;
// Set initial security capabilities
ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT;
ble_hs_cfg.sm_bonding = 0;
ble_hs_cfg.sm_mitm = 0;
ble_hs_cfg.sm_sc = 1;
ble_hs_cfg.sm_our_key_dist = 1;
ble_hs_cfg.sm_their_key_dist = 3;
ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/
// Set the device name.
rc = ble_svc_gap_device_name_set(deviceName.c_str());
assert(rc == 0);
ble_store_config_init();
nimble_port_freertos_init(NimBLEDevice::host_task);
}
// Wait for host and controller to sync before returning and accepting new tasks
while(!m_synced){
taskYIELD();
}
initialized = true; // Set the initialization flag to ensure we are only initialized once.
} // init
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
{
esp_err_t err;
uint32_t btdm_cfg_mask = 0;
#if CONFIG_BTDM_CTRL_HLI
hli_queue_setup_pinned_to_core(CONFIG_BTDM_CTRL_PINNED_TO_CORE);
#endif /* CONFIG_BTDM_CTRL_HLI */
//if all the bt available memory was already released, cannot initialize bluetooth controller
if (btdm_dram_available_region[0].mode == ESP_BT_MODE_IDLE) {
return ESP_ERR_INVALID_STATE;
}
osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
if (osi_funcs_p == NULL) {
return ESP_ERR_NO_MEM;
}
memcpy(osi_funcs_p, &osi_funcs_ro, sizeof(struct osi_funcs_t));
if (btdm_osi_funcs_register(osi_funcs_p) != 0) {
return ESP_ERR_INVALID_ARG;
}
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
if (cfg == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (cfg->controller_task_prio != ESP_TASK_BT_CONTROLLER_PRIO
|| cfg->controller_task_stack_size < ESP_TASK_BT_CONTROLLER_STACK) {
return ESP_ERR_INVALID_ARG;
}
//overwrite some parameters
cfg->bt_max_sync_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF;
cfg->magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL;
if (((cfg->mode & ESP_BT_MODE_BLE) && (cfg->ble_max_conn <= 0 || cfg->ble_max_conn > BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT))
|| ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) && (cfg->bt_max_acl_conn <= 0 || cfg->bt_max_acl_conn > BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_LIMIT))
|| ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) && (cfg->bt_max_sync_conn > BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT))) {
return ESP_ERR_INVALID_ARG;
}
ESP_LOGI(BTDM_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
s_wakeup_req_sem = semphr_create_wrapper(1, 0);
if (s_wakeup_req_sem == NULL) {
err = ESP_ERR_NO_MEM;
goto error;
}
esp_phy_modem_init();
esp_bt_power_domain_on();
btdm_controller_mem_init();
periph_module_enable(PERIPH_BT_MODULE);
#ifdef CONFIG_PM_ENABLE
s_btdm_allow_light_sleep = false;
#endif
// set default sleep clock cycle and its fractional bits
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
#if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
#if CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL
// check whether or not EXT_CRYS is working
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_32K_XTAL) {
btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32kHz XTAL
#ifdef CONFIG_PM_ENABLE
s_btdm_allow_light_sleep = true;
#endif
} else {
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
"light sleep mode will not be able to apply when bluetooth is enabled");
btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
}
#else
btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
#endif
bool select_src_ret __attribute__((unused));
bool set_div_ret __attribute__((unused));
if (btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
set_div_ret = btdm_lpclk_set_div(rtc_clk_xtal_freq_get() * 2 - 1);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
} else { // btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL32K
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
set_div_ret = btdm_lpclk_set_div(0);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
(1000000 >> (15 - RTC_CLK_CAL_FRACT));
assert(btdm_lpcycle_us != 0);
}
btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_ORIG);
#elif CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED
btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_EVED);
#else
btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
#endif
#ifdef CONFIG_PM_ENABLE
if (!s_btdm_allow_light_sleep) {
if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
goto error;
}
}
if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
goto error;
}
esp_timer_create_args_t create_args = {
.callback = btdm_slp_tmr_callback,
.arg = NULL,
.name = "btSlp"
};
if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
goto error;
}
s_pm_lock_acquired = true;
#endif
#if CONFIG_SW_COEXIST_ENABLE
coex_init();
#endif
btdm_cfg_mask = btdm_config_mask_load();
if (btdm_controller_init(btdm_cfg_mask, cfg) != 0) {
err = ESP_ERR_NO_MEM;
goto error;
}
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
return ESP_OK;
error:
bt_controller_deinit_internal();
return err;
}
esp_err_t esp_bt_controller_deinit(void)
{
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
return ESP_ERR_INVALID_STATE;
}
btdm_controller_deinit();
bt_controller_deinit_internal();
return ESP_OK;
}
static void bt_controller_deinit_internal(void)
{
periph_module_disable(PERIPH_BT_MODULE);
#ifdef CONFIG_PM_ENABLE
if (!s_btdm_allow_light_sleep) {
esp_pm_lock_delete(s_light_sleep_pm_lock);
s_light_sleep_pm_lock = NULL;
}
if (s_pm_lock != NULL) {
esp_pm_lock_delete(s_pm_lock);
s_pm_lock = NULL;
}
if (s_btdm_slp_tmr != NULL) {
esp_timer_stop(s_btdm_slp_tmr);
esp_timer_delete(s_btdm_slp_tmr);
s_btdm_slp_tmr = NULL;
}
s_pm_lock_acquired = false;
#endif
if (s_wakeup_req_sem) {
semphr_delete_wrapper(s_wakeup_req_sem);
s_wakeup_req_sem = NULL;
}
if (osi_funcs_p) {
free(osi_funcs_p);
osi_funcs_p = NULL;
}
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
btdm_lpcycle_us = 0;
btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
esp_bt_power_domain_off();
esp_phy_modem_deinit();
}
build test with ke_get_heap_free_size :
Linking .pio\build\smartdisplay_vesc_35v2_pcb210\firmware.elf
c:/users/koxx3/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio/build/smartdisplay_vesc_35v2_pcb210/src/main.o:(.literal._Z4loopv+0x2c): undefined reference to `ke_get_heap_free_size()'
c:/users/koxx3/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio/build/smartdisplay_vesc_35v2_pcb210/src/main.o: in function `loop()':
C:\Users\koxx3\Documents\Coding\SmartController_SmartDisplay_ESP32_priv3/src/main.cpp:1075: undefined reference to `ke_get_heap_free_size()'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\smartdisplay_vesc_35v2_pcb210\firmware.elf] Error 1
in debug level :
D (1299) BTDM_INIT: Release DRAM [0x3ffb2730] - [0x3ffb6388]
D (1300) intr_alloc: Connected src -5 to int 29 (cpu 1)
I (1300) BTDM_INIT: BT controller compile version [d166426]
D (1301) BTDM_INIT: .data initialise [0x3ffae6e0] <== [0x4000d890]
D (1301) BTDM_INIT: .bss initialise [0x3ffb0000] - [0x3ffb09a8]
D (1302) BTDM_INIT: .bss initialise [0x3ffb09a8] - [0x3ffb1ddc]
D (1303) BTDM_INIT: .bss initialise [0x3ffb1ddc] - [0x3ffb2730]
D (1304) BTDM_INIT: .bss initialise [0x3ffb8000] - [0x3ffb9a20]
D (1304) BTDM_INIT: .bss initialise [0x3ffbdb28] - [0x3ffbdb5c]
ESP_ERROR_CHECK failed: esp_err_t 0x101 (ESP_ERR_NO_MEM) at 0x40092ad4
file: ".pio/libdeps/smartdisplay_vesc_35v2_pcb210/nimble/src/NimBLEDevice.cpp" line 879
func: static void NimBLEDevice::init(const string&)
expression: esp_bt_controller_init(&bt_cfg)
abort() was called at PC 0x40092ad7 on core 1
The reason for this issue is the mismatch between the "magic value" externally and internally in the controller. The external controller value is configured by ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL and needs to be consistent internally.
It's worth noting that in version v4.4.4, the internal "magic value" is 0x20200622. If you encounter this problem, you need to verify whether you are using version v4.4.4.
replace esp-idf/components/bt/controller/lib_esp32/esp32/libbtdm_app.a and extern uint16_t ke_get_heap_free_size(void);
make sure:BT controller compile version [d166426]
I managed to remove Tasmota dependencies and work with "pure" packages now (thanks to Jason2866):
PACKAGES:
- framework-arduinoespressif32 @ 3.20016.0 (2.0.16)
- framework-espidf @ 3.40407.0 (4.4.7)
- tool-cmake @ 3.16.4
- tool-esptoolpy @ 1.40501.0 (4.5.1)
- tool-idf @ 1.0.1
- tool-mconf @ 1.4060000.20190628 (406.0.0)
- tool-mkspiffs @ 2.230.0 (2.30)
- tool-ninja @ 1.9.0
- toolchain-esp32ulp @ 1.23500.220830 (2.35.0)
- toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
here are the IDF 4.4.7 results with stock "libbtdm_app.a" :
r_assert at C:\Users\koxx3\.platformio\packages\framework-espidf\components\bt\controller\esp32/bt.c:1902
r_assert_param at ??:?
r_platform_reset at ??:?
?? ??:0
?? ??:0
r_llm_le_adv_report_ind at ??:?
r_llm_pdu_defer at ??:?
r_lld_pdu_check at ??:?
r_lld_evt_deffered_elt_handler at ??:?
?? ??:0
?? ??:0
r_rw_schedule at ??:?
btdm_controller_task at ??:?
vPortTaskWrapper at C:\Users\koxx3\.platformio\packages\framework-espidf\components\freertos\port\xtensa/port.c:142
board 1 crashed after 52 min, then 11h43m board 2 crashed after 12h10m
I tried you patched "libbtdm_app.a" with IDF 4.4.7, but it doesn't work ;)
@Koxx3 can you use ke_get_heap_free_size now?
ok, I'll try to switch back to officiel 4.4.4 and use ke_get_heap_free_size
I guess there might be a subtle memory leak in the controller. Perhaps some patterns could be discovered by using ke_get_heap_free_size... thanks for your testing.
argh. I cleaned everything (build folder & cache). I made sure only 1 framework-espidf remained, then patched ... but it still doesn't link.
Linking .pio\build\smartdisplay_vesc_35v2_pcb210\firmware.elf
c:/users/koxx3/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio/build/smartdisplay_vesc_35v2_pcb210/src/main.o:(.literal._Z4loopv+0x30): undefined reference to `ke_get_heap_free_size()'
c:/users/koxx3/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio/build/smartdisplay_vesc_35v2_pcb210/src/main.o: in function `loop()':
C:\Users\koxx3\Documents\Coding\SmartController_SmartDisplay_ESP32_priv3/src/main.cpp:1075: undefined reference to `ke_get_heap_free_size()'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\smartdisplay_vesc_35v2_pcb210\firmware.elf] Error 1
then in main.cpp :
...
extern uint16_t ke_get_heap_free_size(void);
...
void loop()
{
if (i_loopIdle % 1000 == 0)
{
uint16_t free_size = ke_get_heap_free_size();
Serial.printf("main : free size = %d bytes\n", free_size);
}
}
At execution (without using ke_get_heap_free_size), it clearly state I am using d166426 :
I (1553) BTDM_INIT: BT controller compile version [d166426]
Can you provide me with your current commit ID? I'd like to perform some local testing.
sorry updated too late : At execution (without using ke_get_heap_free_size), it clearly state I am using d166426 : I (1553) BTDM_INIT: BT controller compile version [d166426]
Can you provide me with your current commit ID? I'd like to perform some local testing.
how do I do that ?
; IDF 4.4.4 / arduino 2.0.16 / building fine
platform = espressif32 @ ^6.6.0
platform_packages =
tool-mkspiffs @ 2.230.0
platformio/framework-espidf @ ~3.40404.0
platformio/framework-arduinoespressif32 @ ~3.20016.0
framework = arduino, espidf
board = esp32dev
If you don't call ke_get_heap_free_size, the compilation should still proceed without issues, right?
If you don't call ke_get_heap_free_size, the compilation should still proceed without issues, right?
yes. and the app runs perfectly with BT
running logs in debug level : https://koxx3.fr.eu.org:8086/device-monitor-240511-095738.zip
oh !!! you gave me an idea ! I forced the declaration in esp_bt.h.
and it works now !
10:54:16.786 > main : free size = 6760 bytes
10:54:22.126 > main : free size = 6760 bytes
10:54:27.461 > main : free size = 6760 bytes
10:54:32.778 > main : free size = 6748 bytes
yes, it really seems to leak :
10:54:16.786 > main : free size = 6760 bytes
10:54:22.126 > main : free size = 6760 bytes
10:54:27.461 > main : free size = 6760 bytes
10:54:32.778 > main : free size = 6748 bytes
10:54:38.107 > main : free size = 6768 bytes
10:54:43.449 > main : free size = 6744 bytes
10:54:48.793 > main : free size = 6760 bytes
10:54:54.135 > main : free size = 6944 bytes
10:54:59.476 > main : free size = 6760 bytes
10:55:04.818 > main : free size = 6760 bytes
10:55:10.156 > main : free size = 6748 bytes
10:55:15.527 > main : free size = 6760 bytes
10:55:20.861 > main : free size = 6760 bytes
10:55:26.196 > main : free size = 6764 bytes
10:55:31.523 > main : free size = 6744 bytes
10:55:36.860 > main : free size = 6760 bytes
10:55:42.191 > main : free size = 6768 bytes
10:55:47.530 > main : free size = 6748 bytes
10:55:52.854 > main : free size = 6748 bytes
10:55:58.180 > main : free size = 6768 bytes
10:56:03.504 > main : free size = 6760 bytes
10:56:08.836 > main : free size = 6744 bytes
10:56:14.177 > main : free size = 6744 bytes
10:56:19.519 > main : free size = 6760 bytes
10:56:24.847 > main : free size = 6768 bytes
10:56:30.171 > main : free size = 6760 bytes
10:56:35.532 > main : free size = 6944 bytes
10:56:40.872 > main : free size = 6740 bytes
10:56:46.223 > main : free size = 6748 bytes
10:56:51.581 > main : free size = 6760 bytes
10:56:56.925 > main : free size = 6760 bytes
10:57:02.262 > main : free size = 6760 bytes
10:57:07.604 > main : free size = 6744 bytes
10:57:12.935 > main : free size = 6744 bytes
10:57:18.281 > main : free size = 6744 bytes
10:57:23.634 > main : free size = 6744 bytes
10:57:28.973 > main : free size = 6732 bytes
10:57:34.309 > main : free size = 6744 bytes
10:57:39.651 > main : free size = 6744 bytes
10:57:45.000 > main : free size = 6736 bytes
10:57:50.340 > main : free size = 6732 bytes
10:57:55.664 > main : free size = 6744 bytes
10:58:01.005 > main : free size = 6728 bytes
10:58:06.342 > main : free size = 6744 bytes
10:58:11.688 > main : free size = 6728 bytes
10:58:17.031 > main : free size = 6928 bytes
10:58:22.377 > main : free size = 6744 bytes
10:58:27.711 > main : free size = 6744 bytes
10:58:33.060 > main : free size = 6744 bytes
10:58:38.405 > main : free size = 6764 bytes
10:58:43.738 > main : free size = 6744 bytes
10:58:49.068 > main : free size = 6744 bytes
10:58:54.401 > main : free size = 6728 bytes
10:58:59.731 > main : free size = 6744 bytes
10:59:05.089 > main : free size = 6744 bytes
10:59:10.424 > main : free size = 6728 bytes
10:59:15.767 > main : free size = 6724 bytes
10:59:21.146 > main : free size = 6724 bytes
10:59:26.511 > main : free size = 6724 bytes
10:59:31.861 > main : free size = 6712 bytes
also, disconnecting and reconnecting BLE doesn't release the memory.
11:01:46.296 > main : free size = 6736 bytes
11:01:51.729 > main : free size = 6724 bytes
11:01:57.162 > main : free size = 6692 bytes
11:02:02.586 > main : free size = 6704 bytes
11:02:08.002 > main : free size = 6676 bytes
11:02:13.441 > main : free size = 6692 bytes
11:02:18.865 > main : free size = 6692 bytes
11:02:21.880 > BLH : onDisconnect - BEGIN
11:02:21.880 > BLH : onDisconnect - getConnectedCount = 0
11:02:21.881 > BLH : onDisconnect - END
11:02:21.881 > W NimBLEAdvertising: Advertising already active
11:02:24.226 > main : free size = 6964 bytes
11:02:25.223 > BLH : onConnect1 - getConnectedCount() : 1
11:02:25.224 > BLH : onConnect1 - nbFailure : 0
11:02:25.224 > BLH : onConnect2 - getPeerMTU() : 23
11:02:25.224 > BLH : onConnect2 - mtuReal - 3 : 20
11:02:25.438 > BLH : onAuthenticationComplete - BEGIN
11:02:25.438 > BLH : onAuthenticationComplete : success
11:02:25.454 > BLH : onAuthenticationComplete - END
11:02:25.620 > BLH : onMTUChange : 255
11:02:27.901 > BLH : onRead : beb5483e-36e1-4688-b7f5-ea07361b26a3
11:02:27.990 > BLH : onWrite : beb5483e-36e1-4688-b7f5-ea07361b26b7
11:02:27.990 > BLH : dateBle = 1715418148
11:02:27.993 > Saturday, May 11 2024 11:02:28
11:02:28.530 > BLH : onRead : beb5483e-36e1-4688-b7f5-ea07361b26a2
11:02:28.530 > BLH : setEbFirmwaresDataPacket
11:02:28.620 > BLH : onRead : beb5483e-36e1-4688-b7f5-ea07361b26a5
11:02:29.429 > BLH : onRead : beb5483e-36e1-4688-b7f5-ea07361b26a7
11:02:29.429 > ErrorLogger - getHistoryBytes ind = 0
11:02:29.520 > BLH : onRead : beb5483e-36e1-4688-b7f5-ea07361b26a8
11:02:29.610 > BLH : onRead : beb5483e-36e1-4688-b7f5-ea07361b26fc
11:02:29.643 > main : free size = 6672 bytes
11:02:29.730 > BLH : onWrite : beb5483e-36e1-4688-b7f5-ea07361b26fe
11:02:29.734 > W NimBLECharacteristic: Sending indication to client subscribed to notification, sending notification instead
11:02:29.757 > W NimBLECharacteristic: Sending indication to client subscribed to notification, sending notification instead
11:02:29.777 > W NimBLECharacteristic: Sending indication to client subscribed to notification, sending notification instead
11:02:30.240 > BLH : onWrite : beb5483e-36e1-4688-b7f5-ea07361b26a5
11:02:35.155 > main : free size = 6692 bytes
11:02:40.610 > main : free size = 6692 bytes
11:02:46.045 > main : free size = 6676 bytes
11:02:51.475 > main : free size = 6692 bytes
If you can analyze the scenarios of memory leaks (broadcasting, scanning, connecting, etc.), it would be very helpful in resolving the issue. What operations trigger memory leaks?
I recently discovered an issue with bidirectional frequent initiation of connection parameter updates leading to memory leaks. Are both ends frequently initiating updates of connection parameters over there? It seems like it might not be the same issue as yours ...
If you can analyze the scenarios of memory leaks (broadcasting, scanning, connecting, etc.), it would be very helpful in resolving the issue.
yes, I'll try.
during this basic test, my IDLE loop call processBLE :
- send 3 notifications
- check is scan is running, if not :
- set filter policy
- reset device whitelist if needed
- start a 1s scan
- the scan results processing is made inside the callback
void BluetoothHandler::processBLE()
{
// notify changed value
if (deviceStatus == BLE_STATUS_CONNECTED_AND_AUTHENTIFIED)
{
uint16_t period = 250;
if ((shrd->fastUpdate) && (shrd->navMode == 0))
period = 100;
/*
Serial.print(millis());
Serial.print("BLH : / ");
Serial.print(shrd->timeLastNotifyBle);
Serial.print("BLH : / ");
Serial.print(period);
Serial.println(" / ");
*/
if (millis() > shrd->timeLastNotifyBle + period)
{
notifyMeasurements();
notifyBleLockAndErrors();
shrd->timeLastNotifyBle = millis();
}
if (millis() > shrd->timeLastNotifyBleBms + 500)
{
notifyMeasurementsBms();
shrd->timeLastNotifyBleBms = millis();
}
}
// reset BLE stack if impossible to connect to BLE anymore
if (bleNbFailure > 2)
{
deinit();
delay(100);
init();
delay(100);
bleScanEnabled = 1;
bleNbFailure = 0;
}
// fail-safe restart for scan
if ((!pBLEScan->isScanning()) && (bleScanEnabled >= 0) /*&& (bleScanStartFailedInMillis != 0) && (millis() - bleScanStartFailedInMillis > BEACON_SCAN_PERIOD_IN_SECONDS * 1000)*/)
{
// Serial.println("BLH : millis() - bleScanStartFailedInMillis = " + (String)(millis() - bleScanStartFailedInMillis));
/*
char print_buffer[200];
sprintf(print_buffer, "BLH : backup scan restart / isScanning = %d / bleScanEnabled = %d", pBLEScan->isScanning(), bleScanEnabled);
Serial.println(print_buffer);
// notifyBleLogs(print_buffer);
*/
startBleScan();
}
oldDeviceStatus = deviceStatus;
}
void BluetoothHandler::startBleScan()
{
/*
Serial.println("BLH : startBleScan / beacon scan : enabled = " + (String)bleScanEnabled +
" / vescToolMode = " + (String)shrd->vescToolMode +
" / bleScanMode = " + (String)shrd->bleScanMode +
" / beacon1 = " + (String)settings->get_Ble_beacon_mac_address1() +
" / beacon2 = " + (String)settings->get_Ble_beacon_mac_address2() +
" / tpms1 = " + (String)settings->get_Tpms_mac_address1() +
" / tpms2 = " + (String)settings->get_Tpms_mac_address2());
*/
// start scan only if different from dummy mac address
if ((bleScanEnabled >= 0) && (shrd->vescToolMode == 0) &&
(((settings->get_Ble_beacon_mac_address1() != "aa:bb:cc:dd:ee:ff") || //
(settings->get_Ble_beacon_mac_address2() != "aa:bb:cc:dd:ee:ff") || //
(settings->get_Tpms_mac_address1() != "aa:bb:cc:dd:ee:ff") || //
(settings->get_Tpms_mac_address2() != "aa:bb:cc:dd:ee:ff")) || //
(shrd->bleScanMode != 0)))
{
// Serial.println("BLH : startBleScan / trying to start scan");
if ((pBLEScan != NULL) && (pBLEScan->isScanning()))
pBLEScan->stop();
// Start scanning
pBLEScan = BLEDevice::getScan(); // create new scan
/*
pBLEScan->setActiveScan(true); // active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(98); // less or equal setInterval value
*/
#if SCAN_USE_WHITELIST
if (shrd->bleScanMode == 0)
{
// Serial.println("BLH : startBleScan / set white list");
pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_USE_WL);
for (auto i = 0; i < NimBLEDevice::getWhiteListCount(); ++i)
NimBLEDevice::whiteListRemove(NimBLEDevice::getWhiteListAddress(i));
NimBLEDevice::whiteListAdd(NimBLEAddress(settings->get_Ble_beacon_mac_address1().c_str()));
NimBLEDevice::whiteListAdd(NimBLEAddress(settings->get_Ble_beacon_mac_address2().c_str()));
NimBLEDevice::whiteListAdd(NimBLEAddress(settings->get_Tpms_mac_address1().c_str()));
NimBLEDevice::whiteListAdd(NimBLEAddress(settings->get_Tpms_mac_address2().c_str()));
}
else
{
// Serial.println("BLH : startBleScan / clear white list");
pBLEScan->setFilterPolicy(BLE_HCI_SCAN_FILT_NO_WL);
}
#endif
// NEW TEST - no improvement
// pBLEScan->clearResults();
bool bleScanStarted = pBLEScan->start(BEACON_SCAN_PERIOD_IN_SECONDS, &bleOnScanResults, false);
if (!bleScanStarted)
{
Serial.println("BLH : startBleScan / scan start failed");
notifyBleLogs("BLH : scan start failed");
bleScanStartFailedInMillis = millis();
}
else
{
bleScanStartFailedInMillis = 0;
}
// Serial.println("BLH : startBleScan / Beacon scan start res = " + (String)bleScanStarted);
}
else
{
Serial.println("BLH : startBleScan / Beacon scan disabled - conditions not ok - addresses or bleScanMode or vesctool");
}
}
I recently discovered an issue with bidirectional frequent initiation of connection parameter updates leading to memory leaks. Are both ends frequently initiating updates of connection parameters over there? It seems like it might not be the same issue as yours ...
hum ... no, the connection is stable in my test.
here is the nimble serverCallbacks class :
class BLEServerCallback : public NimBLEServerCallbacks
{
void onConnect(NimBLEServer *pServer)
{
deviceStatus = BLE_STATUS_CONNECTED_AND_AUTHENTIFYING;
...
/*
// TODO : add again
// ble_svc_gatt_changed(0x0000, 0xFFFF);
*/
// TODO : add again
// NimBLEDevice::startAdvertising();
Serial.println("BLH : onConnect1 - getConnectedCount() : " + (String)pServer->getConnectedCount());
Serial.println("BLH : onConnect1 - nbFailure : " + (String)bleNbFailure);
bleNbFailure++;
};
void onConnect(NimBLEServer *pServer, ble_gap_conn_desc *desc)
{
Serial.println("BLH : onConnect2 - getPeerMTU() : " + (String)pServer->getPeerMTU(desc->conn_handle));
mtuReal = pServer->getPeerMTU(desc->conn_handle) - 3;
Serial.println("BLH : onConnect2 - mtuReal - 3 : " + (String)mtuReal);
}
void onAuthenticationComplete(ble_gap_conn_desc *desc)
{
Serial.println(F("BLH : onAuthenticationComplete - BEGIN"));
if (!desc->sec_state.encrypted)
{
Serial.println(F("BLH : onAuthenticationComplete : Encrypt connection failed - disconnecting"));
NimBLEDevice::getServer()->disconnect(desc->conn_handle);
deviceStatus = BLE_STATUS_DISCONNECTED;
deviceStatusConnectedStartTime = 0;
}
else
{
Serial.println(F("BLH : onAuthenticationComplete : success"));
deviceStatus = BLE_STATUS_CONNECTED_AND_AUTHENTIFIED;
deviceStatusConnectedStartTime = millis();
}
ble_svc_gatt_changed(0x0000, 0xFFFF);
if (bleNbFailure > 0)
bleNbFailure--;
Serial.println(F("BLH : onAuthenticationComplete - END"));
}
bool onConfirmPIN(uint32_t pin)
{
Serial.println(F("BLH : onConfirmPIN - BEGIN"));
uint32_t pinCode = std::stoi(settings->get_Ble_pin_code2().c_str());
Serial.println(pinCode);
Serial.print(F("BLH : onConfirmPIN - END"));
Serial.println(pinCode == pin);
return pinCode == pin;
}
void onDisconnect(NimBLEServer *pServer)
{
Serial.println(F("BLH : onDisconnect - BEGIN"));
deviceStatus = BLE_STATUS_DISCONNECTED;
// shrd->isRecording = 1;
if (shrd->bleLockForced == 0)
{
if (settings->get_Bluetooth_lock_mode() == settings->LIST_Bluetooth_lock_mode_Smartphone_connected)
{
shrd->isLocked = 1;
Serial.println(F("BLH : ==> device disconnected ==> LOCK decision"));
Serial.println(F("BLH : -------------------------------------"));
}
if (settings->get_Bluetooth_lock_mode() == settings->LIST_Bluetooth_lock_mode_Smartphone_connected_or_beacon_visible)
{
if ((!shrd->bleBeaconVisible1) && (!shrd->bleBeaconVisible2))
{
shrd->isLocked = 1;
Serial.println(F(" ==> device disconnected / Beacon not visible ==> LOCK decision"));
Serial.println(F("-------------------------------------"));
}
}
}
shrd->dateIsSyncedInBle = false;
NimBLEDevice::startAdvertising();
Serial.println("BLH : onDisconnect - getConnectedCount = " + (String)pServer->getConnectedCount());
Serial.println(F("BLH : onDisconnect - END"));
}
void onMTUChange(uint16_t mtu, ble_gap_conn_desc *desc)
{
Serial.println("BLH : onMTUChange : " + (String)mtu);
mtuReal = mtu - 3;
}
};