diff --git a/.gitignore b/.gitignore index 1eaf759..2f69858 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,8 @@ __pycache__ .vscode main/old -main/drop_mqtt \ No newline at end of file +main/drop_mqtt + +tcp_client_image.py +tcp_client.py +tcp_server.py \ No newline at end of file diff --git a/main/main.h b/main/main.h index b7b7657..583ac84 100644 --- a/main/main.h +++ b/main/main.h @@ -23,7 +23,6 @@ static const uint8_t MESH_ID[6] = { 0x77, 0x77, 0x77, 0x77, 0x77, 0x76 }; #define CONFIG_MESH_NON_MESH_AP_CONNECTIONS 0 // number of non-node devices #define CONFIG_TCP_DEBUG 0 -#define CONFIG_TCP_SERVER_ADDRESS "10.0.0.1" #define CONFIG_TCP_SERVER_PORT "3030" #define CONFIG_TCP_RXBUFFER_SIZE 4096 // tcp raw data max size #define CONFIG_IMAGE_BUF_SLICE_SIZE 2048 // map["data"] max size diff --git a/main/mesh_main.c b/main/mesh_main.c index ad69fed..84a47e7 100644 --- a/main/mesh_main.c +++ b/main/mesh_main.c @@ -49,6 +49,8 @@ static int s_route_table_size = 0; static SemaphoreHandle_t s_route_table_lock = NULL; static uint8_t s_mesh_tx_payload[CONFIG_MESH_ROUTE_TABLE_SIZE*6+1]; +char *s_current_gateway_ip = NULL; + /******************************************************* * Function Declarations @@ -158,6 +160,24 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base, ESP_LOGI(MESH_TAG, "reason:%d", disconnected->reason); + + #if CONFIG_TCP_DEBUG == 0 + // 如果當前是 Root,且發生了認證相關錯誤 (例如 210 或 WIFI_REASON_CONNECTION_FAIL) + // 代表這個節點雖然當選了 Root,但因為沒有密碼根本連不上 Router + if (esp_mesh_is_root()) { + if (disconnected->reason == 210 || + disconnected->reason == WIFI_REASON_CONNECTION_FAIL || + disconnected->reason == WIFI_REASON_HANDSHAKE_TIMEOUT || + disconnected->reason == WIFI_REASON_AUTH_EXPIRE) { + + ESP_LOGW(MESH_TAG, "Root auth failed (reason:%d), waiving root status to scan for new parent...", disconnected->reason); + + // 關鍵:主動放棄 Root 資格,強制重新掃描 + esp_mesh_waive_root(NULL, MESH_VOTE_REASON_ROOT_INITIATED); + } + } + #endif + mesh_layer = esp_mesh_get_layer(); mesh_netifs_stop(); } @@ -269,8 +289,17 @@ void ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data; - ESP_LOGI(MESH_TAG, "IP:" IPSTR, IP2STR(&event->ip_info.ip)); + ESP_LOGI(MESH_TAG, "IP:" IPSTR " Gateway:" IPSTR, IP2STR(&event->ip_info.ip), IP2STR(&event->ip_info.gw)); s_current_ip.addr = event->ip_info.ip.addr; + + if (s_current_gateway_ip) { + free(s_current_gateway_ip); + s_current_gateway_ip = NULL; + } + s_current_gateway_ip = (char *)malloc(32); + memset(s_current_gateway_ip, 0, 32); + snprintf(s_current_gateway_ip, 32, IPSTR, IP2STR(&event->ip_info.gw)); + //#if !CONFIG_MESH_USE_GLOBAL_DNS_IP esp_netif_t *netif = event->esp_netif; esp_netif_dns_info_t dns; @@ -323,13 +352,8 @@ void mesh_main(void) cfg.channel = CONFIG_MESH_CHANNEL; cfg.router.ssid_len = strlen(CONFIG_MESH_ROUTER_SSID); memcpy((uint8_t *) &cfg.router.ssid, CONFIG_MESH_ROUTER_SSID, cfg.router.ssid_len); - -#if CONFIG_TCP_DEBUG memcpy((uint8_t *) &cfg.router.password, CONFIG_MESH_ROUTER_PASSWD, strlen(CONFIG_MESH_ROUTER_PASSWD)); -#else - memset((uint8_t *) &cfg.router.password, 0, 64); -#endif /* mesh softAP */ ESP_ERROR_CHECK(esp_mesh_set_ap_authmode(CONFIG_MESH_AP_AUTHMODE)); diff --git a/main/mesh_netif.h b/main/mesh_netif.h index 145339c..aee06a7 100644 --- a/main/mesh_netif.h +++ b/main/mesh_netif.h @@ -32,6 +32,8 @@ typedef void (mesh_raw_recv_cb_t)(mesh_addr_t *from, mesh_data_t *data); extern "C" { #endif +extern char *s_current_gateway_ip; + /** * @brief Initializes netifs in a default way before knowing if we are going to be a root * diff --git a/main/tcphelper.c b/main/tcphelper.c index 10822e0..3d7c130 100644 --- a/main/tcphelper.c +++ b/main/tcphelper.c @@ -16,8 +16,10 @@ #include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" +#include "esp_wifi.h" #include "main.h" +#include "mesh_netif.h" /** * @brief Indicates that the file descriptor represents an invalid (uninitialized or closed) socket @@ -127,10 +129,10 @@ static void tcp_client_task(void *pvParameters) struct addrinfo hints = { .ai_socktype = SOCK_STREAM }; struct addrinfo *address_info; - int res = getaddrinfo(CONFIG_TCP_SERVER_ADDRESS, CONFIG_TCP_SERVER_PORT, &hints, &address_info); + int res = getaddrinfo(s_current_gateway_ip, CONFIG_TCP_SERVER_PORT, &hints, &address_info); if (res != 0 || address_info == NULL) { ESP_LOGE(TAG, "couldn't get hostname for `%s` " - "getaddrinfo() returns %d, addrinfo=%p", CONFIG_TCP_SERVER_ADDRESS, res, address_info); + "getaddrinfo() returns %d, addrinfo=%p", s_current_gateway_ip, res, address_info); goto error; } @@ -140,7 +142,7 @@ static void tcp_client_task(void *pvParameters) log_socket_error(TAG, sock, errno, "Unable to create socket"); goto error; } - ESP_LOGI(TAG, "Socket created, connecting to %s:%s", CONFIG_TCP_SERVER_ADDRESS, CONFIG_TCP_SERVER_PORT); + ESP_LOGI(TAG, "Socket created, connecting to %s:%s", s_current_gateway_ip, CONFIG_TCP_SERVER_PORT); // Marking the socket as non-blocking int flags = fcntl(sock, F_GETFL); @@ -182,6 +184,7 @@ static void tcp_client_task(void *pvParameters) } } + ESP_LOGI(TAG, "Connected to %s:%s", s_current_gateway_ip, CONFIG_TCP_SERVER_PORT); // Keep receiving message do { // receive