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

  • Hi,

    The elements you are queueing are of your type buffer_t, and that only hold a pointer to the data, not the data itself. So the data is still located in whatever location they were originally, and which I assume is overwritten. I assume you want to queue the actual data, not just the pointers to where it was at the time. So your buffer_t needs to contain an array which should hold  the data.

  • Hi Einar,

    Thanks for your analyze and this must be the root cause!

    I'll try it out and get back to you later. Thanks!

    Best regard,

    Ava

  • 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