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

Lost packet on RX (Central->Device)

Hi,

When working with Windows 10 laptop BLE we get sometimes a lost packet occurrence from Central (PC) to our BLE device.

We are using a Python Bleak based app on the Windows side. Our device is nRF52840 based.

Attached is a sniffer trace caught in WireShark, using the BLE Sniffer addin. We detected the lost packet using an Index/CRC mechanism in the payload. Device did not receive index 15306, but in the sniffer we can see it line No. 201659, payload begins with 0x34C2 (15306 decimal).

PC laptop model is Dell 7490.

lost_packet_15306.zip

Parents Reply Children
  • I think you just need to look at the handling of BLE_GATTS_EVT_WRITE events, maybe add some debug information to see it it's possible you receive the BLE_GATTS_EVT_WRITE event but you somehow don't buffer/handle the received data in your application.

    Kenneth

  • Hi Kenneth,

    Update - after changing implementation on SPI bus handling from polling to interrupt-driven, still issue persists. We thought it might be related to a performance issue due to SPI handling.

    the on_write() handle is as follow. you can see we check CRC and index as part of our protocol over the BLE write, and we get the index error here. I added logging in the blocks which are ot the main block to see if we get in there by mistake, but we don't.

    Note: we are not using an OS. I thought of moving the BLE write handling to the main loop, but still, how will the Central be informed to "wait"?

    Question: how can we use the BLE write-with-response? I think we might use this to have a belter ACK mechanism, on each BLE write packet.

    Thanks!

    static void on_write(ble_am_t *p_am, ble_evt_t const *p_ble_evt)
    {
    ble_gatts_evt_write_t const *p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    ble_am_evt_t event = {.p_am = p_am};
    p_am->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;

    // INFO Handle CCCD write (subscribe) for data_out_handle
    if ((p_evt_write->handle == p_am->data_out_handle.cccd_handle) && (p_evt_write->len == 2)) {
    nrfx_atomic_u32_store(&m_index_tx, 0);
    on_generic_sessions_cccd_write(p_am, p_evt_write, BLE_AM_EVENT_DATA_OUT_NOTIFICATION_STARTED,
    BLE_AM_EVENT_DATA_OUT_NOTIFICATION_STOPPED, &m_notify.data_out);
    NRF_LOG_INFO("here 1");

    // INFO Handle write for data_in_handle
    } else if ((p_evt_write->handle == p_am->data_in_handle.value_handle) && (p_evt_write->len > 0)) {

    uint32_t rec_index = uint32_decode(p_evt_write->data);

    if (rec_index != rx_index)
    NRF_LOG_INFO("BLE index error! rec_index: %d, %d",rec_index, rx_index);

    rx_index++;

    uint32_t calc_crc = crc32_compute(p_evt_write->data, p_evt_write->len - sizeof(uint32_t), NULL);

    uint32_t rec_crc = uint32_decode(p_evt_write->data + p_evt_write->len - sizeof(uint32_t));
    if (rec_crc != calc_crc)
    NRF_LOG_INFO("BLE CRC error! cal_crc: 0x%x, 0x%x",calc_crc,rec_crc);

    event.type = BLE_AM_EVENT_DATA_IN_WRITE;
    event.params.p_data = (uint8_t *)p_evt_write->data + sizeof(uint32_t);
    event.params.data_len = p_evt_write->len - sizeof(uint32_t) - sizeof(uint32_t);
    //ble_write_ev = event;
    p_am->event_handler(&event, NULL);

    } else {
    NRF_LOG_INFO("here 2");
    NRFX_LOG_WARNING("%s unknown CCCD (0x%x)", __func__, p_evt_write->handle);
    }
    }

Related