diff --git a/include/SysConfiguration.h b/include/SysConfiguration.h index 75f28fc..30d6793 100644 --- a/include/SysConfiguration.h +++ b/include/SysConfiguration.h @@ -71,14 +71,12 @@ typedef struct struct { - char bIsOTAEnabled :1; - char bIsResetOTAEnabled :1; - char bIsLedsEnabled :1; ///< Indication LEDs enable - char bIsLoRaConfirm :1; ///< Enable send back confirmation in LoRa channel - char bIsTCPConfirm :1; ///< Enable send back confirmation in TCP channel - char bit5 :1; - char bit6 :1; - char bit7 :1; + bool bIsOTAEnabled; + bool bIsResetOTAEnabled; + bool bIsLedsEnabled; ///< Indication LEDs enable + bool bIsLoRaConfirm; ///< Enable send back confirmation in LoRa channel + bool bIsTCPConfirm; ///< Enable send back confirmation in TCP channel + } Flags1; // Flag structure struct diff --git a/include/SystemApplication.h b/include/SystemApplication.h index 1b0c82a..c24967c 100644 --- a/include/SystemApplication.h +++ b/include/SystemApplication.h @@ -29,6 +29,8 @@ #include "jWrite.h" #define EXPECTED_MAX_DATA_RESPONSE_SIZE (4096) +#define VAR_MAX_NAME_LENGTH 16 +#define VAR_MAX_VALUE_LENGTH 128 typedef enum { @@ -46,6 +48,7 @@ typedef enum SYS_ERROR_PARSE_KEY1, SYS_ERROR_PARSE_KEY2, + SYS_ERROR_PARSE_VARIABLES, SYS_ERROR_NO_MEMORY = 300, SYS_ERROR_UNKNOWN, @@ -61,17 +64,8 @@ typedef enum typedef struct { -int key1; -int key2; -} payload_type_50; - -typedef struct -{ -int key1; -int key2; -} payload_type_10; - +} payload_type_vars; #define DATA_MESSAGE_TYPE_COMMAND (1) @@ -97,6 +91,9 @@ typedef struct int err_code; } data_message_t; +esp_err_t GetConfVar(char* name, char* val); +esp_err_t SetConfVar(char* name, char* val); + esp_err_t SysServiceDataHandler(data_message_t *MSG); sys_error_code SysVarsPayloadHandler(data_message_t *MSG); void GetSysErrorDetales(sys_error_code err, const char **br, const char **ds); diff --git a/src/RestApiHandler.c b/src/RestApiHandler.c index fb7fa2e..3fbda74 100644 --- a/src/RestApiHandler.c +++ b/src/RestApiHandler.c @@ -1,4 +1,4 @@ - /*! Copyright 2023 Bogdan Pilyugin +/*! Copyright 2023 Bogdan Pilyugin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,102 +28,82 @@ extern SYS_CONFIG SysConfig; const rest_var_t ConfigVariables[] = -{ - {0, "netname", &SysConfig.NetBIOSName, VAR_STRING, 3, 31}, - {1, "otaurl", &SysConfig.OTAURL, VAR_STRING, 3, 128} + { + { 0, "netname", &SysConfig.NetBIOSName, VAR_STRING, 3, 31 }, + { 1, "otaurl", &SysConfig.OTAURL, VAR_STRING, 3, 128 }, + { 2, "ledenab", &SysConfig.Flags1.bIsLedsEnabled, VAR_BOOL, 0, 1 }, + { 3, "otaint", &SysConfig.OTAAutoInt, VAR_INT, 0, 65535 } + }; -}; - -esp_err_t SetConfVar(char* valias, rest_var_types* vtype, void* val) +esp_err_t SetConfVar(char *name, char *val) { rest_var_t *V = NULL; - for (int i = 0; i< sizeof(ConfigVariables)/sizeof(rest_var_t); ++i) + for (int i = 0; i < sizeof(ConfigVariables) / sizeof(rest_var_t); ++i) { - if (!strcmp(ConfigVariables[i].alias, valias)) + if (!strcmp(ConfigVariables[i].alias, name)) { - V = &ConfigVariables[i]; + V = (rest_var_t*) (&ConfigVariables[i]); break; } } - if (!V) return ESP_ERR_NOT_FOUND; - int vallen = strlen(val); - if (vallen < V->minlen || vallen >= V->maxlen) - return ESP_ERR_INVALID_ARG; - - switch(*vtype) + if (!V) + return ESP_ERR_NOT_FOUND; + int constr; + switch (V->vartype) { case VAR_BOOL: - V->ref = (val)?true:false; - break; + if (!strcmp(val, "true")) + *((bool*) V->ref) = true; + else if (!strcmp(val, "false")) + *((bool*) V->ref) = 0; + else + return ESP_ERR_INVALID_ARG; + break; case VAR_INT: - V->ref = (int*)val; - break; + constr = atoi(val); + if (constr < V->minlen || constr > V->maxlen) + return ESP_ERR_INVALID_ARG; + *((int*) V->ref) = constr; + break; case VAR_STRING: - strcpy(V->ref, (char*)val); - break; + constr = strlen(val); + if (constr < V->minlen || constr > V->maxlen) + return ESP_ERR_INVALID_ARG; + strcpy(V->ref, val); + break; } return ESP_OK; } - -esp_err_t GetConfVar(char* valias, rest_var_types* vtype, void* val) +esp_err_t GetConfVar(char *name, char *val) { - rest_var_types *faketp = vtype; - void *fakepointer = val; rest_var_t *V = NULL; - for (int i = 0; i< sizeof(ConfigVariables)/sizeof(rest_var_t); ++i) + for (int i = 0; i < sizeof(ConfigVariables) / sizeof(rest_var_t); ++i) { - if (!strcmp(ConfigVariables[i].alias, valias)) + if (!strcmp(ConfigVariables[i].alias, name)) { - V = &ConfigVariables[i]; + V = (rest_var_t*) (&ConfigVariables[i]); break; } } - if (!V) return ESP_ERR_NOT_FOUND; - vtype = &V->vartype; + if (!V) + return ESP_ERR_NOT_FOUND; + switch (V->vartype) + { + case VAR_BOOL: + strcpy(val, *((bool*) V->ref) ? "true" : "false"); + break; + case VAR_INT: + itoa(*((int*) V->ref), val, 10); + break; + case VAR_STRING: + strcpy(val, (char*) V->ref); + break; + + } + val = V->ref; return ESP_OK; } - -sys_error_code SysVarsPayloadHandler(data_message_t *MSG) -{ - struct jReadElement result; - payload_type_50 *payload; - payload = ((payload_type_50*) (MSG->parsedData.payload)); - if (MSG->parsedData.msgType == DATA_MESSAGE_TYPE_COMMAND) - { - //Extract 'key1' or throw exception - jRead(MSG->inputDataBuffer, "{'data'{'payload'{'key1'", &result); - if (result.elements == 1) - { - - } - else - return SYS_ERROR_PARSE_KEY1; - - //Extract 'key1' or throw exception - jRead(MSG->inputDataBuffer, "{'data'{'payload'{'key2'", &result); - if (result.elements == 1) - { - - } - else - return SYS_ERROR_PARSE_KEY2; - //return StartTransactionPayloadType1(MSG); - - } - - else if (MSG->parsedData.msgType == DATA_MESSAGE_TYPE_REQUEST) - { - PrepareResponsePayloadType50(MSG); - return SYS_OK_DATA; - } - else - return SYS_ERROR_PARSE_MSGTYPE; - - return SYS_OK; -} - - diff --git a/src/SysComm.c b/src/SysComm.c index 930e60f..367fd8a 100644 --- a/src/SysComm.c +++ b/src/SysComm.c @@ -22,43 +22,62 @@ */ /* - //Example of remote transaction [payloadtype=1] start[msgtype=1] + //Example of SET [msgtype=1] variables [payloadtype=1] { "data":{ "msgid":123456789, "time":"2023-06-03T12:25:24+00:00", "msgtype":1, - "payloadtype":50, + "payloadtype":1, "payload":{ - "key1":"value1", - "key2":"value2"}}, + "variables":[ + {"name":"variablename1","val":"variablevalue1"}, + {"name":"variablename2","val":"variablevalue2"}, + {"name":"variablename3","val":"variablevalue3"}, + {"name":"variablename4","val":"variablevalue4"}, + {"name":"variablename5","val":"variablevalue5"}, + {"name":"variablename6","val":"variablevalue6"},] + }}, "signature":"6a11b872e8f766673eb82e127b6918a0dc96a42c5c9d184604f9787f3d27bcef"} - - //Example of request [msgtype=2] of information related to transaction [payloadtype=1] + //Example of GET [msgtype=2] variables [payloadtype=1] { "data":{ "msgid":123456789, "time":"2023-06-03T12:25:24+00:00", "msgtype":2, - "payloadtype":50}, + "payloadtype":1 + "payload":{ + "variables":[ + {"name":"variablename1","val":""}, + {"name":"variablename2","val":""}, + {"name":"variablename3","val":""}, + {"name":"variablename4","val":""}, + {"name":"variablename5","val":""}, + {"name":"variablename6","val":""},] + }}, "signature":"3c1254d5b0e7ecc7e662dd6397554f02622ef50edba18d0b30ecb5d53e409bcb"} - //Example of response [msgtype=3] to request related to the transaction [payloadtype=1] + //Example of RESPONSE [msgtype=3] with variables [payloadtype=1] { "data":{ "msgid":123456789, "time":"2023-06-03T12:25:24+00:00", "msgtype": 3, - "payloadtype":50, + "payloadtype":1, "payload":{ - "key1":"value1", - "key2":"value2"}, + "variables":[ + {"name":"variablename1","val":"variablevalue1"}, + {"name":"variablename2","val":"variablevalue2"}, + {"name":"variablename3","val":"variablevalue3"}, + {"name":"variablename4","val":"variablevalue4"}, + {"name":"variablename5","val":"variablevalue5"}, + {"name":"variablename6","val":"variablevalue6"},] + }, "error":"SYS_OK", "error_descr":"Result successful"}, "signature":"0d3b545b7c86274a6bf5a6e606b260f32b1999de40cb7d29d0949ecc9389cd9d"} - */ #include "webguiapp.h" @@ -94,68 +113,76 @@ static void Timestamp(char *ts) sprintf(ts, "%llu", ms); } -void PrepareResponsePayloadType50(data_message_t *MSG) +static sys_error_code SysPayloadTypeVarsHandler(data_message_t *MSG) { + char VarName[VAR_MAX_NAME_LENGTH]; + char VarValue[VAR_MAX_VALUE_LENGTH]; + struct jReadElement result; const char *err_br; const char *err_desc; - jwOpen(MSG->outputDataBuffer, MSG->outputDataLength, JW_OBJECT, JW_PRETTY); + + if (!(MSG->parsedData.msgType == DATA_MESSAGE_TYPE_COMMAND || MSG->parsedData.msgType == DATA_MESSAGE_TYPE_REQUEST)) + return SYS_ERROR_PARSE_MSGTYPE; + + jwOpen(MSG->outputDataBuffer, MSG->outputDataLength, JW_OBJECT, JW_COMPACT); + jwObj_object("data"); jwObj_int("msgid", MSG->parsedData.msgID); char time[RFC3339_TIMESTAMP_LENGTH]; GetRFC3339Time(time); jwObj_string("time", time); jwObj_int("messtype", DATA_MESSAGE_TYPE_RESPONSE); - jwObj_int("payloadtype", 50); - //PAYLOAD BEGIN + jwObj_int("payloadtype", 1); jwObj_object("payload"); + jwObj_array("variables"); - jwObj_string("param1", "value1"); - jwObj_string("param2", "value2"); + jRead(MSG->inputDataBuffer, "{'data'{'payload'{'variables'", &result); + if (result.dataType == JREAD_ARRAY) + { //Write variables + for (int i = 0; i < result.elements; ++i) + { + jRead_string(MSG->inputDataBuffer, "{'data'{'payload'{'variables'[*{'name'", VarName, + VAR_MAX_NAME_LENGTH, + &i); + jRead_string(MSG->inputDataBuffer, "{'data'{'payload'{'variables'[*{'val'", VarValue, + VAR_MAX_VALUE_LENGTH, + &i); + ESP_LOGI(TAG, "Got write variable %s:%s", VarName, VarValue); + jwArr_object(); + if (MSG->parsedData.msgType == DATA_MESSAGE_TYPE_COMMAND) + { //Write variables + esp_err_t res = SetConfVar(VarName, VarValue); + if (res == ESP_OK) + GetConfVar(VarName, VarValue); + else + strcpy(VarValue, esp_err_to_name(res)); + jwObj_string("name", VarName); + jwObj_string("val", VarValue); + } + else + { //Read variables + esp_err_t res = GetConfVar(VarName, VarValue); + if ( res != ESP_OK) + strcpy(VarValue, esp_err_to_name(res)); + jwObj_string("name", VarName); + jwObj_string("val", VarValue); + } + jwEnd(); + } + } + else + return SYS_ERROR_PARSE_VARIABLES; + jwEnd(); jwEnd(); GetSysErrorDetales((sys_error_code) MSG->err_code, &err_br, &err_desc); jwObj_string("error", (char*) err_br); jwObj_string("error_descr", (char*) err_desc); jwEnd(); + jwEnd(); + jwObj_string("signature", "1234567890"); jwClose(); -} -static sys_error_code SysPayloadType50Handler(data_message_t *MSG) -{ - struct jReadElement result; - payload_type_50 *payload; - payload = ((payload_type_50*) (MSG->parsedData.payload)); - if (MSG->parsedData.msgType == DATA_MESSAGE_TYPE_COMMAND) - { - //Extract 'key1' or throw exception - jRead(MSG->inputDataBuffer, "{'data'{'payload'{'key1'", &result); - if (result.elements == 1) - { - - } - else - return SYS_ERROR_PARSE_KEY1; - - //Extract 'key1' or throw exception - jRead(MSG->inputDataBuffer, "{'data'{'payload'{'key2'", &result); - if (result.elements == 1) - { - - } - else - return SYS_ERROR_PARSE_KEY2; - //return StartTransactionPayloadType1(MSG); - - } - - else if (MSG->parsedData.msgType == DATA_MESSAGE_TYPE_REQUEST) - { - PrepareResponsePayloadType50(MSG); - return SYS_OK_DATA; - } - else - return SYS_ERROR_PARSE_MSGTYPE; - - return SYS_OK; + return SYS_OK_DATA; } static sys_error_code SysDataParser(data_message_t *MSG) @@ -230,12 +257,9 @@ static sys_error_code SysDataParser(data_message_t *MSG) switch (MSG->parsedData.payloadType) { - case 50: - MSG->parsedData.payload = malloc(sizeof(payload_type_50)); - return SysPayloadType50Handler(MSG); - case 51: - MSG->parsedData.payload = malloc(sizeof(payload_type_10)); - return SysVarsPayloadHandler(MSG); + case 1: + //MSG->parsedData.payload = malloc(sizeof(payload_type_vars)); Not needed for this case + return SysPayloadTypeVarsHandler(MSG); break; } diff --git a/src/SysConfiguration.c b/src/SysConfiguration.c index 62c13e7..bec1da6 100644 --- a/src/SysConfiguration.c +++ b/src/SysConfiguration.c @@ -58,7 +58,7 @@ #endif #endif -static SYS_CONFIG SysConfig; +SYS_CONFIG SysConfig; #define SPI_LOCK_TIMEOUT_MS (1000) SemaphoreHandle_t xSemaphoreSPIHandle = NULL; diff --git a/src/SysErr.c b/src/SysErr.c index e34442f..863b889 100644 --- a/src/SysErr.c +++ b/src/SysErr.c @@ -44,6 +44,7 @@ const sys_error_t SysErrors[] = { { SYS_ERROR_PARSE_KEY1, "SYS_ERROR_PARSE_KEY1", "Key 'key1' not found or have illegal value"}, { SYS_ERROR_PARSE_KEY2, "SYS_ERROR_PARSE_KEY2", "Key 'key2' not found or have illegal value"}, + { SYS_ERROR_PARSE_VARIABLES, "SYS_ERROR_PARSE_VARIABLES", "Key 'variables' not found or have illegal value"}, { SYS_ERROR_NO_MEMORY, "SYS_ERROR_NO_MEMORY", "ERROR allocate memory for JSON parser" }, { SYS_ERROR_UNKNOWN, "SYS_ERROR_UNKNOWN", "Unknown ERROR" }