Packet framing bug fixed. SQL based user accounts working.

This commit is contained in:
Scott Duensing 2022-02-10 19:01:36 -06:00
parent 6cec5e7f10
commit cddb5c27e1
18 changed files with 226 additions and 158 deletions

View file

@ -162,6 +162,9 @@ void loginShow() {
tagListRun(uiLogin);
_channel = netChannelGet(packetHandler);
textboxValueSet(_txtUser, "test");
textboxValueSet(_txtPass, "test");
}
@ -172,7 +175,6 @@ static void packetHandler(PacketDecodeDataT *packet) {
switch (packet->packetType) {
case PACKET_TYPE_LOGIN_RESULT:
packetContentUnpack(packet->data, "is", &success, &packetData);
logWrite("Login: %d %s\n", success, packetData);
if (success) {
netChannelRelease(_channel);
guiDelete(D(_winLogin));

View file

@ -70,6 +70,8 @@ static void eventLoop(void);
static uint8_t hasValidSettings(void);
static void shutdown(void);
static uint8_t startup(int argc, char *argv[]);
static void tableLoad(void);
static void tableSave(void);
static void checkSettings(void) {
@ -121,12 +123,14 @@ static void shutdown(void) {
imageUnload(&_pointer);
cacheShutdown();
tableSave();
netShutdown();
guiShutdown();
mouseShutdown();
surfaceShutdown();
vbeShutdown();
cacheShutdown();
configShutdown();
osShutdown();
logClose();
@ -183,19 +187,111 @@ static uint8_t startup(int argc, char *argv[]) {
return 1;
}
cacheStartup(argv[0]);
surfaceStartup();
mouseStartup();
guiStartup();
netStartup();
cacheStartup(argv[0]);
_pointer = imageLoad(cacheFilenameGet("system:mouse"));
_alpha = imagePixelGet(_pointer, 5, 0);
tableLoad();
return 0;
}
static void tableLoad(void) {
FILE *cache = NULL;
char *line = NULL;
char *p = NULL;
char *temp = NULL;
__runtimeData.integers = NULL;
__runtimeData.strings = NULL;
__runtimeData.protocolVersion = 0;
sh_new_strdup(__runtimeData.integers);
sh_new_strdup(__runtimeData.strings);
// ***TODO*** Default initial tables
line = (char *)malloc(4096);
if (line) {
// Load string cache.
cache = cacheFOpen("system:strings", "rt");
if (cache) {
while (fscanf(cache, "%s\n", line) != EOF) {
p = strstr(line, "=");
if (p) {
*p = 0;
p++;
// Do we have this string already?
temp = shget(__runtimeData.strings, line);
if (temp) {
DEL(temp);
shdel(__runtimeData.strings, line);
}
shput(__runtimeData.strings, line, strdup(p));
}
}
cacheFClose(cache);
}
// Load integer cache.
cache = cacheFOpen("system:integers", "rt");
if (cache) {
while (fscanf(cache, "%s\n", line) != EOF) {
p = strstr(line, "=");
if (p) {
*p = 0;
p++;
shput(__runtimeData.integers, line, atol(p));
}
}
cacheFClose(cache);
}
free(line);
line = NULL;
}
}
static void tableSave(void) {
FILE *cache = NULL;
// Save & free integer table.
cache = cacheFOpen("system:integers", "wt");
if (cache) {
if (__runtimeData.integers) {
while (shlen(__runtimeData.integers) > 0) {
//logWrite("[%s]=[%d]\n", __runtimeData.integers[0].key, __runtimeData.integers[0].value);
fprintf(cache, "%s=%ld\n", __runtimeData.integers[0].key, (long)__runtimeData.integers[0].value);
shdel(__runtimeData.integers, __runtimeData.integers[0].key);
}
shfree(__runtimeData.integers);
}
cacheFClose(cache);
}
// Save & free string table.
cache = cacheFOpen("system:strings", "wt");
if (cache) {
if (__runtimeData.strings) {
while (shlen(__runtimeData.strings) > 0) {
//logWrite("[%s]=[%s]\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value);
fprintf(cache, "%s=%s\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value);
DEL(__runtimeData.strings[0].value);
shdel(__runtimeData.strings, __runtimeData.strings[0].key);
}
shfree(__runtimeData.strings);
}
cacheFClose(cache);
}
}
int main(int argc, char *argv[]) {
if (startup(argc, argv)) return 1;

View file

@ -249,6 +249,13 @@ void signupShow(void) {
tagListRun(uiSignUp);
_channel = netChannelGet(packetHandler);
textboxValueSet(_txtEmail, "scott.duensing@gmail.com");
textboxValueSet(_txtFirst, "Test");
textboxValueSet(_txtLast, "User");
textboxValueSet(_txtUser, "test");
textboxValueSet(_txtPass1, "test");
textboxValueSet(_txtPass2, "test");
}
@ -267,7 +274,6 @@ static void timSignUpProgress(WidgetT *widget) {
textboxValueGet(_txtPass1),
textboxValueGet(_txtUser)
);
// Send signup request.
encoded.packetType = PACKET_TYPE_SIGNUP;
encoded.control = PACKET_CONTROL_DAT;
@ -278,6 +284,7 @@ static void timSignUpProgress(WidgetT *widget) {
DEL(packetData);
// Wait for response.
timerQuarterSecondsSet(_timProgress, 10 * 4);
_state = S_SIGNUP_WAIT;
break;
case S_SIGNUP_WAIT:

View file

@ -234,6 +234,12 @@ uint8_t cacheExists(void) {
}
void cacheFClose(FILE *handle) {
// Just wrap fclose() for now.
fclose(handle);
}
static char *cacheFieldGet(char *virtualPath, uint8_t field) {
FILE *in = NULL;
char index[16] = { 0 };
@ -290,6 +296,38 @@ char *cacheFilenameGet(char *virtualPath) {
}
FILE *cacheFOpen(char *vpath, char *mode) {
FILE *handle = NULL;
char *entry = NULL;
char *dir = NULL;
char *temp = NULL;
// Does this file already exist?
entry = cacheEntryNameGet(vpath);
// If we're writing or appending, do we need to create it?
if ((entry == NULL) && (mode[0] == 'w' || mode[0] == 'a')) {
do {
entry = cacheEntryNameGenerate();
dir = cacheEntryNameDirGet(entry, 1);
temp = osLastPathComponentGetUpTo(dir);
osMkDirP(temp);
DEL(temp);
} while (osFileExists(dir));
// Dummy SHA for files we create ourselves. They're never checked against the server.
cacheEntryAdd("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", entry, vpath);
}
// Did we get a file?
if (entry) {
dir = cacheEntryNameDirGet(entry, 1);
handle = fopen(dir, mode);
}
return handle;
}
uint8_t cachePrePack(char *name, CachePreMakeListT *list) {
FILE *in = NULL;

View file

@ -38,7 +38,9 @@ uint8_t cacheDelete(char *virtualPath);
uint8_t cacheEntryAdd(char *sha256, char *entryName, char *virtualPath);
char *cacheEntryNameGet(char *virtualPath);
uint8_t cacheExists(void);
void cacheFClose(FILE *handle);
char *cacheFilenameGet(char *virtualPath);
FILE *cacheFOpen(char *vpath, char *mode);
uint8_t cachePrePack(char *name, CachePreMakeListT *list);
uint8_t cachePreUnpack(char *name);
char *cacheSha256Get(char *virtualPath);

View file

@ -170,104 +170,18 @@ void netProcess(void) {
void netShutdown(void) {
FILE *cache = NULL;
netPacketHandlerStop();
if (_netStarted) {
_netStarted = 0;
// Save & free integer table.
cache = fopen("cache/integer.dat", "wt");
if (cache) {
if (__runtimeData.integers) {
while (shlen(__runtimeData.integers) > 0) {
//logWrite("[%s]=[%d]\n", __runtimeData.integers[0].key, __runtimeData.integers[0].value);
fprintf(cache, "%s=%ld\n", __runtimeData.integers[0].key, (long)__runtimeData.integers[0].value);
shdel(__runtimeData.integers, __runtimeData.integers[0].key);
}
shfree(__runtimeData.integers);
}
fclose(cache);
}
// Save & free string table.
cache = fopen("cache/string.dat", "wt");
if (cache) {
if (__runtimeData.strings) {
while (shlen(__runtimeData.strings) > 0) {
//logWrite("[%s]=[%s]\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value);
fprintf(cache, "%s=%s\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value);
DEL(__runtimeData.strings[0].value);
shdel(__runtimeData.strings, __runtimeData.strings[0].key);
}
shfree(__runtimeData.strings);
}
fclose(cache);
}
packetThreadDataDestroy(&__packetThreadData);
}
}
void netStartup(void) {
FILE *cache = NULL;
char *line = NULL;
char *p = NULL;
char *temp = NULL;
if (!_netStarted) {
_netStarted = 1;
__packetThreadData = packetThreadDataCreate(NULL);
packetSenderRegister(comPacketSender);
__runtimeData.integers = NULL;
__runtimeData.strings = NULL;
__runtimeData.protocolVersion = 0;
sh_new_strdup(__runtimeData.integers);
sh_new_strdup(__runtimeData.strings);
// ***TODO*** Default initial tables
line = (char *)malloc(4096);
if (line) {
// Load string cache.
cache = fopen("cache/string.dat", "rt");
if (cache) {
while (fscanf(cache, "%s\n", line) != EOF) {
p = strstr(line, "=");
if (p) {
*p = 0;
p++;
// Do we have this string already?
temp = shget(__runtimeData.strings, line);
if (temp) {
DEL(temp);
shdel(__runtimeData.strings, line);
}
shput(__runtimeData.strings, line, strdup(p));
}
}
fclose(cache);
}
// Load integer cache.
cache = fopen("cache/integer.dat", "rt");
if (cache) {
while (fscanf(cache, "%s\n", line) != EOF) {
p = strstr(line, "=");
if (p) {
*p = 0;
p++;
shput(__runtimeData.integers, line, atol(p));
}
}
fclose(cache);
}
free(line);
line = NULL;
}
}
}

View file

@ -44,11 +44,11 @@ return function ($kirby) {
if(option('debug')) {
$alert['error'] = 'Invalid email or password: ' . $e->getMessage();
$alert['error'] = 'Invalid E-mail or password: ' . $e->getMessage();
}
else {
$alert['error'] = 'Invalid email or password!';
$alert['error'] = 'Invalid E-mail or password!';
}
}

View file

@ -21,8 +21,8 @@ TEMPLATE = subdirs
CONFIG *= ORDERED
SUBDIRS = \
# client \
server
client
# server
# precache
# font
# primes

View file

@ -24,6 +24,7 @@ DROP TABLE IF EXISTS `config`;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`host` varchar(256) NOT NULL,
`name` varchar(32) NOT NULL,
`data` varchar(1024) NOT NULL,
`description` varchar(255) NOT NULL,
@ -117,4 +118,4 @@ CREATE TABLE `users` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2022-02-08 21:09:37
-- Dump completed on 2022-02-09 15:58:23

View file

@ -39,14 +39,13 @@ void clientApiLogin(ClientThreadT *client, PacketDecodeDataT *data) {
DEL(user);
DEL(pass);
}
if (result) {
if (result == SUCCESS) {
buffer = "Logged in.";
client->authenticated = 1;
} else {
// Something bad happened.
buffer = "Unknown error. Sorry.";
buffer = "Invalid username or password.";
}
logWrite("Login: %d %s\r\n", result, buffer);
packetData = packetContentPack(&length, "is", result, buffer);
// Build packet.
encoded.control = PACKET_CONTROL_DAT;

View file

@ -40,9 +40,18 @@ void clientApiSignup(ClientThreadT *client, PacketDecodeDataT *data) {
// This only makes sense if they're not logged in.
if (!client->authenticated) {
packetDebugPrint((uint8_t *)data->data, data->length);
// Get info for the user.
packetContentUnpack(data->data, "sssss", &email, &first, &last, &pass, &user);
logWrite("Email: %s\n\r", email);
logWrite("First: %s\n\r", first);
logWrite(" Last: %s\n\r", last);
logWrite(" Pass: %s\n\r", pass);
logWrite(" User: %s\n\r", user);
// See if they already exist in the database.
if (dbUserNameExists(user)) {
// User name already exists.

View file

@ -42,7 +42,7 @@ void clientApiVersionOkay(ClientThreadT *client, PacketDecodeDataT *data) {
(void)data;
// Fetch string table from DB.
if (dbTableGet("strings", table) == SUCCESS) {
if (dbTableGet("strings", &table) == SUCCESS) {
while (arrlen(table)) {
record = table[0];
arrdel(table, 0);
@ -66,10 +66,10 @@ void clientApiVersionOkay(ClientThreadT *client, PacketDecodeDataT *data) {
// Send it.
packetSend(client->packetThreadData, &encoded);
DEL(buffer);
//consoleMessageQueue("PACKET_TYPE_STRING [%s] sent.\n", record->name);
DEL(record->name);
DEL(record->data);
DEL(record);
consoleMessageQueue("PACKET_TYPE_STRING [%s] sent.\n", record->name);
}
arrfree(table);
} else {
@ -78,7 +78,7 @@ void clientApiVersionOkay(ClientThreadT *client, PacketDecodeDataT *data) {
}
// Fetch number table from DB.
if (dbTableGet("numbers", table) == SUCCESS) {
if (dbTableGet("numbers", &table) == SUCCESS) {
while (arrlen(table)) {
record = table[0];
arrdel(table, 0);
@ -103,10 +103,10 @@ void clientApiVersionOkay(ClientThreadT *client, PacketDecodeDataT *data) {
// Send it.
packetSend(client->packetThreadData, &encoded);
DEL(buffer);
//consoleMessageQueue("PACKET_TYPE_NUMBER [%s] sent.\n", record->name);
DEL(record->name);
DEL(record->data);
DEL(record);
consoleMessageQueue("PACKET_TYPE_NUMBER [%s] sent.\n", record->name);
}
arrfree(table);
} else {

View file

@ -65,7 +65,7 @@ uint8_t dbDisconnect(void) {
}
uint8_t dbSettingsStringGet(char *key, char *value, uint32_t max) {
uint8_t dbSettingsStringGet(char *host, char *key, char *value, uint32_t max) {
char statement[STATEMENT_MAX];
char *p = statement;
MYSQL_RES *result = NULL;
@ -81,6 +81,8 @@ uint8_t dbSettingsStringGet(char *key, char *value, uint32_t max) {
p += sprintf(p, "SELECT data FROM config WHERE name='");
p += mysql_real_escape_string(_sql, p, key, strlen(key));
p += sprintf(p, "' AND host='");
p += mysql_real_escape_string(_sql, p, host, strlen(host));
p += sprintf(p, "'");
if (mysql_real_query(_sql, statement, p - statement) != 0) {
logWrite("dbConfigValueGet: %s\n", mysql_error(_sql));
@ -113,10 +115,10 @@ uint8_t dbSettingsStringGet(char *key, char *value, uint32_t max) {
}
uint8_t dbSettingsValueGet(char *key, int32_t *value) {
uint8_t dbSettingsValueGet(char *host, char *key, int32_t *value) {
char temp[DB_CONFIG_ITEM_SIZE] = { 0 };
if (dbSettingsStringGet(key, temp, DB_CONFIG_ITEM_SIZE) == FAIL) return FAIL;
if (dbSettingsStringGet(host, key, temp, DB_CONFIG_ITEM_SIZE) == FAIL) return FAIL;
*value = atoi(temp);
@ -124,7 +126,7 @@ uint8_t dbSettingsValueGet(char *key, int32_t *value) {
}
uint8_t dbTableGet(char *which, DBTableT **table) {
uint8_t dbTableGet(char *which, DBTableT ***table) {
char statement[STATEMENT_MAX];
char *p = statement;
MYSQL_RES *result = NULL;
@ -158,7 +160,7 @@ uint8_t dbTableGet(char *which, DBTableT **table) {
NEW(DBTableT, record);
record->name = strdup(row[0]);
record->data = strdup(row[1]);
arrput(table, record);
arrput(*table, record);
}
mysql_free_result(result);
@ -214,7 +216,8 @@ uint8_t dbUserEmailExists(char *email) {
char statement[STATEMENT_MAX];
char *p = statement;
MYSQL_RES *result = NULL;
int count;
int32_t count = 0;
uint8_t status = FAIL;
pthread_mutex_lock(&_mutex);
@ -234,18 +237,14 @@ uint8_t dbUserEmailExists(char *email) {
result = mysql_store_result(_sql);
count = mysql_num_rows(result);
if (count != 1) {
logWrite("dbUserEmailExists: Too many rows returned: %d.\n", count);
mysql_free_result(result);
pthread_mutex_unlock(&_mutex);
return FAIL;
}
if (count == 1) status = SUCCESS;
if ((count != 1) && (count != 0)) logWrite("dbUserEmailExists: Invalid number of rows returned: %d.\n", count);
mysql_free_result(result);
pthread_mutex_unlock(&_mutex);
return SUCCESS;
return status;
}
@ -266,7 +265,7 @@ uint8_t dbUserLogin(char *user, char *password) {
p += sprintf(p, "SELECT pass FROM users WHERE user='");
p += mysql_real_escape_string(_sql, p, user, strlen(user));
p += sprintf(p, "' AND enabled = 1");
p += sprintf(p, "' AND enabled=1");
if (mysql_real_query(_sql, statement, p - statement) != 0) {
logWrite("dbUserLogin: %s\n", mysql_error(_sql));
pthread_mutex_unlock(&_mutex);
@ -276,7 +275,7 @@ uint8_t dbUserLogin(char *user, char *password) {
result = mysql_store_result(_sql);
count = mysql_num_rows(result);
if (count != 1) {
logWrite("dbUserLogin: Too many rows returned: %d.\n", count);
//logWrite("dbUserLogin: Too many rows returned: %d.\n", count);
mysql_free_result(result);
pthread_mutex_unlock(&_mutex);
return FAIL;
@ -290,7 +289,7 @@ uint8_t dbUserLogin(char *user, char *password) {
// Not thread safe. Protected by SQL _mutex.
p = crypt(password, row[0]);
if (strcmp(p, password) == 0) status = SUCCESS;
if (strcmp(p, row[0]) == 0) status = SUCCESS;
mysql_free_result(result);
@ -304,7 +303,8 @@ uint8_t dbUserNameExists(char *user) {
char statement[STATEMENT_MAX];
char *p = statement;
MYSQL_RES *result = NULL;
int count;
int32_t count = 0;
uint8_t status = FAIL;
pthread_mutex_lock(&_mutex);
@ -324,18 +324,14 @@ uint8_t dbUserNameExists(char *user) {
result = mysql_store_result(_sql);
count = mysql_num_rows(result);
if (count != 1) {
logWrite("dbUserNameExists: Too many rows returned: %d.\n", count);
mysql_free_result(result);
pthread_mutex_unlock(&_mutex);
return FAIL;
}
if (count == 1) status = SUCCESS;
if ((count != 1) && (count != 0)) logWrite("dbUserNameExists: Invalid number of rows returned: %d.\n", count);
mysql_free_result(result);
pthread_mutex_unlock(&_mutex);
return SUCCESS;
return status;
}

View file

@ -36,9 +36,9 @@ typedef struct DBTableS {
uint8_t dbConnect(char *host, uint16_t port, char *database, char *user, char *password);
uint8_t dbDisconnect(void);
uint8_t dbSettingsStringGet(char *key, char *value, uint32_t max);
uint8_t dbSettingsValueGet(char *key, int32_t *value);
uint8_t dbTableGet(char *which, DBTableT **table);
uint8_t dbSettingsStringGet(char *host, char *key, char *value, uint32_t max);
uint8_t dbSettingsValueGet(char *host, char *key, int32_t *value);
uint8_t dbTableGet(char *which, DBTableT ***table);
uint8_t dbUserCreate(char *first, char *last, char *user, char *pass, char *email);
uint8_t dbUserEmailExists(char *email);
uint8_t dbUserLogin(char *user, char *password);

View file

@ -124,29 +124,23 @@ int main(int argc, char *argv[]) {
// Find our hostname.
gethostname(hostname, 256);
// Get settings entries for this host.
snprintf(settingsFile, DB_CONFIG_ITEM_SIZE, "%s_file", hostname);
snprintf(settingsRest, DB_CONFIG_ITEM_SIZE, "%s_rest", hostname);
snprintf(settingsUser, DB_CONFIG_ITEM_SIZE, "%s_user", hostname);
snprintf(settingsPass, DB_CONFIG_ITEM_SIZE, "%s_pass", hostname);
// Connect to database.
if (!dbConnect(_configServer, _configPort, _configDatabase, _configUser, _configPassword)) {
utilDie("Unable to connect to database.\n");
}
// Fetch settings needed to start server.
if (!dbSettingsValueGet("maxClients", (int32_t *)&settingsMaxClients)) utilDie("Unable to load maxClients.\n");
if (!dbSettingsValueGet("portNumber", (int32_t *)&settingsPortNumber)) utilDie("Unable to load portNumber.\n");
if (!dbSettingsValueGet("clientVersion", (int32_t *)&settingsClientVersion)) utilDie("Unable to load clientVersion.\n");
if (!dbSettingsStringGet(settingsFile, settingsFile, DB_CONFIG_ITEM_SIZE)) utilDie("Unable to load file location.\n");
if (!dbSettingsStringGet(settingsRest, settingsRest, DB_CONFIG_ITEM_SIZE)) utilDie("Unable to load REST URL.\n");
if (!dbSettingsStringGet(settingsUser, settingsUser, DB_CONFIG_ITEM_SIZE)) utilDie("Unable to load REST user.\n");
if (!dbSettingsStringGet(settingsPass, settingsPass, DB_CONFIG_ITEM_SIZE)) utilDie("Unable to load REST password.\n");
if (!dbSettingsValueGet(hostname, "maxClients", (int32_t *)&settingsMaxClients)) utilDie("Unable to load maxClients.\n");
if (!dbSettingsValueGet(hostname, "portNumber", (int32_t *)&settingsPortNumber)) utilDie("Unable to load portNumber.\n");
if (!dbSettingsValueGet(hostname, "clientVersion", (int32_t *)&settingsClientVersion)) utilDie("Unable to load clientVersion.\n");
if (!dbSettingsStringGet(hostname, "fileLocation", settingsFile, DB_CONFIG_ITEM_SIZE)) utilDie("Unable to load file location.\n");
if (!dbSettingsStringGet(hostname, "restEndpoint", settingsRest, DB_CONFIG_ITEM_SIZE)) utilDie("Unable to load REST URL.\n");
if (!dbSettingsStringGet(hostname, "restUser", settingsUser, DB_CONFIG_ITEM_SIZE)) utilDie("Unable to load REST user.\n");
if (!dbSettingsStringGet(hostname, "restPassword", settingsPass, DB_CONFIG_ITEM_SIZE)) utilDie("Unable to load REST password.\n");
// Start up REST.
if (!restStartup(settingsRest, settingsUser, settingsPass)) {
logWrite("Unable to locate REST API. Web site integration disabled.\n");
logWrite("Unable to locate REST endpoint. Web site integration disabled.\n");
__restAvailable = 0;
}

View file

@ -111,8 +111,6 @@ json_object *restRequest(char *command, char *format, ...) {
json_object_put(response);
response = NULL;
}
} else {
logWrite("restRequest: No response.\n");
}
return response;
@ -231,9 +229,7 @@ static json_object *restUrlPost(json_object *request) {
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
logWrite("restUrlPost: %s\n", curl_easy_strerror(res));
} else {
if (res == CURLE_OK) {
response = json_tokener_parse_verbose(data.data, &error);
if (error) {
logWrite("Error: %s\n", json_tokener_error_desc(error));

View file

@ -139,8 +139,10 @@ void packetContentUnpack(char *buffer, char *format, ...) {
case 's':
// Copy string including the terminating zero.
string = va_arg(args, char **);
if (&buffer[length] != NULL) {
*string = strdup(&buffer[length]);
length += strlen(*string) + 1;
}
break;
default:
@ -182,11 +184,18 @@ static uint8_t packetCRC(char *data, uint16_t length, uint8_t startAt) {
}
void packetDebugPrint(uint8_t *data, uint16_t length) {
uint16_t i;
for (i=0; i<length; i++) logWrite("%02x [%c] ", data[i], data[i]);
logWrite("\n\r");
}
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeData, char *input, uint16_t inputLength) {
//uint8_t sequence = 0;
uint16_t unpadded = 0;
int32_t x = 0;
char c = 0;
uint8_t c = 0;
PacketEncodeDataT encoded = { 0 };
// input and inputLength are incoming raw data or NULL and 0 to continue processing already received data.
@ -219,7 +228,11 @@ uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeDat
if (threadData->inEscape) {
threadData->inEscape = 0;
// Is this the end of the packet?
if (c != PACKET_FRAME) {
if (c == PACKET_FRAME) {
// Nope! Add the byte.
threadData->decodeBuffer[threadData->length++] = c;
} else {
// Yes! Process it and set up for the next packet.
threadData->newPacket = 1;
/*
@ -458,13 +471,13 @@ uint8_t packetEncode(PacketThreadDataT *threadData, PacketEncodeDataT *data, cha
}
// Add payload.
while (inputLength--) {
for (x=0; x<inputLength; x++) {
// Is this a frame character? If so, escape it.
if (*inputBuffer == PACKET_FRAME) threadData->encodeBuffer[data->length++] = PACKET_FRAME;
if ((uint8_t)inputBuffer[x] == PACKET_FRAME) threadData->encodeBuffer[data->length++] = PACKET_FRAME;
// CRC data.
crc = packetCRC(inputBuffer, 1, crc);
crc = packetCRC(&inputBuffer[x], 1, crc);
// Add data.
threadData->encodeBuffer[data->length++] = *inputBuffer++;
threadData->encodeBuffer[data->length++] = inputBuffer[x];
}
// Add CRC.

View file

@ -121,6 +121,7 @@ typedef void (*packetSender)(char *data, uint32_t length, void *userData);
char *packetContentPack(uint16_t *length, char *format, ...);
void packetContentUnpack(char *buffer, char *format, ...);
void packetDebugPrint(uint8_t *data, uint16_t length);
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeData, char *input, uint16_t inputLength);
void packetDecodeDataDestroy(PacketDecodeDataT **packet);
void packetDecodeDataStaticDestroy(PacketDecodeDataT *packet);