Question for C only, C++ and vectors do not solve problem.
I have such structure:
typedef __packed struct Packet_s
{
U8 head;
U16 len;
U32 id;
U
You should split your processing function into two distinct functions:
One which will discard everything until it finds the head
byte. This byte usually is a constant byte, marking the start of a packet. This is done this way, in order to avoid start to read in the middle of a previously sent packet (think i.e. the startup order of the sender and the listener devices).
Once it finds the start of the packet, it can read the header, len
and id
and receive all the data storing it into your Buffer
variable, until it reads the end
byte or there is a buffer overflow, in which case it would just discard the data and start again.
NOTE that into the Buffer variable only should be written the actual data. All the other fields (len, id and so) can be stored in different variables, or in a struct containing only the Packet information
, but no data. This way, you spit the application data from the transmission information.
Note also that this function does not interpret the id
field, nor the data
field. It just sends this information to the other funciton, which will do the processing or discard if the id
or the data
are not correct / known.
Once the end
byte is found, you can pass the information to the actual processing
function. Its header would be something like:
void processPacket(U8 *data, U32 id, U16 len);
and the call to it would be:
void receiveFrame() {
//Receive head
//Receive id
//Receive len
//Fill in Buffer with the actual data
//Call the processPacket function
processPacket(&Buffer[0], id, len);
}
A more complete example could be:
//It is not packet, since you fill it reading from the buffer and assigning
//to it, not casting the buffer into it.
//It has no data field. The data is in a different variable.
typedef struct Packet_s
{
U8 head;
U16 len;
U32 id;
U8 end;
U16 crc;
} PacketInfo_t;
U8 Buffer[MAX_BUFFER_SIZE];
PacketInfo_t info;
void receiveFrame() {
info.head=//Receive head
info.len=//Receive len
info.id=//Receive id
//Fill the buffer variable
processPacket(&Buffer[0], &info);
}
void processPacket(U8 *data, PacketInfo_t *info);
For sending, just use the same format:
void sendPacket(U8 *data, PacketInfo_t *info);
This function sould prepare the Packet header from info
and read the data from data
.
And finally, a word of caution: casting (or memcpy) a received packet directly into a struct is almost never a good idea. You have to take into account not only the zero holes (using the __packet attribute), but also the endianness and the data format representation of the sender and receiver systems, since if they are different, you would end up with the wrong values.