Unable to allocate buffer for op 0x1b when notifying

Dear all,

I stubled upon the following issue when developing a BLE sensor product. 

When I try to bt_gatt_notify(); With only one characteristic, there is not an issue at all and it is working like it should. But when I subscribe to 2 or more characteristics.
it prints the error: 


[00:06:18.153,180] <wrn> bt_conn: Unable to allocate buffer within timeout
[00:06:18.153,199] <err> bt_att: Unable to allocate buffer for op 0x1b
[00:06:18.153,210] <wrn> bt_gatt: No buffer available to send notification

Could any body help me to unwind / explain this issue?
The context of this project is a as follows:
1. There is a LIS2DH mems accelerometer that is bieng polled every 60ms. Every 60ms each accelerometer channel (3 in total) is being bt_gatt_notify()'ed to the central. so 3 notifications for every separate channel, X,Y,Z. 
2. The main MCU is the 54L15 (DevKit).
3. The polling of the accelerometer is done (via triggers) at the Connection interval. In this way the central device can control the sampling frequency from 60ms up to 1000ms.

I have searched for hours and hours but no result.


I hope you can help me Slight smile
Dennis
Here is my prj.conf:
# Logger module
CONFIG_LOG=y

# Button and LED library
CONFIG_DK_LIBRARY=y

# Bluetooth LE
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Level"

# Increase stack size for the main thread and System Workqueue
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_MAIN_STACK_SIZE=2048

#Added to solve hanging on k_sleep();
CONFIG_NRF_GRTC_START_SYSCOUNTER=y

# For LIS2DH sensor
CONFIG_SPI=y
CONFIG_SENSOR=y
CONFIG_LIS2DH=y
CONFIG_LIS2DH_TRIGGER_NONE=n
CONFIG_LIS2DH_MEASURE_TEMPERATURE=y

#for floating point printing (disable when in production code this floating print is inefficient)
CONFIG_CBPRINTF_FP_SUPPORT=y

#for the Connection interval trigger
CONFIG_BT_CTLR_SDC_EVENT_TRIGGER=y
CONFIG_IRQ_OFFLOAD=n
CONFIG_ZERO_LATENCY_IRQS=y
Parents
  • Hello,

    From which context are the bt_gatt_notify() calls made? If they are executed from the system workqueue, it may prevent notification packets from being dequeued as they are sent out. In that case, please try to send the data from another thread such as main() or create a dedicated sender thread like in the peripheral_uart sample.

    Best regards,

    Vidar

  • Hi Vidar,

    Thanks for the suggestion—trying out the peripheral_uart sample worked like a charm!

    Here’s a quick summary of how I tested it:

    • The TestRunner() function (which is triggered by the connection interval) sets a boolean flag to true.

    • A separate thread continuously checks this boolean flag.

    • When the flag is true, it calls bt_gatt_notify(), then resets the flag to false.

    Now, I have a follow-up question:

    What would be the best strategy to make this setup more energy efficient?
    Currently, the thread continuously loops to check the flag, which consumes power. Ideally, I’d like it to run only when TestRunner() is triggered (which, again, is aligned with the connection interval).

    Is it possible to put the thread to sleep when it’s done, and somehow wake it up when TestRunner() runs?
    If so, what would be the most efficient way to implement that?

    Or is there a way way better energy stratigy than this?

    Thanks again for your help!

    Dennis

Reply
  • Hi Vidar,

    Thanks for the suggestion—trying out the peripheral_uart sample worked like a charm!

    Here’s a quick summary of how I tested it:

    • The TestRunner() function (which is triggered by the connection interval) sets a boolean flag to true.

    • A separate thread continuously checks this boolean flag.

    • When the flag is true, it calls bt_gatt_notify(), then resets the flag to false.

    Now, I have a follow-up question:

    What would be the best strategy to make this setup more energy efficient?
    Currently, the thread continuously loops to check the flag, which consumes power. Ideally, I’d like it to run only when TestRunner() is triggered (which, again, is aligned with the connection interval).

    Is it possible to put the thread to sleep when it’s done, and somehow wake it up when TestRunner() runs?
    If so, what would be the most efficient way to implement that?

    Or is there a way way better energy stratigy than this?

    Thanks again for your help!

    Dennis

Children
No Data
Related