From 993cad1b4a8120b06459f80c2b978137f48741ac Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 15 Apr 2022 11:11:26 +1000 Subject: [PATCH] wifi: esp_at: cleanup sockets at network close Some sockets (UDP sockets at least) do not generate ",CLOSED" messages when the WiFi network drops. As a result the networking stack thinks these sockets are still open after the network has dropped, and after any subsequent reconnections. This affects the DNS resolver library in particular, which leaves UDP sockets open permanently by default. Manually close these sockets when the network drops to ensure a clean state the next time the network connects. Signed-off-by: Jordan Yates --- drivers/wifi/esp_at/esp.c | 28 +++++++++++++++++++++++----- drivers/wifi/esp_at/esp.h | 1 + 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/wifi/esp_at/esp.c b/drivers/wifi/esp_at/esp.c index 9cba27bf4f7..0fa2d77f7a6 100644 --- a/drivers/wifi/esp_at/esp.c +++ b/drivers/wifi/esp_at/esp.c @@ -384,13 +384,20 @@ MODEM_CMD_DEFINE(on_cmd_wifi_connected) return 0; } -MODEM_CMD_DEFINE(on_cmd_wifi_disconnected) +static void esp_mgmt_disconnect_work(struct k_work *work) { - struct esp_data *dev = CONTAINER_OF(data, struct esp_data, - cmd_handler_data); + struct esp_socket *sock; + struct esp_data *dev; - if (!esp_flags_are_set(dev, EDF_STA_CONNECTED)) { - return 0; + dev = CONTAINER_OF(work, struct esp_data, disconnect_work); + + /* Cleanup any sockets that weren't closed */ + for (int i = 0; i < ARRAY_SIZE(dev->sockets); i++) { + sock = &dev->sockets[i]; + if (esp_socket_connected(sock)) { + LOG_WRN("Socket %d left open, manually closing", i); + esp_socket_close(sock); + } } esp_flags_clear(dev, EDF_STA_CONNECTED); @@ -398,6 +405,16 @@ MODEM_CMD_DEFINE(on_cmd_wifi_disconnected) net_if_ipv4_addr_rm(dev->net_iface, &dev->ip); wifi_mgmt_raise_disconnect_result_event(dev->net_iface, 0); +} + +MODEM_CMD_DEFINE(on_cmd_wifi_disconnected) +{ + struct esp_data *dev = CONTAINER_OF(data, struct esp_data, + cmd_handler_data); + + if (esp_flags_are_set(dev, EDF_STA_CONNECTED)) { + k_work_submit_to_queue(&dev->workq, &dev->disconnect_work); + } return 0; } @@ -1102,6 +1119,7 @@ static int esp_init(const struct device *dev) k_work_init_delayable(&data->ip_addr_work, esp_ip_addr_work); k_work_init(&data->scan_work, esp_mgmt_scan_work); k_work_init(&data->connect_work, esp_mgmt_connect_work); + k_work_init(&data->disconnect_work, esp_mgmt_disconnect_work); k_work_init(&data->mode_switch_work, esp_mode_switch_work); if (IS_ENABLED(CONFIG_WIFI_ESP_AT_DNS_USE)) { k_work_init(&data->dns_work, esp_dns_work); diff --git a/drivers/wifi/esp_at/esp.h b/drivers/wifi/esp_at/esp.h index 2a08b33844b..4a0b141f064 100644 --- a/drivers/wifi/esp_at/esp.h +++ b/drivers/wifi/esp_at/esp.h @@ -250,6 +250,7 @@ struct esp_data { struct k_work_delayable ip_addr_work; struct k_work scan_work; struct k_work connect_work; + struct k_work disconnect_work; struct k_work mode_switch_work; struct k_work dns_work;