integrated new REST data format

This commit is contained in:
Bogdan Pilyugin 2023-07-26 15:11:23 +02:00
parent 93c35bf7da
commit c76fe416e0
17 changed files with 619 additions and 36 deletions

View File

@ -25,7 +25,7 @@ idf_component_register(
PRIV_INCLUDE_DIRS ${libespfs_PRIV_INCLUDE_DIRS}
PRIV_REQUIRES ${libespfs_PRIV_REQUIRES}
SRCS "src/WebGUIAppMain.c"
SRCS "src/SysConfiguration.c"
"src/romfs.c"
"src/spifs.c"
"src/HTTPServer.c"
@ -41,6 +41,9 @@ idf_component_register(
"src/MQTT.c"
"src/MQTTSysHandler.c"
src/OTA.c
src/RestApiHandler.c
src/SysComm.c
src/SysErr.c
# "src/mDNS.c"
INCLUDE_DIRS "."

View File

@ -41,7 +41,7 @@
#include "esp_netif.h"
#include "esp_eth.h"
#include "mbedtls/base64.h"
#include "WebGUIAppMain.h"
#include "SysConfiguration.h"
#define MAX_DYNVAR_NAME_LENGTH 32
#define MAX_DYNVAR_LENGTH 256

View File

@ -29,6 +29,24 @@
#include "esp_netif.h"
#include "sdkconfig.h"
typedef enum{
VAR_BOOL = 0,
VAR_INT,
VAR_STRING
} rest_var_types;
typedef struct
{
int id;
char alias[32];
void* ref;
rest_var_types vartype;
int minlen;
int maxlen;
} rest_var_t;
// Application-dependent structure used to contain address information
/**

View File

@ -0,0 +1,96 @@
/*! 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file SystemApplication.h
* \version 1.0
* \date 2023-07-26
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#ifndef COMPONENTS_WEBGUIAPP_INCLUDE_SYSTEMAPPLICATION_H_
#define COMPONENTS_WEBGUIAPP_INCLUDE_SYSTEMAPPLICATION_H_
#include "webguiapp.h"
#include "esp_err.h"
#include "jRead.h"
#include "jWrite.h"
#define EXPECTED_MAX_DATA_RESPONSE_SIZE (4096)
typedef enum
{
SYS_OK_DATA = 0,
SYS_OK,
SYS_ERROR_WRONG_JSON_FORMAT = 200,
SYS_ERROR_PARSE_DATA,
SYS_ERROR_SHA256_DATA,
SYS_ERROR_PARSE_SIGNATURE,
SYS_ERROR_PARSE_MESSAGEID,
SYS_ERROR_PARSE_MSGTYPE,
SYS_ERROR_PARSE_PAYLOADTYPE,
SYS_ERROR_PARSE_KEY1,
SYS_ERROR_PARSE_KEY2,
SYS_ERROR_NO_MEMORY = 300,
SYS_ERROR_UNKNOWN,
} sys_error_code;
typedef enum
{
MSG_COMMAND = 1,
MSG_REQUEST,
MSG_RESPONSE
} msg_type;
typedef struct
{
int key1;
int key2;
} payload_type_50;
#define DATA_MESSAGE_TYPE_COMMAND (1)
#define DATA_MESSAGE_TYPE_REQUEST (2)
#define DATA_MESSAGE_TYPE_RESPONSE (3)
typedef struct
{
char *inputDataBuffer;
int inputDataLength;
int chlidx;
char *outputDataBuffer;
int outputDataLength;
struct
{
uint64_t msgID;
time_t time;
int msgType;
int payloadType;
void *payload;
unsigned char sha256[32];
} parsedData;
int err_code;
} data_message_t;
esp_err_t SysServiceDataHandler(data_message_t *MSG);
void GetSysErrorDetales(sys_error_code err, const char **br, const char **ds);
#endif /* COMPONENTS_WEBGUIAPP_INCLUDE_SYSTEMAPPLICATION_H_ */

View File

@ -21,7 +21,7 @@
#include <stdio.h>
#include <string.h>
#include <WebGUIAppMain.h>
#include <SysConfiguration.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_netif.h"

View File

@ -21,7 +21,7 @@
#include <string.h>
#include "../include/WebGUIAppMain.h"
#include "../include/SysConfiguration.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"

View File

@ -20,10 +20,10 @@
*/
#include "HTTPServer.h"
#include "jWrite.h"
#include "jRead.h"
#include "SystemApplication.h"
#define API_VER "1.00"
#define SYS_API_VER "1.00"
#define TAG "HTTPAPISystem"
HTTP_IO_RESULT HTTPPostSysAPI(httpd_req_t *req, char *PostData)
{
@ -31,23 +31,26 @@ HTTP_IO_RESULT HTTPPostSysAPI(httpd_req_t *req, char *PostData)
httpd_req_get_hdr_value_str(req, "Content-Type", (char*) data, 31);
if (!memcmp(data, "application/json", sizeof("application/json")))
{
char key[32] = {0};
struct jReadElement result;
jRead(PostData, "", &result);
if (result.dataType == JREAD_OBJECT)
char *respbuf = malloc(EXPECTED_MAX_DATA_RESPONSE_SIZE);
if (respbuf)
{
jRead_string(PostData, "{'key'", key, sizeof(key), NULL);
data_message_t M = { 0 };
M.inputDataBuffer = PostData;
M.inputDataLength = strlen(PostData);
M.chlidx = 100;
M.outputDataBuffer = respbuf;
M.outputDataLength = EXPECTED_MAX_DATA_RESPONSE_SIZE;
SysServiceDataHandler(&M);
httpd_resp_sendstr(req, respbuf);
free(respbuf);
return HTTP_IO_DONE_API;
}
else
{
ESP_LOGE(TAG, "Out of free RAM for HTTP API handle");
httpd_resp_set_status(req, HTTPD_500);
return HTTP_IO_DONE_API;
}
//ESP_LOGI(TAG, "JSON data:%s", PostData);
jwOpen(data, sizeof(data), JW_OBJECT, JW_COMPACT);
jwObj_string("apiver", API_VER);
jwObj_string("key", key);;
jwObj_raw("result", "OK");
jwEnd();
jwClose();
httpd_resp_sendstr(req, data);
return HTTP_IO_DONE_API;
}
httpd_resp_set_status(req, HTTPD_400);

View File

@ -363,11 +363,8 @@ static esp_err_t GETHandler(httpd_req_t *req)
//check if the file can contains dynamic variables
if (IS_FILE_EXT(filename, ".html") ||
IS_FILE_EXT(filename, ".json") ||
IS_FILE_EXT(filename, ".css") ||
IS_FILE_EXT(filename, ".js"))
isDynamicVars = false;
if (IS_FILE_EXT(filename, ".json") )
isDynamicVars = true;
//check if file is compressed by GZIP and add correspondent header

View File

@ -28,7 +28,8 @@
#include "NetTransport.h"
#include "webguiapp.h"
#include "LoRaWAN.h"
#include "../include/WebGUIAppMain.h"
#include "../include/SysConfiguration.h"
// Pins and other resources
/*Defined in global configuration*/

View File

@ -18,7 +18,8 @@
* Author: Bogdan Pilyugin
* Description:
*/
#include <WebGUIAppMain.h>
#include <SysConfiguration.h>
#include <SystemApplication.h>
#include "esp_log.h"
#include "Helpers.h"
#include "NetTransport.h"
@ -108,6 +109,30 @@ void ComposeTopic(char *topic, int idx, char *service_name, char *direct)
strcat((char*) topic, direct); // Data direction UPLINK or DOWNLINK
}
esp_err_t SysServiceMQTTSend(char *data, int len, int idx)
{
if (GetMQTTHandlesPool(idx)->mqtt_queue == NULL)
return ESP_ERR_NOT_FOUND;
char *buf = (char*) malloc(len);
if (buf)
{
memcpy(buf, data, len);
MQTT_DATA_SEND_STRUCT DSS;
ComposeTopic(DSS.topic, idx, "SYSTEM", "UPLINK");
DSS.raw_data_ptr = buf;
DSS.data_length = len;
if (xQueueSend(GetMQTTHandlesPool(idx)->mqtt_queue, &DSS, pdMS_TO_TICKS(1000)) == pdPASS)
return ESP_OK;
else
{
free(buf);
return ESP_ERR_TIMEOUT;
}
}
return ESP_ERR_NO_MEM;
}
static void mqtt_system_event_handler(int idx, void *handler_args, esp_event_base_t base, int32_t event_id,
void *event_data)
{
@ -174,10 +199,26 @@ static void mqtt_system_event_handler(int idx, void *handler_args, esp_event_bas
ComposeTopic(topic, idx, "SYSTEM", "DWLINK");
if (!memcmp(topic, event->topic, event->topic_len))
{
SystemDataHandler(event->data, event->data_len, idx);
#if MQTT_DEBUG_MODE > 0
ESP_LOGI(TAG, "Control data handler on client %d", idx);
//SystemDataHandler(event->data, event->data_len, idx); //Old API
char *respbuf = malloc(EXPECTED_MAX_DATA_RESPONSE_SIZE);
if (respbuf != NULL)
{
data_message_t M = { 0 };
M.inputDataBuffer = event->data;
M.inputDataLength = event->data_len;
M.chlidx = idx;
M.outputDataBuffer = respbuf;
M.outputDataLength = EXPECTED_MAX_DATA_RESPONSE_SIZE;
SysServiceDataHandler(&M);
SysServiceMQTTSend(M.outputDataBuffer, strlen(M.outputDataBuffer), idx);
free(respbuf);
#if(MQTT_DEBUG_MODE > 0)
ESP_LOGI(TAG, "SERVICE data handler on client %d", idx);
#endif
}
else
ESP_LOGE(TAG, "Out of free RAM for MQTT API handle");
}
break;
case MQTT_EVENT_ERROR:

View File

@ -19,7 +19,7 @@
* Description:
*/
#include <WebGUIAppMain.h>
#include <SysConfiguration.h>
#include "NetTransport.h"
#include "sdkconfig.h"
#include "lwip/netif.h"

View File

@ -34,7 +34,7 @@
#include "nvs.h"
#include <sys/socket.h>
#include <WebGUIAppMain.h>
#include <SysConfiguration.h>
#include "NetTransport.h"
TaskHandle_t ota_task_handle;

88
src/RestApiHandler.c Normal file
View File

@ -0,0 +1,88 @@
/*! 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file RestApiHandler.c
* \version 1.0
* \date 2023-07-26
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#include <SysConfiguration.h>
#include <webguiapp.h>
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}
};
esp_err_t SetConfVar(char* valias, rest_var_types* vtype, void* val)
{
rest_var_t *V = NULL;
for (int i = 0; i< sizeof(ConfigVariables)/sizeof(rest_var_t); ++i)
{
if (!strcmp(ConfigVariables[i].alias, valias))
{
V = &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)
{
case VAR_BOOL:
V->ref = (val)?true:false;
break;
case VAR_INT:
V->ref = (int*)val;
break;
case VAR_STRING:
strcpy(V->ref, (char*)val);
break;
}
return ESP_OK;
}
esp_err_t GetConfVar(char* valias, rest_var_types* vtype, void* 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)
{
if (!strcmp(ConfigVariables[i].alias, valias))
{
V = &ConfigVariables[i];
break;
}
}
if (!V) return ESP_ERR_NOT_FOUND;
vtype = &V->vartype;
val = V->ref;
return ESP_OK;
}

263
src/SysComm.c Normal file
View File

@ -0,0 +1,263 @@
/*! 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file SysComm.c
* \version 1.0
* \date 2023-07-26
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
/*
//Example of remote transaction [payloadtype=1] start[msgtype=1]
{
"data":{
"msgid":123456789,
"time":"2023-06-03T12:25:24+00:00",
"msgtype":1,
"payloadtype":50,
"payload":{
"key1":"value1",
"key2":"value2"}},
"signature":"6a11b872e8f766673eb82e127b6918a0dc96a42c5c9d184604f9787f3d27bcef"}
//Example of request [msgtype=2] of information related to transaction [payloadtype=1]
{
"data":{
"msgid":123456789,
"time":"2023-06-03T12:25:24+00:00",
"msgtype":2,
"payloadtype":50},
"signature":"3c1254d5b0e7ecc7e662dd6397554f02622ef50edba18d0b30ecb5d53e409bcb"}
//Example of response [msgtype=3] to request related to the transaction [payloadtype=1]
{
"data":{
"msgid":123456789,
"time":"2023-06-03T12:25:24+00:00",
"msgtype": 3,
"payloadtype":50,
"payload":{
"key1":"value1",
"key2":"value2"},
"error":"SYS_OK",
"error_descr":"Result successful"},
"signature":"0d3b545b7c86274a6bf5a6e606b260f32b1999de40cb7d29d0949ecc9389cd9d"}
*/
#include "webguiapp.h"
#include "SystemApplication.h"
#include "mbedtls/md.h"
#define TAG "SysComm"
#define MAX_JSON_DATA_SIZE 1024
static esp_err_t SHA256hmacHash(unsigned char *data,
int datalen,
unsigned char *key,
int keylen,
unsigned char *res)
{
mbedtls_md_context_t ctx;
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
mbedtls_md_init(&ctx);
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1);
mbedtls_md_hmac_starts(&ctx, key, keylen);
mbedtls_md_hmac_update(&ctx, (const unsigned char*) data, datalen);
mbedtls_md_hmac_finish(&ctx, res);
mbedtls_md_free(&ctx);
return ESP_OK;
}
static void Timestamp(char *ts)
{
struct timeval tp;
gettimeofday(&tp, NULL);
unsigned long long ms = (((unsigned long long) tp.tv_sec) * 1000000 + tp.tv_usec);
sprintf(ts, "%llu", ms);
}
void PrepareResponsePayloadType50(data_message_t *MSG)
{
const char *err_br;
const char *err_desc;
jwOpen(MSG->outputDataBuffer, MSG->outputDataLength, JW_OBJECT, JW_PRETTY);
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_object("payload");
jwObj_string("param1", "value1");
jwObj_string("param2", "value2");
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();
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;
}
static sys_error_code SysDataParser(data_message_t *MSG)
{
struct jReadElement result;
jRead(MSG->inputDataBuffer, "", &result);
if (result.dataType != JREAD_OBJECT)
return SYS_ERROR_WRONG_JSON_FORMAT;
MSG->parsedData.msgID = 0;
char *hashbuf = malloc(MSG->inputDataLength);
if (hashbuf == NULL)
return SYS_ERROR_NO_MEMORY;
jRead_string(MSG->inputDataBuffer, "{'data'", hashbuf, MSG->inputDataLength, 0);
if (strlen(hashbuf) > 0)
{
SHA256hmacHash((unsigned char*) hashbuf, strlen(hashbuf), (unsigned char*) "mykey", sizeof("mykey"),
MSG->parsedData.sha256);
unsigned char sha_print[32 * 2 + 1];
BytesToStr(MSG->parsedData.sha256, sha_print, 32);
sha_print[32 * 2] = 0x00;
ESP_LOGI(TAG, "SHA256 of DATA object is %s", sha_print);
free(hashbuf);
}
else
{
free(hashbuf);
return SYS_ERROR_PARSE_DATA;
}
jRead(MSG->inputDataBuffer, "{'signature'", &result);
if (result.elements == 1)
{
ESP_LOGI(TAG, "Signature is %.*s", 64, (char* )result.pValue);
//Here compare calculated and received signature;
}
else
return SYS_ERROR_PARSE_SIGNATURE;
//Extract 'messidx' or throw exception
jRead(MSG->inputDataBuffer, "{'data'{'msgid'", &result);
if (result.elements == 1)
{
MSG->parsedData.msgID = jRead_long(MSG->inputDataBuffer, "{'data'{'msgid'", 0);
if (MSG->parsedData.msgID == 0)
return SYS_ERROR_PARSE_MESSAGEID;
}
else
return SYS_ERROR_PARSE_MESSAGEID;
//Extract 'msgtype' or throw exception
jRead(MSG->inputDataBuffer, "{'data'{'msgtype'", &result);
if (result.elements == 1)
{
MSG->parsedData.msgType = atoi((char*) result.pValue);
if (MSG->parsedData.msgType > 2 || MSG->parsedData.msgType < 1)
return SYS_ERROR_PARSE_MSGTYPE;
}
else
return SYS_ERROR_PARSE_MSGTYPE;
//Extract 'payloadtype' or throw exception
jRead(MSG->inputDataBuffer, "{'data'{'payloadtype'", &result);
if (result.elements == 1)
{
MSG->parsedData.payloadType = atoi((char*) result.pValue);
if (MSG->parsedData.payloadType < 1 && MSG->parsedData.payloadType > 100)
return SYS_ERROR_PARSE_PAYLOADTYPE;
MSG->parsedData.payload = malloc(sizeof(payload_type_50));
}
else
return SYS_ERROR_PARSE_PAYLOADTYPE;
switch (MSG->parsedData.payloadType)
{
case 50:
return SysPayloadType50Handler(MSG);
break;
}
return SYS_ERROR_UNKNOWN;
}
esp_err_t SysServiceDataHandler(data_message_t *MSG)
{
MSG->err_code = (int) SysDataParser(MSG);
if (MSG->err_code)
{
jwOpen(MSG->outputDataBuffer, MSG->outputDataLength, JW_OBJECT, JW_PRETTY);
jwObj_int("msgid", MSG->parsedData.msgID);
char time[RFC3339_TIMESTAMP_LENGTH];
GetRFC3339Time(time);
jwObj_string("time", time);
jwObj_int("messtype", DATA_MESSAGE_TYPE_RESPONSE);
const char *err_br;
const char *err_desc;
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();
jwClose();
}
return ESP_OK;
}

View File

@ -21,8 +21,9 @@
* \copyright Apache License, Version 2.0
*/
#include "WebGUIAppMain.h"
#include "../include/SysConfiguration.h"
#include "SystemApplication.h"
#include <webguiapp.h>
#include "stdlib.h"
#include "string.h"

72
src/SysErr.c Normal file
View File

@ -0,0 +1,72 @@
/*! 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* \file SysErr.c
* \version 1.0
* \date 2023-07-26
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#include "SystemApplication.h"
typedef struct
{
sys_error_code errcode;
char *errbreaf;
char *errdescr;
} sys_error_t;
const sys_error_t SysErrors[] = {
{SYS_OK_DATA, "SYS_OK_DATA", "Result successful, data attached" },
{SYS_OK, "SYS_OK", "Result successful" },
{ SYS_ERROR_WRONG_JSON_FORMAT, "SYS_ERROR_WRONG_JSON_FORMAT", "Wrong JSON format or not JSON data" },
{ SYS_ERROR_PARSE_DATA, "SYS_ERROR_PARSE_PAYLOAD", "Payload object not found"},
{ SYS_ERROR_SHA256_DATA, "SYS_ERROR_SHA256_PAYLOAD", "SHA256 signature is not valid"},
{ SYS_ERROR_PARSE_SIGNATURE, "SYS_ERROR_PARSE_SIGNATURE", "Key 'signature' not found"},
{ SYS_ERROR_PARSE_MESSAGEID, "SYS_ERROR_PARSE_MESSAGEID", "Key 'msgid' not found or have illegal value" },
{ SYS_ERROR_PARSE_MSGTYPE, "SYS_ERROR_PARSE_MSGTYPE", "Key 'msgtype' not found or have illegal value"},
{ SYS_ERROR_PARSE_PAYLOADTYPE, "SYS_ERROR_PARSE_PAYLOADTYPE", "Key 'payloadtype' not found or have illegal value"},
{ 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_NO_MEMORY, "SYS_ERROR_NO_MEMORY", "ERROR allocate memory for JSON parser" },
{ SYS_ERROR_UNKNOWN, "SYS_ERROR_UNKNOWN", "Unknown ERROR" }
};
void GetSysErrorDetales(sys_error_code err, const char **br, const char **ds)
{
*br = SysErrors[sizeof(SysErrors) / sizeof(sys_error_t) - 1].errbreaf;
*ds = SysErrors[sizeof(SysErrors) / sizeof(sys_error_t) - 1].errdescr;
for (int i = 0; i < sizeof(SysErrors) / sizeof(sys_error_t); i++)
{
if (err == SysErrors[i].errcode)
{
*br = SysErrors[i].errbreaf;
*ds = SysErrors[i].errdescr;
return;
}
}
return;
}
#define TAG "SysErr"

View File

@ -19,7 +19,7 @@
* Description:
*/
#include "WebGUIAppMain.h"
#include <SysConfiguration.h>
#include "esp_log.h"
#include "Helpers.h"
#include "esp_system.h"