Files
maze32/components/maze32_network/maze32_provisioning_protocol.c
T

114 lines
3.5 KiB
C

#include "maze32_provisioning_protocol.h"
#include <ctype.h>
#include <string.h>
static const char *skip_space(const char *cursor, const char *end)
{
while (cursor < end && isspace((unsigned char)*cursor)) {
++cursor;
}
return cursor;
}
static int parse_json_string(const char **cursor_pointer,
const char *end,
char *output,
size_t capacity)
{
const char *cursor = *cursor_pointer;
size_t length = 0U;
if (cursor >= end || *cursor++ != '"') {
return 0;
}
while (cursor < end && *cursor != '"') {
unsigned char value = (unsigned char)*cursor++;
if (value == '\\') {
if (cursor >= end) {
return 0;
}
char escaped = *cursor++;
if (escaped == '"' || escaped == '\\' || escaped == '/') {
value = (unsigned char)escaped;
} else if (escaped == 'b') {
value = '\b';
} else if (escaped == 'f') {
value = '\f';
} else if (escaped == 'n') {
value = '\n';
} else if (escaped == 'r') {
value = '\r';
} else if (escaped == 't') {
value = '\t';
} else {
return 0;
}
}
if (value < 0x20U || length + 1U >= capacity) {
return 0;
}
output[length++] = (char)value;
}
if (cursor >= end || *cursor++ != '"') {
return 0;
}
output[length] = '\0';
*cursor_pointer = cursor;
return 1;
}
int maze32_provisioning_parse_credentials(const char *body,
size_t length,
maze32_wifi_credentials_t *credentials)
{
if (body == NULL || credentials == NULL) {
return 0;
}
const char *cursor = body;
const char *end = body + length;
int have_ssid = 0;
int have_password = 0;
memset(credentials, 0, sizeof(*credentials));
cursor = skip_space(cursor, end);
if (cursor >= end || *cursor++ != '{') {
return 0;
}
for (int field_index = 0; field_index < 2; ++field_index) {
char key[12];
char value[MAZE32_WIFI_PASSWORD_MAX_BYTES + 1U];
cursor = skip_space(cursor, end);
if (!parse_json_string(&cursor, end, key, sizeof(key))) {
return 0;
}
cursor = skip_space(cursor, end);
if (cursor >= end || *cursor++ != ':') {
return 0;
}
cursor = skip_space(cursor, end);
if (!parse_json_string(&cursor, end, value, sizeof(value))) {
return 0;
}
if (strcmp(key, "ssid") == 0 && !have_ssid &&
strlen(value) <= MAZE32_WIFI_SSID_MAX_BYTES) {
memcpy(credentials->ssid, value, strlen(value) + 1U);
have_ssid = 1;
} else if (strcmp(key, "password") == 0 && !have_password) {
memcpy(credentials->password, value, strlen(value) + 1U);
have_password = 1;
} else {
return 0;
}
cursor = skip_space(cursor, end);
if (field_index == 0 && (cursor >= end || *cursor++ != ',')) {
return 0;
}
}
cursor = skip_space(cursor, end);
if (cursor >= end || *cursor++ != '}') {
return 0;
}
cursor = skip_space(cursor, end);
return cursor == end && have_ssid && have_password &&
maze32_wifi_credentials_validate(credentials) == MAZE32_WIFI_CONFIG_VALID;
}