126 lines
3.3 KiB
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;
|
|
}
|