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

Missing BLE_GATTS_EVT_HVN_TX_COMPLETE events

I can't comment in  https://devzone.nordicsemi.com/f/nordic-q-a/56685/missing-ble_gatts_evt_hvn_tx_complete-events as it is closed but I am also seeing issues with the TX_COMPLETE event. Please keep me informed of progress.

I use a fifo to push handles as I transmit and a pop on TX_COMPLETE.  This fifo is filling at times (perhaps when bt connection is poor).

nrf52832 / sdk15.3 / softdevice6.1.1

    ret_code_t err_code = BLE_ERROR_GATTS_SYS_ATTR_MISSING;
    uint8_t retry_count = 0;
    while(err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING && retry_count++ < 10) {
        err_code = sd_ble_gatts_hvx(m_conn_handle, &hvx_params);
        if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) {
            nrf_delay_ms(50);
        }
    }
    if (err_code == NRF_SUCCESS) {
        // push the handle of the characteristic so we can pop it in the txdone callback
        uint32_t write_count = sizeof(cccd_handle);
        ret_code_t err_code2 = app_fifo_write(&m_tx_fifo,
                                              (uint8_t*) &cccd_handle,
                                              &write_count);
        if (err_code2 != NRF_SUCCESS) {
            // debug for https://github.com/ProxxiTech/proxxiband-fw-nrf52/issues/166
            // and https://github.com/ProxxiTech/proxxiband-fw-nrf52/issues/104
            prx_error_handler_metadata_t metadata;
            metadata.u16[0] = m_tx_fifo.read_pos;
            metadata.u16[1] = m_tx_fifo.write_pos;
            metadata.u16[2] = m_tx_fifo.buf_size_mask;
            prx_error_handler_set_metadata(&metadata);
        }

        APP_ERROR_CHECK(err_code2);
        APP_ERROR_CHECK_BOOL(write_count == sizeof(cccd_handle));
    }

        case BLE_GATTS_EVT_HVN_TX_COMPLETE:
        {
            for (uint32_t count = 0; count < p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; count++) {
                uint16_t handle = 0; 
                uint32_t size = sizeof(handle);
                ret_code_t err_code = app_fifo_read(&m_tx_fifo,
                                                    (uint8_t*) &handle,
                                                    &size);
                APP_ERROR_CHECK(err_code);
                APP_ERROR_CHECK_BOOL(size == sizeof(handle));
                ble_ems_char_t* p_char = ble_ems_get_characteristic(handle);
                if (p_char != NULL) {
                    ble_ems_on_tx_complete(p_char);
                }
            }
        }

I asked to have the handles returned from the callback over a year ago, this would be so much easier.

https://devzone.nordicsemi.com/f/nordic-q-a/37979/identifying-the-source-of-a-callback-defined-with-nrf_sdh_ble_observer

Parents Reply Children
  • Hi Tom

    It sounds strange that 32 entries would be insufficient. 

    I don't think there is an API for reading out the buffer size, but I will double check with the team. 

    A naive way to test it is simply to upload dummy packets in a loop until the NRF_ERROR_RESOURCES error is returned, and count how many packets you are able to upload before that. As long as the buffer is filled before the stack has time to send any of them (and receive an ACK) that should show how many packets you can queue up at a time. 

    Best regards
    Torbjørn

  • Hi Torbjørn,

    I have multiple characteristics that send data so it is hard for me to send until I see NRF_ERROR_RESOURCES all the time as they starve each other of the chance to transmit.  If I can read the queue water mark dynamically I can ensure low priority characteristics don't starve high priority ones by ensuring there is always some space in the queue.

    It is a pity that so many of you examples are so simple with just one characterstic.  eg. I can't use the ble uart because it assumes it is the only transmitter and asssumes that it generated every BLE_GATTS_EVT_HVN_TX_COMPLETE event.

    Thanks.
    Tom

  • Hi Torbjørn,

    I think you can close this. 

    We were not flushing the fifo when we received BLE_GAP_EVT_DISCONNECTED.  This is important advice to give to people.  If you're transmitting when a connection drops then you'll have a whole bunch of packets in the queue that (I'm presuming) the softdevice will discard.  You'll never get BLE_GATTS_EVT_HVN_TX_COMPLETE for those packets so the fifo will leak.

    There might be more to this but I think I've found the main issue so please close this.

    Thanks,
    Tom

  • Hi Tom

    Thanks for the update, that explains why you will see an overflow even if you have 32 entries in the FIFO. 

    TomKeddie said:
    If I can read the queue water mark dynamically I can ensure low priority characteristics don't starve high priority ones by ensuring there is always some space in the queue.

    I think the best workaround here is to upload data freely until the NRF_ERROR_RESOURCES error occurs, wait for the BLE_GATTS_EVT_HVN_TX_COMPLETE event, and then check in with your higher priority characteristics first before you service the low priority ones. 

    If you need to maximize bandwidth while allocating a different percentage of the bandwidth to each characteristic you probably need some layer in between the Bluetooth stack and the characteristic updates to handle this prioritization. 

    Best regards
    Torbjørn

Related