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

  • Hi Tom

    The problem in the case you refer to was eventually traced down to a bug in the application code, not a problem with the SoftDevice. 

    I would be surprised if a bug of this magnitude would still remain in the SoftDevice, now that it has been used in countless designs by a variety of customers, but we will obviously help you investigate the issues you are experiencing. 

    As for returning the handles the Bluetooth link layer is implemented as a strict FIFO, and the method of pushing the handles to a FIFO and reading them back like you do should work fine. 

    What is the size of your FIFO?

    Best regards
    Torbjørn

  • Hi Torbjørn, thanks I would agree it would be surprising but the timer bug (https://devzone.nordicsemi.com/f/nordic-q-a/47742/app_timer2-timer-list-corruption-seen-on-rtc-overflow) I found recently was also surprising so I'm keeping an open mind.

    My fifo is 32 entries long.  I've verified it is full using the read and write pointers.  The problem is very hard to reproduce, seems to be related to poor connection quality.

    Is there an api that would let me read the free space in the tx buffer?

    Thanks,
    Tom

  • 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

Related