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

MAX MTU Size using Serialization SDK 17.0.2

We are using NRF52832 with STM32L4A6 using serialization.  We have the serialization working properly, but having an issue with the MAX MTU size.  We can set the NRF_SDH_BLE_GATT_MAX_MTU_SIZE between 23 to 48 and serialization works fine.  When we increase to 49 or later, the serialization hangs.  Further investigation shows that in the on_connected_evt method, calling sd_ble_gattc_exchange_mtu_request method ultimately calls the ser_phy_tx_pkt_send which checks for the mp_tx_buffer and this buffer pointer is not NULL.  Our guess is that previous serialization call did not complete properly (thus does not reset the mp_tx_buffer).  It seems very odd that changing the NRF_SDH_BLE_GATT_MAX_MTU_SIZE causes the serialization issue.

In the SDK17.0.2 example project, ble_peripheral | ble_app_hrs | pca10040 | SER_132_spi, we noticed that the NRF_SDH_BLE_GATT_MAX_MTU_SIZE is set to 23.  However, in the non serialized example of the ble peripheral, the NRF_SDH_BLE_GATT_MAX_MTU_SIZE is set to 247 and works properly.  The NRF_SDH_BLE_GAP_DATA_LENGTH is set to 27.

Has anyone had success setting the NRF_SDH_BLE_GATT_MAX_MTU_SIZE to larger than 48 using the serialization?  If so, what was the test setup and the values for the NRF_SDH_BLE_GATT_MAX_MTU_SIZE.

We are using SDK 17.0.2 with softdevice s132_nrf52_7.2.0 on PCA10040 as connectivity module.

  • Hi,

    Has anyone had success setting the NRF_SDH_BLE_GATT_MAX_MTU_SIZE to larger than 48 using the serialization?  If so, what was the test setup and the values for the NRF_SDH_BLE_GATT_MAX_MTU_SIZE.

    In pc-ble-driver we use a (slightly modified) version of the connectivity fw from the nRF5-SDK, and here we set NRF_SDH_BLE_GATT_MAX_MTU_SIZE to 250. We use UART and not SPI though, but I have not seen any issues like you describe before.

    We are using SDK 17.0.2 with softdevice s132_nrf52_7.2.0 on PCA10040 as connectivity module.

    Are you the peripheral or the central? What BLE device are in a BLE connection with? Have you tried connecting to other devices?

    Our guess is that previous serialization call did not complete properly (thus does not reset the mp_tx_buffer).

     Do you know what previous serialization call was ?

    Note that there are often a lot BLE events happening right after you connect. Could you try to delay the call to sd_ble_gattc_exchange_mtu_request(), and see if that have any impact?

  • Nordic is BLE Peripheral and communicating with iOS and Android as BLE Central.  iOS and Android both have the same issue.  I was trying to debug what was the previous serialization call was but it is really hard to debug it.  I can try to add some delay, but my guess is that it won't help.  I set a break point on on_connected_evt and step through the calls and and it hangs due to mp_tx_buffer not being NULL.  For NRF_SDH_BLE_GATT_MAX_MTU_SIZE of 23, it does not hang (mp_tx_buffer is NULL).  I see that pc-ble-driver example softdevice is not the same as what we are using s132_nrf52_7.2.0.  Not sure if I can use it as is.

    We will be getting two PCA10040 soon, so I will use the examples from SDK 17.0.2 from ble_peripheral | ble_app_hrs | pca10040 | SER_132_spi and see if we can get NRF_SDH_BLE_GATT_MAX_MTU_SIZE larger than 23 consistently only using the Nordic code.  Has anyone already tried using SDK 17.0.2 using s132_nrf52_7.2.0 to see if serialization works for NRF_SDH_BLE_GATT_MAX_MTU_SIZE greater than 23?

  • jkim said:
    mp_tx_buffer not being NULL

     But does ser_phy_tx_pkt_send() not return NRF_ERROR_BUSY in this case?

    uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
    {
        uint32_t status = NRF_SUCCESS;
    
        if ( p_buffer == NULL || num_of_bytes == 0)
        {
            return NRF_ERROR_NULL;
        }
    
        ser_phy_interrupts_disable();
    
        if ( m_p_tx_buffer == NULL)
        {
            m_tx_packet_length = num_of_bytes;
            m_p_tx_buffer      = p_buffer;
            set_request_line();
        }
        else
        {
            status = NRF_ERROR_BUSY;
        }
        ser_phy_interrupts_enable();
    
        return status;
    }

  • Yes.  It does return NRF_ERROR_BUSY.  However, in the, APP_ERROR_CHECK(err_code), our implementation does not handle the NRF_ERROR_BUSY.  Also, ser_sd_transport_cmd_write does not appear to handle the retry.  Is this correct assessment?

    uint32_t ser_sd_transport_cmd_write(const uint8_t * p_buffer,
    uint16_t length,
    ser_sd_transport_rsp_handler_t cmd_rsp_decode_callback)
    {
    uint32_t err_code = NRF_SUCCESS;

    m_rsp_wait = true;
    m_rsp_dec_handler = cmd_rsp_decode_callback;
    err_code = ser_hal_transport_tx_pkt_send(p_buffer, length);
    APP_ERROR_CHECK(err_code);

    /* Execute callback for response decoding only if one was provided.*/
    if ((err_code == NRF_SUCCESS) && cmd_rsp_decode_callback)
    {
    if (m_ot_rsp_wait_handler)
    {
    m_ot_rsp_wait_handler();
    m_ot_rsp_wait_handler = NULL;
    }

    m_os_rsp_wait_handler();
    err_code = m_return_value;
    }
    else
    {
    m_rsp_wait = false;
    }

    NRF_LOG_DEBUG("[SD_CALL]:%s, err_code= 0x%X", (uint32_t)ser_dbg_sd_call_str_get(p_buffer[1]), err_code);
    return err_code;
    }

  • It appears that adding 250ms delay before calling sd_ble_gattc_exchange_mtu_request in on_connected_evt helps with the m_p_tx_buffer != NULL issue.  We can change the logic regarding the APP_ERROR_CHECK implementation to not to generate exception on NRF_ERROR_BUSY and allow retry logic to work.

    I now have related issue that I mentioned earlier.  With the NRF_SDH_BLE_GATT_MAX_MTU_SIZE set to 83 (43 appears OK), I now get the following error:

    In tx_buf_alloc, calling ser_hal_transport_tx_pkt_alloc returns err_code of NRF_ERROR_NO_MEM because the m_tx_state is set to 28 (which is invalid), thus results in NRF_ERROR_NO_MEM.  We do have quite a few characteristics, but as far as I know, I did not get NRF_ERROR_NO_MEM when creating the characteristics (I can double check).  What conditions will result in NRF_ERROR_NO_MEM when calling ser_hal_transport_tx_pkt_alloc?  I could not see where m_tx_state set to invalid value of 28.

    uint32_t _sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle,
    uint16_t client_rx_mtu)
    {
    uint8_t * p_buffer;
    uint32_t buffer_length = 0;

    tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);

    const uint32_t err_code = ble_gattc_exchange_mtu_request_req_enc(conn_handle,
    client_rx_mtu,
    &(p_buffer[1]),
    &buffer_length);
    APP_ERROR_CHECK(err_code);

    //@note: Increment buffer length as internally managed packet type field must be included.
    return ser_sd_transport_cmd_write(p_buffer,
    (++buffer_length),
    gattc_exchange_mtu_request_rsp_dec);
    }

Related