msgba/src/packet.c

126 lines
3.3 KiB
C

#include <pthread.h>
#include <endian.h>
#include <msgba/packet.h>
#include <msgba/packet/hello.h>
#define PRINT_DEBUG(NAME, CLIENT_FD) \
printf ("Received packet %s from client fd %d\n", #NAME, CLIENT_FD);
bool
msPacketHandle(struct msPacket *packet, int client_fd,
struct msClientConnectionData *const data) {
bool result = false;
switch (packet->id) {
case PACKET_GET_HELLO:
PRINT_DEBUG(PACKET_HELLO, client_fd);
result = msPacketHelloGet(packet, client_fd, data);
break;
}
return result;
}
static bool
msPacketWrite(int fd, const void *data, size_t len) {
bool result = false;
ssize_t written_bytes = 0;
const unsigned char *bytes = (const unsigned char *)data;
while (written_bytes < len) {
ssize_t wrote_in_this_write = write(fd, (const void *)&bytes[written_bytes], (sizeof *bytes * len) - written_bytes);
if (wrote_in_this_write == -1) {
goto return_ms_packet_write;
}
written_bytes += wrote_in_this_write;
}
result = true;
return_ms_packet_write:
return result;
}
bool
msPacketSend(const struct msPacket *const packet, struct msClientConnectionData *const data) {
pthread_mutex_lock(data->mutexSendPacket);
int fd = data->clientFd;
size_t id = packet->id;
size_t size = packet->size;
bool result = false;
id = htobe64(id);
size = htobe64(size);
if(!msPacketWrite(fd, (const void *)&id, sizeof packet->id)) {
goto return_ms_packet_send;
}
if (!msPacketWrite(fd, (const void *)&size, sizeof packet->size)) {
goto return_ms_packet_send;
}
if (!msPacketWrite(fd, (const void *)packet->raw_data, sizeof *packet->raw_data * packet->size)){
goto return_ms_packet_send;
}
result = true;
return_ms_packet_send:
pthread_mutex_unlock(data->mutexSendPacket);
return result;
}
struct msPacket *
msPacketNew(const size_t id, const size_t size, unsigned char *raw_data) {
struct msPacket *packet = malloc(sizeof *packet);
packet->id = id;
packet->size = size;
packet->raw_data = raw_data;
return packet;
}
void
msPacketDestroy(struct msPacket **packet) {
if ((*packet)->raw_data) {
free((*packet)->raw_data);
}
free(*packet);
*packet=NULL;
}
struct msPacket *
msPacketRead(int client_fd) {
struct msPacket *packet = NULL;
size_t id = 0;
size_t size = 0;
ssize_t result;
unsigned char *raw_data = NULL;
result = read(client_fd, &id, sizeof id);
if (result < sizeof id) {
printf("Unable to read id\n");
goto return_read_packet;
}
result = read(client_fd, &size, sizeof size);
if (result < sizeof size) {
printf("Unable to read packet\n");
goto return_read_packet;
}
size = be64toh(size);
raw_data = malloc(size);
size_t to_read_size = size;
while (to_read_size > 0) {
result = read(client_fd, &raw_data[size - to_read_size], to_read_size);
if (result == -1) {
printf("Unable to read raw_data\n");
goto return_read_packet;
}
to_read_size -= result;
}
if (result < size) {
}
packet = calloc (1, sizeof *packet);
packet->id = id;
packet->size = size;
packet->raw_data = raw_data;
return_read_packet:
if (!packet && raw_data) {
free(raw_data);
}
return packet;
}