diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | license | 21 | ||||
-rw-r--r-- | main/component.mk | 1 | ||||
-rw-r--r-- | main/main.c | 249 | ||||
-rw-r--r-- | makefile | 14 |
5 files changed, 289 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b995ea6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +compile_commands.json +build/ +.cache/ +sdkconfig* @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 lonkaars + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/main/component.mk b/main/component.mk new file mode 100644 index 0000000..bf066e4 --- /dev/null +++ b/main/component.mk @@ -0,0 +1 @@ +# required for compilation, but the defaults already work diff --git a/main/main.c b/main/main.c new file mode 100644 index 0000000..1c532b8 --- /dev/null +++ b/main/main.c @@ -0,0 +1,249 @@ +/* Simple HTTP Server Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include <sys/param.h> + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "protocol_examples_common.h" +#include "nvs.h" +#include "nvs_flash.h" + +#include <esp_http_server.h> + +static const char *TAG="APP"; + +/* An HTTP GET handler */ +esp_err_t hello_get_handler(httpd_req_t *req) +{ + char* buf; + size_t buf_len; + + /* Get header value string length and allocate memory for length + 1, + * extra byte for null termination */ + buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1; + if (buf_len > 1) { + buf = malloc(buf_len); + /* Copy null terminated value string into buffer */ + if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) { + ESP_LOGI(TAG, "Found header => Host: %s", buf); + } + free(buf); + } + + buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-2") + 1; + if (buf_len > 1) { + buf = malloc(buf_len); + if (httpd_req_get_hdr_value_str(req, "Test-Header-2", buf, buf_len) == ESP_OK) { + ESP_LOGI(TAG, "Found header => Test-Header-2: %s", buf); + } + free(buf); + } + + buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-1") + 1; + if (buf_len > 1) { + buf = malloc(buf_len); + if (httpd_req_get_hdr_value_str(req, "Test-Header-1", buf, buf_len) == ESP_OK) { + ESP_LOGI(TAG, "Found header => Test-Header-1: %s", buf); + } + free(buf); + } + + /* Read URL query string length and allocate memory for length + 1, + * extra byte for null termination */ + buf_len = httpd_req_get_url_query_len(req) + 1; + if (buf_len > 1) { + buf = malloc(buf_len); + if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) { + ESP_LOGI(TAG, "Found URL query => %s", buf); + char param[32]; + /* Get value of expected key from query string */ + if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) { + ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param); + } + if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) { + ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param); + } + if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) { + ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param); + } + } + free(buf); + } + + /* Set some custom headers */ + httpd_resp_set_hdr(req, "Custom-Header-1", "Custom-Value-1"); + httpd_resp_set_hdr(req, "Custom-Header-2", "Custom-Value-2"); + + /* Send response with custom headers and body set as the + * string passed in user context*/ + const char* resp_str = (const char*) req->user_ctx; + httpd_resp_send(req, resp_str, strlen(resp_str)); + + /* After sending the HTTP response the old HTTP request + * headers are lost. Check if HTTP request headers can be read now. */ + if (httpd_req_get_hdr_value_len(req, "Host") == 0) { + ESP_LOGI(TAG, "Request headers lost"); + } + return ESP_OK; +} + +httpd_uri_t hello = { + .uri = "/hello", + .method = HTTP_GET, + .handler = hello_get_handler, + /* Let's pass response string in user + * context to demonstrate it's usage */ + .user_ctx = "Hello World!" +}; + +/* An HTTP POST handler */ +esp_err_t echo_post_handler(httpd_req_t *req) +{ + char buf[100]; + int ret, remaining = req->content_len; + + while (remaining > 0) { + /* Read the data for the request */ + if ((ret = httpd_req_recv(req, buf, + MIN(remaining, sizeof(buf)))) <= 0) { + if (ret == HTTPD_SOCK_ERR_TIMEOUT) { + /* Retry receiving if timeout occurred */ + continue; + } + return ESP_FAIL; + } + + /* Send back the same data */ + httpd_resp_send_chunk(req, buf, ret); + remaining -= ret; + + /* Log data received */ + ESP_LOGI(TAG, "=========== RECEIVED DATA =========="); + ESP_LOGI(TAG, "%.*s", ret, buf); + ESP_LOGI(TAG, "===================================="); + } + + // End response + httpd_resp_send_chunk(req, NULL, 0); + return ESP_OK; +} + +httpd_uri_t echo = { + .uri = "/echo", + .method = HTTP_POST, + .handler = echo_post_handler, + .user_ctx = NULL +}; + +/* An HTTP PUT handler. This demonstrates realtime + * registration and deregistration of URI handlers + */ +esp_err_t ctrl_put_handler(httpd_req_t *req) +{ + char buf; + int ret; + + if ((ret = httpd_req_recv(req, &buf, 1)) <= 0) { + if (ret == HTTPD_SOCK_ERR_TIMEOUT) { + httpd_resp_send_408(req); + } + return ESP_FAIL; + } + + if (buf == '0') { + /* Handler can be unregistered using the uri string */ + ESP_LOGI(TAG, "Unregistering /hello and /echo URIs"); + httpd_unregister_uri(req->handle, "/hello"); + httpd_unregister_uri(req->handle, "/echo"); + } + else { + ESP_LOGI(TAG, "Registering /hello and /echo URIs"); + httpd_register_uri_handler(req->handle, &hello); + httpd_register_uri_handler(req->handle, &echo); + } + + /* Respond with empty body */ + httpd_resp_send(req, NULL, 0); + return ESP_OK; +} + +httpd_uri_t ctrl = { + .uri = "/ctrl", + .method = HTTP_PUT, + .handler = ctrl_put_handler, + .user_ctx = NULL +}; + +httpd_handle_t start_webserver(void) +{ + httpd_handle_t server = NULL; + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + + // Start the httpd server + ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port); + if (httpd_start(&server, &config) == ESP_OK) { + // Set URI handlers + ESP_LOGI(TAG, "Registering URI handlers"); + httpd_register_uri_handler(server, &hello); + httpd_register_uri_handler(server, &echo); + httpd_register_uri_handler(server, &ctrl); + return server; + } + + ESP_LOGI(TAG, "Error starting server!"); + return NULL; +} + +void stop_webserver(httpd_handle_t server) +{ + // Stop the httpd server + httpd_stop(server); +} + +static httpd_handle_t server = NULL; + +static void disconnect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server) { + ESP_LOGI(TAG, "Stopping webserver"); + stop_webserver(*server); + *server = NULL; + } +} + +static void connect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server == NULL) { + ESP_LOGI(TAG, "Starting webserver"); + *server = start_webserver(); + } +} + +void app_main() +{ + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + + ESP_ERROR_CHECK(example_connect()); + + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server)); + + server = start_webserver(); +} diff --git a/makefile b/makefile new file mode 100644 index 0000000..b13b1cb --- /dev/null +++ b/makefile @@ -0,0 +1,14 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := esp8266-rgbstrip + +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + +include $(IDF_PATH)/make/project.mk + +compile_commands: + bear -- make + |