feat(websocket) json api
This commit is contained in:
parent
90782fda82
commit
a4d65c367d
|
@ -13,13 +13,15 @@
|
|||
#include "static_buffer.h"
|
||||
#include "request_runner.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
void app_main()
|
||||
{
|
||||
assert(static_buffer_init() == 0);
|
||||
assert(request_runner_init() == 0);
|
||||
wt_storage_init();
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
wifi_manager_init();
|
||||
DAP_Setup();
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <cJSON.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct api_json_req_t {
|
||||
cJSON *in;
|
||||
cJSON *out;
|
||||
|
@ -21,11 +20,6 @@ typedef struct api_json_module_async_t {
|
|||
req_task_cb_t req_task;
|
||||
} api_json_module_async_t;
|
||||
|
||||
//typedef struct api_json_send_out_t {
|
||||
// void (*func)(void *arg);
|
||||
// void *arg; /* socket context */
|
||||
//} api_json_send_out_t;
|
||||
|
||||
|
||||
typedef enum api_json_req_status_e {
|
||||
API_JSON_OK = 0,
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
#include <sys/queue.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/cdefs.h>
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 kerms
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "request_runner.h"
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/queue.h>
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
static QueueHandle_t long_run_queue = NULL;
|
||||
static QueueHandle_t send_out_queue = NULL;
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
file(GLOB SOURCES
|
||||
web_server.c
|
||||
web_uri_module.c
|
||||
uri_modules/uri_html_base.c
|
||||
uri_modules/uri_ws.c
|
||||
uri_modules/uri_api.c
|
||||
uri_modules/uri_html_base.c
|
||||
)
|
||||
|
||||
idf_component_register(
|
||||
SRCS ${SOURCES}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES esp_http_server api_router json
|
||||
PRIV_REQUIRES request_runner static_buffer
|
||||
REQUIRES esp_http_server
|
||||
PRIV_REQUIRES request_runner api_router json static_buffer utils
|
||||
)
|
||||
|
||||
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON)
|
||||
|
|
|
@ -19,7 +19,7 @@ typedef struct post_request_t {
|
|||
char buf[0];
|
||||
} post_request_t;
|
||||
|
||||
static void async_send_out_cb(void *req, int module_status);
|
||||
static void async_send_out_cb(void *arg, int module_status);
|
||||
static int uri_api_send_out(httpd_req_t *req, post_request_t *post_req);
|
||||
|
||||
|
||||
|
@ -66,12 +66,12 @@ static esp_err_t api_post_handler(httpd_req_t *req)
|
|||
|
||||
post_req->json.out = NULL;
|
||||
err = api_json_route(&post_req->json, &post_req->async);
|
||||
cJSON_Delete(post_req->json.in);
|
||||
if (err == API_JSON_ASYNC) {
|
||||
httpd_req_async_handler_begin(req, &post_req->req_out);
|
||||
post_req->async.req_task.send_out.cb = async_send_out_cb;
|
||||
post_req->async.req_task.send_out.arg = post_req;
|
||||
if (req_queue_push_long_run(&post_req->async.req_task, pdMS_TO_TICKS(20))) {
|
||||
/* queued failed */
|
||||
httpd_req_async_handler_complete(post_req->req_out);
|
||||
httpd_resp_set_status(req, HTTPD_STATUS_503);
|
||||
goto end;
|
||||
|
@ -91,6 +91,7 @@ static esp_err_t api_post_handler(httpd_req_t *req)
|
|||
goto put_buf;
|
||||
|
||||
end:
|
||||
cJSON_Delete(post_req->json.in);
|
||||
err = httpd_resp_send(req, NULL, 0);
|
||||
if (unlikely(err)) {
|
||||
ESP_LOGE(TAG, "resp_send err: %s", esp_err_to_name(err));
|
||||
|
@ -112,6 +113,7 @@ int uri_api_send_out(httpd_req_t *req, post_request_t *post_req)
|
|||
httpd_resp_set_type(req, HTTPD_TYPE_JSON);
|
||||
err = !cJSON_PrintPreallocated(post_req->json.out, buf, buf_len - 5, 0);
|
||||
cJSON_Delete(post_req->json.out);
|
||||
cJSON_Delete(post_req->json.in);
|
||||
if (unlikely(err)) {
|
||||
httpd_resp_set_status(req, HTTPD_500);
|
||||
return httpd_resp_send(req, NULL, 0);
|
||||
|
@ -146,13 +148,13 @@ static const httpd_uri_t uri_api = {
|
|||
.user_ctx = NULL
|
||||
};
|
||||
|
||||
int URI_API_INIT(const httpd_uri_t **uri_conf) {
|
||||
static 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) {
|
||||
static int URI_API_EXIT(const httpd_uri_t **uri_conf) {
|
||||
*uri_conf = &uri_api;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -83,12 +83,12 @@ static const httpd_uri_t hello = {
|
|||
.user_ctx = "Hello World!"
|
||||
};
|
||||
|
||||
int URI_HTML_BASE_INIT(const httpd_uri_t **uri_conf) {
|
||||
static 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) {
|
||||
static int URI_HTML_BASE_EXIT(const httpd_uri_t **uri_conf) {
|
||||
*uri_conf = &hello;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2024 kerms
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "web_uri_module.h"
|
||||
#include "api_json_router.h"
|
||||
#include "static_buffer.h"
|
||||
|
||||
#include <esp_http_server.h>
|
||||
#include <esp_log.h>
|
||||
#include <list.h>
|
||||
|
||||
#include <cJSON.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define TAG __FILE_NAME__
|
||||
#define MSG_BUSY_ERROR "{\"error\":\"Resource busy\"}"
|
||||
#define MSG_JSON_ERROR "{\"error\":\"JSON parse error\"}"
|
||||
#define MSG_SEND_JSON_ERROR "{\"error\":\"JSON generation error\"}"
|
||||
#define MSG_INTERNAL_ERROR "{\"error\":\"\"}"
|
||||
|
||||
typedef struct ws_msg_t {
|
||||
api_json_req_t json;
|
||||
api_json_module_async_t async;
|
||||
httpd_handle_t hd;
|
||||
int fd;
|
||||
httpd_ws_frame_t ws_pkt;
|
||||
uint8_t delim[0];
|
||||
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)
|
||||
|
||||
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 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);
|
||||
|
||||
static void test(void *arg)
|
||||
{
|
||||
ESP_LOGE(TAG, "this is a test");
|
||||
}
|
||||
|
||||
static esp_err_t ws_req_handler(httpd_req_t *req)
|
||||
{
|
||||
if (unlikely(req->method == HTTP_GET)) {
|
||||
int sock_fd = httpd_req_to_sockfd(req);
|
||||
/**
|
||||
* TODO: add socket to array
|
||||
* */
|
||||
ESP_LOGI(TAG, "ws open: %d", sock_fd);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "ws_handler: httpd_handle_t=%p, sockfd=%d, client_info:%d", req->handle,
|
||||
httpd_req_to_sockfd(req), httpd_ws_get_fd_info(req->handle, httpd_req_to_sockfd(req)));
|
||||
|
||||
int err = ESP_OK;
|
||||
httpd_ws_frame_t *ws_pkt;
|
||||
ws_msg_t *ws_msg;
|
||||
|
||||
ws_msg = static_buffer_get(pdMS_TO_TICKS(10));
|
||||
if (unlikely(ws_msg == NULL)) {
|
||||
httpd_ws_frame_t resp_pkt;
|
||||
resp_pkt.type = HTTPD_WS_TYPE_TEXT;
|
||||
resp_pkt.len = strlen(MSG_BUSY_ERROR);
|
||||
resp_pkt.payload = (uint8_t *)MSG_BUSY_ERROR;
|
||||
resp_pkt.final = 1;
|
||||
httpd_ws_send_frame_async(req->handle, httpd_req_to_sockfd(req), &resp_pkt);
|
||||
goto end;
|
||||
}
|
||||
ws_pkt = &ws_msg->ws_pkt;
|
||||
ws_pkt->len = 0;
|
||||
|
||||
/* get and check frame size */
|
||||
err = httpd_ws_recv_frame(req, ws_pkt, 0);
|
||||
if (unlikely(err != ESP_OK)) {
|
||||
ESP_LOGE(TAG, "ws recv len error");
|
||||
goto end;
|
||||
}
|
||||
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");
|
||||
err = ESP_FAIL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
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");
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (ws_pkt->type) {
|
||||
case HTTPD_WS_TYPE_CONTINUE:
|
||||
break;
|
||||
case HTTPD_WS_TYPE_TEXT:
|
||||
return ws_on_text_data(req, ws_msg);
|
||||
case HTTPD_WS_TYPE_BINARY:
|
||||
return ws_on_binary_data(req, ws_msg);
|
||||
case HTTPD_WS_TYPE_CLOSE:
|
||||
/* Read the rest of the CLOSE frame and response */
|
||||
/* Please refer to RFC6455 Section 5.5.1 for more details */
|
||||
ws_pkt->len = 0;
|
||||
ws_pkt->type = HTTPD_WS_TYPE_CLOSE;
|
||||
err = httpd_ws_send_frame(req, ws_pkt);
|
||||
break;
|
||||
case HTTPD_WS_TYPE_PING:
|
||||
/* Now turn the frame to PONG */
|
||||
ws_pkt->type = HTTPD_WS_TYPE_PONG;
|
||||
err = httpd_ws_send_frame(req, ws_pkt);
|
||||
break;
|
||||
case HTTPD_WS_TYPE_PONG:
|
||||
err = ESP_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
static_buffer_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,
|
||||
/* in esp-idf v5.2.0, set to false cause infinite queue_work fail on wifi disconnect when at least 1 ws client */
|
||||
.handle_ws_control_frames = true,
|
||||
};
|
||||
|
||||
static int WS_REQ_INIT(const httpd_uri_t **uri_conf) {
|
||||
*uri_conf = &uri_api;
|
||||
api_json_router_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int WS_REQ_EXIT(const httpd_uri_t **uri_conf) {
|
||||
*uri_conf = &uri_api;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEB_URI_MODULE_REGISTER(101, WS_REQ_INIT, WS_REQ_EXIT)
|
||||
|
||||
int ws_on_text_data(httpd_req_t *req, ws_msg_t *ws_msg)
|
||||
{
|
||||
int err = ESP_OK;
|
||||
int ret;
|
||||
httpd_ws_frame_t *ws_pkt;
|
||||
|
||||
ws_pkt = &ws_msg->ws_pkt;
|
||||
ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");
|
||||
ESP_LOGI(TAG, "%.*s", ws_pkt->len, ws_pkt->payload);
|
||||
ESP_LOGI(TAG, "====================================");
|
||||
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);
|
||||
if (unlikely(ws_msg->json.in == NULL)) {
|
||||
ws_pkt->payload = (uint8_t *) MSG_JSON_ERROR;
|
||||
ws_pkt->len = strlen(MSG_JSON_ERROR);
|
||||
goto put_buf;
|
||||
}
|
||||
|
||||
ws_msg->json.out = NULL;
|
||||
ret = api_json_route(&ws_msg->json, &ws_msg->async);
|
||||
if (ret == API_JSON_ASYNC) {
|
||||
ws_msg->hd = req->handle;
|
||||
ws_msg->fd = httpd_req_to_sockfd(req);
|
||||
ws_msg->async.req_task.send_out.cb = async_send_out_cb;
|
||||
ws_msg->async.req_task.send_out.arg = ws_msg;
|
||||
if (req_queue_push_long_run(&ws_msg->async.req_task, pdMS_TO_TICKS(20))) {
|
||||
/* queued failed */
|
||||
goto end;
|
||||
}
|
||||
/* 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);
|
||||
goto end;
|
||||
} else if (ws_msg->json.out == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* api function returns something, send it to http client */
|
||||
json_to_text(ws_msg);
|
||||
|
||||
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);
|
||||
return err;
|
||||
}
|
||||
|
||||
int ws_on_binary_data(httpd_req_t *req, ws_msg_t *ws_msg)
|
||||
{
|
||||
static_buffer_put(ws_msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ws_async_resp(void *arg)
|
||||
{
|
||||
ws_msg_t *req = arg;
|
||||
httpd_handle_t hd = req->hd;
|
||||
int fd = req->fd;
|
||||
int err;
|
||||
|
||||
ESP_LOGI(TAG, "ws async fd : %d", fd);
|
||||
err = httpd_ws_send_frame_async(hd, fd, &req->ws_pkt);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "%s", esp_err_to_name(err));
|
||||
}
|
||||
static_buffer_put(req);
|
||||
}
|
||||
|
||||
void async_send_out_cb(void *arg, int module_status)
|
||||
{
|
||||
ws_msg_t *req = arg;
|
||||
if (module_status != API_JSON_OK) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
int err;
|
||||
json_to_text(req);
|
||||
err = httpd_queue_work(req->hd, ws_async_resp, req);
|
||||
if (likely(err == ESP_OK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGE(TAG, "errno: %d, fd %p: %s", errno, req->hd, esp_err_to_name(err));
|
||||
|
||||
end:
|
||||
/* clean resources */
|
||||
static_buffer_put(req);
|
||||
}
|
||||
|
||||
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);
|
||||
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->final = 1;
|
||||
}
|
||||
ws_pkt->len = strlen((char *) ws_pkt->payload);
|
||||
};
|
|
@ -96,7 +96,6 @@ static void web_server_on_close(httpd_handle_t hd, int sockfd)
|
|||
|
||||
void start_webserver(void)
|
||||
{
|
||||
httpd_handle_t server = NULL;
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
int err;
|
||||
|
||||
|
@ -108,14 +107,13 @@ void start_webserver(void)
|
|||
config.close_fn = web_server_on_close;
|
||||
|
||||
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
|
||||
if ((err = httpd_start(&server, &config) != ESP_OK)) {
|
||||
if ((err = httpd_start(&http_server, &config)) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error starting server!");
|
||||
ESP_ERROR_CHECK(err);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Registering URI handlers");
|
||||
uri_module_init(server);
|
||||
http_server = server;
|
||||
uri_module_init(http_server);
|
||||
}
|
||||
|
||||
static esp_err_t stop_webserver(httpd_handle_t server)
|
||||
|
|
|
@ -1,49 +1,52 @@
|
|||
#include "web_uri_module.h"
|
||||
#include "list.h"
|
||||
|
||||
#include <esp_log.h>
|
||||
|
||||
|
||||
#define URI_MODULE_MAX 8
|
||||
|
||||
#define TAG __FILE_NAME__
|
||||
|
||||
static uri_module_t module_arr[URI_MODULE_MAX];
|
||||
typedef struct uri_module_list_t {
|
||||
struct dl_list list;
|
||||
uri_module_t module;
|
||||
} uri_module_list_t;
|
||||
|
||||
static uri_module_list_t module_arr[URI_MODULE_MAX];
|
||||
static uint8_t module_count = 0;
|
||||
static DEFINE_DL_LIST(list_head);
|
||||
|
||||
int uri_module_init(httpd_handle_t server)
|
||||
{
|
||||
int err;
|
||||
const httpd_uri_t *uri;
|
||||
uri_module_list_t *item;
|
||||
uint8_t index = 0;
|
||||
|
||||
for (int i = 0; i < module_count; ++i) {
|
||||
err = module_arr[i].init(&uri);
|
||||
dl_list_for_each(item, &list_head, uri_module_list_t, list) {
|
||||
err = item->module.init(&uri);
|
||||
ESP_LOGI(TAG, "uri %s init", uri->uri);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "%d init error", i);
|
||||
ESP_LOGE(TAG, "%d init error", index);
|
||||
}
|
||||
|
||||
err = httpd_register_uri_handler(server, uri);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "%d %s", i, esp_err_to_name(err));
|
||||
ESP_LOGE(TAG, "%d %s", index, esp_err_to_name(err));
|
||||
}
|
||||
index++;
|
||||
}
|
||||
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)
|
||||
int uri_module_add(uint8_t priority, uri_module_func init, uri_module_func exit)
|
||||
{
|
||||
ESP_LOGE(TAG, "adding module %p", init);
|
||||
|
||||
|
@ -52,8 +55,17 @@ int uri_module_add(uri_module_func init, uri_module_func exit)
|
|||
return 1;
|
||||
}
|
||||
|
||||
module_arr[module_count].exit = exit;
|
||||
module_arr[module_count].init = init;
|
||||
module_arr[module_count].module.exit = exit;
|
||||
module_arr[module_count].module.init = init;
|
||||
module_arr[module_count].module.priority = priority;
|
||||
|
||||
uri_module_list_t *item;
|
||||
dl_list_for_each(item, &list_head, uri_module_list_t, list) {
|
||||
if (item->module.priority <= priority) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
dl_list_add(&item->list, &module_arr[module_count].list);
|
||||
module_count++;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -8,16 +8,17 @@ typedef int (*uri_module_func)(const httpd_uri_t **uri);
|
|||
typedef struct uri_module_t {
|
||||
uri_module_func init;
|
||||
uri_module_func exit;
|
||||
uint8_t priority;
|
||||
} uri_module_t;
|
||||
|
||||
int uri_module_add(uri_module_func init, uri_module_func exit);
|
||||
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.
|
||||
*/
|
||||
#define WEB_URI_MODULE_REGISTER(PRI, INIT, EXIT) \
|
||||
__attribute__((used, constructor(PRI))) void cons_ ## INIT(); \
|
||||
void cons_ ## INIT() { uri_module_add(INIT, EXIT); }
|
||||
void cons_ ## INIT() { uri_module_add(PRI, INIT, EXIT); }
|
||||
|
||||
int uri_module_init(httpd_handle_t server);
|
||||
int uri_module_exit(httpd_handle_t server);
|
||||
|
|
|
@ -76,10 +76,13 @@ static void wifi_manager_scan_done(uint16_t ap_found, wifi_ap_record_t *records,
|
|||
scan_done_cb(ap_found, ap_info, arg);
|
||||
}
|
||||
|
||||
|
||||
int wifi_api_trigger_scan(uint16_t *max_ap_count, wifi_api_scan_done_cb cb, void *cb_arg)
|
||||
{
|
||||
wifi_manager_trigger_scan(wifi_manager_scan_done, cb_arg);
|
||||
int err;
|
||||
err = wifi_manager_trigger_scan(wifi_manager_scan_done, cb_arg);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
scan_done_cb = cb;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <lwip/ip4_addr.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define TAG __FILENAME__
|
||||
|
||||
|
@ -123,7 +124,7 @@ static void scan_loop()
|
|||
wifi_event_scan_channel_done, number,
|
||||
&scan_ctx.ap[scan_ctx.total_aps])) {
|
||||
ESP_LOGE(TAG, "trigger scan %d error", scan_channel);
|
||||
goto end;
|
||||
return;
|
||||
}
|
||||
/* shadow wifi_event_scan_channel_done() called */
|
||||
vTaskDelay(100);
|
||||
|
@ -132,20 +133,19 @@ static void scan_loop()
|
|||
if (ret == 0) {
|
||||
/* timeout */
|
||||
ESP_LOGE(TAG, "scan channel %d timeout", scan_channel);
|
||||
goto end;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (scan_ctx.cb) {
|
||||
// scan_ctx.cb(scan_ctx.total_aps, scan_ctx.ap);
|
||||
}
|
||||
}
|
||||
|
||||
static void wifi_manager_scan_task(void *arg)
|
||||
{
|
||||
scan_loop();
|
||||
free(scan_ctx.ap);
|
||||
/* callback */
|
||||
if (scan_ctx.cb) {
|
||||
scan_ctx.cb(scan_ctx.total_aps, scan_ctx.ap, arg);
|
||||
}
|
||||
xSemaphoreGive(scan_ctx.lock);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ int wifi_manager_trigger_scan(wifi_manager_scan_done_cb cb, void *arg)
|
|||
|
||||
ulTaskNotifyTake(pdTRUE, 0);
|
||||
xTaskCreatePinnedToCore(wifi_manager_scan_task, "scan task", 4 * 1024,
|
||||
NULL, 7, &scan_ctx.task, 0);
|
||||
arg, 7, &scan_ctx.task, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue