apache / mynewt-nimble

Apache mynewt
https://mynewt.apache.org/
Apache License 2.0
691 stars 394 forks source link

BLE disconnected, reason code: 520 #1777

Closed BOZHENG001 closed 4 months ago

BOZHENG001 commented 4 months ago

Hi NimBLE developers,

Through this post, I would like to share some issues I am facing now and ask for some feedback/help if possible.

Laptop OS: Ubuntu 22.04 Real-time operating system (RTOS): RIOT OS (newest) Bluetooth Low Energy (BLE) stack: NimBLE in RIOT OS Development boards: feather-nrf52840-sense Examples/Apps used: NimBLE "central" and "peripheral" implemented in RIOT OS

As shown above, I am currently developing some BLE applications based on NimBLE and RIOT OS. However, some issues showed up. In the beginning, I tried the existing BLE examples in RIOT OS together with my phone, i.e., "nimble_gatt" and "nimble_heart_rate_sensor". When I tried to connect my phone (Android) to the development board (feather-nrf52840-sense), GATT 133 connection error happened. This error was shown in the "nRF Connect" app on my Android phone. By checking the error code table, it basically suggests a connection timeout.

To make sure it is not an issue of Android (Since some complaints can be seen online about Android BLE already.), I further developed two applications using NimBLE on RIOT, based on “central” and “peripheral” applications from GitHub mynewt-nimble project. They were flashed to two feather-nrf52840-sense boards respectively. However, again, the connection cannot be continued due to connection timeout. This time, the NimBLE offers an error code of 520 (decimal), i.e., 0x0208 (hex), which suggests connection timeout. The peripheral board this time can be connected to my Android phone sometimes without an error or connection loss. But still, the GATT 133 connection error occurs from time to time.

However, after looking into a sniffer record, I notice that the BLE connection has never been established properly, which is the reason why the connection timeout occurs all the time. According to the sniffer, after receiving the advertisements from the peripheral, the central initializes the connection establishment. However, after few connection events (1 ~ 25) between the central and the peripheral, the peripheral does not respond to the central anymore. What I see is that all the packets are from the central to the peripheral, and there are no packets from the peripheral to the central. Besides, all the packets from the central are retransmissions. After multiple retransmissions, the connection is lost due to connection timeout (I suppose it reaches the defined supervision timeout). Then the peripheral starts to advertise again, and the above process is repeated.

It is worth mentioning that I also tried the above examples on an nRF52840dk board. It seems they work properly on it, e.g., the nRF52840dk can be connected to my phone without a connection loss due to timeout.

If possible, I would like some help with this case. Are there any explanations for it? What can I do to avoid/solve it?

Thanks in advance for any possible reply and help.

andrzej-kaczmarek commented 4 months ago

could you please share sniffer trace?

BOZHENG001 commented 4 months ago

20240514_Sniffer_files.zip

Hi @andrzej-kaczmarek, please find in the attachment two sniffer traces. One for the connection between two feather-nrf52840-sense board (central + peripheral), the other one for the connection between an Android phone (central) and a feather-nrf52840-sense board (peripheral).

andrzej-kaczmarek commented 4 months ago

Thanks. The connection is established properly since there are PDU from both sides on 1st connection event, but then slave indeed stops responding on events.

The problem is likely clock accuracy setting. The nRF52840 Feather board file includes cfg_clock_32_0.h which sets LFCLK to LFRC since it doesn't have LFXO by default. This requires clock accuracy in the range of 251-500ppm so you need to set BLE_LL_SCA=500 in NimBLE configuration (syscfg) to make it work properly. Also LFRC needs to be calibrated iirc.

The nRF52840 DK board includes cfg_clock_32_1.h which sets LFCLK to LFXO so the default accuracy (60ppm) is more than enough and thus it works properly ootb.

BOZHENG001 commented 4 months ago

Hi @andrzej-kaczmarek, indeed, the clock accuracy setting is the cause. Thanks a lot for your straight-to-the-point answer and help!