Skip to content
Snippets Groups Projects
Unverified Commit c9879e71 authored by Jake's avatar Jake
Browse files

Restructured packet and command parsing

Prepared for parsing the new data formats. Data isn't formatted
or parsed yet, though.

No more memory leaks! Unfortunately each memory leak was replaced
by a potential buffer overflow. Basically, the code was riddled
with functions that accept a char ** data, which
is malloced and then formatted. This was then leaked.
Now, it accepts a char * data, which is allocated on the stack
by the calling function. However, there is no bounds checking,
because that is slightly more involved.
parent e2292305
No related branches found
No related tags found
No related merge requests found
......@@ -616,8 +616,9 @@ static void client_recv(int fd) {
buffer[newline] = '\0';
printf("Client(%d) : '%s'\n",fd, buffer);
unsigned char * packet;
if(formatCommand(buffer, &packet) == -1) {
unsigned char packet[1024];
ssize_t packetSize;
if((packetSize = formatCommand(buffer, packet)) == -1) {
/* buffer was not a quad command, handling internally to
* backend instead of forwarding to quad
*/
......@@ -658,13 +659,14 @@ static void client_recv(int fd) {
}
}
/* Don't know about this */
int datalen = (packet[6] << 8) | (packet[5]);
printf("sending %lf '", getFloat(packet, 7));
for(int i = 0; i < datalen + 8; ++i) {
printf(" 0x%.2x", (signed) packet[i]);
}
printf("'\n");
writeQuad((char *) packet, datalen +8);
writeQuad((char *) packet, packetSize);
}
char * rest = &buffer[newline] + 1;
......@@ -680,7 +682,7 @@ static void quad_recv() {
*/
int validPacket;
unsigned char *data;
unsigned char data[256];
metadata_t metadata;
static unsigned char respBuf[2048];
static size_t respBufLen;
......@@ -703,7 +705,7 @@ static void quad_recv() {
}
// Validate the message is correctly formatted
validPacket = parse_packet((unsigned char *) respBuf, &data, &metadata);
validPacket = parse_packet((unsigned char *) respBuf, data, &metadata);
if (validPacket == -1) {
warnx("Doesn't have start byte.");
/* nuke packet */
......
......@@ -4,151 +4,84 @@
#include <ctype.h>
static int msgNum = 0;
tokenList_t tokenize(char* cmd) {
int maxTokens = 16;
tokenList_t ret;
ret.numTokens = 0;
ret.tokens = malloc(sizeof(char*) * maxTokens);
ret.tokens[0] = NULL;
int i = 0;
char* token = strtok(cmd, " ");
while (token != NULL && i < maxTokens - 1) {
ret.tokens[i++] = token;
ret.tokens[i] = NULL;
ret.numTokens++;
token = strtok(NULL, " ");
}
return ret;
}
int checkFloat(char *floatString, float *value) {
char *tmp;
*value = strtod(floatString, &tmp);
if(!(isspace(*tmp) || *tmp == 0)) {
fprintf(stderr, "%s is not a valid floating-point number\n", floatString);
return 0;
}
return 1;
}
int checkInt(char *intString, int *value) {
char *tmp;
long temp_long;
temp_long = strtol(intString, &tmp, 0); // base 10 number inputted
if(temp_long < INT_MIN || temp_long > INT_MAX || !(isspace(*tmp) || *tmp == 0)) {
fprintf(stderr, "%s is not a valid integer number\n", intString);
return 0;
}
printf("temp: %ld\n\n", temp_long);
*value = (int) temp_long;
return 1;
}
//--------------------------------
// Ground Station
//--------------------------------
// Formatting commands from ground station CLI
int formatCommand(char *command, unsigned char **formattedCommand) {
int formatCommand(char *command, unsigned char *formattedCommand) {
//fprintf(stderr, "length = %li , received '%s'\n", strlen(command), command);
char cmd[strlen(command)];
strncpy(cmd, command, strlen(command));
cmd[strlen(command)] = '\0';
char cmd[512];
strncpy(cmd, command, 512);
char * cmdText = strtok(cmd, " ");
tokenList_t tokens = tokenize(cmd);
float floatValue = 0.0;
int intValue = 0;
int valid;
metadata_t metadata;
// ----------------------------------------------
if(tokens.numTokens > 0) {
if(cmdText != NULL) {
for(int type = 0; type < MAX_TYPE_ID; type++)
{
if(strcmp(tokens.tokens[0], MessageTypes[type].cmdText) == 0)
if(strcmp(cmdText, MessageTypes[type].cmdText) == 0)
{
printf("Sending\n\ttype: %d, \n\tcommand: %s\n", type, MessageTypes[type].cmdText);
metadata.begin_char = (char) BEGIN_CHAR;
metadata.msg_type = type;
metadata.msg_id = msgNum++;
metadata.data_len = 0;
/* TODO: Format data correctly
* - Switch on Type instead of cmdDataType
* - Implement a case for every type
* - Format the tokens as appropriate for the type,
* - Format the tokens into data as appropriate for the type,
* based on the quad's callbacks.c.
* - Pass the formatted tokens and metadata into
* - Pass the data and metadata into
* formatPacket
* - Purge cmdDataType from existence
*/
// Make sure the second token is the right type
switch (MessageTypes[type].cmdDataType)
{
// Validate the float input
case floatType:
metadata.begin_char = (char) BEGIN_CHAR;
metadata.msg_type = type;
if(type == 0x01) {
valid = checkFloat(tokens.tokens[1], &floatValue);
if(!valid) {
return -1;
}
metadata.data_len = sizeof(floatValue);
} else {
metadata.data_len = 0;
}
metadata.msg_id = msgNum++;
formatPacket(&metadata, &floatValue, formattedCommand);
/* Static data buffer */
char data[256];
switch (type) {
// In each case, us strtok(NULL, " ") to tokenize,
// format,
// and append to data buffer (increase
// metadat.data_len appropriately).
case DEBUG_ID:
break;
// Validate the integer input
case intType:
metadata.begin_char = (char) BEGIN_CHAR;
metadata.msg_type = type;
if(type == 0x01) {
valid = checkInt(tokens.tokens[1], &intValue);
if(!valid) {
return -1;
}
metadata.data_len = sizeof(intValue);
} else {
metadata.data_len = 0;
}
metadata.msg_id = msgNum++;
formatPacket(&metadata, &intValue, formattedCommand);
case PACKETLOG_ID:
break;
// Validate the string input (doesn't need to happen)
case stringType:
metadata.begin_char = (char) BEGIN_CHAR;
metadata.msg_type = type;
metadata.msg_id = msgNum++;
metadata.data_len = strlen(tokens.tokens[1]);
formatPacket(&metadata, &tokens.tokens[1], formattedCommand);
case GETPACKETLOGS_ID:
break;
case UPDATE_ID:
break;
case BEGINUPDATE_ID:
break;
case LOG_ID:
break;
case RESPONSE_ID:
break;
case SETCONTROL_ID:
break;
case GETCONTROL_ID:
break;
case RESPCONTROL_ID:
break;
default:
return -1;
break;
}
return 0;
return formatPacket(&metadata, data, formattedCommand);
}
}
}
// Only gets here if the command does not exist
return -1;
}
// QUAD & Ground Station
// Format the log data from log_message
//int formatData(unsigned char *log_msg, unsigned char *formattedCommand)
int formatPacket(metadata_t *metadata, void *data, unsigned char **formattedCommand)
int formatPacket(metadata_t *metadata, void *data, unsigned char *formattedCommand)
{
*formattedCommand = malloc(sizeof(unsigned char) * metadata->data_len + 8);
//----------------------------------------------------------------------------------------------
// index|| 0 | 1 | 2 | 3 & 4 | 5 & 6 | 7+ | end |
//---------------------------------------------------------------------------------------------|
......@@ -158,21 +91,21 @@ int formatPacket(metadata_t *metadata, void *data, unsigned char **formattedComm
//----------------------------------------------------------------------------------------------
// Begin Char:
(*formattedCommand)[0] = metadata->begin_char;
formattedCommand[0] = metadata->begin_char;
// Msg type:
(*formattedCommand)[1] = metadata->msg_type;
(*formattedCommand)[2] = ((metadata->msg_type >> 8) & 0x000000ff);
formattedCommand[1] = metadata->msg_type;
formattedCommand[2] = ((metadata->msg_type >> 8) & 0x000000ff);
//Msg id (msgNum is 2 bytes)
(*formattedCommand)[3] = (metadata->msg_id & 0x000000ff);
(*formattedCommand)[4] = ((metadata->msg_id >> 8) & 0x000000ff);
formattedCommand[3] = (metadata->msg_id & 0x000000ff);
formattedCommand[4] = ((metadata->msg_id >> 8) & 0x000000ff);
// Data length and data - bytes 5&6 for len, 7+ for data
(*formattedCommand)[5] = metadata->data_len & 0x000000ff;
(*formattedCommand)[6] = (metadata->data_len >> 8) & 0x000000ff;
formattedCommand[5] = metadata->data_len & 0x000000ff;
formattedCommand[6] = (metadata->data_len >> 8) & 0x000000ff;
memcpy(&((*formattedCommand)[7]), data, metadata->data_len);
memcpy(&(formattedCommand[7]), data, metadata->data_len);
// Checksum
// receive data and calculate checksum
......@@ -180,12 +113,13 @@ int formatPacket(metadata_t *metadata, void *data, unsigned char **formattedComm
char data_checksum = 0;
for(i = 0; i < 7 + metadata->data_len; i++)
{
data_checksum ^= (*formattedCommand)[i];
data_checksum ^= formattedCommand[i];
}
(*formattedCommand)[7 + metadata->data_len] = data_checksum;
formattedCommand[7 + metadata->data_len] = data_checksum;
return 0;
/* Return data length */
return metadata->data_len + 7;
}
// returns the length of the data in bytes (datalen from packet) and fills data
......@@ -196,7 +130,7 @@ int formatPacket(metadata_t *metadata, void *data, unsigned char **formattedComm
// data is an unallocated (char *) (pass it to this function as &data)
// meta_data is a pointer to an instance of metadata_t
//
int parse_packet(unsigned char * packet, unsigned char ** data, metadata_t * meta_data)
int parse_packet(unsigned char * packet, unsigned char * data, metadata_t * meta_data)
{
//----------------------------------------------------------------------------------------------
// index|| 0 | 1 | 2 | 3 & 4 | 5 & 6 | 7+ | end |
......@@ -221,10 +155,9 @@ int parse_packet(unsigned char * packet, unsigned char ** data, metadata_t * met
int i;
// receive data
*data = malloc(meta_data->data_len);
for(i = 0; i < meta_data->data_len; i++)
{
(*data)[i] = packet[7+i];
data[i] = packet[7+i];
}
// calculate checksum
......@@ -245,11 +178,11 @@ int parse_packet(unsigned char * packet, unsigned char ** data, metadata_t * met
// Process the command received
int processCommand(unsigned char *packet, modular_structs_t *structs) {
int validPacket;
unsigned char *data;
unsigned char data[256];
metadata_t metadata;
// Validate the message is correctly formatted
validPacket = parse_packet(packet, &data, &metadata);
validPacket = parse_packet(packet, data, &metadata);
if(validPacket != 0) {
return -1;
}
......
......@@ -7,13 +7,10 @@
#include <limits.h>
#include "type_def.h"
tokenList_t tokenize(char* cmd);
int checkFloat(char *floatString, float *value);
int checkInt(char *intString, int *value);
int formatCommand(char *command, unsigned char **formattedCommand);
int formatPacket(metadata_t *metadata, void *data, unsigned char **formattedCommand);
int parse_packet(unsigned char * packet, unsigned char ** data, metadata_t * meta_data);
int formatCommand(char *command, unsigned char *formattedCommand);
int formatPacket(metadata_t *metadata, void *data, unsigned char *formattedCommand);
int parse_packet(unsigned char * packet, unsigned char * data, metadata_t * meta_data);
int processCommand(unsigned char *command, modular_structs_t *structs);
int logData(unsigned char *log_msg, unsigned char *formattedCommand);
#endif /* __COMMUNICATION_H */
\ No newline at end of file
#endif /* __COMMUNICATION_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment