Parse sync response from server

This commit is contained in:
2024-09-28 16:35:05 +02:00
parent 5704f2b57f
commit 58abf4ec9b
10 changed files with 205 additions and 23 deletions

View File

@ -1,4 +1,4 @@
idf_component_register(SRCS "jwt.c" "secure_api.c" "http_client.c" "ethernet.c" "unsecure_api.c" "system.c" "crypto.c" "random.c" "storage.c" "main.c"
idf_component_register(SRCS "sync_response.c" "jwt.c" "secure_api.c" "http_client.c" "ethernet.c" "unsecure_api.c" "system.c" "crypto.c" "random.c" "storage.c" "main.c"
"dev_name.c"
INCLUDE_DIRS ".")

View File

@ -43,4 +43,9 @@
/**
* Secure origin len
*/
#define SEC_ORIG_LEN 255
#define SEC_ORIG_LEN 255
/**
* Interval of time (in seconds) between two synchronisations
*/
#define SYNC_TIME_INTERVAL 5

View File

@ -21,6 +21,8 @@ void app_main(void)
ESP_LOGI(TAG, "SolarEnergy WT32-ETH01 device");
// TODO : turn off all relays
// Initialize storage
if (storage_init() == false)
{
@ -167,22 +169,40 @@ void app_main(void)
// Main loop
ESP_LOGI(TAG, "Starting main loop");
// TODO : implement more properly
size_t fails = 0;
while (true)
{
if (!secure_api_sync_device())
sync_response *res = secure_api_sync_device();
if (!res)
{
fails += 1;
ESP_LOGE(TAG, "Failed to synchronise device!");
}
else
{
ESP_LOGI(TAG, "Successfully synchronised device!");
// Safely turn off all relays after a given number of failures
if (fails > 5)
{
ESP_LOGE(TAG, "Many failures, will stop all relays...");
// TODO : turn off all relays
}
// Restart the card after too much failures
if (fails > 10)
{
ESP_LOGE(TAG, "Too many failures, will try to reboot in 3 secs...");
system_sleep(3);
reboot();
}
system_sleep(SYNC_TIME_INTERVAL);
continue;
}
system_sleep(10);
// TODO : apply sync
sync_response_print(res);
sync_response_free(res);
system_sleep(SYNC_TIME_INTERVAL);
}
system_sleep(120);
reboot();
}

View File

@ -148,16 +148,16 @@ int secure_api_enroll_device()
free(csr);
char *body = cJSON_PrintUnformatted(obj);
cJSON_Delete(obj);
if (!body)
{
ESP_LOGE(TAG, "Failed to generate JSON body!");
cJSON_Delete(obj);
return 1;
}
char *res = process_secure_request("/devices_api/mgmt/enroll", body);
cJSON_Delete(obj);
free(body);
if (res == NULL)
@ -195,7 +195,7 @@ char *secure_api_get_dev_certificate()
return res;
}
void *secure_api_sync_device()
sync_response *secure_api_sync_device()
{
cJSON *obj = cJSON_CreateObject();
if (!obj)
@ -215,10 +215,53 @@ void *secure_api_sync_device()
return NULL;
}
printf("JWT: %s\n", encoded_req);
// Prepare request body
cJSON *json_body = cJSON_CreateObject();
if (!json_body)
{
ESP_LOGE(TAG, "Failed to allocated memory to store sync request body!");
free(encoded_req);
return NULL;
}
cJSON_AddStringToObject(json_body, "payload", encoded_req);
free(encoded_req);
// TODO : replace
printf("here implement sync device logic\n");
return NULL;
char *body = cJSON_PrintUnformatted(json_body);
cJSON_Delete(json_body);
if (!body)
{
ESP_LOGE(TAG, "Failed to allocated memory to store encoded sync request body!");
return NULL;
}
// Send request
char *res = process_secure_request("/devices_api/mgmt/sync", body);
if (res == NULL)
{
ESP_LOGE(TAG, "Sync request failed!");
return NULL;
}
// Parse response
cJSON *states = cJSON_Parse(res);
free(res);
if (!states)
{
ESP_LOGE(TAG, "Failed to decode sync response from server!");
return NULL;
}
sync_response *sync_res = sync_response_parse(states);
cJSON_Delete(states);
if (!sync_res)
{
ESP_LOGE(TAG, "Failed to parse sync response from server!");
return NULL;
}
return sync_res;
}

View File

@ -2,6 +2,11 @@
* Secure API functions
*/
#include <stddef.h>
#include <stdbool.h>
#include "sync_response.h"
#pragma once
#ifdef __cplusplus
@ -45,7 +50,7 @@ extern "C"
*
* Returns NULL in case of failure
*/
void *secure_api_sync_device();
sync_response *secure_api_sync_device();
#ifdef __cplusplus
}

View File

@ -0,0 +1,63 @@
#include "sync_response.h"
#include <stdlib.h>
#include <esp_log.h>
const static char *TAG = "sync_response";
sync_response *sync_response_parse(cJSON *res)
{
cJSON *relays_json = cJSON_GetObjectItem(res, "relays");
if (relays_json == NULL)
{
ESP_LOGE(TAG, "Missing relays status in sync response!");
return NULL;
}
int relays_size = cJSON_GetArraySize(relays_json);
sync_response *sync_res = calloc(1, sizeof(sync_response) + relays_size * sizeof(bool));
if (!sync_res)
{
ESP_LOGE(TAG, "Failed to allocate memory to store synchronization response!");
return NULL;
}
sync_res->len = relays_size;
for (int i = 0; i < sync_res->len; i++)
{
sync_res->relays[i] = false;
cJSON *item = cJSON_GetArrayItem(relays_json, i);
assert(item != NULL);
cJSON *enabled = cJSON_GetObjectItem(item, "enabled");
if (enabled == NULL)
{
ESP_LOGE(TAG, "At least a relay is missing the enabled field. Assuming false.");
continue;
}
if (cJSON_IsTrue(enabled))
{
sync_res->relays[i] = true;
}
}
return sync_res;
}
void sync_response_print(sync_response *res)
{
ESP_LOGI(TAG, " === sync response begin === ");
for (size_t i = 0; i < res->len; i++)
ESP_LOGI(TAG, "Relay[%d]=%s", i, res->relays[i] ? "ON" : "off");
ESP_LOGI(TAG, " === sync response end === ");
}
void sync_response_free(sync_response *res)
{
if (res != NULL)
free(res);
}

View File

@ -0,0 +1,39 @@
/**
* Synchronisation response
*/
#pragma once
#include <stddef.h>
#include <stdbool.h>
#include <cJSON.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct sync_response
{
size_t len;
bool relays[];
} sync_response;
/**
* Decode synchronize response from server
*/
sync_response *sync_response_parse(cJSON *res);
/**
* Print synchronize reponse content
*/
void sync_response_print(sync_response *res);
/**
* Free memory allocated for synchronize response
*/
void sync_response_free(sync_response *res);
#ifdef __cplusplus
}
#endif