About to make the processing queue lock properly
This commit is contained in:
14
src/packet/CMakeLists.txt
Normal file
14
src/packet/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2025 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_TARGET_NAME}
|
||||
PRIVATE
|
||||
packet.c
|
||||
packetwelcome.c
|
||||
packetdisconnect.c
|
||||
packetqueue.c
|
||||
packetping.c
|
||||
)
|
29
src/packet/packet.c
Normal file
29
src/packet/packet.c
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "packet.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
void packetInit(
|
||||
packet_t *packet,
|
||||
const packettype_t type,
|
||||
const uint32_t length
|
||||
) {
|
||||
assertNotNull(packet, "Packet is NULL");
|
||||
|
||||
memoryZero(packet, sizeof(packet_t));
|
||||
|
||||
assertTrue(length > 0, "Packet length is 0");
|
||||
assertTrue(
|
||||
length <= sizeof(packetdata_t),
|
||||
"Packet length is too large"
|
||||
);
|
||||
|
||||
packet->type = type;
|
||||
packet->length = length;
|
||||
}
|
45
src/packet/packet.h
Normal file
45
src/packet/packet.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
#include "packetwelcome.h"
|
||||
#include "packetdisconnect.h"
|
||||
#include "packetping.h"
|
||||
|
||||
typedef enum {
|
||||
PACKET_TYPE_INVALID = 0,
|
||||
PACKET_TYPE_WELCOME = 1,
|
||||
PACKET_TYPE_DISCONNECT = 2,
|
||||
PACKET_TYPE_PING = 3,
|
||||
} packettype_t;
|
||||
|
||||
typedef union {
|
||||
packetwelcome_t welcome;
|
||||
packetdisconnect_t disconnect;
|
||||
packetping_t ping;
|
||||
} packetdata_t;
|
||||
|
||||
typedef struct packet_s {
|
||||
packettype_t type;
|
||||
uint32_t length;
|
||||
packetdata_t data;
|
||||
} packet_t;
|
||||
|
||||
/**
|
||||
* Initializes a packet with the given type. This is only to be used by sub
|
||||
* initializers, such as packetWelcomeCreate for example.
|
||||
*
|
||||
* @param packet Pointer to the packet structure to initialize.
|
||||
* @param type The type of the packet.
|
||||
* @param length The length of the packet data.
|
||||
*/
|
||||
void packetInit(
|
||||
packet_t *packet,
|
||||
const packettype_t type,
|
||||
const uint32_t length
|
||||
);
|
46
src/packet/packetdisconnect.c
Normal file
46
src/packet/packetdisconnect.c
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "packet.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void packetDisconnectCreate(
|
||||
packet_t *packet,
|
||||
const packetdisconnectreason_t reason
|
||||
) {
|
||||
packetInit(packet, PACKET_TYPE_DISCONNECT, sizeof(packetdisconnect_t));
|
||||
packet->data.disconnect.reason = reason;
|
||||
}
|
||||
|
||||
errorret_t packetDisconnectClient(packet_t *packet) {
|
||||
assertNotNull(packet, "Packet is NULL");
|
||||
assertTrue(
|
||||
packet->type == PACKET_TYPE_DISCONNECT,
|
||||
"Packet type is not DISCONNECT"
|
||||
);
|
||||
|
||||
if(packet->length != sizeof(packetdisconnect_t)) {
|
||||
return error("Disconnect packet length is not correct");
|
||||
}
|
||||
|
||||
packetdisconnect_t *data = (packetdisconnect_t *)&packet->data;
|
||||
switch(data->reason) {
|
||||
case PACKET_DISCONNECT_REASON_UNKNOWN:
|
||||
return error("Server disconnected: Unknown reason");
|
||||
case PACKET_DISCONNECT_REASON_INVALID_VERSION:
|
||||
return error("Server disconnected: Invalid version");
|
||||
case PACKET_DISCONNECT_REASON_MALFORMED_PACKET:
|
||||
return error("Server disconnected: Malformed packet");
|
||||
case PACKET_DISCONNECT_REASON_SERVER_FULL:
|
||||
return error("Server disconnected: Server full");
|
||||
case PACKET_DISCONNECT_REASON_SERVER_SHUTDOWN:
|
||||
return error("Server disconnected: Server shutdown");
|
||||
default:
|
||||
return error("Server disconnected: Unknown reason");
|
||||
}
|
||||
}
|
42
src/packet/packetdisconnect.h
Normal file
42
src/packet/packetdisconnect.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
|
||||
typedef struct packet_s packet_t;
|
||||
|
||||
typedef enum {
|
||||
PACKET_DISCONNECT_REASON_UNKNOWN = 0,
|
||||
PACKET_DISCONNECT_REASON_INVALID_VERSION = 1,
|
||||
PACKET_DISCONNECT_REASON_MALFORMED_PACKET = 2,
|
||||
PACKET_DISCONNECT_REASON_SERVER_FULL = 3,
|
||||
PACKET_DISCONNECT_REASON_SERVER_SHUTDOWN = 4,
|
||||
} packetdisconnectreason_t;
|
||||
|
||||
typedef struct {
|
||||
packetdisconnectreason_t reason;
|
||||
} packetdisconnect_t;
|
||||
|
||||
/**
|
||||
* Creates a disconnect packet.
|
||||
*
|
||||
* @param packet Pointer to the packet structure to initialize.
|
||||
* @param reason The reason for the disconnect.
|
||||
*/
|
||||
void packetDisconnectCreate(
|
||||
packet_t *packet,
|
||||
const packetdisconnectreason_t reason
|
||||
);
|
||||
|
||||
/**
|
||||
* Handles a disconnect packet received FROM a server INTO a client.
|
||||
*
|
||||
* @param packet Pointer to the packet structure to handle.
|
||||
* @return ERROR_OK on success, or an error code on failure.
|
||||
*/
|
||||
errorret_t packetDisconnectClient(packet_t *packet);
|
26
src/packet/packetping.c
Normal file
26
src/packet/packetping.c
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "packet.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void packetPingCreate(packet_t *packet) {
|
||||
packetInit(packet, PACKET_TYPE_PING, sizeof(packetping_t));
|
||||
packet->data.ping.number = GetRandomValue(0, INT32_MAX);
|
||||
}
|
||||
|
||||
errorret_t packetPingClient(packet_t *packet) {
|
||||
assertNotNull(packet, "Packet is NULL");
|
||||
assertTrue(packet->type == PACKET_TYPE_PING, "Packet type is not PING");
|
||||
|
||||
if(packet->length != sizeof(packetping_t)) {
|
||||
return error("Ping packet length is not %d", sizeof(packetping_t));
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
28
src/packet/packetping.h
Normal file
28
src/packet/packetping.h
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t number;
|
||||
} packetping_t;
|
||||
|
||||
/**
|
||||
* Creates a ping packet.
|
||||
*
|
||||
* @param packet Pointer to the packet structure to initialize.
|
||||
*/
|
||||
void packetPingCreate(packet_t *packet);
|
||||
|
||||
/**
|
||||
* Handles a ping packet received FROM a server INTO a client.
|
||||
*
|
||||
* @param packet Pointer to the packet structure to handle.
|
||||
* @return ERROR_OK on success, or an error code on failure.
|
||||
*/
|
||||
errorret_t packetPingClient(packet_t *packet);
|
35
src/packet/packetqueue.c
Normal file
35
src/packet/packetqueue.c
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "packetqueue.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
void packetQueueInit(packetqueue_t *queue) {
|
||||
assertNotNull(queue, "Packet queue is NULL");
|
||||
memoryZero(queue, sizeof(packetqueue_t));
|
||||
}
|
||||
|
||||
void packetQueuePushIn(packetqueue_t *queue, const packet_t *packet) {
|
||||
assertNotNull(queue, "Packet queue is NULL");
|
||||
assertNotNull(packet, "Packet is NULL");
|
||||
assertTrue(
|
||||
queue->packetsInCount < PACKET_QUEUE_MAX_SIZE, "Packet queue is full"
|
||||
);
|
||||
|
||||
queue->packetsIn[queue->packetsInCount++] = *packet;
|
||||
}
|
||||
|
||||
void packetQueuePushOut(packetqueue_t *queue, const packet_t *packet) {
|
||||
assertNotNull(queue, "Packet queue is NULL");
|
||||
assertNotNull(packet, "Packet is NULL");
|
||||
assertTrue(
|
||||
queue->packetsOutCount < PACKET_QUEUE_MAX_SIZE, "Packet queue is full"
|
||||
);
|
||||
|
||||
queue->packetsOut[queue->packetsOutCount++] = *packet;
|
||||
}
|
49
src/packet/packetqueue.h
Normal file
49
src/packet/packetqueue.h
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "packet/packet.h"
|
||||
|
||||
#define PACKET_QUEUE_MAX_SIZE 512
|
||||
|
||||
typedef struct {
|
||||
packet_t packetsIn[PACKET_QUEUE_MAX_SIZE];
|
||||
uint32_t packetsInCount;
|
||||
packet_t packetsOut[PACKET_QUEUE_MAX_SIZE];
|
||||
uint32_t packetsOutCount;
|
||||
|
||||
// Mutex for thread safety
|
||||
pthread_mutex_t mutex;
|
||||
// Condition variables for signaling
|
||||
pthread_cond_t condIn;
|
||||
pthread_cond_t condOut;
|
||||
// Thread ID of the thread that owns the queue
|
||||
|
||||
} packetqueue_t;
|
||||
|
||||
/**
|
||||
* Initializes the packet queue.
|
||||
*
|
||||
* @param queue Pointer to the packet queue structure.
|
||||
*/
|
||||
void packetQueueInit(packetqueue_t *queue);
|
||||
|
||||
/**
|
||||
* Pushes a packet into the inbound packet queue.
|
||||
*
|
||||
* @param queue Pointer to the packet queue structure.
|
||||
* @param packet Pointer to the packet to be pushed.
|
||||
*/
|
||||
void packetQueuePushIn(packetqueue_t *queue, const packet_t *packet);
|
||||
|
||||
/**
|
||||
* Pushes a packet from the outbound packet queue.
|
||||
*
|
||||
* @param queue Pointer to the packet queue structure.
|
||||
* @param packet Pointer to the packet to be pushed.
|
||||
*/
|
||||
void packetQueuePushOut(packetqueue_t *queue, const packet_t *packet);
|
36
src/packet/packetwelcome.c
Normal file
36
src/packet/packetwelcome.c
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "packet.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void packetWelcomeCreate(packet_t *packet) {
|
||||
packetInit(packet, PACKET_TYPE_WELCOME, PACKET_WELCOME_SIZE);
|
||||
memoryCopy(
|
||||
packet->data.welcome.dusk, PACKET_WELCOME_STRING, PACKET_WELCOME_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
errorret_t packetWelcomeClient(packet_t *packet) {
|
||||
assertNotNull(packet, "Packet is NULL");
|
||||
assertTrue(packet->type == PACKET_TYPE_WELCOME, "Packet type is not WELCOME");
|
||||
|
||||
if(packet->length != PACKET_WELCOME_SIZE) {
|
||||
return error("Welcome packet length is not %d", PACKET_WELCOME_SIZE);
|
||||
}
|
||||
|
||||
if(
|
||||
memoryCompare(
|
||||
packet->data.welcome.dusk, PACKET_WELCOME_STRING, PACKET_WELCOME_SIZE
|
||||
) != 0
|
||||
) {
|
||||
return error("Welcome packet data is not %s", PACKET_WELCOME_STRING);
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
33
src/packet/packetwelcome.h
Normal file
33
src/packet/packetwelcome.h
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
|
||||
typedef struct packet_s packet_t;
|
||||
|
||||
#define PACKET_WELCOME_STRING "DUSK"
|
||||
#define PACKET_WELCOME_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
char_t dusk[PACKET_WELCOME_SIZE];
|
||||
} packetwelcome_t;
|
||||
|
||||
/**
|
||||
* Creates a welcome packet.
|
||||
*
|
||||
* @param packet Pointer to the packet structure to initialize.
|
||||
*/
|
||||
void packetWelcomeCreate(packet_t *packet);
|
||||
|
||||
/**
|
||||
* Handles a welcome packet received FROM a server INTO a client.
|
||||
*
|
||||
* @param packet Pointer to the packet structure to handle.
|
||||
* @return ERROR_OK on success, or an error code on failure.
|
||||
*/
|
||||
errorret_t packetWelcomeClient(packet_t *packet);
|
Reference in New Issue
Block a user