nRF52832 using QUEUE to store data while disconnected

Dear all,

I've been adjusting BLE data sending mode to increase BLE throughput but have some problem using queue.

Here are some basic ideas of my development:

  1. Keep pushing data into queue whether BLE is connected or not
  2. Pop out data and send it while BLE is connected
  3. Queue size is set to hold 10 seconds data to prevent data loss caused by unstable connection

The problem occurs on No.3, when disconnected, system is keep pushing data into queue. However, when reconnected, the popped data seems discontinuous. For example, if I disconnect BLE at the third second and reconnect at the tenth second to keep receiving data, data should be start from the fourth second. But the truth is, data starts from the tenth second. It behaves like a small queue in overflow mode.

My code is attached as follow:

  • Queue initiate:

typedef struct {
    uint8_t * p_data;
    uint16_t length;
} buffer_t;

NRF_QUEUE_DEF(buffer_t, m_buf_queue, 80, NRF_QUEUE_MODE_NO_OVERFLOW);

  • Queue sending function, placed in 50ms interval timer handler:

void ble_data_send_with_queue(void)
{
	static buffer_t m_buf;
	uint32_t err_code;
	uint16_t length = 0;
	static bool retry = false;

	
	if(retry)
	{
		length = m_buf.length;
		err_code = ble_nus_data_send(&m_nus, m_buf.p_data, &length, m_conn_handle);
		if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_RESOURCES) &&
				 (err_code != NRF_ERROR_NOT_FOUND) )
		{

		}
		if (err_code == NRF_SUCCESS)
		{
			retry = false;
		}
	}
	

	while(!nrf_queue_is_empty(&m_buf_queue) && !retry)
	{
		err_code = nrf_queue_pop(&m_buf_queue, &m_buf);
		APP_ERROR_CHECK(err_code);		
		length = m_buf.length;
					
		err_code = ble_nus_data_send(&m_nus, m_buf.p_data, &length, m_conn_handle);

		if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_RESOURCES) &&
				 (err_code != NRF_ERROR_NOT_FOUND) )
		{

		}
		if (err_code == NRF_SUCCESS)
		{
			retry = false;
		}
		else
		{
			retry = true;
			break;
		}

	}			
}

  • data push to queue in main loop, interval is around 120ms,data length is 139:

buffer_t buf;
					
buf.length = 139;
buf.p_data = data_pack;
nrf_queue_push(&m_buf_queue, &buf);
					

But I'm not quite sure which section goes wrong. Your suggestion is appreciated.

Best regards,

Ava

Parents Reply Children
  • Sorry to be the bearer of bad news, but we find that a data packet sent via ble_nus_data_send() is silently discarded (flushed) if the BLE connection drops before the packet has completed transmission. This can be clearly seen by streaming packets and having repeated disconnect/connect events (shield antenna with hand) where the number of lost packets corresponds to the number of disconnect/connect events.

    This means any front-end queue can't just buffer packets to be sent, it must also check whether the packet was sent, typically by having a response from Central saying (for example) last contiguous packet number received a bit like TCP/IP. A second option is to add code in the delete/discard code that reports back that a packet delivered to ble_nus_data_send() was discarded due to such a disconnect.

Related