Failed to start advertising, err -12 (-ENOMEM)

Hi,

I'm working on an application that combines both central and peripheral roles. My 'gateway' should connect to 2 peripherals and sometimes start advertising to make allow connecting to another central (called 'central' going forward). I seem to be encountering some issues when the central disconnects from the gateway (sometimes initiated by the gateway, sometimes initiated by the central). When I want to restart advertising on the gateway, I get an error -12 (-ENOMEM) because bt_conn_add_le returns NULL. I tried increasing my CONFIG_BT_MAX_CONN and CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT, and while this seems to give me a couple of extra tries, eventually it starts failing. I retry advertising every second when it fails, but it just keeps failing. I logged all the conn objects by using bt_conn_foreach and printing the state they're in, and it seems that I keep adding some conn references that are in disconnected state.

Is there some cleaning up of these conn objects necessary? I was under the impression that these would be cleared automatically after calling bt_conn_unref. I tried calling it once more in the disconnected callback, but that didn't help. I then enabled the LOG statements in the bt_conn_unref and bt_conn_ref to see what the values of the ref are, and it seems that it is going negative even. I see that there is an assert checking for this, but it seems that I don't have this enabled. So I'm wondering, is a negative ref a reason to keep the conn object alive? Or is there another reason that could explain why my connection objects keep filling up?

Alternatively, is there a way to start advertising without creating a new conn and reusing an older one?

All this is with ncs v2.5.0 on an nRF52840 (from the nRF9160DK).

Best,

Wout

Parents
  • Hello Wout,

    I did not know that it was possible to get a negative reference count. But from what you describe it sounds like the problem is likely related to maintaining the correct connection reference count. For central connections, you must release the reference on disconnect since the bt_conn_le_create() takes one reference:

    For peripheral connection on the other hand it is only needed if you explicitly take a reference with bt_conn_ref() on the object in your code. 

    Alternatively, is there a way to start advertising without creating a new conn and reusing an older one?

    It can't be reused until it has been released. 

    It's also important that you don't try to start the advertiser immediately from the disconnect callback as the connection object will not be freed at that point. We have updated our sample codes in the more recent SDK versions to always restart the advertiser from the system workqueue.

    Best regards,

    Vidar 

  • Hi Vidar,

    Thank you for the feedback. Good to know that it's not necessary to unref the conn object in the context of being the peripheral. I currently do the unref in the on_disconnect callback which is called in both instances, for peripheral connection as well as for central connection. This would be what causes the negative reference count. I'll test a workaround to see if removing this in the peripheral connection case would solve the issue, and let you know.

    Best,

    Wout

Reply
  • Hi Vidar,

    Thank you for the feedback. Good to know that it's not necessary to unref the conn object in the context of being the peripheral. I currently do the unref in the on_disconnect callback which is called in both instances, for peripheral connection as well as for central connection. This would be what causes the negative reference count. I'll test a workaround to see if removing this in the peripheral connection case would solve the issue, and let you know.

    Best,

    Wout

Children
No Data
Related