LL_LENGTH_REQ & LL_LENGTH_RSP on nRF52840 with different TX and RX size

Hello!

I am building Central app to read data from not a fully conformant BLE devices.

When I connect to device with my Android or Windows app, the connection establishes immediately. Connecting with Zephyr default stack lead device into "broken connection" mode (all I know, the status LED starts fast-blinking instead of steady light as it should be).

I have ruled out all other options, and the issue is -- the device requires that central confirm it's LL_LENGTH_REQ:

Peripheral => Central:
Control Opcode: LL_LENGTH_REQ (0x14)
Max RX octets: 251
Max RX time: 2120 microseconds
Max TX octets: 27
Max TX time: 328 microseconds

Phone & windows & TI BLE stack does that with ease, but I am failing to configure project to get the same on nRF52840. 

No matter how I set parameters in prj.conf:

CONFIG_BT_BUF_ACL_RX_SIZE
CONFIG_BT_BUF_ACL_TX_SIZE
CONFIG_BT_CTLR_DATA_LENGTH_MAX
(I've tried varied settings of 27 and 251 there)
And in child_image/hci_rpmsg.conf:
CONFIG_BT_CTLR_TX_BUFFER_SIZE=27
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_RX_BUF_LEN=255
The generated response packet
Control Opcode: LL_LENGTH_RSP (0x15)
Max RX octets: 251
Max RX time: 2120 microseconds
Max TX octets: 251
Max TX time: 2120 microseconds

has RX and TX equals - either 251 or 27.

The current settings are:

CONFIG_BT=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_SMP=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_DM=n
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_PHY_CODED=y
CONFIG_BT_USER_PHY_UPDATE=n
CONFIG_BT_SMP=y
CONFIG_BT_GATT_AUTO_UPDATE_MTU=n
CONFIG_BT_AUTO_PHY_UPDATE=n
CONFIG_BT_AUTO_DATA_LEN_UPDATE=n
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=27
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_CTLR=y

# hci_rpmsg.conf -- but I really think this one is unused

CONFIG_BT_EXT_ADV=y
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_PHY_CODED=y
CONFIG_BT_CTLR_TX_BUFFER_SIZE=27
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_RX_BUF_LEN=255
Parents
  • Hi Anton, 
    Could you capture a sniffer trace of the communication so we can check if the peripheral reject the connection because of the data length ? 

    I will need to double check if it's possible to adjust RX length different to TX data length. From what I can see the 

    bt_conn_le_data_len_update() only allow update the tx length, not the rx.
  • The peripheral doesn't reject the connection, it just doesn't work, failing inside of its firmware either allocating the receive buffers (if it's 251/251) either failing to send non-fragmented notification (27/27).

    The original central has:

    CONN_IND

    LL_LENGTH_REQ(27/251)

    LL_LENGTH_RSP(27/251)

    NOOP + GATT_NOTIFICATION

    phone connection has more stuff going on, but practically the same the gist of it. 

    The nRF52840 trace is

    CONN_IND

    LL_LENGTH_REQ(27/251)

    LL_LENGTH_RSP(251/251) or 27/27

    and after only NOOPs... Open mouthDisappointed

Reply
  • The peripheral doesn't reject the connection, it just doesn't work, failing inside of its firmware either allocating the receive buffers (if it's 251/251) either failing to send non-fragmented notification (27/27).

    The original central has:

    CONN_IND

    LL_LENGTH_REQ(27/251)

    LL_LENGTH_RSP(27/251)

    NOOP + GATT_NOTIFICATION

    phone connection has more stuff going on, but practically the same the gist of it. 

    The nRF52840 trace is

    CONN_IND

    LL_LENGTH_REQ(27/251)

    LL_LENGTH_RSP(251/251) or 27/27

    and after only NOOPs... Open mouthDisappointed

Children
  • Please capture a sniffer trace. 

    Have you made sure you do a write command from the central to the peripheral to enable notification. Without that the peripheral will not send anything to the central. 
    What is NOOP ? You meant empty packets ? 

  • Here is the traces:

        original-to-original-slice.pcapng.gz -- it's the trace of original central to original peripheral
        phone-to-original-slice.pcapng.gz -- this is the trace of the phone to original peripheral
        nRF-to-original-slice.pcapng.gz -- this is the trace of nRF connect() to original peropheral

    I've also patched the firmware of the peripheral to send 251/251 at the connection time, but surprisingly, the phone replies with 27/251 to this packets:

        phone-to-patched-slice.pcapng.gz

    And nRF same responds with equal TX & RX as to the original:

        nRF-to-patched-slice.pcapng.gz

    Yes, "Empty PDU" is what I called NOOP, sorry for wrong word usage.

    The peripheral is NOT properly GATT-compliant, it actually just sends stream of notifications with no other GATT server functionality, basically that's why I need a central-on-chip where I can get these notifications (android ble stack doesn't give access to raw notification data out of native code unless device gives list of characteristics).

    I had an cc2640r2-based central implementation that was working fine, it also connected using 27/251 (same as original central do), but I can't show you the trace because I've burned it out Smiley and nRFs is the only kits i have left atm.

    Regardless of these, answer LL_LENGTH_REQ with 251/251 to 27/251 looks like a bug to me, as it should use effectively MIN() between requested of the both sides, isn't it?

    Even if I not rely on the default only and add a request for MTU from the central, it looks like this:

      Peri=>Cen: LL_LENGTH_REQ(27/251)
      Cen=>Peri: LL_LENGTH_RSP(251/251)
      Cen=>Peri: LL_LENGTH_REQ(251/251)
      Peri=>Cen: LL_LENGTH_RSP(27/251)

    Which also seems weird to me.

    5670.traces.zip

Related