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

Max data length over BLE

Hello,

I'm a little bit confused about max datalength that can be read/written in a characteristic.

See attached, a MTU of 64 bytes is negotiated thus 61 bytes available for the data itself in a packet.

In case I want to send data from an App over the NUS service for example, what is the maximum data length I can send in one packet: 61 or 27 ? (see max_rx_octets in the log)

I have an application that was developped when only Bluetooth 4.0 and 4.1 smartphones were available, I sent packets of maximum only 20 bytes so I 've divided the data to be sent in multiple 20 bytes packets. I'd like to speed a little bit up now and would like to know on which packet length I can rely on.

an someone explain my shortly about this?

Thanks in advance.

Parents
  • Hi,

     

    In the "older scenario", where the actual throughput was 20 bytes of user data, this scenario is valid:

    https://devzone.nordicsemi.com/f/nordic-q-a/1105/how-do-i-calculate-throughput-for-a-ble-link

     

    Since you mention larger MTU size, the nRF52xxx can have a MTU size of up to 247 bytes (sdk_config.h::NRF_SDH_BLE_GATT_MAX_MTU_SIZE) vs. the "legacy" 23 bytes (note: 3 bytes overhead, 20 bytes user data).

    However, since the peripheral can do up to 247 bytes does not automatically mean that the central will also accept this MTU size. You might get 64 bytes (or 23 bytes) once the link between the peripheral and central is established. In order to satisfy the size as given by the central, you can store the agreed upon MTU size, which will be located in the callback for the GATT handler module (here taken from the ble_app_hrs example in SDK 15):

    /**@brief GATT module event handler.
     */
    static void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)
        {
            NRF_LOG_INFO("GATT ATT MTU on connection 0x%x changed to %d.",
                         p_evt->conn_handle,
                         p_evt->params.att_mtu_effective);
        }
    
        ble_hrs_on_gatt_evt(&m_hrs, p_evt);
    }

     

    In addition to this, you have a parameter called "GAP event length" (sdk_config.h::NRF_SDH_BLE_GAP_EVENT_LENGTH), which gives you the maximum length of each connection interval (in 1.25 ms slots), which states how many packets per interval you can potentially send within one connection interval. This is the same principle as the MTU size, meaning that the central and peripheral has to agree upon a number (up to define NRF_SDH_BLE_GAP_EVENT_LENGTH).

     

    I'd recommend that you set the two above mentioned defines high (or use the default values in most examples in SDK 15) and try to continuously push packets through the link to see what speed you get with different phones.

     

    Kind regards,

    Håkon

Reply
  • Hi,

     

    In the "older scenario", where the actual throughput was 20 bytes of user data, this scenario is valid:

    https://devzone.nordicsemi.com/f/nordic-q-a/1105/how-do-i-calculate-throughput-for-a-ble-link

     

    Since you mention larger MTU size, the nRF52xxx can have a MTU size of up to 247 bytes (sdk_config.h::NRF_SDH_BLE_GATT_MAX_MTU_SIZE) vs. the "legacy" 23 bytes (note: 3 bytes overhead, 20 bytes user data).

    However, since the peripheral can do up to 247 bytes does not automatically mean that the central will also accept this MTU size. You might get 64 bytes (or 23 bytes) once the link between the peripheral and central is established. In order to satisfy the size as given by the central, you can store the agreed upon MTU size, which will be located in the callback for the GATT handler module (here taken from the ble_app_hrs example in SDK 15):

    /**@brief GATT module event handler.
     */
    static void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)
        {
            NRF_LOG_INFO("GATT ATT MTU on connection 0x%x changed to %d.",
                         p_evt->conn_handle,
                         p_evt->params.att_mtu_effective);
        }
    
        ble_hrs_on_gatt_evt(&m_hrs, p_evt);
    }

     

    In addition to this, you have a parameter called "GAP event length" (sdk_config.h::NRF_SDH_BLE_GAP_EVENT_LENGTH), which gives you the maximum length of each connection interval (in 1.25 ms slots), which states how many packets per interval you can potentially send within one connection interval. This is the same principle as the MTU size, meaning that the central and peripheral has to agree upon a number (up to define NRF_SDH_BLE_GAP_EVENT_LENGTH).

     

    I'd recommend that you set the two above mentioned defines high (or use the default values in most examples in SDK 15) and try to continuously push packets through the link to see what speed you get with different phones.

     

    Kind regards,

    Håkon

Children
No Data
Related