Client/Server data setup working!

This commit is contained in:
Scott Duensing 2022-01-13 20:00:01 -06:00
parent d7dcd43c5f
commit 5a840ab1bf
8 changed files with 96 additions and 39 deletions

View file

@ -260,12 +260,16 @@ int main(int argc, char *argv[]) {
sh_new_strdup(__runtimeData.integers);
sh_new_strdup(__runtimeData.strings);
// ***TODO*** Load tables from disk cache
//taskCreate(taskComDebugLoop, NULL);
taskCreate(taskWelcome, NULL);
taskCreate(taskGuiEventLoop, NULL);
taskRun();
// ***TODO*** Write tables from disk cache
// Free integer table.
if (__runtimeData.integers) {
while (shlen(__runtimeData.integers) > 0) {

View file

@ -85,15 +85,17 @@ void taskNetwork(void *data) {
do {
//***TODO*** Detect disconnection. Maybe have callbacks registered that can notify tasks?
// ***TODO*** Detect disconnection. Maybe have callbacks registered that can notify tasks?
// Read pending bytes.
r = comRead(__configData.serialCom - 1, buffer, 1024);
if (r > 0) {
// Decode them into packets.
// New data or not, process anything in the queue.
if (packetDecode(__packetThreadData, &decoded, buffer, r)) {
// Is this a PONG? If so, ignore it.
if (decoded.packetType == PACKET_TYPE_PONG) continue;
if (decoded.packetType == PACKET_TYPE_PONG) {
packetDecodeDataStaticDestroy(&decoded);
continue;
}
// Copy the packet out.
NEW(PacketDecodeDataT, packet);
@ -112,11 +114,12 @@ void taskNetwork(void *data) {
}
// Add new packet to existing list.
arrput(_packets[r].value, packet);
packetDecodeDataStaticDestroy(&decoded);
}
} else {
// No bytes pending, yield to UI.
// Yield to UI.
taskYield();
}
// Send a ping to the server every 5 seconds, because, ping.
if (__timerSecondTick) {

View file

@ -136,10 +136,6 @@ static void taskConnectClick(void *data) {
return;
}
// Connected! Show icon.
widgetVisibleSet(W(_picConnect), 1);
taskYield();
// Start packet handler and negotiate encryption.
taskCreate(taskNetwork, NULL);
packetEncryptionSetup(__packetThreadData);
@ -155,6 +151,8 @@ static void taskConnectClick(void *data) {
return;
}
// ***TODO*** Should probably cleanly handle a full server here with some kind of SERVER_FULL packet.
// Wait for version and table packets to arrive.
timeout = 10;
do {
@ -170,6 +168,7 @@ static void taskConnectClick(void *data) {
break;
case PACKET_TYPE_PROCEED:
logWrite("Received PACKET_TYPE_PROCEED\n");
waiting = 0;
break;
@ -217,6 +216,14 @@ static void taskConnectClick(void *data) {
return;
}
// Connected! Show icon.
widgetVisibleSet(W(_picConnect), 1);
timeout = 6; // Roughly 1.5 seconds.
while (timeout > 0) {
taskYield();
if (__timerQuarterSecondTick) timeout--;
}
// Switch to Login window.
guiDelete(D(_winWelcome));
taskCreate(taskLogin, NULL);

View file

@ -50,7 +50,7 @@ static uint8_t clientDequeuePacket(ClientThreadT *client) {
// New data or not, process anything in the queue.
if (packetDecode(client->packetThreadData, &decode, data, length)) {
clientProcessPacket(client, &decode);
DEL(decode.data);
if (decode.data) DEL(decode.data);
if (packet) {
DEL(packet->data);
DEL(packet);
@ -257,8 +257,14 @@ void *clientThread(void *data) {
}
// Clean up client data on the way out.
while (arrlen(client->packetQueue) > 0) {
if (client->packetQueue[0]->data) DEL(client->packetQueue[0]->data);
arrdel(client->packetQueue, 0);
}
arrfree(client->packetQueue);
pthread_mutex_destroy(&client->packetQueueMutex);
packetThreadDataDestroy(&client->packetThreadData);
DEL(client);
pthread_exit(NULL);
}

View file

@ -64,7 +64,6 @@ void consoleRun(void) {
uint8_t commandOk = 0;
struct timespec remaining = { 0, 0 };
struct timespec sleepTime = { 0, 1000000000/4 }; // 1/4th second
size_t i = 0;
if (pthread_mutex_init(&_messageQueueMutex, NULL)) utilDie("Unable to create console message queue mutex.\n");
@ -168,8 +167,9 @@ void consoleRun(void) {
}
// Anything left in the message queue?
for (i=0; i<arrlenu(_consoleMessageQueue); i++) {
free(_consoleMessageQueue[i]);
while (arrlen(_consoleMessageQueue) > 0) {
DEL(_consoleMessageQueue[0]);
arrdel(_consoleMessageQueue, 0);
}
arrfree(_consoleMessageQueue);

View file

@ -32,7 +32,7 @@
#include <pthread.h>
// Should be after system headers in this file.
//#define MEMORY_CHECK_ENABLED
#define MEMORY_CHECK_ENABLED
#include "memory.h"
// Now our headers.

View file

@ -23,6 +23,24 @@
// Encryption: https://erev0s.com/blog/tiny-aes-cbc-mode-pkcs7-padding-written-c
/*
* NOTE:
*
* The reliable transport / packet retry code has been commented out.
* Structly speaking, it isn't needed. Enet handles reliable delivery
* across the internet. The only place there can be corruption is
* between a real serial port and the enet softmodem.
*
* In any case, if the code ends up being re-enabled, the sequence
* numbers have no bounding and will run off the end of the history
* array. Not only that, but due to the limited number of sequence
* numbers available, there needs to be a sending queue added for
* when the server attempts to send more packets than there are
* history slots.
*
*/
#include "packet.h"
#include "primes.h"
@ -65,7 +83,7 @@ static uint8_t packetCRC(char *data, uint16_t length, uint8_t startAt) {
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeData, char *input, uint16_t inputLength) {
uint8_t sequence = 0;
//uint8_t sequence = 0;
uint16_t unpadded = 0;
int32_t x = 0;
char c = 0;
@ -107,6 +125,7 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeDat
// Check CRC.
if ((uint8_t)threadData->decodeBuffer[threadData->length - 1] != packetCRC(threadData->decodeBuffer, threadData->length - 1, 0)) continue;
/*
// Get sequence value.
sequence = ((uint8_t)threadData->decodeBuffer[0]) & 0x1f;
@ -151,6 +170,7 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeDat
packetSend(threadData, &encoded);
continue;
}
*/
// Fill decoded data fields.
decodeData->packetType = threadData->decodeBuffer[1];
@ -241,13 +261,21 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeDat
void packetDecodeDataDestroy(PacketDecodeDataT **packet) {
PacketDecodeDataT *d = *packet;
free(d->data);
packetDecodeDataStaticDestroy(d);
free(d);
d = NULL;
*packet = d;
}
void packetDecodeDataStaticDestroy(PacketDecodeDataT *packet) {
if (packet->data) {
free(packet->data);
packet->data = NULL;
}
}
static uint16_t packetDHCompute(uint32_t a, uint32_t m, uint32_t n) {
uint32_t r = 0;
uint32_t y = 1;
@ -282,9 +310,11 @@ uint8_t packetEncode(PacketThreadDataT *threadData, PacketEncodeDataT *data, cha
data->dataPointer = NULL;
data->length = 0;
/*
if (data->control == PACKET_CONTROL_DAT) {
data->sequence = threadData->sequence++;
}
*/
// Make needed header bytes.
control = (((uint8_t)data->control) << 6) + (data->encrypt << 5) + (data->sequence & 0x1f);
@ -387,9 +417,10 @@ void packetSend(PacketThreadDataT *threadData, PacketEncodeDataT *data) {
logWrite("Invalid PACKET_CONTROL!\n\r");
}
/*
// Add to history?
if (data->control == PACKET_CONTROL_DAT) {
//***TODO*** Must change control to use CONTROL_RTX & fix framing changes
// ***TODO*** Must change control to use CONTROL_RTX & fix framing changes
threadData->history[threadData->historyPosition].sequence = data->sequence;
threadData->history[threadData->historyPosition].length = data->length;
memcpy(threadData->history[threadData->historyPosition].data, data->dataPointer, data->length);
@ -398,6 +429,7 @@ void packetSend(PacketThreadDataT *threadData, PacketEncodeDataT *data) {
threadData->historyPosition = 0;
}
}
*/
// Mark invalid so caller has to change it.
data->control = PACKET_CONTROL_BAD;
@ -414,9 +446,11 @@ PacketThreadDataT *packetThreadDataCreate(void *senderData) {
data = (PacketThreadDataT *)malloc(sizeof(PacketThreadDataT));
if (data) {
/*
data->sequence = 0;
data->lastRemoteSequence = 0;
data->historyPosition = 0;
*/
data->decodeQueueHead = 0;
data->decodeQueueTail = 0;
data->newPacket = 1;

View file

@ -90,10 +90,12 @@ typedef struct PacketHistoryDataS {
typedef struct PacketThreadDataS {
// Internal state per thread for packet processing.
/*
uint8_t sequence;
uint8_t lastRemoteSequence;
PacketHistoryDataT history[PACKET_SEQUENCE_MAX];
uint8_t historyPosition;
*/
char decodeBuffer[PACKET_MAX];
char encodeBuffer[PACKET_BUFFER_SIZE];
char decodeQueue[PACKET_INPUT_QUEUE_SIZE];
@ -119,6 +121,7 @@ typedef void (*packetSender)(char *data, uint32_t length, void *userData);
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeData, char *input, uint16_t inputLength);
void packetDecodeDataDestroy(PacketDecodeDataT **packet);
void packetDecodeDataStaticDestroy(PacketDecodeDataT *packet);
uint8_t packetEncode(PacketThreadDataT *threadData, PacketEncodeDataT *data, char *input, uint16_t length);
uint8_t packetEncryptionReady(void);
void packetEncryptionSetup(PacketThreadDataT *threadData);