I have a problem with SPP on reconnecting a Bluetooth device to the spp_acceptor example.
If I first connect the device to the acceptor, I can write data over SPP with the function esp_spp_write().
But if I disconnect and reconnect the device, I get a new handle for the connection and the esp resets with the following message:
assertion !list_is_empty(list) failed: file /home/alex/esp32/esp-idf/components/tabort() was called at PC 0x400d4117 on core 0
I think I have backtraced the problem to the function "list_remove" in the file /esp-idf/components/bt/bluedroid/btc/profile/std/spp/btc_spp.c in the line 469.
If I comment out this line, the example works. I know this is not a good solution, but I hope you could help me with this problem
@blueMoodBHD Please help to see this problem.
Same problem here, if the client disconnects and reconnects the board crashes with this log:
assertion "!list_is_empty(list)" failed: file "C:/msys32/home/Note/esp/esp-idf/components/bt/bluedroid/osi/list.c", line 82, function: list_front
abort() was called at PC 0x400d44d3 on core 0
@LosDeiblos @copercini Sorry for the late reply because of holiday. And thanks for your issues. The reason is that we free the list when disconnect and don't use lock. I have fixed the bug and will merger to the master as soon as possible.
@blueMoodBHD Thanks for the response. Do you have a approximate time when the bug fix will be included in a commit?
@LosDeiblos We will merge it next week, Thanks!
Looking forward to the fix... this problem is kicking my butt!
@LosDeiblos @copercini @Demolitron We added a lock for SPP slot on the latest master, refer to commit 275fa2cc36343ebf59b8e9da0f8bf672b0cf917b
Please test whether the bug has been fixed, thanks
After update, it fails immediately for me.
Here is my code:
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT()
esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT);
esp_bluedroid_init();
esp_bluedroid_enable();
esp_spp_init(ESP_SPP_MODE_CB);
esp_spp_register_callback(esp_spp_cb);
And the exception:
C:/esp/msys32/home/aaron/esp/esp-idf/components/freertos/queue.c:1441 (xQueueGenericReceive)- assert failed!
abort() was called at PC 0x4008ad2d on core 0
0x4008ad2d: xQueueGenericReceive at C:/esp/msys32/home/aaron/esp/esp-idf/components/freertos/queue.c:2037
Backtrace: 0x4008cd1c:0x3ffe2fb0 0x4008cebf:0x3ffe2fd0 0x4008ad2d:0x3ffe2ff0 0x400eba51:0x3ffe3030 0x400edb47:0x3ffe
3050 0x4011b841:0x3ffe3080 0x4011a4a9:0x3ffe30b0 0x40111669:0x3ffe30d0 0x400faf69:0x3ffe30f0
0x4008cd1c: invoke_abort at C:/esp/msys32/home/aaron/esp/esp-idf/components/esp32/panic.c:648
0x4008cebf: abort at C:/esp/msys32/home/aaron/esp/esp-idf/components/esp32/panic.c:648
0x4008ad2d: xQueueGenericReceive at C:/esp/msys32/home/aaron/esp/esp-idf/components/freertos/queue.c:2037
0x400eba51: osi_mutex_lock at C:/esp/msys32/home/aaron/esp/esp-idf/components/bt/bluedroid/osi/mutex.c:49
0x400edb47: btc_spp_dm_inter_cb at C:/esp/msys32/home/aaron/esp/esp-idf/components/bt/bluedroid/btc/profile/std/spp/
btc_spp.c:214
0x4011b841: bta_jv_enable at C:/esp/msys32/home/aaron/esp/esp-idf/components/bt/bluedroid/bta/jv/bta_jv_act.c:649
0x4011a4a9: bta_jv_sm_execute at C:/esp/msys32/home/aaron/esp/esp-idf/components/bt/bluedroid/bta/jv/bta_jv_main.c:9
3
0x40111669: bta_sys_event at C:/esp/msys32/home/aaron/esp/esp-idf/components/bt/bluedroid/bta/sys/bta_sys_main.c:636
0x400faf69: btu_task_thread_handler at C:/esp/msys32/home/aaron/esp/esp-idf/components/bt/bluedroid/stack/btu/btu_ta
sk.c:232
CPU halted.
Added to btc_spp.c @ line 214 this:
if (spp_slot_mutex==NULL){
if (osi_mutex_new(&spp_slot_mutex) != 0) {
LOG_ERROR("%s osi_mutex_new failed\n", __func__);
}
}
This stopped the assertion and everything seems fine, but I am no longer able to connect to the device. I try connecting from Windows 10 and also android phone. Both worked before the update, but would crash on re-connection.
I moved back to 1e6f52fb6f6a1c225b0e5c7a9fa99d49f102d368 and confirmed that BT SPP works again, albeit with the original issue.
Further investigation reveals that the list is not NULL but is instead Empty for some reason. The assertion is really being thrown by the list_front call because the list is empty. To test I changed the original line 469 in btc_spp.c
list_remove(slot->list, list_front(slot->list));
to
if (slot->list!=NULL && !list_is_empty(slot->list)) list_remove(slot->list, list_front(slot->list));
and I no longer get the problem. I can connect and reconnect from windows + android phone without exception. Also, I can connect both at once.
I think the original fix (Adding Locking Mutex) is causing a deadlock somewhere and that is why it no longer works for me.
I have also tested the new version, but like said before it fails immediately.
The fix that @Demolitron suggested works for me and I can now connect and reconnect without problems.
Thanks for your helps, and please test again on the latest master,
refer to commit 8b36a8523eda299c1805b1070e78aeabd8f77bef
Thanks
@blueMoodBHD The previous assertion due to the lock object being null is fixed and the BT SPP is working in that I can connect to it. But, it still has the original problem with disconnect and reconnect causing the same assertion in list_front.
The same change to check if the list is empty before calling list_front prevents the issue from happening. The bigger question to me is, why is the list empty? I agree that the lock should prevent accessing a free'd object but since the slot and also slot->list is not null I don't think the problem originates from a concurrency issue around the freeing of the slot.
@Demolitron I disconnect and reconnect to spp_acceptor, too. but it works well. So, can you provide your project if it is convenient? Thanks!
@Demolitron I find the reason why the list is empty, it is because of that the event from btu task to btc task is with wrong handle, so we search another list.
Please replace components/bt/bluedroid/bta/jv/bta_jv_act.c then test again. Thanks for you help!
@blueMoodBHD Yes! This works well.
I'm glad that this problem has been solved, we will merge it to master ASAP. Thanks for your help again.
hi all, the bug has fixed, we will merge it into IDF this week , thanks.
this is merged or still not?
@reaper7 I'm sorry to tell you this is not merged yet. I will notify you as soon as it merged. Thanks!
Hi ,all. the bug_fix has merged,now. Please refer to commit 0a83733d2d630e52fd2bdd33d5d9876fa7c1c5d3
Most helpful comment
Further investigation reveals that the list is not NULL but is instead Empty for some reason. The assertion is really being thrown by the list_front call because the list is empty. To test I changed the original line 469 in btc_spp.c
list_remove(slot->list, list_front(slot->list));to
if (slot->list!=NULL && !list_is_empty(slot->list)) list_remove(slot->list, list_front(slot->list));and I no longer get the problem. I can connect and reconnect from windows + android phone without exception. Also, I can connect both at once.
I think the original fix (Adding Locking Mutex) is causing a deadlock somewhere and that is why it no longer works for me.