Something went wrong on our end
packet.c 2.37 KiB
#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;
}