Connection parameter update issue

Hello,

we are currently facing ann issue with the connection parameter update function.

wee initialized our connection parameters as following:

#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(7.5 , UNIT_1_25_MS)        /**< Minimum acceptable connection interval (7.5 ms). */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(7.5, UNIT_1_25_MS)         /**< Maximum acceptable connection interval (30 ms). */
#define SLAVE_LATENCY                   0                                       /**< Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(2000, UNIT_10_MS)         /**< Connection supervisory timeout (2 seconds). */
#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                   /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                  /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                       /**< Number of attempts before giving up the connection parameter negotiation. */ 

connection parameters are set here:

static uint32_t gap_params_init(void)
{
...
}

static uint32_t conn_params_init(void)
{
...
}

and updated in when we receive an event

    case BLE_GAP_EVT_CONN_PARAM_UPDATE:
    {
      // Accepting parameters requested
      err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update.conn_params);
      APP_ERROR_CHECK(err_code);
    } break;

so we thought we'll set our parameters and if the other device sends other parameters we set and accept them. i think the slave is our bluetooth device and the master was an iphone.

we used the sniffer to check what's going on.

our device is requesting the connection parameters first:

No.     Time           Source                Destination           Protocol Length Info
236     9.589153       Slave_0x506573e6      Master_0x506573e6     L2CAP    42     Connection Parameter Update Request
    
Frame 236: 42 bytes on wire (336 bits), 42 bytes captured (336 bits) on interface COM6-4.0, id 0
nRF Sniffer for Bluetooth LE
Bluetooth Low Energy Link Layer
    Access Address: 0x506573e6
    [Master Address: 55:11:5c:c4:15:5e (55:11:5c:c4:15:5e)]
    [Slave Address: fe:95:21:38:7b:d5 (fe:95:21:38:7b:d5)]
    Data Header
        .... ..10 = LLID: Start of an L2CAP message or a complete L2CAP message with no fragmentation (0x2)
        .... .0.. = Next Expected Sequence Number: 0 [ACK]
        .... 1... = Sequence Number: 1 [OK]
        ...0 .... = More Data: False
        ..0. .... = CTE Info: Not Present
        00.. .... = RFU: 0
        Length: 16
    [L2CAP Index: 29]
    [Connection Parameters in: 58]
    CRC: 0x299bf1
Bluetooth L2CAP Protocol
    Length: 12
    CID: Low Energy L2CAP Signaling Channel (0x0005)
    Command: Connection Parameter Update Request
        Command Code: Connection Parameter Update Request (0x12)
        Command Identifier: 0x03
        Command Length: 8
        Min. Interval: 6 (7.5 msec)
        Max. Interval: 6 (7.5 msec)
        Slave Latency: 0 LL Connection Events
        Timeout Multiplier: 200 (2 sec)

Then i think the iphone is responding with some other parameters:

No.     Time           Source                Destination           Protocol Length Info
237     9.618916       Master_0x506573e6     Slave_0x506573e6      LE LL    38     Control Opcode: LL_CONNECTION_UPDATE_IND

Frame 237: 38 bytes on wire (304 bits), 38 bytes captured (304 bits) on interface COM6-4.0, id 0
nRF Sniffer for Bluetooth LE
Bluetooth Low Energy Link Layer
    Access Address: 0x506573e6
    [Master Address: 55:11:5c:c4:15:5e (55:11:5c:c4:15:5e)]
    [Slave Address: fe:95:21:38:7b:d5 (fe:95:21:38:7b:d5)]
    Data Header
        .... ..11 = LLID: Control PDU (0x3)
        .... .0.. = Next Expected Sequence Number: 0 [ACK]
        .... 0... = Sequence Number: 0 [OK]
        ...1 .... = More Data: True
        ..0. .... = CTE Info: Not Present
        00.. .... = RFU: 0
        Length: 12
    Control Opcode: LL_CONNECTION_UPDATE_IND (0x00)
    Window Size: 3 (3.75 msec)
    Window Offset: 0 (0 msec)
    Interval: 24 (30 msec)
    Latency: 0
    Timeout: 200 (2000 msec)
    Instant: 93
    [Connection Parameters in: 58]
    CRC: 0x041631

then the master sends two times that the connection parameters were accepted:

No.     Time           Source                Destination           Protocol Length Info
239     9.619435       Master_0x506573e6     Slave_0x506573e6      L2CAP    36     Connection Parameter Update Response (Accepted)

Frame 239: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on interface COM6-4.0, id 0
nRF Sniffer for Bluetooth LE
Bluetooth Low Energy Link Layer
    Access Address: 0x506573e6
    [Master Address: 55:11:5c:c4:15:5e (55:11:5c:c4:15:5e)]
    [Slave Address: fe:95:21:38:7b:d5 (fe:95:21:38:7b:d5)]
    Data Header
        .... ..10 = LLID: Start of an L2CAP message or a complete L2CAP message with no fragmentation (0x2)
        .... .1.. = Next Expected Sequence Number: 1 [ACK]
        .... 1... = Sequence Number: 1 [OK]
        ...0 .... = More Data: False
        ..0. .... = CTE Info: Not Present
        00.. .... = RFU: 0
        Length: 10
    [L2CAP Index: 31]
    [Connection Parameters in: 58]
    CRC: 0x204260
