I am attempting to code a driver for RF Beam K-MD2 communication. This is my first time working with sockets so bear with me. See the pictures below to see the command and message format of the packets. These are taken directly from the datasheet.
Message Layout 1
Message Layout 2
One of the biggest problems I am having is that the message breakdown changes datatypes throughout the messages sent from the radar. Currently I am able to read the first header and the payload length message after it but then I do not know how to proceed. Should I read the payload length and then perform a loop corresponding to that integer value or do I just proceed until my read function returns 0? See my current code below and thanks for your time!
MY READ FUNCTION
void ReadHeaderPayload(int socket, void* header, int *num)
{
uint32_t payloadLen;
uint32_t uret32;
uint16_t uret16;
int left = sizeof(uret32);
char *readPayloadLen = (char *)&payloadLen;
char *readUint32 = (char *)&uret32;
char *readUInt16 = (char *)&uret16;
readReturn = read(socket, header, 4);
if (readReturn < 0) printf ("Error on First Read");
printf("
Header value %s
", header);
readReturn = read(socket, &payloadLen, sizeof(payloadLen+1));
printf("
Payload Length value %d
", payloadLen);
printf("
Payload Data Type Length %d
", sizeof(payloadLen));
// if (readReturn < 0) printf ("Error on PayloadLength Read");
// do
// {
// readReturn = read(socket, readPayloadLen, left);
// if (readReturn < 0) printf ("Error on PayloadLength Read");
// else
// {
// readPayloadLen += readReturn;
// left -= readReturn;
// }
// }
// while (left > 0);
// *num = uret32;
// printf("
Payload Length value %d
", *num);
}
I have commented out some code that I have built off other stuff I have seen on stack overflow that uses the do while loop to read the data until the end of the packet BUT every time I ran it I was getting segmentation faults. If anyone knows why this is happening I would greatly appreciate some insight.
MY MAIN CODE:
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
unsigned int length = 0;
char* buffer3 = 0;
int *payloadlength = 0;
char header[256];
char buffer[256];
char buffer2[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port
", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
printf("
argv[1] hostname %s
argv[2] port number %s
", argv[1], argv[2]);
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host
");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
if (inet_pton(AF_INET, "MYIP", &serv_addr.sin_addr)<=0) //converts IPv4 addresses from text to binary
{
printf("
Invalid address or address not supported ");
return -1;
}
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR connecting");
//Connection Ready, Time to read stuff from the Radar
bzero(header,256); //Empty All Arrays
bzero(buffer,256);
bzero(buffer2,256);
// ReadHeader(sockfd, header);
ReadHeaderPayload(sockfd, header, payloadlength);
// ReadAllDataToFile(sockfd);
return 0;
}
I was attempting to make a function that has a switch case structure to deal with each message from the radar (I.E RADC is its own case, RMRD is its own case so each different data type can be dealt with in each case). I was still able to get RADC and the payload length but was reading only 0's from the rest of the message.
switch (case_increment)
{
case 1:
{ //RADC, Raw ADC values 786432 Length
readReturn = read(socket, header, 4); //Header Readout
if (readReturn < 0) errorCount++;
readReturn = read(socket, &payloadlength, sizeof(payloadlength+1)); //Payload Length Readout
if (readReturn < 0) errorCount++;
fprintf(fptr,"
HEADER: %s
PAYLOAD LENGTH: %d
", header, payloadlength);
uint16_t RADCPL[payloadlength] = {0};
for (i=0; i<payloadlength; i++ )
{
readReturn = read(socket, &RADCPL[i],sizeof(u16));
iterations++;
if (readReturn < 0 )
{
errorCount++;
printf("Error Count %d
", errorCount);
fclose(fptr);
return 1;
}
fprintf(fptr,"%d
", RADCPL[i]);
}
readReturn = read(socket, header2, 4); //Header Readout
if (readReturn < 0 )
{
errorCount++;
printf("Error Count %d
", errorCount);
fclose(fptr);
return 1;
}
printf("Header 2 : %s
", header2);
}break;
default:
printf("
Default Case
");
}
fclose(fptr);
printf("
Error Count %d
", errorCount);
return 0;
}
This currently is giving me data (not sure if its good or not) in my TEST_DATA.txt for 786432 points (as listed as the first payload on the datasheet) but when I try to get to get the next header file afterwards I get ?? on my printf which appears to be an issue with reading a binary as a char.
Thanks in advance!