apache / mynewt-nimble

Apache mynewt
https://mynewt.apache.org/
Apache License 2.0
664 stars 384 forks source link

Failed assertion due to big connection interval and small notification interval #1788

Open BOZHENG001 opened 1 month ago

BOZHENG001 commented 1 month 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: 2 feather-nrf52840-sense boards (1 central + 1 peripheral) 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 while playing with BLE parameters, i.e., connection interval and notification interval. The applications implemented on the 2 feather boards are the NimBLE "central" and "peripheral" examples. Some further codes are added to the two examples to achieve notification (battery service and characteristic) between the central and peripheral devices. A notification interval is defined in the peripheral application to periodically notify the central application about the battery level (The battery level is a number generated by code instead of real measurement.).

The interesting thing is there is no failed assertion when the connection interval is much smaller than the notification interval, e.g. connection interval = 10 ms and notification interval = 100 ms. However, the failed assertion starts to show up when the connection interval is closer to, equal to, or larger than the notification interval, e.g., connection interval = 80 / 100 / 200 ms and notification interval = 100 ms. I expect no failed assertion when the connection interval is equal to the notification interval at least, since it suggests each connection interval/event has one notification.

I further looked into the assertion failure and tried to trace it. The following path is found:

  1. ble_gatts_notify_custom() in main.c
  2. ble_att_clt_tx_notify in ble_gattc.c
  3. ble_att_cmd_get() in ble_alt_clt.c
  4. ble_hs_mbuf_l2cap_pkt() in ble_att_cmd.c
  5. ble_hs_mbuf_gen_pkt() in ble_hs_mbuf.c
  6. os_msys_get_pkthdr() in ble_hs_mbuf.c
  7. os_mbuf_get() in os_mbuf.c Then I lost in the definition of function os_mbuf_get() in os_mempool.c.

By the way, the return code of ble_gatts_notify_custom() in main.c is 6, which in NimBLE suggests BLE_HS_ENOMEM (Operation failed due to resource exhaustion.) I suppose. The same return code from the same function also occurs when I try to send big packets (such as 50 bytes and 100 bytes), even when the MTU between central and peripheral has been negotiated to 256. It is worth noting that the limit of the data size in a single packet seems to be 35 or 45 bytes, even when the MTU is set to 256.

May I kindly ask for some help here to check what can be the issue/cause of the failed assertion? Maybe I did something wrong in my applications? Or is it a limitation of NimBLE? What can I do to solve this problem?

Thanks in advance for any possible reply and help.