Bluetooth L2CAP Protocol
    Length: 6
    CID: Low Energy L2CAP Signaling Channel (0x0005)
    Command: Connection Parameter Update Response
        Command Code: Connection Parameter Update Response (0x13)
        Command Identifier: 0x03
        Command Length: 2
        Move Result: Accepted (0x0000)

No.     Time           Source                Destination           Protocol Length Info
240     9.648916       Master_0x506573e6     Slave_0x506573e6      L2CAP    36     Connection Parameter Update Response (Accepted)

Frame 240: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on interface COM6-4.0, id 0
nRF Sniffer for Bluetooth LE
Bluetooth Low Energy Link Layer
    Access Address: 0x506573e6
    [Master Address: 55:11:5c:c4:15:5e (55:11:5c:c4:15:5e)]
    [Slave Address: fe:95:21:38:7b:d5 (fe:95:21:38:7b:d5)]
    Data Header
        .... ..10 = LLID: Start of an L2CAP message or a complete L2CAP message with no fragmentation (0x2)
        .... .1.. = Next Expected Sequence Number: 1 [ACK]
        .... 1... = Sequence Number: 1 [Retransmit]
        ...0 .... = More Data: False
        ..0. .... = CTE Info: Not Present
        00.. .... = RFU: 0
        Length: 10
    [L2CAP Index: 32]
    [Connection Parameters in: 58]
    CRC: 0x204260
Bluetooth L2CAP Protocol
    Length: 6
    CID: Low Energy L2CAP Signaling Channel (0x0005)
    Command: Connection Parameter Update Response
        Command Code: Connection Parameter Update Response (0x13)
        Command Identifier: 0x03
        Command Length: 2
        Move Result: Accepted (0x0000)

Afterwards the slave sends update requests regularly, but all of them get rejected by the master.

No.     Time           Source                Destination           Protocol Length Info
255     9.859114       Slave_0x506573e6      Master_0x506573e6     L2CAP    42     Connection Parameter Update Request

Frame 255: 42 bytes on wire (336 bits), 42 bytes captured (336 bits) on interface COM6-4.0, id 0
nRF Sniffer for Bluetooth LE
Bluetooth Low Energy Link Layer
    Access Address: 0x506573e6
    [Master Address: 55:11:5c:c4:15:5e (55:11:5c:c4:15:5e)]
    [Slave Address: fe:95:21:38:7b:d5 (fe:95:21:38:7b:d5)]
    Data Header
        .... ..10 = LLID: Start of an L2CAP message or a complete L2CAP message with no fragmentation (0x2)
        .... .1.. = Next Expected Sequence Number: 1 [ACK]
        .... 0... = Sequence Number: 0 [OK]
        ...0 .... = More Data: False
        ..0. .... = CTE Info: Not Present
        00.. .... = RFU: 0
        Length: 16
    [L2CAP Index: 33]
    [Connection Parameters in: 237]
    CRC: 0xd15ede
Bluetooth L2CAP Protocol
    Length: 12
    CID: Low Energy L2CAP Signaling Channel (0x0005)
    Command: Connection Parameter Update Request
        Command Code: Connection Parameter Update Request (0x12)
        Command Identifier: 0x05
        Command Length: 8
        Min. Interval: 24 (30 msec)
        Max. Interval: 24 (30 msec)
        Slave Latency: 0 LL Connection Events
        Timeout Multiplier: 200 (2 sec)

No.     Time           Source                Destination           Protocol Length Info
256     9.888921       Master_0x506573e6     Slave_0x506573e6      L2CAP    36     Connection Parameter Update Response (Rejected)

Frame 256: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on interface COM6-4.0, id 0
nRF Sniffer for Bluetooth LE
Bluetooth Low Energy Link Layer
    Access Address: 0x506573e6
    [Master Address: 55:11:5c:c4:15:5e (55:11:5c:c4:15:5e)]
    [Slave Address: fe:95:21:38:7b:d5 (fe:95:21:38:7b:d5)]
    Data Header
        .... ..10 = LLID: Start of an L2CAP message or a complete L2CAP message with no fragmentation (0x2)
        .... .1.. = Next Expected Sequence Number: 1 [ACK]
        .... 1... = Sequence Number: 1 [OK]
        ...0 .... = More Data: False
        ..0. .... = CTE Info: Not Present
        00.. .... = RFU: 0
        Length: 10
    [L2CAP Index: 34]
    [Connection Parameters in: 237]
    CRC: 0x6491d7
