now all api variables handle in webguiapp component

This commit is contained in:
Bogdan Pilyugin 2023-08-17 11:38:07 +02:00
parent 54eaadf551
commit f69835c8d4
9 changed files with 10 additions and 540 deletions

@ -1 +1 @@
Subproject commit 4ec665e5d97a3762a403291ea6978210554c5bad
Subproject commit ac3be6bfdc745ec23e97961657fc9bc19e55333f

View File

@ -1,111 +0,0 @@
/* 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 name: Application.h
* Project: webguiapp_ref_implement
* Created on: 2023-06-10
* Author: bogdan
* Description:
*/
#ifndef MAIN_INCLUDE_APPLICATION_H_
#define MAIN_INCLUDE_APPLICATION_H_
#include "webguiapp.h"
#include "esp_err.h"
#include "AppConfiguration.h"
#include "SystemApplication.h"
typedef enum
{
APP_OK_DATA = 0,
APP_OK,
APP_ERROR_WRONG_JSON_FORMAT = 200,
APP_ERROR_PARSE_DATA,
APP_ERROR_SHA256_DATA,
APP_ERROR_PARSE_SIGNATURE,
APP_ERROR_PARSE_MESSAGEID,
APP_ERROR_PARSE_MSGTYPE,
APP_ERROR_PARSE_PAYLOADTYPE,
APP_ERROR_PARSE_KEY1,
APP_ERROR_PARSE_KEY2,
APP_ERROR_NO_MEMORY = 300,
APP_ERROR_UNKNOWN,
} app_error_code;
typedef enum
{
APP_MSG_COMMAND = 1,
APP_MSG_REQUEST,
APP_MSG_RESPONSE
} app_msg_type;
typedef struct
{
int key1;
int key2;
} payload_type_1;
#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;
*/
typedef struct
{
char transID[64];
char transTime[32];
int64_t transact_sm_timer; // ocpp state machine timeout timer
int64_t interpulse_timer;
bool isActive;
bool isInitialised;
int idx;
} app_handle_t;
esp_err_t AppServiceDataHandler(data_message_t *MSG);
void GetAppErrorDetales(app_error_code err, const char **br, const char **ds);
HTTP_IO_RESULT HTTPPostCustomAPI(httpd_req_t *req, char *PostData);
#endif /* MAIN_INCLUDE_APPLICATION_H_ */

View File

@ -1,290 +0,0 @@
/*! 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 SpiralControllerComm.c
* \version 1.0
* \date 2023-06-03
* \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":1,
"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":1},
"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":1,
"payload":{
"key1":"value1",
"key2":"value2"},
"error":"APP_OK",
"error_descr":"Result successful"},
"signature":"0d3b545b7c86274a6bf5a6e606b260f32b1999de40cb7d29d0949ecc9389cd9d"}
*/
#include "webguiapp.h"
#include "Application.h"
#include "mbedtls/md.h"
#define TAG "AppComm"
#define MAX_JSON_DATA_SIZE 1024
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);
}
app_error_code StartTransactionPayloadType1(data_message_t *MSG)
{
payload_type_1 *payload;
payload = ((payload_type_1*) (MSG->parsedData.payload));
return APP_OK;
}
void PrepareResponsePayloadType1(data_message_t *MSG)
{
const char *err_br;
const char *err_desc;
struct jWriteControl jwc;
jwOpen(&jwc, MSG->outputDataBuffer, MSG->outputDataLength, JW_OBJECT, JW_PRETTY);
jwObj_int(&jwc, "msgid", MSG->parsedData.msgID);
char time[RFC3339_TIMESTAMP_LENGTH];
GetRFC3339Time(time);
jwObj_string(&jwc, "time", time);
jwObj_int(&jwc, "messtype", DATA_MESSAGE_TYPE_RESPONSE);
jwObj_int(&jwc, "payloadtype", 1);
//PAYLOAD BEGIN
jwObj_object(&jwc, "payload");
jwObj_string(&jwc, "param1", "value1");
jwObj_string(&jwc, "param2", "value2");
jwEnd(&jwc);
GetAppErrorDetales((app_error_code) MSG->err_code, &err_br, &err_desc);
jwObj_string(&jwc, "error", (char*) err_br);
jwObj_string(&jwc, "error_descr", (char*) err_desc);
jwEnd(&jwc);
jwClose(&jwc);
}
static app_error_code AppPayloadType1Handler(data_message_t *MSG)
{
struct jReadElement result;
payload_type_1 *payload;
payload = ((payload_type_1*) (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 APP_ERROR_PARSE_KEY1;
//Extract 'key1' or throw exception
jRead(MSG->inputDataBuffer, "{'data'{'payload'{'key2'", &result);
if (result.elements == 1)
{
}
else
return APP_ERROR_PARSE_KEY2;
return StartTransactionPayloadType1(MSG);
}
else if (MSG->parsedData.msgType == DATA_MESSAGE_TYPE_REQUEST)
{
jRead(MSG->inputDataBuffer, "{'data'{'payload'{'key1'", &result);
if (result.elements == 1)
{
return APP_OK_DATA;
}
else
{
}
}
else
return APP_ERROR_PARSE_MSGTYPE;
return APP_OK;
}
static app_error_code AppDataParser(data_message_t *MSG)
{
struct jReadElement result;
jRead(MSG->inputDataBuffer, "", &result);
if (result.dataType != JREAD_OBJECT)
return APP_ERROR_WRONG_JSON_FORMAT;
MSG->parsedData.msgID = 0;
char *hashbuf = malloc(MSG->inputDataLength);
if (hashbuf == NULL)
return APP_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 APP_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 APP_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 APP_ERROR_PARSE_MESSAGEID;
}
else
return APP_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 APP_ERROR_PARSE_MSGTYPE;
}
else
return APP_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 > 2)
return APP_ERROR_PARSE_PAYLOADTYPE;
MSG->parsedData.payload = malloc(sizeof(payload_type_1));
}
else
return APP_ERROR_PARSE_PAYLOADTYPE;
switch (MSG->parsedData.payloadType)
{
case 1:
return AppPayloadType1Handler(MSG);
}
return APP_ERROR_UNKNOWN;
}
esp_err_t AppServiceDataHandler(data_message_t *MSG)
{
MSG->err_code = (int) AppDataParser(MSG);
if (MSG->err_code)
{
struct jWriteControl jwc;
jwOpen(&jwc, MSG->outputDataBuffer, MSG->outputDataLength, JW_OBJECT, JW_PRETTY);
jwObj_int(&jwc, "msgid", MSG->parsedData.msgID);
char time[RFC3339_TIMESTAMP_LENGTH];
GetRFC3339Time(time);
jwObj_string(&jwc, "time", time);
jwObj_int(&jwc, "messtype", DATA_MESSAGE_TYPE_RESPONSE);
const char *err_br;
const char *err_desc;
GetAppErrorDetales((app_error_code) MSG->err_code, &err_br, &err_desc);
jwObj_string(&jwc, "error", (char*) err_br);
jwObj_string(&jwc, "error_descr", (char*) err_desc);
jwEnd(&jwc);
jwClose(&jwc);
}
return ESP_OK;
}

View File

@ -1,71 +0,0 @@
/*! 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 SpiralControllerErr.c
* \version 1.0
* \date 2023-06-03
* \author Bogdan Pilyugin
* \brief
* \details
* \copyright Apache License, Version 2.0
*/
#include "Application.h"
#define TAG "AppErr"
typedef struct
{
app_error_code errcode;
char *errbreaf;
char *errdescr;
} spiral_error_t;
const spiral_error_t Errors[] = {
{APP_OK_DATA, "APP_OK_DATA", "Result successful, data attached" },
{APP_OK, "APP_OK", "Result successful" },
{ APP_ERROR_WRONG_JSON_FORMAT, "APP_ERROR_WRONG_JSON_FORMAT", "Wrong JSON format or not JSON data" },
{ APP_ERROR_PARSE_DATA, "APP_ERROR_PARSE_PAYLOAD", "Payload object not found"},
{ APP_ERROR_SHA256_DATA, "APP_ERROR_SHA256_PAYLOAD", "SHA256 signature is not valid"},
{ APP_ERROR_PARSE_SIGNATURE, "APP_ERROR_PARSE_SIGNATURE", "Key 'signature' not found"},
{ APP_ERROR_PARSE_MESSAGEID, "APP_ERROR_PARSE_MESSAGEID", "Key 'msgid' not found or have illegal value" },
{ APP_ERROR_PARSE_MSGTYPE, "APP_ERROR_PARSE_MSGTYPE", "Key 'msgtype' not found or have illegal value"},
{ APP_ERROR_PARSE_PAYLOADTYPE, "APP_ERROR_PARSE_PAYLOADTYPE", "Key 'payloadtype' not found or have illegal value"},
{ APP_ERROR_PARSE_KEY1, "APP_ERROR_PARSE_KEY1", "Key 'key1' not found or have illegal value"},
{ APP_ERROR_PARSE_KEY2, "APP_ERROR_PARSE_KEY2", "Key 'key2' not found or have illegal value"},
{ APP_ERROR_NO_MEMORY, "APP_ERROR_NO_MEMORY", "ERROR allocate memory for JSON parser" },
{ APP_ERROR_UNKNOWN, "APP_ERROR_UNKNOWN", "Unknown ERROR" }
};
void GetAppErrorDetales(app_error_code err, const char **br, const char **ds)
{
*br = Errors[sizeof(Errors) / sizeof(spiral_error_t) - 1].errbreaf;
*ds = Errors[sizeof(Errors) / sizeof(spiral_error_t) - 1].errdescr;
for (int i = 0; i < sizeof(Errors) / sizeof(spiral_error_t); i++)
{
if (err == Errors[i].errcode)
{
*br = Errors[i].errbreaf;
*ds = Errors[i].errdescr;
return;
}
}
return;
}

