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

How BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event works ?

Hi,

I was testing the BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and I did trigger the event but i was wondering if that it's normal that It triggers after I send all my packets instead of triggering after one packet. 

That's my logs : 

<info> app: packet sent
<info> app: packet sent
<info> app: packet sent
<info> app: packet sent
<info> app: Buffer empty
<info> app: Buffer empty
<info> app: Buffer empty
<info> app: Buffer empty

For information the version of my SDK is nRF5_SDK_17.0.2_d674dde
And I put the event in the void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)

Here is my code : 

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint16_t index = 0;
    uint32_t ret_val;
	static uint16_t length = 120;
	static uint8_t send_data[BLE_NUS_MAX_DATA_LEN];

    for (uint8_t i=0; i<length; i++)
	{
		send_data[i]=i;
	}


    switch (p_event->evt_type)
    {
        /**@snippet [Handling data from UART] */
        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)))
            {
                NRF_LOG_INFO("Ready to send data over BLE NUS");
                NRF_LOG_HEXDUMP_INFO(data_array, index);
				
                do
                {
					for (uint8_t i; i<4; i++)
                    {
						if (ret_val == NRF_ERROR_RESOURCES)
						{
							buf_busy = true;
						}

						if(buf_busy == false)
						{
							ret_val = ble_nus_c_string_send(&m_ble_nus_c, send_data, length);
							NRF_LOG_INFO("packet sent");
						}

                            
					}
					
					

                    if ( (ret_val != NRF_ERROR_INVALID_STATE) && (ret_val != NRF_ERROR_RESOURCES) )
                    {
                        APP_ERROR_CHECK(ret_val);
                    }
                } while (ret_val == NRF_ERROR_RESOURCES);

                index = 0;
            }
            break;

        /**@snippet [Handling data from UART] */
        case APP_UART_COMMUNICATION_ERROR:
            NRF_LOG_ERROR("Communication error occurred while handling UART.");
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:
            NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        default:
            break;
    }
}
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t            err_code;
    ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
            APP_ERROR_CHECK(err_code);

            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);

            // start discovery of services. The NUS Client waits for a discovery result
            err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GAP_EVT_DISCONNECTED:

            NRF_LOG_INFO("Disconnected. conn_handle: 0x%x, reason: 0x%x",
                         p_gap_evt->conn_handle,
                         p_gap_evt->params.disconnected.reason);
            break;

        case BLE_GAP_EVT_TIMEOUT:
            if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
            {
                NRF_LOG_INFO("Connection Request timed out.");
            }
            break;

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            // Pairing not supported.
            err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
            // Accepting parameters requested by peer.
            err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                                    &p_gap_evt->params.conn_param_update_request.conn_params);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            NRF_LOG_INFO("PHY update request.");
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        } break;

        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            NRF_LOG_INFO("GATT Client Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            NRF_LOG_INFO("GATT Server Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;
		case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
			NRF_LOG_INFO("Buffer empty");
			buf_busy = false;
			break;

        default:
            break;
    }
}

Parents
  • Hi,

    Seems to me you are printing: "<info> app: packet sent" when you place the packet in the tx buffer. This can be done at any time as long as there are available tx buffers. So in this case you are placing all 4 packets in the tx buffer before you manage to send one.

    ble_gattc_evt_write_cmd_tx_complete_t is not triggered until the buffer is freed, i.e. the packet has been acked at the link layer. Notice that there is a count there telling you how many buffers has been freed. So you might not get 4 events even if you transmit 4 packets.

Reply
  • Hi,

    Seems to me you are printing: "<info> app: packet sent" when you place the packet in the tx buffer. This can be done at any time as long as there are available tx buffers. So in this case you are placing all 4 packets in the tx buffer before you manage to send one.

    ble_gattc_evt_write_cmd_tx_complete_t is not triggered until the buffer is freed, i.e. the packet has been acked at the link layer. Notice that there is a count there telling you how many buffers has been freed. So you might not get 4 events even if you transmit 4 packets.

Children
Related