Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE5 - Make payload size 200 bytes - the right way

Hello,

I try to configure two nrf52832 devices work with payload of 200 bytes (data should be 200 bytes, not the all ble packet).

I took ble_app_uart_c peripheral and central examples - for 20 bytes everything looks ok.

After that, I tried to understand and implement in my code the ble_app_att_mtu_throughput example, but without luck.

Where can I find the exact algorithm for the increasing the payload size?

My algorithm now:

Common definitions:

NRF_SDH_BLE_GATT_MAX_MTU_SIZE             defined for 247 bytes (in sdk_config.h)

BLE_GATT_ATT_MTU_DEFAULT                         defined to 204 bytes (in ble_gatt.h)

Central:

in function ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) - the function handles all BLE events

- in event BLE_GAP_EVT_PHY_UPDATE_REQUEST

-- I define the 2MBPS speed:

ble_gap_phys_t const phys =
 {
       .rx_phys = BLE_GAP_PHY_2MBPS,
       .tx_phys = BLE_GAP_PHY_2MBPS,
};
sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);

in function gatt_init() - the function initiates the gatt library

- nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);

- nrf_ble_gatt_att_mtu_central_set(&m_gatt, BLE_GATT_ATT_MTU_DEFAULT); //to 204 bytes

in function data_len_ext_set() - the function should set the new MTU size. the function placed in main() function, after all initializations, but before scan_start() call

- nrf_ble_gatt_data_length_set(&m_gatt, BLE_CONN_HANDLE_INVALID, 200 + L2CAP_HDR_LEN);  - according to example. 200 - needed payload, L2CAP_HDR_LEN - defined as 4

in function conn_evt_len_ext_set() - not sure, but looks that the function enables length increasing option in the stack, called just after the data_len_ext_set() function

- memset(&opt, 0x00, sizeof(opt));
- opt.common_opt.conn_evt_ext.enable = 1;
- sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);

Peripheral

in ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) - the function handles all BLE events

- I define the 2MBPS speed:

ble_gap_phys_t const phys =
 {
       .rx_phys = BLE_GAP_PHY_2MBPS,
       .tx_phys = BLE_GAP_PHY_2MBPS,
};

- in event BLE_GAP_EVT_CONNECTED

-- sd_ble_gap_phy_update(p_gap_evt->conn_handle, &phys); //request for 2MBPS

- in event BLE_GAP_EVT_PHY_UPDATE_REQUEST

-- sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);

- in event BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST

-- memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t));

-- sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL);

in function gatt_init() - the function initiates the gatt library

- nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);

- nrf_ble_gatt_att_mtu_periph_set(&m_gatt, BLE_GATT_ATT_MTU_DEFAULT); //to 204 bytes

in function data_len_ext_set() - the function should set the new MTU size. the function placed in main() function, after all initializations, but before ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); call

- nrf_ble_gatt_data_length_set(&m_gatt, BLE_CONN_HANDLE_INVALID, 200 + L2CAP_HDR_LEN);  - according to example. 200 - needed payload, L2CAP_HDR_LEN - defined as 4

in function conn_evt_len_ext_set() - not sure, but looks that the function enables length increasing option in the stack, called just after the data_len_ext_set() function

- memset(&opt, 0x00, sizeof(opt));
- opt.common_opt.conn_evt_ext.enable = 1;
- sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);

So, is it looks ok? Some mistakes that you could point me on? Something is missing?

Thanks a lot!

