From 759b90a5e190484120740c4b6ceb9ebd4a869cab Mon Sep 17 00:00:00 2001 From: Piyush Shah Date: Fri, 1 Feb 2019 18:20:37 +0530 Subject: [PATCH] protocomm_httpd: Allow applications to pass HTTPD handle This will be useful if a webserver is already running and the application does not want protocomm to start a new instance. Signed-off-by: Piyush Shah --- .../include/transports/protocomm_httpd.h | 28 ++++++++- .../src/transports/protocomm_httpd.c | 63 +++++++++++-------- .../api-reference/provisioning/protocomm.rst | 7 ++- 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/components/protocomm/include/transports/protocomm_httpd.h b/components/protocomm/include/transports/protocomm_httpd.h index 701fa9683..92b5c43bc 100644 --- a/components/protocomm/include/transports/protocomm_httpd.h +++ b/components/protocomm/include/transports/protocomm_httpd.h @@ -22,10 +22,11 @@ .task_priority = tskIDLE_PRIORITY + 5, \ } -/** - * @brief Config parameters for protocomm HTTP server - */ + + +/** Protocomm HTTP Server Configuration */ typedef struct { + uint16_t port; /*!< Port on which the http server will listen */ /** @@ -34,6 +35,27 @@ typedef struct { */ size_t stack_size; unsigned task_priority; /*!< Priority of server task */ +} protocomm_http_server_config_t; /*!< HTTP Server Configuration, if HTTP Server has not been started already */ + +/** Protocomm HTTPD Configuration Data */ +typedef union { + /** HTTP Server Handle, if ext_handle_provided is set to true */ + void *handle; + /** HTTP Server Configuration, if a server is not already active */ + protocomm_http_server_config_t config; +} protocomm_httpd_config_data_t; + +/** + * @brief Config parameters for protocomm HTTP server + */ +typedef struct { + /** Flag to indicate of an external HTTP Server Handle has been provided. + * In such as case, protocomm will use the same HTTP Server and not start + * a new one internally. + */ + bool ext_handle_provided; + /** Protocomm HTTPD Configuration Data */ + protocomm_httpd_config_data_t data; } protocomm_httpd_config_t; /** diff --git a/components/protocomm/src/transports/protocomm_httpd.c b/components/protocomm/src/transports/protocomm_httpd.c index a7c9b5599..e81bf7fb9 100644 --- a/components/protocomm/src/transports/protocomm_httpd.c +++ b/components/protocomm/src/transports/protocomm_httpd.c @@ -26,6 +26,7 @@ static const char *TAG = "protocomm_httpd"; static protocomm_t *pc_httpd; /* The global protocomm instance for HTTPD */ +static bool pc_ext_httpd_handle_provided; static uint32_t session_id = PROTOCOMM_NO_SESSION_ID; #define MAX_REQ_BODY_LEN 4096 @@ -124,7 +125,7 @@ out: return ret; } -esp_err_t protocomm_httpd_add_endpoint(const char *ep_name, +static esp_err_t protocomm_httpd_add_endpoint(const char *ep_name, protocomm_req_handler_t req_handler, void *priv_data) { @@ -207,28 +208,36 @@ esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t return ESP_ERR_NOT_SUPPORTED; } - /* Private data will point to the HTTP server handle */ - pc->priv = calloc(1, sizeof(httpd_handle_t)); - if (!pc->priv) { - ESP_LOGE(TAG, "Malloc failed for HTTP server handle"); - return ESP_ERR_NO_MEM; + if (config->ext_handle_provided) { + if (config->data.handle) { + pc->priv = config->data.handle; + pc_ext_httpd_handle_provided = true; + } else { + return ESP_ERR_INVALID_ARG; + } + } else { + /* Private data will point to the HTTP server handle */ + pc->priv = calloc(1, sizeof(httpd_handle_t)); + if (!pc->priv) { + ESP_LOGE(TAG, "Malloc failed for HTTP server handle"); + return ESP_ERR_NO_MEM; + } + + /* Configure the HTTP server */ + httpd_config_t server_config = HTTPD_DEFAULT_CONFIG(); + server_config.server_port = config->data.config.port; + server_config.stack_size = config->data.config.stack_size; + server_config.task_priority = config->data.config.task_priority; + server_config.lru_purge_enable = true; + server_config.max_open_sockets = 1; + + esp_err_t err; + if ((err = httpd_start((httpd_handle_t *)pc->priv, &server_config)) != ESP_OK) { + ESP_LOGE(TAG, "Failed to start http server: %s", esp_err_to_name(err)); + free(pc->priv); + return err; + } } - - /* Configure the HTTP server */ - httpd_config_t server_config = HTTPD_DEFAULT_CONFIG(); - server_config.server_port = config->port; - server_config.stack_size = config->stack_size; - server_config.task_priority = config->task_priority; - server_config.lru_purge_enable = true; - server_config.max_open_sockets = 1; - - esp_err_t err; - if ((err = httpd_start((httpd_handle_t *)pc->priv, &server_config)) != ESP_OK) { - ESP_LOGE(TAG, "Failed to start http server: %s", esp_err_to_name(err)); - free(pc->priv); - return err; - } - pc->add_endpoint = protocomm_httpd_add_endpoint; pc->remove_endpoint = protocomm_httpd_remove_endpoint; pc_httpd = pc; @@ -238,9 +247,13 @@ esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t esp_err_t protocomm_httpd_stop(protocomm_t *pc) { if ((pc != NULL) && (pc == pc_httpd)) { - httpd_handle_t *server_handle = (httpd_handle_t *) pc_httpd->priv; - httpd_stop(*server_handle); - free(server_handle); + if (!pc_ext_httpd_handle_provided) { + httpd_handle_t *server_handle = (httpd_handle_t *) pc_httpd->priv; + httpd_stop(*server_handle); + free(server_handle); + } else { + pc_ext_httpd_handle_provided = false; + } pc_httpd->priv = NULL; pc_httpd = NULL; return ESP_OK; diff --git a/docs/en/api-reference/provisioning/protocomm.rst b/docs/en/api-reference/provisioning/protocomm.rst index 8dc72c50a..3ef0b7e5c 100644 --- a/docs/en/api-reference/provisioning/protocomm.rst +++ b/docs/en/api-reference/provisioning/protocomm.rst @@ -54,8 +54,13 @@ For complete example see :example:`provisioning/softap_prov` { protocomm_t *pc = protocomm_new(); + /* Config for protocomm_httpd_start() */ - protocomm_httpd_config_t pc_config = PROTOCOMM_HTTPD_DEFAULT_CONFIG(); + protocomm_httpd_config_t pc_config = { + .data = { + .config = PROTOCOMM_HTTPD_DEFAULT_CONFIG() + } + }; /* Start protocomm server on top of HTTP */ protocomm_httpd_start(pc, &pc_config);