From b00f2b2dd4da4a2b8cf058e9e10f1da63c73407f Mon Sep 17 00:00:00 2001 From: kerms Date: Thu, 1 Feb 2024 09:19:42 +0800 Subject: [PATCH] add base uri api using http post/json --- main/main.c | 2 + project_components/api_router/CMakeLists.txt | 9 ++ .../api_router/api_json_module.c | 61 ++++++++ .../api_router/api_json_module.h | 37 +++++ .../api_router/api_json_router.c | 37 +++++ .../api_router/api_json_router.h | 10 ++ project_components/web_server/CMakeLists.txt | 15 ++ .../web_server/uri_modules/uri_api.c | 91 ++++++++++++ .../web_server/uri_modules/uri_html_base.c | 96 ++++++++++++ project_components/web_server/web_server.c | 140 ++++++++++++++++++ project_components/web_server/web_server.h | 16 ++ .../web_server/web_uri_module.c | 59 ++++++++ .../web_server/web_uri_module.h | 25 ++++ .../wifi_manager/CMakeLists.txt | 9 +- project_components/wifi_manager/wifi_api.c | 19 +++ project_components/wifi_manager/wifi_api.h | 18 +++ .../wifi_manager/wifi_api_json.c | 63 ++++++++ .../wifi_manager/wifi_api_json.h | 12 ++ .../wifi_manager/wifi_json_utils.c | 25 ++++ .../wifi_manager/wifi_json_utils.h | 8 + .../wifi_manager/wifi_manager.c | 24 +++ .../wifi_manager/wifi_manager.h | 3 + 22 files changed, 777 insertions(+), 2 deletions(-) create mode 100644 project_components/api_router/CMakeLists.txt create mode 100644 project_components/api_router/api_json_module.c create mode 100644 project_components/api_router/api_json_module.h create mode 100644 project_components/api_router/api_json_router.c create mode 100644 project_components/api_router/api_json_router.h create mode 100644 project_components/web_server/CMakeLists.txt create mode 100644 project_components/web_server/uri_modules/uri_api.c create mode 100644 project_components/web_server/uri_modules/uri_html_base.c create mode 100644 project_components/web_server/web_server.c create mode 100644 project_components/web_server/web_server.h create mode 100644 project_components/web_server/web_uri_module.c create mode 100644 project_components/web_server/web_uri_module.h create mode 100644 project_components/wifi_manager/wifi_api.c create mode 100644 project_components/wifi_manager/wifi_api.h create mode 100644 project_components/wifi_manager/wifi_api_json.c create mode 100644 project_components/wifi_manager/wifi_api_json.h create mode 100644 project_components/wifi_manager/wifi_json_utils.c create mode 100644 project_components/wifi_manager/wifi_json_utils.h diff --git a/main/main.c b/main/main.c index 4417b91..0c0a6c6 100644 --- a/main/main.c +++ b/main/main.c @@ -9,6 +9,7 @@ #include "wt_mdns_config.h" #include "wt_storage.h" #include "wifi_manager.h" +#include "web_server.h" void app_main() { @@ -18,6 +19,7 @@ void app_main() wifi_manager_init(); DAP_Setup(); + start_webserver(); wt_mdns_init(); diff --git a/project_components/api_router/CMakeLists.txt b/project_components/api_router/CMakeLists.txt new file mode 100644 index 0000000..b1f3e62 --- /dev/null +++ b/project_components/api_router/CMakeLists.txt @@ -0,0 +1,9 @@ +file(GLOB SOURCES * + ) + + +idf_component_register( + SRCS ${SOURCES} + INCLUDE_DIRS "." + REQUIRES json +) diff --git a/project_components/api_router/api_json_module.c b/project_components/api_router/api_json_module.c new file mode 100644 index 0000000..f504f3b --- /dev/null +++ b/project_components/api_router/api_json_module.c @@ -0,0 +1,61 @@ +#include "api_json_module.h" + +#include +#include +#include + +#define TAG __FILE_NAME__ + +#define API_MODULE_MAX 10 + +typedef struct api_json_module_t { + api_json_on_req on_req; +} api_json_module_t; + +static api_json_module_t module_arr[API_MODULE_MAX] = {0}; +static uint8_t module_count = 0; + +void api_json_module_dump() +{ + for (int i = 0; i < API_MODULE_MAX; ++i) { + printf("%d = %p\n", i, module_arr[i].on_req); + } +} + +int api_json_module_add(api_json_init_func func) +{ + api_json_module_cfg_t api_module; + int err; + + api_module.module_id = -1; + api_module.on_req = NULL; + + err = func(&api_module); + if (err) { + printf("module %p init failed\n", func); + } + + if (api_module.module_id >= API_MODULE_MAX) { + printf("module ID should be smaller than API_MODULE_MAX=%d\n", API_MODULE_MAX); + return 1; + } + + if (module_arr[api_module.module_id].on_req != NULL) { + printf("module ID %d is already in use\n", api_module.module_id); + return 1; + } + + module_arr[api_module.module_id].on_req = api_module.on_req; + module_count++; + printf("%p is added\n", func); + return 0; +} + +int api_json_module_call(uint8_t id, uint16_t cmd, api_json_req_t *in, api_json_resp_t *out) +{ + if (unlikely(id >= API_MODULE_MAX || module_arr[id].on_req == NULL)) { + return 1; + } + + return module_arr[id].on_req(cmd, in, out); +} diff --git a/project_components/api_router/api_json_module.h b/project_components/api_router/api_json_module.h new file mode 100644 index 0000000..ccc71bb --- /dev/null +++ b/project_components/api_router/api_json_module.h @@ -0,0 +1,37 @@ +#ifndef API_JSON_MODULE_H_GUARD +#define API_JSON_MODULE_H_GUARD + +#include +#include + +typedef struct api_json_req_t { + cJSON *json; +} api_json_req_t; + +typedef struct api_json_resp_t { + cJSON *json; +} api_json_resp_t; + +typedef int (*api_json_on_req)(uint16_t cmd, api_json_req_t *req, api_json_resp_t *rsp); + +typedef struct api_json_module_cfg_t { + api_json_on_req on_req; + uint8_t module_id; +} api_json_module_cfg_t; + +typedef int (*api_json_init_func)(api_json_module_cfg_t *api_module); + +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); } + +int api_json_module_call(uint8_t id, uint16_t cmd, api_json_req_t *in, api_json_resp_t *out); + +#endif //API_JSON_MODULE_H_GUARD diff --git a/project_components/api_router/api_json_router.c b/project_components/api_router/api_json_router.c new file mode 100644 index 0000000..8db745f --- /dev/null +++ b/project_components/api_router/api_json_router.c @@ -0,0 +1,37 @@ +#include "api_json_router.h" + +#include +#include +#include + +int api_json_router_init() +{ + api_json_module_dump(); + return 0; +} + +int api_json_route(api_json_req_t *req, api_json_resp_t *rsp) +{ + uint16_t cmd; + uint8_t module_id; + cJSON *cmd_json; + cJSON *module_json; + + if (unlikely(req->json == NULL)) { + return 1; + } + + cmd_json = cJSON_GetObjectItem(req->json, "cmd"); + module_json = cJSON_GetObjectItem(req->json, "module"); + + if (!cJSON_IsNumber(cmd_json) || !cJSON_IsNumber(module_json)) { + return 1; + } + + cmd = cmd_json->valueint; + module_id = module_json->valueint; + + printf("cmd %d received\n", cmd); + + return api_json_module_call(module_id, cmd, req, rsp); +} diff --git a/project_components/api_router/api_json_router.h b/project_components/api_router/api_json_router.h new file mode 100644 index 0000000..d19e798 --- /dev/null +++ b/project_components/api_router/api_json_router.h @@ -0,0 +1,10 @@ +#ifndef API_JSON_ROUTER_H_GUARD +#define API_JSON_ROUTER_H_GUARD + +#include "api_json_module.h" + +int api_json_router_init(); + +int api_json_route(api_json_req_t *req, api_json_resp_t *out); + +#endif //API_JSON_ROUTER_H_GUARD \ No newline at end of file diff --git a/project_components/web_server/CMakeLists.txt b/project_components/web_server/CMakeLists.txt new file mode 100644 index 0000000..c33fb3a --- /dev/null +++ b/project_components/web_server/CMakeLists.txt @@ -0,0 +1,15 @@ +file(GLOB SOURCES + web_server.c + web_uri_module.c + uri_modules/uri_html_base.c + uri_modules/uri_api.c + ) + +idf_component_register( + SRCS ${SOURCES} + INCLUDE_DIRS "." + REQUIRES esp_http_server api_router json +) + +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 new file mode 100644 index 0000000..cf8a8aa --- /dev/null +++ b/project_components/web_server/uri_modules/uri_api.c @@ -0,0 +1,91 @@ +#include "web_uri_module.h" +#include "api_json_router.h" + +#include +#include + +#include + +#define TAG __FILE_NAME__ + +static char buf[2048]; +static api_json_req_t json_in; +static api_json_resp_t json_out; + +static esp_err_t api_post_handler(httpd_req_t *req) +{ + int data_len; + int err; + uint32_t remaining = req->content_len; + + data_len = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf))); + if (unlikely(data_len <= 0)) { + ESP_LOGE(TAG, "httpd recv error"); + return ESP_FAIL; + } + + ESP_LOGI(TAG, "=========== RECEIVED DATA =========="); + ESP_LOGI(TAG, "%.*s", data_len, buf); + ESP_LOGI(TAG, "===================================="); + + /* Decode */ + json_in.json = cJSON_ParseWithLength(buf, data_len); + if (unlikely(json_in.json == NULL)) { + httpd_resp_set_status(req, HTTPD_400); + httpd_resp_send(req, NULL, 0); + return ESP_OK; + } + + /* DEBUG print the actual decoded string */ + cJSON_PrintPreallocated(json_in.json, buf, sizeof(buf), 0); + printf("json: %s\n", buf); + + err = api_json_route(&json_in, &json_out); + if (err) { + httpd_resp_set_status(req, HTTPD_400); + httpd_resp_send(req, NULL, 0); + return ESP_OK; + } + cJSON_Delete(json_in.json); + + if (json_out.json == NULL) { + return httpd_resp_send(req, NULL, 0); + } + + /* api function returns something, send back to http client */ + httpd_resp_set_type(req, HTTPD_TYPE_JSON); + err = !cJSON_PrintPreallocated(json_out.json, buf, sizeof(buf) - 5, 0); + cJSON_Delete(json_out.json); + json_out.json = NULL; + + if (err) { + httpd_resp_set_status(req, HTTPD_500); + return httpd_resp_send(req, NULL, 0); + } + + return httpd_resp_send(req, buf, strlen(buf)); +} + +/** + * REGISTER MODULE + * */ + +static const httpd_uri_t uri_api = { + .uri = "/api", + .method = HTTP_POST, + .handler = api_post_handler, + .user_ctx = NULL +}; + +int URI_API_INIT(const httpd_uri_t **uri_conf) { + *uri_conf = &uri_api; + api_json_router_init(); + return 0; +} + +int URI_API_EXIT(const httpd_uri_t **uri_conf) { + *uri_conf = &uri_api; + return 0; +} + +WEB_URI_MODULE_REGISTER(0x81, URI_API_INIT, URI_API_EXIT); diff --git a/project_components/web_server/uri_modules/uri_html_base.c b/project_components/web_server/uri_modules/uri_html_base.c new file mode 100644 index 0000000..fe731f6 --- /dev/null +++ b/project_components/web_server/uri_modules/uri_html_base.c @@ -0,0 +1,96 @@ +#include "web_uri_module.h" + +#include +#include + +#define TAG __FILE_NAME__ + +static 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); + /* Get value of expected key from query string */ + ESP_LOGI(TAG, "query: %s", buf); + } + 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, HTTPD_RESP_USE_STRLEN); + + /* 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; +} + +/** + * REGISTER MODULE + * */ + +static const 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!" +}; + +int URI_HTML_BASE_INIT(const httpd_uri_t **uri_conf) { + *uri_conf = &hello; + return 0; +} + +int URI_HTML_BASE_EXIT(const httpd_uri_t **uri_conf) { + *uri_conf = &hello; + return 0; +} + +WEB_URI_MODULE_REGISTER(0x90, URI_HTML_BASE_INIT, URI_HTML_BASE_EXIT); diff --git a/project_components/web_server/web_server.c b/project_components/web_server/web_server.c new file mode 100644 index 0000000..5491b08 --- /dev/null +++ b/project_components/web_server/web_server.c @@ -0,0 +1,140 @@ +#include "web_server.h" +#include "web_uri_module.h" + +#include +#include + +#include +#include +#include + +#define TAG "web server" +#define EXAMPLE_HTTP_QUERY_KEY_MAX_LEN (64) +#define MAKE_U32(b0, b1, b2, b3) ((b0) | (b1) << 8 | (b2) << 16 | (b3) << 24) + +#define URI_WS_STR MAKE_U32('/', 'w', 's', '\0') +#define URI_API_STR MAKE_U32('/', 'a', 'p', 'i') + +static httpd_handle_t http_server = NULL; + +/** + * 3 types of ref: + * - 1. "/" + * - 2. "/entry" + * - 3. "/dir/" + * 4 types of target + * - 1. "/.*" + * - 2. "/entry" + * - 2. "/dir/" + * - 3. "/dir/.*" + * */ +static bool uri_match(const char *reference_uri, const char *uri_to_match, size_t match_upto) +{ + const uint32_t *ptr32_ref = (const uint32_t *) reference_uri; + const uint32_t *ptr32_target = (const uint32_t *) uri_to_match; + size_t ref_length; + + /* optimized for /ws quick access */ + if (likely(match_upto == 3)) { + if (likely(*ptr32_ref == URI_WS_STR)) { + ESP_LOGI(TAG, "cmp ws"); + return *ptr32_target == *ptr32_ref; + } + } + + /* ref should be shorter than target */ + ref_length = strlen(reference_uri); + if (ref_length > match_upto) { + ESP_LOGI(TAG, "no match length"); + return false; + } + + // strict matching "/entry" for ref = "/entry" + if (ref_length == match_upto) { + if (memcmp(reference_uri, uri_to_match, ref_length) == 0) { + ESP_LOGI(TAG, "strict match %s", reference_uri); + return true; + } + } + + // if ref = /dir/ targets are /dir/ and /dir/* + if (reference_uri[ref_length - 1] == '/' && ref_length > 1) { + if (memcmp(reference_uri, uri_to_match, ref_length) == 0) { + ESP_LOGI(TAG, "match /dir/"); + return true; + } else { + ESP_LOGI(TAG, "no match /dir/"); + return false; + } + } + + /* Fall back to root pages */ + // match /* when ref if / + if (reference_uri[ref_length - 1] == '/') { + ESP_LOGI(TAG, "match /"); + return true; + } + + ESP_LOGI(TAG, "fall back false"); + return false; +} + +static int8_t opened_socket = 0; + +static esp_err_t web_server_on_open(httpd_handle_t hd, int sockfd) +{ + opened_socket++; + printf("%d open, now: %d\n", sockfd, opened_socket); + return ESP_OK; +} + +static void web_server_on_close(httpd_handle_t hd, int sockfd) +{ + opened_socket--; + printf("%d closed, now: %d\n", sockfd, opened_socket); + close(sockfd); +} + +void start_webserver(void) +{ + httpd_handle_t server = NULL; + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + int err; + + config.lru_purge_enable = true; + config.uri_match_fn = uri_match; + config.open_fn = web_server_on_open; + config.close_fn = web_server_on_close; + + // Start the httpd server + ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port); + + if ((err = httpd_start(&server, &config) != ESP_OK)) { + ESP_LOGE(TAG, "Error starting server!"); + ESP_ERROR_CHECK(err); + } + + // Set URI handlers + ESP_LOGI(TAG, "Registering URI handlers"); + + /* + * load http service + * TODO: make ws a module + * make http api POST a module + * make update a module + * */ + + uri_module_init(server); + http_server = server; +} + +static esp_err_t stop_webserver(httpd_handle_t server) +{ + // Stop the httpd server + return httpd_stop(server); +} + +int server_is_running() +{ + return http_server != NULL; +} diff --git a/project_components/web_server/web_server.h b/project_components/web_server/web_server.h new file mode 100644 index 0000000..2af6e0b --- /dev/null +++ b/project_components/web_server/web_server.h @@ -0,0 +1,16 @@ +#ifndef WEB_SERVER_H_GUARD +#define WEB_SERVER_H_GUARD + +#include +#include + +void disconnect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data); +void connect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data); + +void start_webserver(void); +int server_is_running(); + + +#endif //WEB_SERVER_H_GUARD \ No newline at end of file diff --git a/project_components/web_server/web_uri_module.c b/project_components/web_server/web_uri_module.c new file mode 100644 index 0000000..1a1cc5f --- /dev/null +++ b/project_components/web_server/web_uri_module.c @@ -0,0 +1,59 @@ +#include "web_uri_module.h" + +#include + +#define URI_MODULE_MAX 8 + +#define TAG __FILE_NAME__ + +static uri_module_t module_arr[URI_MODULE_MAX]; +static uint8_t module_count = 0; + +int uri_module_init(httpd_handle_t server) +{ + int err; + const httpd_uri_t *uri; + + for (int i = 0; i < module_count; ++i) { + err = module_arr[i].init(&uri); + ESP_LOGI(TAG, "uri %s init", uri->uri); + if (err) { + ESP_LOGE(TAG, "%d init error", i); + } + + err = httpd_register_uri_handler(server, uri); + if (err) { + ESP_LOGE(TAG, "%d %s", i, esp_err_to_name(err)); + } + } + return 0; +} + +int uri_module_exit(httpd_handle_t server) +{ + int err; + const httpd_uri_t *uri; + for (int i = 0; i < module_count; ++i) { + module_arr[i].exit(&uri); + err = httpd_unregister_uri_handler(server, uri->uri, uri->method); + if (err) { + ESP_LOGE(TAG, "%d %s", i, esp_err_to_name(err)); + } + } + return 0; +} + +int uri_module_add(uri_module_func init, uri_module_func exit) +{ + ESP_LOGE(TAG, "adding module %p", init); + + if (module_count >= URI_MODULE_MAX) { + ESP_LOGE(TAG, "too much module > URI_MODULE_MAX"); + return 1; + } + + module_arr[module_count].exit = exit; + module_arr[module_count].init = init; + module_count++; + return 0; +} diff --git a/project_components/web_server/web_uri_module.h b/project_components/web_server/web_uri_module.h new file mode 100644 index 0000000..89ece87 --- /dev/null +++ b/project_components/web_server/web_uri_module.h @@ -0,0 +1,25 @@ +#ifndef WEB_URI_MODULE_H_GUARD +#define WEB_URI_MODULE_H_GUARD + +#include + +typedef int (*uri_module_func)(const httpd_uri_t **uri); + +typedef struct uri_module_t { + uri_module_func init; + uri_module_func exit; +} uri_module_t; + +int uri_module_add(uri_module_func init, uri_module_func exit); + +/** + * @brief Register a uri module that will be init with PRI(priority) order. + */ +#define WEB_URI_MODULE_REGISTER(PRI, INIT, EXIT) \ + __attribute__((used, constructor(PRI))) void cons_ ## INIT(); \ + void cons_ ## INIT() { uri_module_add(INIT, EXIT); } + +int uri_module_init(httpd_handle_t server); +int uri_module_exit(httpd_handle_t server); + +#endif //WEB_URI_MODULE_H_GUARD \ No newline at end of file diff --git a/project_components/wifi_manager/CMakeLists.txt b/project_components/wifi_manager/CMakeLists.txt index d1cdcf3..84a8ac1 100644 --- a/project_components/wifi_manager/CMakeLists.txt +++ b/project_components/wifi_manager/CMakeLists.txt @@ -1,11 +1,16 @@ file(GLOB SOURCES wifi_event_handler.c wifi_manager.c + wifi_api_json.c + wifi_api.c + wifi_json_utils.c ) idf_component_register( SRCS ${SOURCES} INCLUDE_DIRS "." - PRIV_REQUIRES mdns esp_wifi esp_event -) \ No newline at end of file + PRIV_REQUIRES mdns esp_wifi esp_event api_router +) + +idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON) diff --git a/project_components/wifi_manager/wifi_api.c b/project_components/wifi_manager/wifi_api.c new file mode 100644 index 0000000..55e73fa --- /dev/null +++ b/project_components/wifi_manager/wifi_api.c @@ -0,0 +1,19 @@ +#include "wifi_api.h" +#include "wifi_manager.h" +#include + +void wifi_api_get_ap_info(wifi_api_ap_info_t *ap_info) +{ + wifi_ap_record_t ap_record; + esp_wifi_sta_get_ap_info(&ap_record); + strncpy(ap_info->ssid, (const char *)ap_record.ssid, sizeof(ap_info->ssid)); + strncpy(ap_info->mac, (const char *)ap_record.bssid, sizeof(ap_info->mac)); + ap_info->rssi = ap_record.rssi; + + esp_netif_t *sta_netif = wifi_manager_get_sta_netif(); + esp_netif_ip_info_t ip_info; + esp_netif_get_ip_info(sta_netif, &ip_info); + ip4_addr_set(&ap_info->ip, &ip_info.ip); + ip4_addr_set(&ap_info->gateway, &ip_info.gw); + ip4_addr_set(&ap_info->netmask, &ip_info.netmask); +} diff --git a/project_components/wifi_manager/wifi_api.h b/project_components/wifi_manager/wifi_api.h new file mode 100644 index 0000000..609c26f --- /dev/null +++ b/project_components/wifi_manager/wifi_api.h @@ -0,0 +1,18 @@ +#ifndef WIFI_API_H_GUARD +#define WIFI_API_H_GUARD + +#include + +typedef struct wifi_api_ap_info_t { + ip4_addr_t ip; + ip4_addr_t gateway; + ip4_addr_t netmask; + char ssid[33]; + char mac[6]; + signed char rssi; +} wifi_api_ap_info_t; + +void wifi_api_get_ap_info(wifi_api_ap_info_t *ap_info); + + +#endif //WIFI_API_H_GUARD \ No newline at end of file diff --git a/project_components/wifi_manager/wifi_api_json.c b/project_components/wifi_manager/wifi_api_json.c new file mode 100644 index 0000000..2281a10 --- /dev/null +++ b/project_components/wifi_manager/wifi_api_json.c @@ -0,0 +1,63 @@ +#include "wifi_api_json.h" + +#include "api_json_router.h" +#include "wifi_api.h" +#include "wifi_json_utils.h" + +#include + +static int wifi_api_json_get_ap_info(api_json_req_t *req, api_json_resp_t *resp); + +static int wifi_api_json_get_scan(api_json_req_t *req, api_json_resp_t *resp); + +static int on_json_req(uint16_t cmd, api_json_req_t *req, api_json_resp_t *rsp) +{ + wifi_api_json_cmd_t wifi_cmd = cmd; + switch (wifi_cmd) { + case WIFI_API_JSON_GET_AP_INFO: + return wifi_api_json_get_ap_info(req, rsp); + case WIFI_API_JSON_CONNECT: + + break; + case WIFI_API_JSON_GET_SCAN: + return wifi_api_json_get_scan(req, rsp); + break; + case UNKNOWN: + default: + break; + } + + printf("%d\n", cmd); + + return 0; +} + +static int wifi_api_json_get_ap_info(api_json_req_t *req, api_json_resp_t *resp) +{ + wifi_api_ap_info_t ap_info; + wifi_api_get_ap_info(&ap_info); + resp->json = wifi_api_json_serialize_ap_info(&ap_info); + return 0; +} + +static int wifi_api_json_get_scan(api_json_req_t *req, api_json_resp_t *resp) +{ + + return 0; +} + + +/* **** + * register module + * */ + +static int wifi_api_json_init(api_json_module_cfg_t *cfg) +{ + cfg->on_req = on_json_req; + cfg->module_id = 1; + return 0; +} + +API_JSON_MODULE_REGISTER(0x90, wifi_api_json_init); + + diff --git a/project_components/wifi_manager/wifi_api_json.h b/project_components/wifi_manager/wifi_api_json.h new file mode 100644 index 0000000..72e5ead --- /dev/null +++ b/project_components/wifi_manager/wifi_api_json.h @@ -0,0 +1,12 @@ +#ifndef WIFI_API_JSON_H_GUARD +#define WIFI_API_JSON_H_GUARD + +typedef enum wifi_api_json_cmd_t { + UNKNOWN = 0, + WIFI_API_JSON_GET_AP_INFO, + WIFI_API_JSON_CONNECT, + WIFI_API_JSON_GET_SCAN, + +} wifi_api_json_cmd_t; + +#endif //WIFI_API_JSON_H_GUARD \ No newline at end of file diff --git a/project_components/wifi_manager/wifi_json_utils.c b/project_components/wifi_manager/wifi_json_utils.c new file mode 100644 index 0000000..8f638ea --- /dev/null +++ b/project_components/wifi_manager/wifi_json_utils.c @@ -0,0 +1,25 @@ +#include + +#include "wifi_json_utils.h" +#include "wifi_api.h" + +cJSON *wifi_api_json_serialize_ap_info(wifi_api_ap_info_t *ap_info) +{ + cJSON *root; + + root = cJSON_CreateObject(); + + cJSON_AddStringToObject(root, "ip", ip4addr_ntoa(&ap_info->ip)); + cJSON_AddStringToObject(root, "gateway", ip4addr_ntoa(&ap_info->gateway)); + cJSON_AddStringToObject(root, "netmask", ip4addr_ntoa(&ap_info->netmask)); + cJSON_AddNumberToObject(root, "rssi", ap_info->rssi); + cJSON_AddStringToObject(root, "ssid", ap_info->ssid); + + char mac_str[18]; + char *m = ap_info->mac; + snprintf(mac_str, sizeof(mac_str), "%02X:%02X:%02X:%02X:%02X:%02X", + m[0], m[1], m[2], m[3], m[4], m[5]); + cJSON_AddStringToObject(root, "mac", mac_str); + + return root; +} diff --git a/project_components/wifi_manager/wifi_json_utils.h b/project_components/wifi_manager/wifi_json_utils.h new file mode 100644 index 0000000..0a387a6 --- /dev/null +++ b/project_components/wifi_manager/wifi_json_utils.h @@ -0,0 +1,8 @@ +#ifndef WIFI_JSON_UTILS_H_GUARD +#define WIFI_JSON_UTILS_H_GUARD + +#include "wifi_api.h" + +cJSON *wifi_api_json_serialize_ap_info(wifi_api_ap_info_t *ap_info); + +#endif //WIFI_JSON_UTILS_H_GUARD \ No newline at end of file diff --git a/project_components/wifi_manager/wifi_manager.c b/project_components/wifi_manager/wifi_manager.c index 8ca42b3..302b69f 100644 --- a/project_components/wifi_manager/wifi_manager.c +++ b/project_components/wifi_manager/wifi_manager.c @@ -83,3 +83,27 @@ void wifi_manager_init(void) ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "wifi started"); } + +void *wifi_manager_get_ap_netif() +{ + return ap_netif; +} + +void *wifi_manager_get_sta_netif() +{ + return sta_netif; +} + + +void test() +{ +// esp_netif_get_ip_info() + wifi_sta_list_t list; + wifi_ap_config_t ap_conf; + wifi_ap_record_t ap_info; + + /* ESP_ERR_WIFI_NOT_CONNECT / ESP_ERR_WIFI_CONN */ + esp_wifi_sta_get_ap_info(&ap_info); + +// esp_wifi_ap_get_sta_list() +} diff --git a/project_components/wifi_manager/wifi_manager.h b/project_components/wifi_manager/wifi_manager.h index c0fed87..a441ff4 100644 --- a/project_components/wifi_manager/wifi_manager.h +++ b/project_components/wifi_manager/wifi_manager.h @@ -7,4 +7,7 @@ int wifi_set_ap_cred(const char *ssid, const char *password); int wifi_set_sta_cred(const char *ssid, const char *password); +void *wifi_manager_get_ap_netif(); +void *wifi_manager_get_sta_netif(); + #endif //WIFI_MANAGER_H_GUARD \ No newline at end of file