Parents
  • Difficult to do first time, but easy to implement once it's working; looking at a diff between SDK14.2.0 and my code I see the minimum changes required below, note pretty much as kenneth describes in his post as only gatt_init() length change is required, if I remember. I also include a graphic I wrote to clarify the packet format. Note using SDv5.1.0 and both central and Peripheral use same SDK version and SD. Some deices - eg older iPhone - will of course not allow a packet size increase, hence the addition of the trace.

    // |<-------------------------------------------- Slave -> Master Data Packet -------------------------------------->|
    // |                                                                                                                 |
    // +-----------------------------------------------------------------------------------------------------------------+
    // |                                            BLE Data Packet Min/Max                                              |
    // +-----------------------------------------------------------------------------------------------------------------+
    // |                                         1MHz: 10/265 octets, 2MHz: 11/266 octets                                |
    // +----------+--------+--------------------------------------------------------------------------------------+------+
    // |          | Access |                                                                                      |      |
    // | Preamble | Address|         Protocol Data Unit PDU                                                       | CRCC |
    // +----------+--------+--------------------------------------------------------------------------------------+------+
    // |   1 (2)  |    4   |                                                   2-257                              |  3   |
    // |          |        +-----------+------------------------------------------------------------------+-------+      |
    // |          |        | LL Header |  Payload                                                         |  MIC  |      |
    // |          |        +-----------+------------------------------------------------------------------+ (opt) |      |
    // |          |        |   2       |                                       0-251                      |   4   |      |
    // |          |        |           +--------+---------------------------------------------------------+       |      |
    // |          |        |           | L2CAP  |                                                         |       |      |
    // |          |        |           | Header |  ATT Data                                               |       |      |
    // |          |        |           +--------+---------------------------------------------------------+       |      |
    // |          |        |           |   4    |                              0-247                      |       |      |
    // |          |        |           |        +-----+-------+-------------------------------------------+       |      |
    // |          |        |           |        | ATT | ATT   |                                           |       |      |
    // |          |        |           |        | Op  | Attrib|  ATT Payload                              |       |      |
    // |          |        |           |        +-----+-------+-------------------------------------------+       |      |
    // |  1 (2)   |   4    |  2        |   4    |  1  |  2    |                0-244                      |  (4)  |  3   |
    // +----------+--------+-----------+--------+-----+-------+-------------------------------------------+-------+------+
    //                                                        |                                           |
    //                                                        |<------ Actual Payload 0-244 bytes ------->|
    //
    //
    // Preamble is 1 byte for LE 1MHz (BLE 4.2) and 2 bytes for 2MHz (BLE 5.0). If the first bit of the ADDRESS is 0 the preamble
    // will be 0xAA otherwise 0x55.
    // The MIC field is optional used when we are using an encrypted connection
    
    /**@brief Function for handling events from the GATT library. */
    void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
        {
            m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
            NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
    
            {
                char     InfoPacket[120];
                // Report
                snprintf(InfoPacket, sizeof(InfoPacket), "\r\nData len is set to 0x%X(%d)\r\n", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
                SendViaHardwareUart(InfoPacket);
            }
        }
        NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                      p_gatt->att_mtu_desired_central,
                      p_gatt->att_mtu_desired_periph);
    }
    
    /**@brief Function for initializing the GATT library. */
    void gatt_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }
    
    
    

Reply
  • Difficult to do first time, but easy to implement once it's working; looking at a diff between SDK14.2.0 and my code I see the minimum changes required below, note pretty much as kenneth describes in his post as only gatt_init() length change is required, if I remember. I also include a graphic I wrote to clarify the packet format. Note using SDv5.1.0 and both central and Peripheral use same SDK version and SD. Some deices - eg older iPhone - will of course not allow a packet size increase, hence the addition of the trace.

    // |<-------------------------------------------- Slave -> Master Data Packet -------------------------------------->|
    // |                                                                                                                 |
    // +-----------------------------------------------------------------------------------------------------------------+
    // |                                            BLE Data Packet Min/Max                                              |
    // +-----------------------------------------------------------------------------------------------------------------+
    // |                                         1MHz: 10/265 octets, 2MHz: 11/266 octets                                |
    // +----------+--------+--------------------------------------------------------------------------------------+------+
    // |          | Access |                                                                                      |      |
    // | Preamble | Address|         Protocol Data Unit PDU                                                       | CRCC |
    // +----------+--------+--------------------------------------------------------------------------------------+------+
    // |   1 (2)  |    4   |                                                   2-257                              |  3   |
    // |          |        +-----------+------------------------------------------------------------------+-------+      |
    // |          |        | LL Header |  Payload                                                         |  MIC  |      |
    // |          |        +-----------+------------------------------------------------------------------+ (opt) |      |
    // |          |        |   2       |                                       0-251                      |   4   |      |
    // |          |        |           +--------+---------------------------------------------------------+       |      |
    // |          |        |           | L2CAP  |                                                         |       |      |
    // |          |        |           | Header |  ATT Data                                               |       |      |
    // |          |        |           +--------+---------------------------------------------------------+       |      |
    // |          |        |           |   4    |                              0-247                      |       |      |
    // |          |        |           |        +-----+-------+-------------------------------------------+       |      |
    // |          |        |           |        | ATT | ATT   |                                           |       |      |
    // |          |        |           |        | Op  | Attrib|  ATT Payload                              |       |      |
    // |          |        |           |        +-----+-------+-------------------------------------------+       |      |
    // |  1 (2)   |   4    |  2        |   4    |  1  |  2    |                0-244                      |  (4)  |  3   |
    // +----------+--------+-----------+--------+-----+-------+-------------------------------------------+-------+------+
    //                                                        |                                           |
    //                                                        |<------ Actual Payload 0-244 bytes ------->|
    //
    //
    // Preamble is 1 byte for LE 1MHz (BLE 4.2) and 2 bytes for 2MHz (BLE 5.0). If the first bit of the ADDRESS is 0 the preamble
    // will be 0xAA otherwise 0x55.
    // The MIC field is optional used when we are using an encrypted connection
    
    /**@brief Function for handling events from the GATT library. */
    void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
        {
            m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
            NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
    
            {
                char     InfoPacket[120];
                // Report
                snprintf(InfoPacket, sizeof(InfoPacket), "\r\nData len is set to 0x%X(%d)\r\n", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
                SendViaHardwareUart(InfoPacket);
            }
        }
        NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                      p_gatt->att_mtu_desired_central,
                      p_gatt->att_mtu_desired_periph);
    }
    
    /**@brief Function for initializing the GATT library. */
    void gatt_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }
    
    
    

Children
Related