/* 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 #include #include #include #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" #include "esp_event.h" #include "esp_log.h" #include "lwip/err.h" #include "lwip/sys.h" #include "esp_netif.h" #include "protocol_examples_common.h" #include "protocol_examples_utils.h" #include "esp_tls_crypto.h" #include #include "esp_event.h" #include "esp_netif.h" #include "esp_tls.h" #include "esp_check.h" #include "driver/gpio.h" #include #include #include "nvs_flash.h" #include "esp_eth.h" #define EXAMPLE_HTTP_QUERY_KEY_MAX_LEN (64) // GPIO pin definition. Use menu config to choose GPIO #define GPIO_OUTPUT_IO_0 CONFIG_GPIO_OUTPUT_0 #define GPIO_OUTPUT_IO_1 CONFIG_GPIO_OUTPUT_1 #define GPIO_OUTPUT_PIN_SEL ((1ULL<ip_info.ip)); xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } } void wifi_init_sta(void) { s_wifi_event_group = xEventGroupCreate(); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_sta(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); esp_event_handler_instance_t instance_any_id; esp_event_handler_instance_t instance_got_ip; ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip)); wifi_config_t wifi_config = { .sta = { .ssid = EXAMPLE_ESP_WIFI_SSID, .password = EXAMPLE_ESP_WIFI_PASS, /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8). * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards. */ .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, .sae_pwe_h2e = ESP_WIFI_SAE_MODE, .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER, }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); ESP_ERROR_CHECK(esp_wifi_start() ); ESP_LOGI(TAG, "wifi_init_sta finished."); /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually * happened. */ if (bits & WIFI_CONNECTED_BIT) { ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); } else if (bits & WIFI_FAIL_BIT) { ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); } else { ESP_LOGE(TAG, "UNEXPECTED EVENT"); } } static atomic_bool status_one = false; static atomic_bool status_two = false; /* An HTTP GET handler */ static esp_err_t status_get_handler(httpd_req_t *req) { /* Send response with custom headers and body set as the * string passed in user context*/ char buf[3]; sprintf(buf, "%d%d", status_one, status_two); httpd_resp_send(req, buf, 2); return ESP_OK; } static const httpd_uri_t status = { .uri = "/status", .method = HTTP_GET, .handler = status_get_handler, }; /* An HTTP POST handler */ static esp_err_t post_one_handler(httpd_req_t *req) { char buf[1]; 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; } bool set = false; if (buf[0] == '1') { status_one = true; set = true; } else if (buf[0] == '0') { status_one = false; set = true; }; if (set) { ESP_LOGI(TAG, "RECEIVED DATA"); gpio_set_level(GPIO_OUTPUT_IO_0, status_one); httpd_resp_send(req, NULL, 0); // TODO check simplification return ESP_OK; }; remaining -= ret; } // Return 400 if found no info for status httpd_resp_set_status(req, HTTPD_400); httpd_resp_send(req, NULL, 0); return ESP_OK; } static const httpd_uri_t post_one = { .uri = "/0", .method = HTTP_POST, .handler = post_one_handler, .user_ctx = NULL }; /* An HTTP POST handler */ static esp_err_t post_two_handler(httpd_req_t *req) { char buf[1]; 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; } bool set = false; if (buf[0] == '1') { status_two = true; set = true; } else if (buf[0] == '0') { status_two = false; set = true; }; if (set) { ESP_LOGI(TAG, "RECEIVED DATA"); gpio_set_level(GPIO_OUTPUT_IO_1, status_two); httpd_resp_send(req, NULL, 0); // TODO check simplification return ESP_OK; }; remaining -= ret; } // Return 400 if found no info for status httpd_resp_set_status(req, HTTPD_400); httpd_resp_send(req, NULL, 0); return ESP_OK; } static const httpd_uri_t post_two = { .uri = "/1", .method = HTTP_POST, .handler = post_two_handler, .user_ctx = NULL }; static httpd_handle_t start_webserver(void) { httpd_handle_t server = NULL; httpd_config_t config = HTTPD_DEFAULT_CONFIG(); config.lru_purge_enable = true; // 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, &status); httpd_register_uri_handler(server, &post_one); httpd_register_uri_handler(server, &post_two); return server; } ESP_LOGI(TAG, "Error starting server!"); return NULL; } static esp_err_t stop_webserver(httpd_handle_t server) { // Stop the httpd server return httpd_stop(server); } 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"); if (stop_webserver(*server) == ESP_OK) { *server = NULL; } else { ESP_LOGE(TAG, "Failed to stop http server"); } } } 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(void) { static httpd_handle_t server = NULL; //Initialize NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); //zero-initialize the config structure. gpio_config_t io_conf = {}; //disable interrupt io_conf.intr_type = GPIO_INTR_DISABLE; //set as output mode io_conf.mode = GPIO_MODE_OUTPUT; //bit mask of the pins that you want to set,e.g.GPIO18/19 io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; //disable pull-down mode io_conf.pull_down_en = 0; //disable pull-up mode io_conf.pull_up_en = 0; //configure GPIO with the given settings gpio_config(&io_conf); gpio_set_level(GPIO_OUTPUT_IO_0, 0); gpio_set_level(GPIO_OUTPUT_IO_1, 0); ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); wifi_init_sta(); /* Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected, * and re-start it upon connection. */ 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)); printf("Minimum free heap size: %"PRIu32" bytes\n", esp_get_minimum_free_heap_size()); /* Start the server for the first time */ server = start_webserver(); while (server) { sleep(5); } }