kpmpgsmkii/shared/packet.h

97 lines
3.3 KiB
C

/*
* Kangaroo Punch MultiPlayer Game Server Mark II
* Copyright (C) 2020-2021 Scott Duensing
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef PACKET_H
#define PACKET_H
#include "os.h"
/*
* Packet format (without framing):
*
* Byte 01: cces ssss - Two control bits, one encryption bit, five sequence bits.
* Byte 02: pppp pppp - Eight bits, packet type.
* Byte 03: cccc cccc - Eight bits, channel.
* Byte 04: dddd dddd \
* Byte ..: dddd dddd > Packet payload.
* Byte X0: dddd dddd /
* Byte X1: cccc cccc - Checksum
*
*/
#define PACKET_MAX 1024 // Maximum number of bytes per packet
#define PACKET_SEQUENCE_MAX 32 // Five bits of data
#define PACKET_INPUT_QUEUE_SIZE 4096
#define PACKET_BUFFER_SIZE (PACKET_MAX * 2 + 2 + 8) // Worst case, every byte is a PACKET_FRAME. Add two for ending frame. Add 8 for worst case header and CRC.
#define PACKET_FRAME 0x7e
#define PACKET_CONTROL_DAT 0 // Regular data packet.
#define PACKET_CONTROL_RTX 1 // Retransmission packet.
#define PACKET_CONTROL_NAK 2 // Negative acknowledge.
#define PACKET_TYPE_NONE 0 // No packet.
typedef struct PacketDecodeDataS {
// Output
uint8_t packetType; // One of PACKET_TYPE_*
char *data; // Buffer received. MUST FREE.
uint16_t length; // Length of buffer.
uint8_t channel; // Which data channel it arrived on.
} PacketDecodeDataT;
typedef struct PacketEncodeDataS {
// Input
uint8_t control; // One of PACKET_CONTROL_*
uint8_t packetType; // One of PACKET_TYPE_*
uint8_t channel; // Which data channel to use.
uint8_t encrypt; // Do we want the packet encrypted?
// Input & Output
uint16_t sequence; // For NAK packets, input the sequence number we missed. Other packets returns the sequence of this packet.
// Output
char *dataPointer; // Buffer ready to send. DO NOT FREE.
uint16_t length; // Length of buffer.
} PacketEncodeDataT;
typedef struct PacketThreadDataS {
// Internal state per thread for packet processing.
uint8_t sequence;
char decodeBuffer[PACKET_MAX];
char encodeBuffer[PACKET_BUFFER_SIZE];
char decodeQueue[PACKET_INPUT_QUEUE_SIZE];
uint16_t decodeQueueHead;
uint16_t decodeQueueTail;
uint8_t inEscape;
uint8_t newPacket;
} PacketThreadDataT;
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *data, char *input, uint16_t length);
uint8_t packetEncode(PacketThreadDataT *threadData, PacketEncodeDataT *data, char *input, uint16_t length);
PacketThreadDataT *packetThreadDataCreate(void);
void packetThreadDataDestroy(PacketThreadDataT **data);
#endif // PACKET_H