This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How do I minimize the number of connection messages sent?

I'm looking at a BLE application using the nRF51822 where we need to send data maybe once every 10 minutes, so it seems like disconnecting in between sending messages will save a lot of battery life. However, each time a connection is made, in between advertising and the actual data transfer, there are a whole bunch of L2CAP messages being sent at about 25 ms intervals.

I haven't yet worked out exactly what they're for, but it seems like they're to do with negotiating the connection parameters and/or synchronizing between the devices. Many of them have the data type L2CAP-C, with no actual data being sent, and some of them contain link layer commands.

I assume they are unavoidable, but what can I do to minimize the number of messages being sent? Failing that, what exactly are they, and what are they for?

Thanks in advance!

  • If your Peripheral device have a bond with the Central, there will be a certain number of packets going back and forth, to re-establish the encrypted link. As you say, there is unfortunately not much you can do with this.

    Having an unencrypted link would remove those encryption packages, but instead, you'd see a complete service discovery being done, which will most often be more packages.

    Finally, the interval between them is given by the connection interval, so reducing that interval can possibly make this go faster. However, depending on the smartphone platform involved, there might be limitations on what connection parameters you are allowed to use.

  • Hi Rory,

    I assume they are unavoidable, but what can I do to minimize the number of messages being sent? Failing that, what exactly are they, and what are they for?

    From what you say those sound like connection parameter updates. Ole Morten suggests they could be related to security, but those wouldn't be labeled as L2CAP-C, so I am leaning towards your implementation requesting a connection parameter update every time it connects to the central. This is by the way completely avoidable, and so you could reconnect every 10min without having to exchange those packets and change the connection parameters.

    If we are indeed talking about a connection parameter update, you should see something like this:

    Peripheral -> L2CAP Conn Param Update Request -> Central Peripheral <- L2CAP Conn Param Update Response <- Central

    Can you share your traces?

    Carles

  • I'm not quite sure what you mean by traces, but this is what I get using a packet sniffer:

    LL_Version_Ind ATT_Read_By_Type_Req LL_Version_Ind LL_Incryption_Req ATT_Read_By_Type_Rsp LL_Encryption_Rsp LL_Reject_Ind ATT_Read_By_Type_Req ATT_Error_Response ATT_Write_Req ATT_Write_Rsp ATT_Read_Req ATT_Read_Rsp ATT_Read_Req ATT_Read_Rsp ATT_Read_Rsp ATT_Write_Req ATT_Write_Rsp ATT_Read_Req ATT_Read_Rsp ATT_Write_Req ATT_Write_Rsp ATT_Handle_Value_Ind ATT_Handle_Value_Confirm

    ...Lots of blank messages... (~300)

    SIG_Connection_Param_Update_Req LL_Connect_Update_Req SIG_Connection_Param_Update_Rsp

    ...some more blank messages... (only 10 or so)

    LL_Terminate_Ind

    There are blank messages with the L2CAP-C header in between the other messages; presumably they're just placeholder messages.

    So it looks like that's the service discovery being done, then a wait for the connection parameter update to happen, then I assume LL_Terminate_Ind means something like "Stop service discovery and wait for indications".

    I don't know how much of this is set by the peripheral end of the connection - for example, maybe the blank messages could be eliminated if the control app responded faster? At the moment I'm using a modified version of the Temperature sensor example code, and the Nordic iOS app, but we are working on our own BLE app for Android, so we will be able to control both ends of the connection.

    Would enabling bonding be the best way to eliminate the service discovery, or are there other ways to do that? And is the delay most likely to be coming from the Central, or the Peripheral?

    Thanks,

    Rory

  • I'm not quite sure what you mean by traces, but this is what I get using a packet sniffer:

    Yes, I meant the output of a sniffer.

    LL_Version_Ind ATT_Read_By_Type_Req LL_Version_Ind LL_Incryption_Req ATT_Read_By_Type_Rsp LL_Encryption_Rsp LL_Reject_Ind ATT_Read_By_Type_Req ATT_Error_Response ATT_Write_Req ATT_Write_Rsp ATT_Read_Req ATT_Read_Rsp ATT_Read_Req ATT_Read_Rsp ATT_Read_Rsp ATT_Write_Req ATT_Write_Rsp ATT_Read_Req ATT_Read_Rsp ATT_Write_Req ATT_Write_Rsp

    Service Discover, not necessary to do this every time?

    ATT_Handle_Value_Ind ATT_Handle_Value_Confirm

    The actual data exchange. You could disconnect after this.

    ...Lots of blank messages... (~300)

    SIG_Connection_Param_Update_Req LL_Connect_Update_Req SIG_Connection_Param_Update_Rsp

    ...some more blank messages... (only 10 or so)

    A connection Parameter Update, you don't need this if you've already sent the data you wanted with the Handle Value Indication.

    LL_Terminate_Ind

    The disconnection.

    So it looks like that's the service discovery being done, then a wait for the connection parameter update to happen, then I assume LL_Terminate_Ind means something like "Stop service discovery and wait for indications".

    No, it means "disconnect now".

    I don't know how much of this is set by the peripheral end of the connection - for example, maybe the blank messages could be eliminated if the control app responded faster? At the moment I'm using a modified version of the Temperature sensor example code, and the Nordic iOS app, but we are working on our own BLE app for Android, so we will be able to control both ends of the connection.

    The service discovery is being performed (I assume) by the central, since you are most probably acting as an ATT server. You will need to optimize the phone side no to do that every time (bonding and then relying on Service Changed).

    Would enabling bonding be the best way to eliminate the service discovery, or are there other ways to do that? And is the delay most likely to be coming from the Central, or the Peripheral?

    Yes, bonding should eliminate the whole discovery procedure. The delay is caused by you not disconnecting immediately after the Handle Value Confirm, which I believe you should do if all you want is to send a value from peripheral to central. Either the peripheral or central could trigger that disconnection.

  • It turns out that I was disconnecting on a connection parameter update event (BLE_GAP_EVT_CONN_PARAM_UPDATE), which is most of the problem, and obviously the reason it was waiting for a connection parameter update. Once I get bonding working properly, that should solve most of the rest of it.

    So I can disconnect properly, what is the bluetooth event ID of an indication acknowledgement? I've just tried disconnecting on BLE_GATTS_EVT_HVC, which seems to do the trick.

    Thanks,

    Rory

Related