diff --git a/.gitignore b/.gitignore index 63bd0d8..8a8ad5f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ package-lock.json **/priv_note.md _priv_tools/ project_components/wifi_manager/wifi_configuration.h +managed_components/ \ No newline at end of file diff --git a/components/global_resource/global_module.c b/components/global_resource/global_module.c new file mode 100644 index 0000000..5dbf3c0 --- /dev/null +++ b/components/global_resource/global_module.c @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2024 kerms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "global_module.h" +#include +#include + +#define TAG __FILE_NAME__ +#define GLOBAL_MODULE_MAX 10 + +static global_module_t module_arr[GLOBAL_MODULE_MAX] = {0}; +static uint8_t module_count = 0; + +int global_module_reg(const global_module_t *g_mod) +{ + if (g_mod->module_id > GLOBAL_MODULE_MAX) { + ESP_LOGE(TAG, "g_id > max"); + return 1; + } + + if (module_arr[g_mod->module_id].init != NULL) { + ESP_LOGE(TAG, "g_id.init not NULL"); + return 1; + } + + ESP_LOGI(TAG, "g_id: %d", g_mod->module_id); + module_arr[g_mod->module_id].module_id = g_mod->module_id; + module_arr[g_mod->module_id].init = g_mod->init; + module_count++; + return 0; +} + +int global_module_init() +{ + for (int i = 0; i < GLOBAL_MODULE_MAX; ++i) { + if (module_arr[i].init) { + module_arr[i].init(); + } + } + return 0; +} diff --git a/components/global_resource/global_module.h b/components/global_resource/global_module.h new file mode 100644 index 0000000..b9d6a26 --- /dev/null +++ b/components/global_resource/global_module.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 kerms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef GLOBAL_MODULE_H_GUARD +#define GLOBAL_MODULE_H_GUARD + +#include + +typedef int (*global_module_init_func)(void); + +typedef struct global_module_t { + global_module_init_func init; + uint8_t module_id; +} global_module_t; + +int global_module_reg(const global_module_t *g_mod); + +int global_module_init(); + +#define GLOBAL_MODULE_REGISTER(NAME, GLOBAL_MODULE_CFG) \ + __attribute__((used, constructor)) void cons_G_MOD_ ## NAME(); \ + void cons_G_MOD_ ## NAME() { global_module_reg(GLOBAL_MODULE_CFG); } + + +#endif //GLOBAL_MODULE_H_GUARD \ No newline at end of file diff --git a/project_components/static_buffer/CMakeLists.txt b/components/memory_pool/CMakeLists.txt similarity index 100% rename from project_components/static_buffer/CMakeLists.txt rename to components/memory_pool/CMakeLists.txt diff --git a/project_components/static_buffer/static_buffer.c b/components/memory_pool/memory_pool.c similarity index 79% rename from project_components/static_buffer/static_buffer.c rename to components/memory_pool/memory_pool.c index 257d022..4f90e44 100644 --- a/project_components/static_buffer/static_buffer.c +++ b/components/memory_pool/memory_pool.c @@ -4,17 +4,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "static_buffer.h" +#include "memory_pool.h" #include #include -#define BUFFER_NR 4 +#define BUFFER_NR 8 #define BUFFER_SZ 2048 static uint8_t buf[BUFFER_NR][BUFFER_SZ]; + +/* TODO: use CAS */ static QueueHandle_t buf_queue = NULL; -int static_buffer_init() +int memory_pool_init() { if (buf_queue != NULL) return 0; @@ -33,14 +35,14 @@ int static_buffer_init() return 0; } -void *static_buffer_get(uint32_t tick_wait) +void *memory_pool_get(uint32_t tick_wait) { void *ptr = NULL; xQueueReceive(buf_queue, &ptr, tick_wait); return ptr; } -void static_buffer_put(void *ptr) +void memory_pool_put(void *ptr) { //printf("put buf %d\n", uxQueueMessagesWaiting(buf_queue)); if (unlikely(xQueueSend(buf_queue, &ptr, 0) != pdTRUE)) { @@ -48,7 +50,7 @@ void static_buffer_put(void *ptr) } } -uint32_t static_buffer_get_buf_size() +inline uint32_t memory_pool_get_buf_size() { return BUFFER_SZ; } diff --git a/project_components/static_buffer/static_buffer.h b/components/memory_pool/memory_pool.h similarity index 50% rename from project_components/static_buffer/static_buffer.h rename to components/memory_pool/memory_pool.h index 5aeaccf..676464a 100644 --- a/project_components/static_buffer/static_buffer.h +++ b/components/memory_pool/memory_pool.h @@ -9,13 +9,13 @@ #include -int static_buffer_init(); +int memory_pool_init(); -void *static_buffer_get(uint32_t tick_wait); +void *memory_pool_get(uint32_t tick_wait); -void static_buffer_put(void *ptr); +void memory_pool_put(void *ptr); -uint32_t static_buffer_get_buf_size(); +uint32_t memory_pool_get_buf_size(); #endif //STATIC_BUFFER_H_GUARD \ No newline at end of file diff --git a/main/main.c b/main/main.c index 2cc4eb6..d28a2af 100644 --- a/main/main.c +++ b/main/main.c @@ -10,7 +10,7 @@ #include "wt_storage.h" #include "wifi_manager.h" #include "web_server.h" -#include "static_buffer.h" +#include "memory_pool.h" #include "request_runner.h" #include "uart_tcp_bridge.h" @@ -18,18 +18,17 @@ void app_main() { - assert(static_buffer_init() == 0); + assert(memory_pool_init() == 0); // static buffer assert(request_runner_init() == 0); wt_storage_init(); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); + wt_mdns_init(); wifi_manager_init(); DAP_Setup(); start_webserver(); - wt_mdns_init(); - xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 14, NULL); // DAP handle task diff --git a/project_components/api_router/CMakeLists.txt b/project_components/api_router/CMakeLists.txt index b0d6fed..f077479 100644 --- a/project_components/api_router/CMakeLists.txt +++ b/project_components/api_router/CMakeLists.txt @@ -1,4 +1,4 @@ -file(GLOB SOURCES * +file(GLOB SOURCES *.c ) diff --git a/project_components/api_router/api_json_module.h b/project_components/api_router/api_json_module.h index 0c720d2..610739f 100644 --- a/project_components/api_router/api_json_module.h +++ b/project_components/api_router/api_json_module.h @@ -25,12 +25,13 @@ typedef enum api_json_req_status_e { API_JSON_OK = 0, API_JSON_ASYNC = 1, API_JSON_BAD_REQUEST = 2, + API_JSON_INTERNAL_ERR = 3, } api_json_req_status_e; typedef int (*api_json_on_req)(uint16_t cmd, api_json_req_t *req, api_json_module_async_t *rsp); typedef struct api_json_module_cfg_t { - api_json_on_req on_req; + api_json_on_req on_req; /* input request callback */ uint8_t module_id; } api_json_module_cfg_t; @@ -40,9 +41,6 @@ void api_json_module_dump(); int api_json_module_add(api_json_init_func); -/** - * @brief Register a module that will be init with PRI(priority) order. - */ #define API_JSON_MODULE_REGISTER(PRI, INIT) \ __attribute__((used, constructor(PRI))) void cons_ ## INIT(); \ void cons_ ## INIT() { api_json_module_add(INIT); } diff --git a/project_components/request_runner/request_runner.c b/project_components/request_runner/request_runner.c index 6bc5413..9a34a99 100644 --- a/project_components/request_runner/request_runner.c +++ b/project_components/request_runner/request_runner.c @@ -26,7 +26,7 @@ _Noreturn void req_long_task(void *arg) if (unlikely(xQueueReceive(long_run_queue, &req, portMAX_DELAY) != pdTRUE)) { continue; } - req->status = req->module.helper_cb(req->module.arg); + req->status = req->module.cb(req->module.arg); /* if send out queue is busy, set status and let the cb to cancel send out * */ diff --git a/project_components/request_runner/request_runner.h b/project_components/request_runner/request_runner.h index 7bff2a1..037252d 100644 --- a/project_components/request_runner/request_runner.h +++ b/project_components/request_runner/request_runner.h @@ -15,7 +15,7 @@ typedef struct req_send_out_cb_t { } req_send_out_cb_t; typedef struct req_module_cb_t { - int (*helper_cb)(void *arg); + int (*cb)(void *arg); void *arg; } req_module_cb_t; diff --git a/project_components/web_server/CMakeLists.txt b/project_components/web_server/CMakeLists.txt index 08f8054..925ace4 100644 --- a/project_components/web_server/CMakeLists.txt +++ b/project_components/web_server/CMakeLists.txt @@ -10,7 +10,7 @@ idf_component_register( SRCS ${SOURCES} INCLUDE_DIRS "." REQUIRES esp_http_server - PRIV_REQUIRES request_runner api_router json static_buffer utils html + PRIV_REQUIRES request_runner api_router json memory_pool utils html ) idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON) diff --git a/project_components/web_server/uri_modules/uri_api.c b/project_components/web_server/uri_modules/uri_api.c index 4fd15b9..22f336e 100644 --- a/project_components/web_server/uri_modules/uri_api.c +++ b/project_components/web_server/uri_modules/uri_api.c @@ -1,7 +1,7 @@ #include "web_uri_module.h" #include "api_json_router.h" #include "request_runner.h" -#include "static_buffer.h" +#include "memory_pool.h" #include #include @@ -32,13 +32,13 @@ static esp_err_t api_post_handler(httpd_req_t *req) char *buf; uint32_t remaining = req->content_len; - buf_len = static_buffer_get_buf_size() - sizeof(post_request_t); + buf_len = memory_pool_get_buf_size() - sizeof(post_request_t); if (unlikely(buf_len < remaining)) { ESP_LOGE(TAG, "req size %lu > buf_len %lu", remaining, buf_len); return ESP_FAIL; } - post_req = static_buffer_get(pdMS_TO_TICKS(20)); + post_req = memory_pool_get(pdMS_TO_TICKS(20)); if (unlikely(post_req == NULL)) { ESP_LOGE(TAG, "static buf busy"); return ESP_FAIL; @@ -97,7 +97,7 @@ end: ESP_LOGE(TAG, "resp_send err: %s", esp_err_to_name(err)); } put_buf: - static_buffer_put(post_req); + memory_pool_put(post_req); return err; } @@ -107,7 +107,7 @@ int uri_api_send_out(httpd_req_t *req, post_request_t *post_req, int err) uint32_t buf_len; buf = post_req->buf; - buf_len = static_buffer_get_buf_size() - sizeof(post_request_t); + buf_len = memory_pool_get_buf_size() - sizeof(post_request_t); cJSON_Delete(post_req->json.in); if (post_req->json.out) { ESP_LOGI(TAG, "json out ok"); @@ -136,7 +136,7 @@ void async_send_out_cb(void *arg, int module_status) /* clean resources */ httpd_req_async_handler_complete(req->req_out); - static_buffer_put(req); + memory_pool_put(req); }; /** diff --git a/project_components/web_server/uri_modules/uri_ws.c b/project_components/web_server/uri_modules/uri_ws.c index 113d243..3c2fb9d 100644 --- a/project_components/web_server/uri_modules/uri_ws.c +++ b/project_components/web_server/uri_modules/uri_ws.c @@ -6,7 +6,7 @@ #include "web_uri_module.h" #include "api_json_router.h" -#include "static_buffer.h" +#include "memory_pool.h" #include #include @@ -20,8 +20,11 @@ #define TAG __FILE_NAME__ #define MSG_BUSY_ERROR "{\"error\":\"Resource busy\"}" #define MSG_JSON_ERROR "{\"error\":\"JSON parse error\"}" +#define MSG_BAD_REQUEST_ERROR "{\"error\":\"Bad json request\"}" #define MSG_SEND_JSON_ERROR "{\"error\":\"JSON generation error\"}" -#define MSG_INTERNAL_ERROR "{\"error\":\"\"}" +#define MSG_INTERNAL_ERROR "{\"error\":\"Internal error\"}" + +#define WS_MODULE_ID 3 typedef struct ws_msg_t { api_json_req_t json; @@ -33,13 +36,13 @@ typedef struct ws_msg_t { uint8_t payload[0]; /* size = static_buf_size - offsetof(this, delim) */ } ws_msg_t; -#define PAYLOAD_LEN static_buffer_get_buf_size() - sizeof(ws_msg_t) +#define PAYLOAD_LEN memory_pool_get_buf_size() - sizeof(ws_msg_t) struct ws_ctx_t { struct ws_client_info_t { httpd_handle_t hd; - int fd; /* range 58 ~ 58+max_socket */ - } clients[CONFIG_LWIP_MAX_SOCKETS+1]; + int fd; /* range 64 - max_socket ~ 64 */ + } clients[CONFIG_LWIP_MAX_SOCKETS + 1]; TaskHandle_t task_heartbeat; int8_t client_count; } ws_ctx; @@ -47,14 +50,14 @@ struct ws_ctx_t { static int ws_on_text_data(httpd_req_t *req, ws_msg_t *ws_msg); static int ws_on_binary_data(httpd_req_t *req, ws_msg_t *ws_msg); static int ws_on_socket_open(httpd_req_t *req); -static int ws_on_close(httpd_req_t *req, ws_msg_t *msg); +static int ws_on_close(httpd_req_t *req, httpd_ws_frame_t *ws_pkt, void *msg); static void ws_async_resp(void *arg); static void async_send_out_cb(void *arg, int module_status); static void json_to_text(ws_msg_t *msg); /* Heartbeat related */ -static inline void ws_add_fd(httpd_handle_t hd, int fd); +static inline int8_t ws_add_fd(httpd_handle_t hd, int fd); static inline void ws_rm_fd(int fd); _Noreturn static void heartbeat_task(void *arg); @@ -69,13 +72,13 @@ static esp_err_t ws_req_handler(httpd_req_t *req) ESP_LOGI(TAG, "ws_handler: httpd_handle_t=%p, sockfd=%d, client_info:%d, client_count: %d", req->handle, httpd_req_to_sockfd(req), httpd_ws_get_fd_info(req->handle, httpd_req_to_sockfd(req)), - ws_ctx.client_count); + ws_ctx.client_count); int err = ESP_OK; httpd_ws_frame_t *ws_pkt; ws_msg_t *ws_msg; - ws_msg = static_buffer_get(pdMS_TO_TICKS(10)); + ws_msg = memory_pool_get(pdMS_TO_TICKS(10)); if (unlikely(ws_msg == NULL)) { httpd_ws_frame_t resp_pkt; resp_pkt.type = HTTPD_WS_TYPE_TEXT; @@ -92,12 +95,12 @@ static esp_err_t ws_req_handler(httpd_req_t *req) err = httpd_ws_recv_frame(req, ws_pkt, 0); if (unlikely(err != ESP_OK)) { ESP_LOGE(TAG, "ws recv len error"); - return ws_on_close(req, ws_msg); + return ws_on_close(req, ws_pkt, ws_msg); } ESP_LOGI(TAG, "frame len: %d, type: %d", ws_pkt->len, ws_pkt->type); if (unlikely(ws_pkt->len > PAYLOAD_LEN)) { ESP_LOGE(TAG, "frame len is too big"); - return ws_on_close(req, ws_msg); + return ws_on_close(req, ws_pkt, ws_msg); } switch (ws_pkt->type) { @@ -109,20 +112,13 @@ static esp_err_t ws_req_handler(httpd_req_t *req) err = httpd_ws_recv_frame(req, ws_pkt, ws_pkt->len); if (unlikely(err != ESP_OK)) { ESP_LOGE(TAG, "ws recv data error"); - return ws_on_close(req, ws_msg); + return ws_on_close(req, ws_pkt, ws_msg); } return ws_on_text_data(req, ws_msg); case HTTPD_WS_TYPE_BINARY: - ws_pkt->payload = ws_msg->payload; - /* read incoming data */ - err = httpd_ws_recv_frame(req, ws_pkt, ws_pkt->len); - if (unlikely(err != ESP_OK)) { - ESP_LOGE(TAG, "ws recv data error"); - return ws_on_close(req, ws_msg); - } return ws_on_binary_data(req, ws_msg); case HTTPD_WS_TYPE_CLOSE: - return ws_on_close(req, ws_msg); + return ws_on_close(req, ws_pkt, ws_msg); case HTTPD_WS_TYPE_PING: /* Now turn the frame to PONG */ ws_pkt->type = HTTPD_WS_TYPE_PONG; @@ -136,39 +132,11 @@ static esp_err_t ws_req_handler(httpd_req_t *req) goto end; } end: - static_buffer_put(ws_msg); + memory_pool_put(ws_msg); return err; } - -/** - * REGISTER MODULE - * */ - -static const httpd_uri_t uri_api = { - .uri = "/ws", - .method = HTTP_GET, - .handler = ws_req_handler, - .user_ctx = NULL, - .is_websocket = true, - .supported_subprotocol = NULL, - .handle_ws_control_frames = true, -}; - -static int WS_REQ_INIT(const httpd_uri_t **uri_conf) { - *uri_conf = &uri_api; - xTaskCreate(heartbeat_task, "hb task", 2048, NULL, 3, &ws_ctx.task_heartbeat); - return 0; -} - -static int WS_REQ_EXIT(const httpd_uri_t **uri_conf) { - *uri_conf = &uri_api; - vTaskDelete(ws_ctx.task_heartbeat); - ws_ctx.task_heartbeat = NULL; - return 0; -} - -WEB_URI_MODULE_REGISTER(101, WS_REQ_INIT, WS_REQ_EXIT) +void ws_set_err_msg(httpd_ws_frame_t *p_frame, api_json_req_status_e ret); int ws_on_text_data(httpd_req_t *req, ws_msg_t *ws_msg) { @@ -183,9 +151,9 @@ int ws_on_text_data(httpd_req_t *req, ws_msg_t *ws_msg) ESP_LOGI(TAG, "heap min: %lu, cur: %lu", esp_get_minimum_free_heap_size(), esp_get_free_heap_size()); /* Decode */ - ws_msg->json.in = cJSON_ParseWithLength((char *) ws_pkt->payload, ws_pkt->len); + ws_msg->json.in = cJSON_ParseWithLength((char *)ws_pkt->payload, ws_pkt->len); if (unlikely(ws_msg->json.in == NULL)) { - ws_pkt->payload = (uint8_t *) MSG_JSON_ERROR; + ws_pkt->payload = (uint8_t *)MSG_JSON_ERROR; ws_pkt->len = strlen(MSG_JSON_ERROR); goto put_buf; } @@ -204,10 +172,7 @@ int ws_on_text_data(httpd_req_t *req, ws_msg_t *ws_msg) /* ret, buf will be release latter in async send out */ return ESP_OK; } else if (ret != API_JSON_OK) { - ws_pkt->len = strlen(MSG_BUSY_ERROR); - ws_pkt->payload = (uint8_t *)MSG_BUSY_ERROR; - ws_pkt->final = 1; - err = httpd_ws_send_frame_async(req->handle, httpd_req_to_sockfd(req), ws_pkt); + ws_set_err_msg(ws_pkt, ret); goto end; } else if (ws_msg->json.out == NULL) { goto end; @@ -220,39 +185,62 @@ end: cJSON_Delete(ws_msg->json.in); put_buf: httpd_ws_send_frame_async(req->handle, httpd_req_to_sockfd(req), ws_pkt); - static_buffer_put(ws_msg); + memory_pool_put(ws_msg); return err; } +void ws_set_err_msg(httpd_ws_frame_t *p_frame, api_json_req_status_e ret) +{ + switch (ret) { + case API_JSON_BAD_REQUEST: + p_frame->len = strlen(MSG_BAD_REQUEST_ERROR); + p_frame->payload = (uint8_t *)MSG_BAD_REQUEST_ERROR; + p_frame->final = 1; + break; + case API_JSON_INTERNAL_ERR: + p_frame->len = strlen(MSG_INTERNAL_ERROR); + p_frame->payload = (uint8_t *)MSG_INTERNAL_ERROR; + p_frame->final = 1; + break; + default: + return; + } +} + +_Static_assert(sizeof(httpd_ws_frame_t) <= 16, "bin_data_internal padding not sufficient for httpd_ws_frame_t"); + int ws_on_binary_data(httpd_req_t *req, ws_msg_t *ws_msg) { (void) req; - static_buffer_put(ws_msg); + memory_pool_put(ws_msg); return 0; } int ws_on_socket_open(httpd_req_t *req) { int sock_fd = httpd_req_to_sockfd(req); - ws_add_fd(req->handle, sock_fd); ESP_LOGI(TAG, "ws open: %d", sock_fd); - return ESP_OK; + return ws_add_fd(req->handle, sock_fd); } -static int ws_on_close(httpd_req_t *req, ws_msg_t *msg) +/** + * @param msg must only used as generic ptr, truncated by ws_on_bin() + * @return + */ +static int ws_on_close(httpd_req_t *req, httpd_ws_frame_t *ws_pkt, void *msg) { /* Read the rest of the CLOSE frame and response */ /* Please refer to RFC6455 Section 5.5.1 for more details */ - msg->ws_pkt.len = 0; - msg->ws_pkt.type = HTTPD_WS_TYPE_CLOSE; + ws_pkt->len = 0; + ws_pkt->type = HTTPD_WS_TYPE_CLOSE; ESP_LOGI(TAG, "ws %d closed", httpd_req_to_sockfd(req)); ws_rm_fd(httpd_req_to_sockfd(req)); - int err = httpd_ws_send_frame(req, &msg->ws_pkt); + int err = httpd_ws_send_frame(req, ws_pkt); if (err) { ESP_LOGE(TAG, "on close %s", esp_err_to_name(err)); } httpd_sess_trigger_close(req->handle, httpd_req_to_sockfd(req)); - static_buffer_put(msg); + memory_pool_put(msg); return err; } @@ -265,10 +253,10 @@ static void ws_async_resp(void *arg) ESP_LOGI(TAG, "ws async fd : %d", fd); err = httpd_ws_send_frame_async(hd, fd, &req->ws_pkt); - if (err) { + if (unlikely(err)) { ESP_LOGE(TAG, "%s", esp_err_to_name(err)); } - static_buffer_put(req); + memory_pool_put(req); } void async_send_out_cb(void *arg, int module_status) @@ -282,6 +270,7 @@ void async_send_out_cb(void *arg, int module_status) json_to_text(req); err = httpd_queue_work(req->hd, ws_async_resp, req); if (likely(err == ESP_OK)) { + /* msg queued, let callee release the buffer */ return; } @@ -289,7 +278,7 @@ void async_send_out_cb(void *arg, int module_status) end: /* clean resources */ - static_buffer_put(req); + memory_pool_put(req); } void json_to_text(ws_msg_t *ws_msg) @@ -297,27 +286,29 @@ void json_to_text(ws_msg_t *ws_msg) int err; httpd_ws_frame_t *ws_pkt = &ws_msg->ws_pkt; /* api function returns something, send it to http client */ - err = !cJSON_PrintPreallocated(ws_msg->json.out, (char *) ws_msg->payload, PAYLOAD_LEN - 5, 0); + err = !cJSON_PrintPreallocated(ws_msg->json.out, (char *)ws_msg->payload, PAYLOAD_LEN - 5, 0); cJSON_Delete(ws_msg->json.out); if (unlikely(err)) { ws_pkt->len = strlen(MSG_SEND_JSON_ERROR); - ws_pkt->payload = (uint8_t *) MSG_SEND_JSON_ERROR; + ws_pkt->payload = (uint8_t *)MSG_SEND_JSON_ERROR; ws_pkt->final = 1; } - ws_pkt->len = strlen((char *) ws_pkt->payload); + ws_pkt->len = strlen((char *)ws_pkt->payload); } /* Clients array manipulation function * */ -static inline void ws_add_fd(httpd_handle_t hd, int fd) +static inline int8_t ws_add_fd(httpd_handle_t hd, int fd) { if (ws_ctx.client_count > CONFIG_LWIP_MAX_SOCKETS) { - return; + return 1; } + ws_ctx.clients[ws_ctx.client_count].fd = fd; ws_ctx.clients[ws_ctx.client_count].hd = hd; ws_ctx.client_count++; + return 0; } /** @@ -328,8 +319,8 @@ static inline void ws_rm_fd(int fd) { for (int i = 0; i < ws_ctx.client_count; ++i) { if (ws_ctx.clients[i].fd == fd) { - ws_ctx.clients[i].fd = ws_ctx.clients[ws_ctx.client_count-1].fd; - ws_ctx.clients[i].hd = ws_ctx.clients[ws_ctx.client_count-1].hd; + ws_ctx.clients[i].fd = ws_ctx.clients[ws_ctx.client_count - 1].fd; + ws_ctx.clients[i].hd = ws_ctx.clients[ws_ctx.client_count - 1].hd; ws_ctx.client_count--; return; } @@ -368,10 +359,41 @@ static inline void ws_broadcast_heartbeat() _Noreturn void heartbeat_task(void *arg) { - (void) arg; + (void)arg; while (1) { vTaskDelay(pdMS_TO_TICKS(2000)); ws_broadcast_heartbeat(); } }; + +/** + * REGISTER MODULE + * */ + +static const httpd_uri_t uri_api = { + .uri = "/ws", + .method = HTTP_GET, + .handler = ws_req_handler, + .user_ctx = NULL, + .is_websocket = true, + .supported_subprotocol = NULL, + .handle_ws_control_frames = true, +}; + +static int WS_REQ_INIT(const httpd_uri_t **uri_conf) +{ + *uri_conf = &uri_api; + xTaskCreate(heartbeat_task, "hb task", 2048, NULL, 3, &ws_ctx.task_heartbeat); + return 0; +} + +static int WS_REQ_EXIT(const httpd_uri_t **uri_conf) +{ + *uri_conf = &uri_api; + vTaskDelete(ws_ctx.task_heartbeat); + ws_ctx.task_heartbeat = NULL; + return 0; +} + +WEB_URI_MODULE_REGISTER(101, WS_REQ_INIT, WS_REQ_EXIT) diff --git a/project_components/web_server/web_uri_module.h b/project_components/web_server/web_uri_module.h index 6181a86..f2a85c9 100644 --- a/project_components/web_server/web_uri_module.h +++ b/project_components/web_server/web_uri_module.h @@ -11,10 +11,15 @@ typedef struct uri_module_t { uint8_t priority; } uri_module_t; +/** + * @param priority smaller number will be called first + * @return 0: SUCCESS, 1: max module count reached + */ int uri_module_add(uint8_t priority, uri_module_func init, uri_module_func exit); /** * @brief Register a uri module that will be init with PRI(priority) order. + * smaller priority will be called first. */ #define WEB_URI_MODULE_REGISTER(PRI, INIT, EXIT) \ __attribute__((used, constructor(PRI))) void cons_ ## INIT(); \ diff --git a/project_components/wifi_manager/wifi_api.h b/project_components/wifi_manager/wifi_api.h index 2caddb3..52bbc59 100644 --- a/project_components/wifi_manager/wifi_api.h +++ b/project_components/wifi_manager/wifi_api.h @@ -3,7 +3,7 @@ #include -#define WIFI_API_MODULE_ID 1 +#define WIFI_MODULE_ID 1 typedef enum wifi_api_json_cmd_t { UNKNOWN = 0, diff --git a/project_components/wifi_manager/wifi_api_json.c b/project_components/wifi_manager/wifi_api_json.c index 522ccc7..2247c9e 100644 --- a/project_components/wifi_manager/wifi_api_json.c +++ b/project_components/wifi_manager/wifi_api_json.c @@ -19,7 +19,7 @@ static int wifi_api_json_disconnect(api_json_req_t *req); static int wifi_api_json_ap_get_info(api_json_req_t *req); - +/* the upper caller call cb() with void *, this let us use custom function arg */ static int async_helper_cb(void *arg) { api_json_module_req_t *req = arg; @@ -30,7 +30,7 @@ static inline int set_async(api_json_req_t *req, api_json_module_async_t *async, { async->module.func = func; async->module.arg = req; - async->req_task.module.helper_cb = async_helper_cb; + async->req_task.module.cb = async_helper_cb; async->req_task.module.arg = &async->module; return API_JSON_ASYNC; } @@ -52,7 +52,6 @@ static int on_json_req(uint16_t cmd, api_json_req_t *req, api_json_module_async_ return wifi_api_json_disconnect(req); case WIFI_API_JSON_AP_GET_INFO: return wifi_api_json_ap_get_info(req); - break; } ESP_LOGI(TAG, "cmd %d not executed\n", cmd); @@ -127,7 +126,7 @@ int wifi_api_json_disconnect(api_json_req_t *req) static int wifi_api_json_init(api_json_module_cfg_t *cfg) { cfg->on_req = on_json_req; - cfg->module_id = WIFI_API_MODULE_ID; + cfg->module_id = WIFI_MODULE_ID; return 0; } diff --git a/project_components/wifi_manager/wifi_json_utils.c b/project_components/wifi_manager/wifi_json_utils.c index c34cd39..24df07c 100644 --- a/project_components/wifi_manager/wifi_json_utils.c +++ b/project_components/wifi_manager/wifi_json_utils.c @@ -6,7 +6,7 @@ static void wifi_api_json_set_header(cJSON *root, uint16_t cmd) { cJSON_AddNumberToObject(root, "cmd", cmd); - cJSON_AddNumberToObject(root, "module", WIFI_API_MODULE_ID); + cJSON_AddNumberToObject(root, "module", WIFI_MODULE_ID); } cJSON *wifi_api_json_serialize_ap_info(wifi_api_ap_info_t *ap_info, wifi_api_json_cmd_t cmd) diff --git a/project_components/wt_mdns/wt_mdns_config.c b/project_components/wt_mdns/wt_mdns_config.c index baf5635..7f1f8ac 100644 --- a/project_components/wt_mdns/wt_mdns_config.c +++ b/project_components/wt_mdns/wt_mdns_config.c @@ -14,6 +14,22 @@ void wt_mdns_init() /* TODO: read instance description from NVS */ ESP_ERROR_CHECK(mdns_instance_name_set(MDSN_INSTANCE_DESC)); + + //structure with TXT records + mdns_txt_item_t serviceTxtData[] = { +#if defined CONFIG_IDF_TARGET_ESP32S3 + {"board", "esp32S3"}, +#elif defined CONFIG_IDF_TARGET_ESP32C3 + {"board", "esp32c3"}, +#elif defined CONFIG_IDF_TARGET_ESP32 + {"board", "esp32"}, +#endif + }; + + //initialize service + ESP_ERROR_CHECK(mdns_service_add("WebServer", "_http", "_tcp", 80, + serviceTxtData, sizeof(serviceTxtData)/sizeof(serviceTxtData[0]))); + ESP_ERROR_CHECK(mdns_service_subtype_add_for_host("WebServer", "_http", "_tcp", NULL, "_server") ); } int wt_mdns_set_hostname(const char *hostname) diff --git a/project_components/wt_mdns/wt_mdns_config.h b/project_components/wt_mdns/wt_mdns_config.h index c5a0516..7820516 100644 --- a/project_components/wt_mdns/wt_mdns_config.h +++ b/project_components/wt_mdns/wt_mdns_config.h @@ -2,7 +2,7 @@ #define WT_MDNS_CONFIG_H_GUARD #define MDSN_DEFAULT_HOSTNAME "dap" // + serial number (4 char) -#define MDSN_INSTANCE_DESC "无线STM32调试器 by 允斯工作室" +#define MDSN_INSTANCE_DESC "ESP32 无线透传" void wt_mdns_init();