Send long packets for Android using low MTU sizes

Hi,

In a ble_app_uart example I have problems to send long packets if the Android smartphone only accepts MTU sizes of 20 bytes. I'm using the nRF5_SDK_17.1.0, the S132 over the SES IDE and the nR52-DK board.

The application adjusts the MTU size to the value negotiated by the smartphone and it's set to 20 bytes. However, when I send longer packets the smartphone only receives a part. It looks like the device only send one packet and doesn't manages automatically the division of the full packet for sendidn it in different subpackets.

How could I setup the Softdevice so it could automatically manages this sending of a long packet in subpackets? Excuse me if there is other similar case about this, but I have not been able to find it.

Thank you in advance.

Regards,

Joel

  • Hi,

    You can see how the ble_app_uart example handles this here:

    void uart_event_handle(app_uart_evt_t * p_event)
    {
        static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
        static uint8_t index = 0;
        uint32_t       err_code;
    
        switch (p_event->evt_type)
        {
            case APP_UART_DATA_READY:
                UNUSED_VARIABLE(app_uart_get(&data_array[index]));
                index++;
    
                if ((data_array[index - 1] == '\n') ||
                    (data_array[index - 1] == '\r') ||
                    (index >= m_ble_nus_max_data_len))
                {
                    if (index > 1)
                    {
                        NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                        NRF_LOG_HEXDUMP_DEBUG(data_array, index);
    
                        do
                        {
                            uint16_t length = (uint16_t)index;
                            err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
                            if ((err_code != NRF_ERROR_INVALID_STATE) &&
                                (err_code != NRF_ERROR_RESOURCES) &&
                                (err_code != NRF_ERROR_NOT_FOUND))
                            {
                                APP_ERROR_CHECK(err_code);
                            }
                        } while (err_code == NRF_ERROR_RESOURCES);
                    }
    
                    index = 0;
                }
                break;

    if the phone does only support 20 bytes MTU, then 

    m_ble_nus_max_data_len is 20, and the data you try to send will be split into chunks, where each chunk is max 20 bytes.
  • Hi Sigurd,

    Thank you for your reply. 

    i also see that in the gatt_evt_handler() the management of the MTU size should also update the m_ble_nus_max_data_len value. But it doesn't look to work:

    /**@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);
        }
        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);
    }

    I understand this piece of code should work, isn't it?

    Regards,

    Joel

  • Hi,

    Default value of m_ble_nus_max_data_len is 20. If there is an MTU update, the m_ble_nus_max_data_len will be updated in gatt_evt_handler() to reflect the new MTU value.

  • Hi,

    I have tested this using the Android nRF Connect app. I have the m_ble_nus_max_data_len  variable set to 20 in the nRF SDK. In nRFConnect Android app I do the next sequence:

    - I connect to the Nordic UART Service of the Dk board program.

    - I open the tab of this service. In the tab, I select Connect.

    - I select the "Nordic UART Service" and the app presents the RX Characteristics values and the TX Characteristics values.

    - I push the icon in the "Tx Characteristics". I understand that this will enable the reception of notifications.

    - I push the icon in the "Rx Characteristics". It opens a window to write a command to my FW. I send it.

    - The DK sends an answer that should be greater than 20 bytes. However, I can only receive 20 bytes and I the app doesn't receive more packets of 20 bytes.

    How could enable the automatic sending of the rest of the packet from the DK to the nRFConnect app?

    Regards,

    Joel

Related