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

Unable to receive full data over BLE

I am trying to receive a string of 708 characters via BLE. As BLE cap a maximum of 20 bytes per transmission, at the mobile app side I break the data to be send every 20 characters (each char is 1 byte as < 7F). The code at Nordic to receive the data is as follows:

uint8_t *buf = NULL;
size_t total_len = 0;
.
.
.
case BLE_GATTS_EVT_WRITE:
{ 
            ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
            size_t len = p_evt_write->len;
            buf = realloc(buf, total_len + len);
        	memcpy(buf + total_len, p_evt_write->data, len); 	
        	total_len += len;
        	SEGGER_RTT_printf(0, "current concatenated str: %s \n", buf);
        	SEGGER_RTT_printf(0, "total_len: %d \n", total_len);
        	if((p_evt_write->data[len-2] == 123) && (p_evt_write->data[len-1] == 123)){
        		 char* strall= malloc(total_len + 1);
        		 memcpy(strall, buf, total_len);
        		 strall[total_len] = 0;
        		 SEGGER_RTT_printf(0, "whole string is: %s \n", strall);
        		 total_len = 0;		
        	}

}

After receiving each round of characters, I concatenate it together to form back the original string. However, I am able to receive up till 429th character before it stops concatenating anymore new data. The 'buf' string either prints 0-429th characters then concatenate with some characters that was already previously received, or it just keep printing 0-429th character repeatedly even when new data is received (total_len keeps increasing till 708).

Why is this the case? Is there anything preventing Nordic from receiving the whole data? I will need to receive and concatenate all the characters.

Parents Reply Children
  • May i know what you mean by global static 1kb buffer? I tried changing declaration to 'uint8_t buf[1000]' but it is still not working even after I removed all malloc/realloc.

  • Yes, I mean static uint8_t buf[1000] at the beginning of your main.c file instead of uint8_t *buf = NULL;. You can set it by memset once after the boot. Also your strall buffer would need similar treatment, but to be honest I don't know why you just don't cast and use reference to buf instead of making another large buffer. Finally I don't see how you get the data to the buffer and why there is this magic condition with 123 but I trust you know what to do there. Oh and one more: why you use size_t and not some reasonable integer like uint32_t for indexes and lengths? Maybe cosmetics, maybe not (depending on how size_t gets recognized during linking after pre-processing all the macros and defines...)

    Maybe I will sound snobbish now but ARM Cortex-M isn't windows machine with x64 core and unlimited resources, coding it like C++ on Win isn't the best idea.

  • Thank you for the help. I tried what you suggested and is still encountering the same error. I made another strall buffer as I intend to manipulate the data received from BLE, and I am afraid there may be new data coming in when I am dealing with the original packet (resulting in strall to be the new data instead of the original one). As for the condition 123, the sending party put that as the indication of the end of the packet, hence in Nordic I am checking for it to know whether it receives the whole data. I changed size_t to uint32_t as well.

  • Oh then I'm sorry that I've promised quick fix, it looks like some deeper bug completely unrelated to the way how you store/handle bytes in this part of your code. Are you sure that if you perform single connection and single transfer that the issue persists and it's exactly at the 430th character regardless of buffer allocation method (static or dynamic)? This would be very very strange.

  • I changed the data to transmit over, which now consist of 536 characters. Currently, up till total_len of 480, Nordic is able to receive all of the data at buf and print out at SEGGER_RTT. But once it receives the next round of data (total_len of 500), printing buf will only contain the data up till 429th character. Subsequently, buf will always print out 0-429th character only. This is really strange, as it did managed to receive more than 429 previously and stored in buf, but all of a sudden those data disappear and only 0-429th characters remain. This happens for both static and dynamic buffer allocation.

Related