PersonalVotingMachine/basic-setup/main/impl/modules/RPCModule.cpp
2020-12-22 14:30:09 +02:00

93 lines
2.3 KiB
C++

/**
* @file RPCModule.cpp
* @brief RPC implementation file
* */
#include "string.h"
#include "module.h"
RPC::RPC(){
this->cfg = new esp_tls_cfg_t();
this->server = NULL;
this->port = 443;
};
cJSON * RPC::send_json_rpc(const char* sni, char* req){
static char buf[512]; // tls connection buffer to read response
int length = 1024;
char *res; // buffer to store whole response body
res = (char *) malloc(length);
memset(res, 0, length);
int ret, len;
/* tls connection config. */
cfg->common_name = sni; //! set SNI extension
struct esp_tls *tls = esp_tls_conn_new(server, strlen(server),port, cfg); //! connect to defined address
if(tls != NULL) {
ESP_LOGI(TLS_TAG, "Connection established with %s", sni);
} else {
printf("available memory: %d\n", (int) heap_caps_get_free_size(MALLOC_CAP_32BIT | MALLOC_CAP_8BIT));
throw "Connection failed";
}
size_t written_bytes = 0;
do {
ret = esp_tls_conn_write(tls, req + written_bytes, strlen(req) - written_bytes); //! send rpc data
if (ret >= 0) {
written_bytes += ret;
} else if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
ESP_LOGE(TLS_TAG, "esp_tls_conn_write returned 0x%x", ret);
esp_tls_conn_delete(tls);
}
} while(written_bytes < strlen(req));
do
{
len = sizeof(buf) - 1;
bzero(buf, sizeof(buf));
ret = esp_tls_conn_read(tls, (char *)buf, len); //! recieve response in chunks
if(ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ)
continue;
if(ret < 0)
{
ESP_LOGE(TLS_TAG, "esp_tls_conn_read returned -0x%x", -ret);
break;
}
if(ret == 0)
{
ESP_LOGI(TLS_TAG, "connection closed");
break;
}
len = ret;
ESP_LOGD(TLS_TAG, "%d bytes read", len);
if(strlen(res) + len + 1 >= length){ //! In case no enough memory, extend res buffer
length += len; //! * increase by amount required
res = (char*) realloc(res, length); //! * reallocate memory
memset(res+length-len,0,len); //! * set new memory blocks 0 to assure the result is null-terminate string
}
memcpy(res + strlen(res), buf, len); //! write chunked response to buffer
} while(1);
cJSON *tmp = cJSON_Parse(res); //! parse response JSON into cJSON struct
free(res);
free(req);
esp_tls_conn_delete(tls);
return tmp;
}
RPC& RPC::Instance(){
static RPC instance;
return instance;
}