BLE RX error Unexpected L2CAP continuation

My Nordic device (nRF52833, using SDK 2.1.2) is a peripheral. 
I need to periodically transfer to it large amount of data from central device over connectable Nordic UART Service.
I perform this data transfer in batches of 16 packets, 128 bytes each (due to max payload limitation of 170).
After each batch of 16, peripheral sends XOFF packet, which causes central to wait, so that peripheral can write the data to SPI flash.
After write to flash is complete, peripheral sends XON packet, and transfer resumes.
Very basic flow control.
That works for the most part, but occasionally, Nordic device throws an error   

(15:14:31.168) E: Unexpected L2CAP continuation
(15:14:31.168) E: Unexpected L2CAP continuation
(15:14:31.168) E: Unexpected L2CAP continuation
(15:14:31.287) E: Unexpected L2CAP continuation
(15:14:31.287) E: Unexpected L2CAP continuation


I tried to introduce a small delay between individual packets within batch of 16, but that doesn't solve the problem.

I found an SDK's  Zephyr BT code where this message is printed, but not sure what to make of it

tatic void bt_acl_recv(struct bt_conn *conn, struct net_buf *buf,
uint8_t flags)
{
uint16_t acl_total_len;

/* Check packet boundary flags */
switch (flags) {
case BT_ACL_START:
if (conn->rx) {
BT_ERR("Unexpected first L2CAP frame"); 
bt_conn_reset_rx_state(conn);
}

BT_DBG("First, len %u final %u", buf->len,
(buf->len < sizeof(uint16_t)) ?
0 : sys_get_le16(buf->data));

conn->rx = buf;
break;
case BT_ACL_CONT:
if (!conn->rx) {
BT_ERR("Unexpected L2CAP continuation"); <-----------------
bt_conn_reset_rx_state(conn);
net_buf_unref(buf);
return;
}
1346.config.zip

Would appreciate any insights to what might be causing it and how to avoid it.
My code recovers form this failure on application level, but it affects performance and I'd rather solve it properly

Parents
  • Hello,

    Interesting, I can't find any obvious reason for this. 

    Are you able to provide an on-air sniffer log of when this situation occurs? You can just do a abrupt soft reset when the issue occurs, so it may be easier to know exactly where it occurred. You can for instance use the nRF sniffer for BLE and send us the .pcapng file from Wireshark if possible.

    Btw, does this happen with specific central devices? Can you send us the .config from the build folder also?

    Kenneth

  • Hi Kenneth,

    The problem is hard to reproduce so it might be a bit problematic to capture it on sniffer, but I'll try, I do have nRF sniffer (nRF52840 DVK).

    > Btw, does this happen with specific central devices?
    Now that you mentioned it...
    I do have several kinds of devices acting as central (all impplementing same file transfer protocol)
    - Custom board based on Analog Devices Maxim 32690 MCU
    - Mobil phones (all kinds)
    - Seed Studio Xiao BLE device nrf52840 based
    So far, I was able to reproduce the problem with Maxim board only, but that could be because it is the most used...

    Attaching .config

  • For some reason the .config was not attached, but you can place it in a zip files with the sniffer trace. I think it will be difficult to understand what is failing without the sniffer file in any case. If it only fails with a specific central device, it could be somewhat related to how data is fragmented on-air, though I am not aware of any issue.

    Kenneth

  • Yeah, DevZone website keeps rejecting .config file, not sure why

  • It surprise me that you have CONFIG_BT_CTLR_DATA_LENGTH_MAX=27, since that will severely limit the throughput and increase fragmentation. Is there any reason why you have kept it as 27? Or maybe you just weren't aware of it.

    Kenneth

  • I actually send packets much larger than 27,
    My negotiated MTU is 247

    Snippet of log from peripheral (Nordic) side

    (

    13:24:08.219) Starting advertising for 20 seconds, 10 seconds ahead of rendez-vous #11
    (13:24:20.490) Connected with MTU(20)
    (13:24:20.490) MTU exchange pending
    (13:24:20.731) MTU exchange successful
    (13:24:20.731) Current MTU: 247
    (13:24:25.660) Cmd: Request Challenge Code [30] recevied..!


    Below is a snippet form my prj.conf

    # NUS service
    CONFIG_BT_NUS=y
    #CONFIG_BT_L2CAP_TX_MTU=75
    CONFIG_BT_L2CAP_TX_MTU=300
    CONFIG_BT_GATT_CLIENT=y
    CONFIG_BT_GATT_DM=y
    CONFIG_BT_MAX_CONN=2
    #CONFIG_BT_BUF_ACL_RX_SIZE=79
    CONFIG_BT_BUF_ACL_RX_SIZE=300
    CONFIG_BT_BUF_ACL_TX_SIZE=300
    #CONFIG_BT_CTLR_DATA_LENGTH_MAX=270


    I did try to increase  BT_CTLR_DATA_LENGTH_MAX, it didn't seem to have an affect on negotiated MTU value, so I ;eft it at default (which apparently is 27

Reply
  • I actually send packets much larger than 27,
    My negotiated MTU is 247

    Snippet of log from peripheral (Nordic) side

    (

    13:24:08.219) Starting advertising for 20 seconds, 10 seconds ahead of rendez-vous #11
    (13:24:20.490) Connected with MTU(20)
    (13:24:20.490) MTU exchange pending
    (13:24:20.731) MTU exchange successful
    (13:24:20.731) Current MTU: 247
    (13:24:25.660) Cmd: Request Challenge Code [30] recevied..!


    Below is a snippet form my prj.conf

    # NUS service
    CONFIG_BT_NUS=y
    #CONFIG_BT_L2CAP_TX_MTU=75
    CONFIG_BT_L2CAP_TX_MTU=300
    CONFIG_BT_GATT_CLIENT=y
    CONFIG_BT_GATT_DM=y
    CONFIG_BT_MAX_CONN=2
    #CONFIG_BT_BUF_ACL_RX_SIZE=79
    CONFIG_BT_BUF_ACL_RX_SIZE=300
    CONFIG_BT_BUF_ACL_TX_SIZE=300
    #CONFIG_BT_CTLR_DATA_LENGTH_MAX=270


    I did try to increase  BT_CTLR_DATA_LENGTH_MAX, it didn't seem to have an affect on negotiated MTU value, so I ;eft it at default (which apparently is 27

Children
Related