#include "packet.h" #include "commands.h" #include "bitwise.h" #include <string.h> /* Combine metadata and data to form a wire-sendable packet. * Returns the size of the encoded packet */ ssize_t EncodePacket( uint8_t * packet, /* Buffer to encode into */ size_t packet_size, /* Max buffer size */ const struct metadata * m, /* Metadata to encode */ const uint8_t * data) /* Data to encode */ { if (packet_size < (HDR_SIZE + CSUM_SIZE + m->data_len)) { return -1; } packet[BEGIN] = BEGIN_CHAR; packet[MTYPE_L] = LSByte16(m->msg_type); packet[MTYPE_H] = MSByte16(m->msg_type); packet[ID_L] = LSByte16(m->msg_id); packet[ID_H] = MSByte16(m->msg_id); packet[DLEN_L] = LSByte16(m->data_len); packet[DLEN_H] = MSByte16(m->data_len); memcpy(&packet[HDR_SIZE], data, m->data_len); packet[HDR_SIZE + m->data_len] = PacketChecksum( packet, HDR_SIZE + m->data_len + CSUM_SIZE); return m->data_len + HDR_SIZE + CSUM_SIZE; } /* Break apart packet, populating metadata. Data is copied * into the space pointed to by data. * Returns the size of the data. */ ssize_t DecodePacket( struct metadata * m, /* Decoded metadata (includes data_len)*/ uint8_t * data, /* Data is copied into this buffer */ size_t data_size, /* Max buffer size */ const uint8_t * packet, /* Packet to decode */ size_t packet_size) /* Size of packet to decode */ { uint8_t checkSum; if (packet[BEGIN] != BEGIN_CHAR) { return -1; } if (packet_size < ((uint8_t) HDR_SIZE + CSUM_SIZE)) { return -2; } m->msg_type = BytesTo16(packet[MTYPE_L], packet[MTYPE_H]); m->msg_id = BytesTo16(packet[ID_L], packet[ID_H]); m->data_len = BytesTo16(packet[DLEN_L], packet[DLEN_H]); if (packet_size < (HDR_SIZE + CSUM_SIZE + m->data_len)) { return -3; } if (data_size < m->data_len) { return -4; } checkSum = PacketChecksum(packet, HDR_SIZE + m->data_len + CSUM_SIZE); if (checkSum != packet[HDR_SIZE + m->data_len]) { return -5; } memcpy(data, &packet[HDR_SIZE], m->data_len); return m->data_len; } uint8_t PacketChecksum(const uint8_t * packet, size_t packet_size) { uint8_t checkSum = 0; for(size_t i = 0; i < packet_size - CSUM_SIZE; i++){ checkSum ^= packet[i]; } return checkSum; } size_t PacketSize(const struct metadata *m) { return m->data_len + HDR_SIZE + CSUM_SIZE; }