View File

@ -1,58 +0,0 @@
/* 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 name: HTTPAPICustom.c
* Project: webguiapp_ref_implement
* Created on: 2023-06-10
* Author: bogdan
* Description:
*/
#include "webguiapp.h"
#include "Application.h"
#define USER_API_VER "1.00"
#define TAG "HTTPAPICustom"
HTTP_IO_RESULT HTTPPostCustomAPI(httpd_req_t *req, char *PostData)
{
char data[1024];
httpd_req_get_hdr_value_str(req, "Content-Type", (char*) data, 31);
if (!memcmp(data, "application/json", sizeof("application/json")))
{
char *respbuf = malloc(EXPECTED_MAX_DATA_RESPONSE_SIZE);
if (respbuf)
{
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;
AppServiceDataHandler(&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;
}
}
httpd_resp_set_status(req, HTTPD_400);
return HTTP_IO_DONE_API;
}

View File

@ -22,7 +22,6 @@
*/
#include "webguiapp.h"
#include "AppConfiguration.h"
#include "Application.h"
#include "CronTimers.h"
const char pg_40[] = "index40.html";
@ -30,7 +29,7 @@ const char pg_42[] = "index42.html";
const char pg_43[] = "index43.html";
const char pg_44[] = "index44.html";
const char url_application[] = "application.html";
const char url_api[] = "api";
static HTTP_IO_RESULT HTTPPostIndex40(httpd_req_t *req, char *PostData);
static HTTP_IO_RESULT HTTPPostIndex42(httpd_req_t *req, char *PostData);
@ -40,8 +39,6 @@ static HTTP_IO_RESULT HTTPPostApplication(httpd_req_t *req, char *PostData);
HTTP_IO_RESULT AfterPostHandlerCustom(httpd_req_t *req, const char *filename, char *PostData)
{
if (!memcmp(filename, url_api, sizeof(url_api)))
return HTTPPostCustomAPI(req, PostData);
if (!memcmp(filename, pg_40, sizeof(pg_40)))
return HTTPPostIndex40(req, PostData);
if (!memcmp(filename, pg_42, sizeof(pg_42)))

View File

@ -21,7 +21,6 @@
* \copyright Apache License, Version 2.0
*/
#include "webguiapp.h"
#include "jWrite.h"
#include "AppConfiguration.h"
#include "CronTimers.h"

View File

@ -21,7 +21,7 @@
* \copyright Apache License, Version 2.0
*/
#include "Application.h"
#include "webguiapp.h"
#define TAG "MQTTCustom"
@ -130,8 +130,12 @@ void UserMQTTEventHndlr(int idx, void *handler_args, esp_event_base_t base, int3
M.chlidx = idx;
M.outputDataBuffer = respbuf;
M.outputDataLength = EXPECTED_MAX_DATA_RESPONSE_SIZE;
AppServiceDataHandler(&M);
SysServiceDataHandler(&M);
//AppServiceDataHandler(&M);
AppServiceMQTTSend(M.outputDataBuffer, strlen(M.outputDataBuffer), idx);
free(respbuf);
#if(MQTT_CUSTOM_HANDLER_DEBUG > 0)
ESP_LOGI(TAG, "SERVICE data handler on client %d", idx);

View File

@ -21,8 +21,8 @@
* \copyright Apache License, Version 2.0
*/
#include "Application.h"
#include "SystemApplication.h"
#include "webguiapp.h"
#include "AppConfiguration.h"
extern APP_CONFIG AppConfig;