#include "esp_wifi.h" #include "esp_http_server.h" static httpd_handle_t _webserver_handle = NULL; static void _ws_async_send(void *arg); static esp_err_t _fav_handler(httpd_req_t *req); static esp_err_t _logo_handler(httpd_req_t *req); static esp_err_t _index_page_handler(httpd_req_t *req); static esp_err_t _index_page_css_handler(httpd_req_t *req); static esp_err_t _index_page_js_handler(httpd_req_t *req); static esp_err_t _index_page_ws_handler(httpd_req_t *req); // static esp_err_t _ws_send(httpd_handle_t *handle, char *payload); static const httpd_uri_t _fav = { .uri = "/favicon.ico", .method = HTTP_GET, .handler = _fav_handler, .user_ctx = NULL}; static const httpd_uri_t _logo = { .uri = "/logo.png", .method = HTTP_GET, .handler = _logo_handler, .user_ctx = NULL}; static const httpd_uri_t _index_page = { .uri = "/", .method = HTTP_GET, .handler = _index_page_handler, .user_ctx = NULL}; static const httpd_uri_t _index_page_css = { .uri = "/index_style.css", .method = HTTP_GET, .handler = _index_page_css_handler, .user_ctx = NULL}; static const httpd_uri_t _index_page_js = { .uri = "/index_script.js", .method = HTTP_GET, .handler = _index_page_js_handler, .user_ctx = NULL}; static const httpd_uri_t _index_page_ws = { .uri = "/ws", .method = HTTP_GET, .handler = _index_page_ws_handler, .user_ctx = NULL, .is_websocket = true}; void _zh_webserver_init(void) { httpd_config_t config = HTTPD_DEFAULT_CONFIG(); httpd_start(&_webserver_handle, &config); httpd_register_uri_handler(_webserver_handle, &_fav); httpd_register_uri_handler(_webserver_handle, &_logo); httpd_register_uri_handler(_webserver_handle, &_index_page); httpd_register_uri_handler(_webserver_handle, &_index_page_css); httpd_register_uri_handler(_webserver_handle, &_index_page_js); httpd_register_uri_handler(_webserver_handle, &_index_page_ws); // httpd_config_t config = HTTPD_DEFAULT_CONFIG(); // httpd_start(&_webserver_handle, &config); // zh_ota_server_init(_webserver_handle); } void _zh_webserver_send(char *payload) { httpd_queue_work(_webserver_handle, _ws_async_send, payload); } static void _ws_async_send(void *arg) { httpd_ws_frame_t ws_package = {0}; // struct async_resp_arg *resp_arg = arg; // httpd_handle_t hd = resp_arg->hd; // int fd = resp_arg->fd; // led_state = !led_state; // // gpio_set_level(LED_PIN, led_state); // char buff[4]; // memset(buff, 0, sizeof(buff)); // sprintf(buff, "%d", led_state); // memset(&ws_package, 0, sizeof(httpd_ws_frame_t)); ws_package.payload = (uint8_t *)arg; ws_package.len = strlen(arg); ws_package.type = HTTPD_WS_TYPE_TEXT; static size_t max_clients = CONFIG_LWIP_MAX_LISTENING_TCP; size_t fds = max_clients; int client_fds[max_clients]; esp_err_t ret = httpd_get_client_list(_webserver_handle, &fds, client_fds); // if (ret != ESP_OK) // { // return ESP_OK; // } for (uint8_t i = 0; i <= fds; ++i) { int client_info = httpd_ws_get_fd_info(_webserver_handle, client_fds[i]); if (client_info == HTTPD_WS_CLIENT_WEBSOCKET) { httpd_ws_send_frame_async(_webserver_handle, client_fds[i], &ws_package); } } // free(resp_arg); } static esp_err_t _fav_handler(httpd_req_t *req) { extern const unsigned char favicon_ico_start[] asm("_binary_favicon_ico_start"); extern const unsigned char favicon_ico_end[] asm("_binary_favicon_ico_end"); const size_t favicon_ico_size = (favicon_ico_end - favicon_ico_start); httpd_resp_set_type(req, "image/x-icon"); httpd_resp_send_chunk(req, (const char *)favicon_ico_start, favicon_ico_size); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } static esp_err_t _logo_handler(httpd_req_t *req) { extern const unsigned char logo_png_start[] asm("_binary_logo_png_start"); extern const unsigned char logo_png_end[] asm("_binary_logo_png_end"); const size_t logo_png_size = (logo_png_end - logo_png_start); httpd_resp_set_type(req, "image/png"); httpd_resp_send_chunk(req, (const char *)logo_png_start, logo_png_size); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } static esp_err_t _index_page_handler(httpd_req_t *req) { extern const unsigned char index_html_start[] asm("_binary_index_html_start"); extern const unsigned char index_html_end[] asm("_binary_index_html_end"); const size_t index_html_size = (index_html_end - index_html_start); httpd_resp_set_type(req, "text/html"); httpd_resp_send_chunk(req, (const char *)index_html_start, index_html_size); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } static esp_err_t _index_page_css_handler(httpd_req_t *req) { extern const unsigned char index_style_css_start[] asm("_binary_index_style_css_start"); extern const unsigned char index_style_css_end[] asm("_binary_index_style_css_end"); const size_t index_style_css_size = (index_style_css_end - index_style_css_start); httpd_resp_set_type(req, "text/css"); httpd_resp_send_chunk(req, (const char *)index_style_css_start, index_style_css_size); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } static esp_err_t _index_page_js_handler(httpd_req_t *req) { extern const unsigned char index_script_js_start[] asm("_binary_index_script_js_start"); extern const unsigned char index_script_js_end[] asm("_binary_index_script_js_end"); const size_t index_script_js_size = (index_script_js_end - index_script_js_start); httpd_resp_set_type(req, "text/javascript"); httpd_resp_send_chunk(req, (const char *)index_script_js_start, index_script_js_size); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } static esp_err_t _index_page_ws_handler(httpd_req_t *req) { if (req->method == HTTP_GET) { // ESP_LOGI(TAG, "Handshake done, the new connection was opened"); // httpd_queue_work(_webserver_handle, ws_async_snd, NULL); return ESP_OK; } httpd_ws_frame_t ws_package = {0}; uint8_t *buf = NULL; ws_package.type = HTTPD_WS_TYPE_TEXT; httpd_ws_recv_frame(req, &ws_package, 0); // ZH_ERROR_CHECK(err == ESP_OK, err, NULL, "Main page ws handler error."); if (ws_package.len > 0) { buf = heap_caps_calloc(1, ws_package.len + 1, MALLOC_CAP_8BIT); // ZH_ERROR_CHECK(buf != NULL, ESP_ERR_NO_MEM, NULL, "Main page ws handler error."); ws_package.payload = buf; httpd_ws_recv_frame(req, &ws_package, ws_package.len); // ZH_ERROR_CHECK(buf != NULL, err, heap_caps_free(buf), "Main page ws handler error."); } if (ws_package.type == HTTPD_WS_TYPE_TEXT) { if (strcmp((char *)ws_package.payload, "toggle") == 0) { heap_caps_free(buf); // return trigger_async_send(req->handle, req); } } return ESP_OK; }