Bluetooth L2CAP Protocol
    Length: 6
    CID: Low Energy L2CAP Signaling Channel (0x0005)
    Command: Connection Parameter Update Response
        Command Code: Connection Parameter Update Response (0x13)
        Command Identifier: 0x05
        Command Length: 2
        Move Result: Rejected (0x0001)

No.     Time           Source                Destination           Protocol Length Info

so to us it looks like we're setting the parameters, the iphone accepts but sends other parameters. and as we try to set them from our device, the iphone always rejects the update. same happens with an android device. both times we used the nrf connect app to test.

here's the full wireshark log:

https://we.tl/t-NgZvdxKJsi

if we remove
sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update.conn_params);
in our event, then it looks like the device tries to change parameters 3 times and then it disconnects due to
#define MAX_CONN_PARAMS_UPDATE_COUNT    3 
we can set this number up, but that looks like a dirty fix to me and if we use the update in our event connection parameter changed is triggered multiple times a second, so i fear that it affects our data transmisson.

we use s112

  • How do you initialize the conn_params module? There is a member in the ble_conn_params_init_t -struct called disconnect_on_fail, which determines if you want to disconnect in case you don't get the parameters you want.

    The same struct also has pointers to event handlers for connection events. I think the example event handler from Nordic also disconnects if parameters end up outside the limits you specify. So if you based your code on an example check that too.

    Or is it the iphone that disconnects if you keep asking too many times? If so the I guess lowering that count is the best option.

  • Hello

    //initialize connection parameters module.
    static uint32_t conn_params_init(void)
    {
      ret_code_t             err_code;
      ble_conn_params_init_t cp_init;
    
      memset(&cp_init, 0, sizeof(cp_init));
    
      cp_init.p_conn_params                  = NULL;
      cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
      cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
      cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
      cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
      cp_init.disconnect_on_fail             = false;
      cp_init.evt_handler                    = on_conn_params_evt;
      cp_init.error_handler                  = conn_params_error_handler;
    
      err_code = ble_conn_params_init(&cp_init);
      return err_code;
    }

    that's the conn_params_init() function. but this one shouldn't cause the issue i think, because we are handling the error and the device should enter an error stat if the return value is not "success".

    i think the update of the connection parameters is the issue

    case BLE_GAP_EVT_CONN_PARAM_UPDATE:
        {
          // Accepting parameters requested
          err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update.conn_params);
          APP_ERROR_CHECK(err_code);
        } break;

    if i remove this line from the code we dont react to connection parameter updates and the connection breaks after 3 attempts (#define MAX_CONN_PARAMS_UPDATE_COUNT    3).
    if i leave this line in the code. the connection parameter update request appears every couple of milliseconds but gets rejected.

  • Hi!

    the iphone always rejects the update


    You wont' get 7.5ms connection interval with a iPhone.

    https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf
    page 193


  • yes i get that

    No.     Time           Source                Destination           Protocol Length Info
    237     9.618916       Master_0x506573e6     Slave_0x506573e6      LE LL    38     Control Opcode: LL_CONNECTION_UPDATE_IND
    
    Frame 237: 38 bytes on wire (304 bits), 38 bytes captured (304 bits) on interface COM6-4.0, id 0
    nRF Sniffer for Bluetooth LE
    Bluetooth Low Energy Link Layer
        Access Address: 0x506573e6
        [Master Address: 55:11:5c:c4:15:5e (55:11:5c:c4:15:5e)]
        [Slave Address: fe:95:21:38:7b:d5 (fe:95:21:38:7b:d5)]
        Data Header
            .... ..11 = LLID: Control PDU (0x3)
            .... .0.. = Next Expected Sequence Number: 0 [ACK]
            .... 0... = Sequence Number: 0 [OK]
            ...1 .... = More Data: True
            ..0. .... = CTE Info: Not Present
            00.. .... = RFU: 0
            Length: 12
        Control Opcode: LL_CONNECTION_UPDATE_IND (0x00)
        Window Size: 3 (3.75 msec)
        Window Offset: 0 (0 msec)
        Interval: 24 (30 msec)
        Latency: 0
        Timeout: 200 (2000 msec)
        Instant: 93
        [Connection Parameters in: 58]
        CRC: 0x041631

    i thought that this message indicates that we want to start with 7.5ms but the iphone wants 30ms. and i thought we update our parameters to 30ms in the update event

        case BLE_GAP_EVT_CONN_PARAM_UPDATE:
        {
          // Accepting parameters requested
          err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update.conn_params);
          APP_ERROR_CHECK(err_code);
        } break;

  • You are using the connection param update module in your code.

    If you have this code below in your main.c, then try removing that.

        case BLE_GAP_EVT_CONN_PARAM_UPDATE:
        {
          // Accepting parameters requested
          err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update.conn_params);
          APP_ERROR_CHECK(err_code);
        } break;

    Also,
    you will get notified about if the negotiation was a success, or if the negotiation procedure failed in on_conn_params_evt() handler.

Related