Commit d6dfc879 authored by Tiago Medicci's avatar Tiago Medicci

Change task to always try to start HTTP/HTTPS server

parent 31a2e74a
...@@ -110,10 +110,10 @@ struct http_context_ { ...@@ -110,10 +110,10 @@ struct http_context_ {
}; };
struct http_server_context_ { struct http_server_context_ {
EventGroupHandle_t start_done;
int port; int port;
err_t server_task_err; err_t server_task_err;
TaskHandle_t task; TaskHandle_t task;
EventGroupHandle_t start_done;
SLIST_HEAD(, http_handler_t) handlers; SLIST_HEAD(, http_handler_t) handlers;
_lock_t handlers_lock; _lock_t handlers_lock;
struct http_context_ connection_context; struct http_context_ connection_context;
...@@ -132,6 +132,7 @@ struct http_server_context_ { ...@@ -132,6 +132,7 @@ struct http_server_context_ {
#define SERVER_STARTED_BIT BIT(0) #define SERVER_STARTED_BIT BIT(0)
#define SERVER_DONE_BIT BIT(1) #define SERVER_DONE_BIT BIT(1)
#define SERVER_ERR_NO_MEM BIT(2)
static const char* http_response_code_to_str(int code); static const char* http_response_code_to_str(int code);
...@@ -915,23 +916,41 @@ static void http_handle_connection(http_server_t server, void *arg_conn) ...@@ -915,23 +916,41 @@ static void http_handle_connection(http_server_t server, void *arg_conn)
static void http_server(void *arg) static void http_server(void *arg)
{ {
uint8_t bits;
http_server_t ctx = (http_server_t) arg; http_server_t ctx = (http_server_t) arg;
#ifdef HTTPS_SERVER
do{
ESP_LOGV(TAG, "Checking Server Status...");
bits = xEventGroupWaitBits(ctx->start_done, SERVER_STARTED_BIT | SERVER_DONE_BIT, 0, 0, 0);
//If server had already been successfully started but it has crashed,
if ((bits & SERVER_STARTED_BIT) & (bits & SERVER_DONE_BIT)) {
ESP_LOGE(TAG, "Server has closed.");
ESP_LOGV(TAG, "Restarting server...");
memset(ctx + sizeof(ctx->start_done), 0, sizeof(ctx) - sizeof(ctx->start_done));
xEventGroupClearBits(ctx->start_done, SERVER_STARTED_BIT);
}
//If server has not successfully been started yet,
if (!(bits & SERVER_STARTED_BIT)) {
#ifdef HTTPS_SERVER
char *error_buf; char *error_buf;
ESP_LOGV(TAG, "Declaring local mbedTLS context on task..."); ESP_LOGV(TAG, "Declaring local mbedTLS context on task...");
int ret; int ret;
mbedtls_net_context listen_fd; mbedtls_net_context listen_fd;
mbedtls_net_context client_fd;
mbedtls_entropy_context entropy; mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl_conn; mbedtls_ssl_context ssl_conn;
mbedtls_ssl_config conf; mbedtls_ssl_config conf;
mbedtls_x509_crt srvcert; mbedtls_x509_crt srvcert;
mbedtls_pk_context pkey; mbedtls_pk_context pkey;
#if defined(MBEDTLS_SSL_CACHE_C) #if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_context cache; mbedtls_ssl_cache_context cache;
(ctx->cache) = &cache; (ctx->cache) = &cache;
#endif #endif
(ctx->listen_fd) = &listen_fd; (ctx->listen_fd) = &listen_fd;
(ctx->connection_context.client_fd) = &client_fd;
(ctx->entropy) = &entropy; (ctx->entropy) = &entropy;
(ctx->ctr_drbg) = &ctr_drbg; (ctx->ctr_drbg) = &ctr_drbg;
(ctx->connection_context.ssl_conn) = &ssl_conn; (ctx->connection_context.ssl_conn) = &ssl_conn;
...@@ -959,10 +978,14 @@ static void http_server(void *arg) ...@@ -959,10 +978,14 @@ static void http_server(void *arg)
extern const unsigned char serverprvtkey_pem_end[] asm("_binary_serverprvtkey_pem_end"); extern const unsigned char serverprvtkey_pem_end[] asm("_binary_serverprvtkey_pem_end");
const unsigned int serverprvtkey_pem_bytes = serverprvtkey_pem_end - serverprvtkey_pem_start; const unsigned int serverprvtkey_pem_bytes = serverprvtkey_pem_end - serverprvtkey_pem_start;
ESP_LOGV(TAG, "Setting mbedTLS context......"); ESP_LOGV(TAG, "Setting server_fd......");
mbedtls_net_init( ctx->listen_fd ); mbedtls_net_init( ctx->listen_fd );
ESP_LOGV(TAG, "OK"); ESP_LOGV(TAG, "OK");
ESP_LOGV(TAG, "Setting client fd......");
mbedtls_net_init( ctx->connection_context.client_fd );
ESP_LOGV(TAG, "OK");
ESP_LOGV(TAG, "SSL server context create ......"); ESP_LOGV(TAG, "SSL server context create ......");
mbedtls_ssl_init( ctx->connection_context.ssl_conn ); mbedtls_ssl_init( ctx->connection_context.ssl_conn );
ESP_LOGV(TAG, "OK"); ESP_LOGV(TAG, "OK");
...@@ -971,9 +994,9 @@ static void http_server(void *arg) ...@@ -971,9 +994,9 @@ static void http_server(void *arg)
mbedtls_ssl_config_init( ctx->conf ); mbedtls_ssl_config_init( ctx->conf );
ESP_LOGV(TAG, "OK"); ESP_LOGV(TAG, "OK");
#if defined(MBEDTLS_SSL_CACHE_C) #if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_init( &cache ); mbedtls_ssl_cache_init( &cache );
#endif #endif
mbedtls_x509_crt_init( ctx->srvcert ); mbedtls_x509_crt_init( ctx->srvcert );
mbedtls_pk_init( ctx->pkey ); mbedtls_pk_init( ctx->pkey );
mbedtls_entropy_init( ctx->entropy ); mbedtls_entropy_init( ctx->entropy );
...@@ -1061,9 +1084,9 @@ static void http_server(void *arg) ...@@ -1061,9 +1084,9 @@ static void http_server(void *arg)
* 4. Setup stuff * 4. Setup stuff
*/ */
ESP_LOGV(TAG, "Setting up the SSL conf data...." ); ESP_LOGV(TAG, "Setting up the SSL conf data...." );
#ifdef CONFIG_MBEDTLS_DEBUG #ifdef CONFIG_MBEDTLS_DEBUG
mbedtls_esp_enable_debug_log(ctx->conf, 4); mbedtls_esp_enable_debug_log(ctx->conf, 4);
#endif #endif
if( ( ret = mbedtls_ssl_config_defaults( ctx->conf, if( ( ret = mbedtls_ssl_config_defaults( ctx->conf,
MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_IS_SERVER,
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_TRANSPORT_STREAM,
...@@ -1075,11 +1098,11 @@ static void http_server(void *arg) ...@@ -1075,11 +1098,11 @@ static void http_server(void *arg)
mbedtls_ssl_conf_rng( ctx->conf, mbedtls_ctr_drbg_random, ctx->ctr_drbg ); mbedtls_ssl_conf_rng( ctx->conf, mbedtls_ctr_drbg_random, ctx->ctr_drbg );
#if defined(MBEDTLS_SSL_CACHE_C) #if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_conf_session_cache( ctx->conf, ctx->cache, mbedtls_ssl_conf_session_cache( ctx->conf, ctx->cache,
mbedtls_ssl_cache_get, mbedtls_ssl_cache_get,
mbedtls_ssl_cache_set ); mbedtls_ssl_cache_set );
#endif #endif
mbedtls_ssl_conf_ca_chain( ctx->conf, (*ctx->srvcert).next, NULL ); mbedtls_ssl_conf_ca_chain( ctx->conf, (*ctx->srvcert).next, NULL );
if( ( ret = mbedtls_ssl_conf_own_cert( ctx->conf, ctx->srvcert, ctx->pkey ) ) != 0 ) if( ( ret = mbedtls_ssl_conf_own_cert( ctx->conf, ctx->srvcert, ctx->pkey ) ) != 0 )
...@@ -1097,23 +1120,9 @@ static void http_server(void *arg) ...@@ -1097,23 +1120,9 @@ static void http_server(void *arg)
xEventGroupSetBits(ctx->start_done, SERVER_STARTED_BIT); xEventGroupSetBits(ctx->start_done, SERVER_STARTED_BIT);
reset: reset:
ESP_LOGI(TAG, "mbedTLS HTTPS server is running! Waiting for new connection..."); ESP_LOGI(TAG, "mbedTLS HTTPS server is running! Waiting for new connection...");
do { do {
mbedtls_net_context client_fd;
(ctx->connection_context.client_fd) = &client_fd;
mbedtls_net_init( ctx->connection_context.client_fd );
#ifdef MBEDTLS_ERROR_C
if( ret != ERR_OK )
{
error_buf = malloc(sizeof(char)*ERROR_BUF_LENGTH);
mbedtls_strerror( ctx->server_task_err, error_buf, sizeof(char)*ERROR_BUF_LENGTH );
ESP_LOGE(TAG, "Error %d: %s", ret, error_buf );
free(error_buf);
}
#endif
mbedtls_net_free( ctx->connection_context.client_fd ); mbedtls_net_free( ctx->connection_context.client_fd );
mbedtls_ssl_session_reset( ctx->connection_context.ssl_conn ); mbedtls_ssl_session_reset( ctx->connection_context.ssl_conn );
...@@ -1151,15 +1160,17 @@ reset: ...@@ -1151,15 +1160,17 @@ reset:
ESP_LOGV(TAG, "OK"); ESP_LOGV(TAG, "OK");
} while (ret == ERR_OK); } while (ret == ERR_OK);
exit: exit:
if (ret != ERR_OK) { if (ret != ERR_OK) {
error_buf = malloc(sizeof(char)*ERROR_BUF_LENGTH); error_buf = malloc(sizeof(char)*ERROR_BUF_LENGTH);
mbedtls_strerror( ctx->server_task_err, error_buf, sizeof(char)*ERROR_BUF_LENGTH ); mbedtls_strerror( ctx->server_task_err, error_buf, sizeof(char)*ERROR_BUF_LENGTH );
ESP_LOGE(TAG, "Error %d: %s", ret, error_buf ); ESP_LOGE(TAG, "Error %d: %s", ret, error_buf );
free(error_buf); free(error_buf);
//Set SERVER_DONE_BIT and save error at http_server_t struct
ctx->server_task_err = ret; ctx->server_task_err = ret;
xEventGroupSetBits(ctx->start_done, SERVER_DONE_BIT); xEventGroupSetBits(ctx->start_done, SERVER_DONE_BIT);
} }
mbedtls_net_free( ctx->connection_context.client_fd ); mbedtls_net_free( ctx->connection_context.client_fd );
mbedtls_net_free( ctx->listen_fd ); mbedtls_net_free( ctx->listen_fd );
...@@ -1167,16 +1178,13 @@ if (ret != ERR_OK) { ...@@ -1167,16 +1178,13 @@ if (ret != ERR_OK) {
mbedtls_pk_free( ctx->pkey ); mbedtls_pk_free( ctx->pkey );
mbedtls_ssl_free( ctx->connection_context.ssl_conn ); mbedtls_ssl_free( ctx->connection_context.ssl_conn );
mbedtls_ssl_config_free( ctx->conf ); mbedtls_ssl_config_free( ctx->conf );
#if defined(MBEDTLS_SSL_CACHE_C) #if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_free( ctx->cache ); mbedtls_ssl_cache_free( ctx->cache );
#endif #endif
mbedtls_ctr_drbg_free( ctx->ctr_drbg ); mbedtls_ctr_drbg_free( ctx->ctr_drbg );
mbedtls_entropy_free( ctx->entropy ); mbedtls_entropy_free( ctx->entropy );
ESP_LOGE(TAG, "Closing Task"); #else
vTaskDelete(NULL);
#else
struct netconn *client_conn; struct netconn *client_conn;
err_t err; err_t err;
ctx->server_conn = netconn_new(NETCONN_TCP); ctx->server_conn = netconn_new(NETCONN_TCP);
...@@ -1203,7 +1211,7 @@ if (ret != ERR_OK) { ...@@ -1203,7 +1211,7 @@ if (ret != ERR_OK) {
netconn_delete(client_conn); netconn_delete(client_conn);
} }
} while (err == ERR_OK); } while (err == ERR_OK);
out: out:
if (ctx->server_conn) { if (ctx->server_conn) {
netconn_close(ctx->server_conn); netconn_close(ctx->server_conn);
netconn_delete(ctx->server_conn); netconn_delete(ctx->server_conn);
...@@ -1213,11 +1221,15 @@ out: ...@@ -1213,11 +1221,15 @@ out:
xEventGroupSetBits(ctx->start_done, SERVER_DONE_BIT); xEventGroupSetBits(ctx->start_done, SERVER_DONE_BIT);
} }
vTaskDelete(NULL); vTaskDelete(NULL);
#endif #endif
}
vTaskDelay(5000 / portTICK_PERIOD_MS);
}while(1);
} }
esp_err_t http_server_start(const http_server_options_t* options, http_server_t* out_server) esp_err_t http_server_start(const http_server_options_t* options, http_server_t* out_server)
{ {
uint8_t bits;
http_server_t ctx = calloc(1, sizeof(*ctx)); http_server_t ctx = calloc(1, sizeof(*ctx));
if (ctx == NULL) { if (ctx == NULL) {
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
...@@ -1230,8 +1242,9 @@ esp_err_t http_server_start(const http_server_options_t* options, http_server_t* ...@@ -1230,8 +1242,9 @@ esp_err_t http_server_start(const http_server_options_t* options, http_server_t*
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
//Start http_server task if it had not been started before
ESP_LOGV(TAG, "Creating http_server task..."); ESP_LOGV(TAG, "Creating http_server task...");
int ret = xTaskCreatePinnedToCore(&http_server, "httpd", int ret = xTaskCreatePinnedToCore(&http_server, "http_server",
options->task_stack_size, ctx, options->task_stack_size, ctx,
options->task_priority, options->task_priority,
&ctx->task, &ctx->task,
...@@ -1241,10 +1254,13 @@ esp_err_t http_server_start(const http_server_options_t* options, http_server_t* ...@@ -1241,10 +1254,13 @@ esp_err_t http_server_start(const http_server_options_t* options, http_server_t*
free(ctx); free(ctx);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
ESP_LOGI(TAG, "Task has been created!"); ESP_LOGI(TAG, "http_server task has been created!");
//Check server status by checking SERVER_STARTED_BIT (it server has been succesfully started) or SERVER_DONE_BIT (if it has crashed)
ESP_LOGV(TAG, "Checking server status..."); ESP_LOGV(TAG, "Checking server status...");
int bits = xEventGroupWaitBits(ctx->start_done, SERVER_STARTED_BIT | SERVER_DONE_BIT, 0, 0, portMAX_DELAY); bits = xEventGroupWaitBits(ctx->start_done, SERVER_STARTED_BIT, 0, 0, portMAX_DELAY);
/*
//If it has crashed, shoe error log
if (bits & SERVER_DONE_BIT) { if (bits & SERVER_DONE_BIT) {
ESP_LOGE(TAG, "SERVER_DONE_BIT Error..."); ESP_LOGE(TAG, "SERVER_DONE_BIT Error...");
#ifdef HTTPS_SERVER #ifdef HTTPS_SERVER
...@@ -1252,13 +1268,17 @@ esp_err_t http_server_start(const http_server_options_t* options, http_server_t* ...@@ -1252,13 +1268,17 @@ esp_err_t http_server_start(const http_server_options_t* options, http_server_t*
mbedtls_strerror( ctx->server_task_err, error_buf, 100 ); mbedtls_strerror( ctx->server_task_err, error_buf, 100 );
ESP_LOGE(TAG, "Error %d: %s", ret, error_buf ); ESP_LOGE(TAG, "Error %d: %s", ret, error_buf );
free(error_buf); free(error_buf);
#endif esp_err_t err = ctx->server_task_err;
vEventGroupDelete(ctx->start_done);
free(ctx);
#else
esp_err_t err = lwip_err_to_esp_err(ctx->server_task_err); esp_err_t err = lwip_err_to_esp_err(ctx->server_task_err);
vEventGroupDelete(ctx->start_done); vEventGroupDelete(ctx->start_done);
free(ctx); free(ctx);
#endif
return err; return err;
} }
*/
ESP_LOGI(TAG, "Server started!"); ESP_LOGI(TAG, "Server started!");
*out_server = ctx; *out_server = ctx;
return ESP_OK; return ESP_OK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment