Setting CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 but payload is limited to 229 bytes.

We are running an HCI controller on nRF52833 based on the Zephyr hci_uart sample code. We are using the Zephyr 3.7.0 LTS version.

We have set CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 and CONFIG_BT_L2CAP_TX_MTU=247

Everything is working as long as our payload size is <= 229 bytes, but we need to understand the 18 byte difference between the configured MTU and the "real" MTU we are getting.

Note the following:

  • The nRF52833 is a HCI controller acting as a central. (See hcu_uart sample.)
  • The peripheral is reporting an MTU of 251 bytes (using ATT_EXCHANGE_MTU_REQ HCI command)
  • We are using the ATT_WRITE_CMD to send L2CAP PDU over HCI to the nRF52833 controller (via UART)
  • If the payload size of the PDU is <= 229 bytes everything works
  • If the payload size is > 229 bytes nothing gets transmitted
    • A sniffer shows no data over the air
    • If ATT_WRITE_REQ is used, not ack (ATT_WRITE_RSP) is received

We don't necessarily need more that 229 bytes of payload. We are just trying to understand the 18 bytes of discrepancy/overhead so that we can implement our firmware properly and robustly.

Thank you in advance for any help you may give!

-Mike 

Parents
  • Hello,

    What do you connect to? Does that device support more than 229 bytes of payload?

    Can you please try to capture a sniffer trace of the connection? (It requires an extra DK/dongle from Nordic). If you do, please upload the .pcapng file here. 

    Alternatively, you can look at the DevAcademy's Bluetooth Low Energy Fundamentals course. Lesson 3 exercise 2 show how to set up a callback function when the connections parameters (Data length) have been negotiated, and it tells you what data length the connection actually has. 

    Best regards,

    Edvin

  • Thank you for your feedback.

    We connect to a specific device that supports an MTU of 251. (We have verified that.)

    We have used the Nordic sniffer, but there is nothing to show because when the payload is bigger than 229, it shows nothing. (As stated before, the sniffer shows no tansmission when payload is greater than 229.)

    We have a working callback which essentially indicates a data length of 244 not 229 (if we subtact the header sizes from the MTU).

    We are still not able to explain the difference.

  • I assume you don't see anything on air, because it is not transmitted, as you say. You need to check the return values of the functions that you use to send the packets. Perhaps you are not aware that they return anything, but if you look at e.g. the peripheral_uart sample, you can see in the function ble_write_thread() in main.c, that it logs "Failed to send data over BLE connection" if the return value of bt_nus_send() is not 0. 

    Even better, you can add something like:

    int ret;
    ret = bt_nus_send();
    if (ret) {
        LOG_ERR("bt_nus_send() returned %d", ret);
    }

    Your function is probably called something else than bt_nus_send(), but look at the implementation of that function, and check the equivalent return value.

    Best regards,

    Edvin

Reply
  • I assume you don't see anything on air, because it is not transmitted, as you say. You need to check the return values of the functions that you use to send the packets. Perhaps you are not aware that they return anything, but if you look at e.g. the peripheral_uart sample, you can see in the function ble_write_thread() in main.c, that it logs "Failed to send data over BLE connection" if the return value of bt_nus_send() is not 0. 

    Even better, you can add something like:

    int ret;
    ret = bt_nus_send();
    if (ret) {
        LOG_ERR("bt_nus_send() returned %d", ret);
    }

    Your function is probably called something else than bt_nus_send(), but look at the implementation of that function, and check the equivalent return value.

    Best regards,

    Edvin

Children
No Data
Related