Search code examples
c++gpsserial-portuart

parsing complete messages from serial port


I am trying to read complete messages from my GPS via serial port.

The message I am looking for starts with:

0xB5 0x62 0x02 0x13

So I read from the serial port like so

while (running !=0)
{

int n = read (fd, input_buffer, sizeof input_buffer); 


for (int i=0; i<BUFFER_SIZE; i++)
{   



if (input_buffer[i]==0xB5  && input_buffer[i+1]== 0x62 && input_buffer[i+2]== 0x02 && input_buffer[i+3]== 0x13    && i<(BUFFER_SIZE-1) )
     { 

            // process the message.
     }

}

The problem I am having is that I need to get a complete message. Half of a message could be in the buffer one iteration. And the other half could come into the message the next iteration.

Somebody suggested that free the buffer up from the complete message. And then I move the rest of data in the buffer to the beginning of the buffer.

How do I do that or any other way that make sure I get every complete selected message that comes in?

edit// enter image description here

I want a particular class and ID. But I can also read in the length


Solution

  • You can break the read into three parts. Find the start of a message. Then get the LENGTH. Then read the rest of the message.

    // Should probably clear these in case data left over from a previous read
    input_buffer[0] = input_buffer[1] = 0;
    
    // First make sure first char is 0xB5
    do {
        n = read(fd, input_buffer, 1); 
    } while (0xB5 != input_buffer[0]);
    
    // Check for 2nd sync char
    n = read(fd, &input_buffer[1], 1);
    
    if (input_buffer[1] != 0x62) {
         // Error
         return;
    }
    
    // Read up to LENGTH
    n = read(fd, &input_buffer[2], 4); 
    
    // Parse length
    //int length = *((int *)&input_buffer[4]);
    // Since I don't know what size an int is on your system, this way is better
    int length = input_buffer[4] | (input_buffer[5] << 8);
    
    // Read rest of message
    n = read(fd, &input_buffer[6], length);
    
    // input_buffer should now have a complete message
    

    You should add error checking...