diff --git a/main/wifi_transport.c b/main/wifi_transport.c index b6ca6d0..e885b71 100644 --- a/main/wifi_transport.c +++ b/main/wifi_transport.c @@ -1,4 +1,6 @@ #include "wifi_transport.h" +#include "wifi_cfg.h" +#include "ble_prov.h" #include "protocol.h" #include #include @@ -6,14 +8,13 @@ #include "freertos/task.h" #include "freertos/queue.h" #include "freertos/semphr.h" +#include "freertos/event_groups.h" #include "esp_wifi.h" #include "esp_wifi_ap_get_sta_list.h" #include "esp_netif.h" #include "esp_event.h" #include "lwip/sockets.h" -#define WIFI_SSID "EIS4" -#define WIFI_PASS "eis4data" #define WIFI_CHANNEL 1 #define WIFI_MAX_CONN 10 @@ -24,8 +25,13 @@ #define REAP_WINDOW_MS 200 #define REAP_INTERVAL_MS 5000 +#define STA_RETRY_MAX 5 +#define RECONNECT_BIT_OK BIT0 +#define RECONNECT_BIT_FAIL BIT1 + static int udp_sock = -1; static esp_netif_t *ap_netif; +static esp_netif_t *sta_netif; static struct { struct sockaddr_in addr; @@ -37,6 +43,11 @@ static struct { static int client_count; static SemaphoreHandle_t client_mutex; +static uint8_t s_sta_state = WIFI_STATE_DISCONNECTED; +static uint32_t s_sta_ip; +static int s_sta_retries; +static EventGroupHandle_t s_reconnect_eg; + static void client_touch(const struct sockaddr_in *addr) { xSemaphoreTake(client_mutex, portMAX_DELAY); @@ -309,30 +320,81 @@ static void wifi_event_handler(void *arg, esp_event_base_t base, } } -#ifndef STA_SSID -#define STA_SSID "" -#endif -#ifndef STA_PASS -#define STA_PASS "" -#endif - static void sta_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data) { (void)arg; if (base == WIFI_EVENT && id == WIFI_EVENT_STA_DISCONNECTED) { - printf("WiFi: STA disconnected, reconnecting...\n"); + s_sta_state = WIFI_STATE_DISCONNECTED; + s_sta_ip = 0; + s_sta_retries++; + printf("WiFi: STA disconnected (retry %d/%d)\n", s_sta_retries, STA_RETRY_MAX); + + if (s_sta_retries >= STA_RETRY_MAX) { + if (s_reconnect_eg) + xEventGroupSetBits(s_reconnect_eg, RECONNECT_BIT_FAIL); + if (!ble_prov_is_active()) { + printf("WiFi: STA retries exhausted, starting BLE provisioning\n"); + ble_prov_start(); + } + } + + s_sta_state = WIFI_STATE_CONNECTING; esp_wifi_connect(); } else if (base == IP_EVENT && id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t *evt = (ip_event_got_ip_t *)data; + s_sta_state = WIFI_STATE_CONNECTED; + s_sta_ip = evt->ip_info.ip.addr; + s_sta_retries = 0; printf("WiFi: STA connected, IP " IPSTR "\n", IP2STR(&evt->ip_info.ip)); + + if (s_reconnect_eg) + xEventGroupSetBits(s_reconnect_eg, RECONNECT_BIT_OK); + + if (ble_prov_is_active()) + ble_prov_stop(); } } +void wifi_transport_get_sta_state(uint8_t *state, uint32_t *ip) +{ + *state = s_sta_state; + *ip = s_sta_ip; +} + +esp_err_t wifi_transport_reconnect_sta(const char *ssid, const char *pass) +{ + s_sta_retries = 0; + s_sta_state = WIFI_STATE_CONNECTING; + + esp_wifi_disconnect(); + + wifi_config_t sta_cfg = {0}; + strncpy((char *)sta_cfg.sta.ssid, ssid, sizeof(sta_cfg.sta.ssid) - 1); + strncpy((char *)sta_cfg.sta.password, pass, sizeof(sta_cfg.sta.password) - 1); + sta_cfg.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + esp_wifi_set_config(WIFI_IF_STA, &sta_cfg); + + if (!s_reconnect_eg) + s_reconnect_eg = xEventGroupCreate(); + xEventGroupClearBits(s_reconnect_eg, RECONNECT_BIT_OK | RECONNECT_BIT_FAIL); + + esp_wifi_connect(); + printf("WiFi: STA reconnecting to \"%s\"\n", ssid); + + EventBits_t bits = xEventGroupWaitBits(s_reconnect_eg, + RECONNECT_BIT_OK | RECONNECT_BIT_FAIL, + pdTRUE, pdFALSE, pdMS_TO_TICKS(15000)); + + if (bits & RECONNECT_BIT_OK) + return ESP_OK; + return ESP_FAIL; +} + static int wifi_ap_init(void) { ap_netif = esp_netif_create_default_wifi_ap(); - esp_netif_create_default_wifi_sta(); + sta_netif = esp_netif_create_default_wifi_sta(); wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT(); esp_err_t err = esp_wifi_init(&wifi_cfg); @@ -346,24 +408,31 @@ static int wifi_ap_init(void) esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, sta_event_handler, NULL, &inst); + char ap_ssid[WIFI_CFG_SSID_MAX], ap_pass[WIFI_CFG_PASS_MAX]; + wifi_cfg_get_ap(ap_ssid, sizeof(ap_ssid), ap_pass, sizeof(ap_pass)); + wifi_config_t ap_cfg = { .ap = { - .ssid = WIFI_SSID, - .ssid_len = sizeof(WIFI_SSID) - 1, .channel = WIFI_CHANNEL, - .password = WIFI_PASS, .max_connection = WIFI_MAX_CONN, .authmode = WIFI_AUTH_WPA2_PSK, }, }; + strncpy((char *)ap_cfg.ap.ssid, ap_ssid, sizeof(ap_cfg.ap.ssid) - 1); + ap_cfg.ap.ssid_len = strlen(ap_ssid); + strncpy((char *)ap_cfg.ap.password, ap_pass, sizeof(ap_cfg.ap.password) - 1); esp_wifi_set_mode(WIFI_MODE_APSTA); esp_wifi_set_config(WIFI_IF_AP, &ap_cfg); - if (strlen(STA_SSID) > 0) { + char sta_ssid[WIFI_CFG_SSID_MAX], sta_pass[WIFI_CFG_PASS_MAX]; + bool has_sta = (wifi_cfg_get_sta(sta_ssid, sizeof(sta_ssid), + sta_pass, sizeof(sta_pass)) == ESP_OK); + + if (has_sta) { wifi_config_t sta_cfg = {0}; - strncpy((char *)sta_cfg.sta.ssid, STA_SSID, sizeof(sta_cfg.sta.ssid) - 1); - strncpy((char *)sta_cfg.sta.password, STA_PASS, sizeof(sta_cfg.sta.password) - 1); + strncpy((char *)sta_cfg.sta.ssid, sta_ssid, sizeof(sta_cfg.sta.ssid) - 1); + strncpy((char *)sta_cfg.sta.password, sta_pass, sizeof(sta_cfg.sta.password) - 1); sta_cfg.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; esp_wifi_set_config(WIFI_IF_STA, &sta_cfg); } @@ -374,12 +443,16 @@ static int wifi_ap_init(void) esp_wifi_set_ps(WIFI_PS_NONE); esp_wifi_set_inactive_time(WIFI_IF_AP, 120); - if (strlen(STA_SSID) > 0) { + if (has_sta) { + s_sta_state = WIFI_STATE_CONNECTING; esp_wifi_connect(); - printf("WiFi: STA connecting to \"%s\"\n", STA_SSID); + printf("WiFi: STA connecting to \"%s\"\n", sta_ssid); + } else { + printf("WiFi: no STA credentials, starting BLE provisioning\n"); + ble_prov_start(); } - printf("WiFi: AP \"%s\" on channel %d\n", WIFI_SSID, WIFI_CHANNEL); + printf("WiFi: AP \"%s\" on channel %d\n", ap_ssid, WIFI_CHANNEL); return 0; } @@ -407,6 +480,7 @@ static int udp_init(void) int wifi_transport_init(void) { client_mutex = xSemaphoreCreateMutex(); + s_reconnect_eg = xEventGroupCreate(); int rc = wifi_ap_init(); if (rc) { diff --git a/main/wifi_transport.h b/main/wifi_transport.h index 3aa6353..5fd9264 100644 --- a/main/wifi_transport.h +++ b/main/wifi_transport.h @@ -2,9 +2,12 @@ #define WIFI_TRANSPORT_H #include +#include "esp_err.h" -int wifi_transport_init(void); -int wifi_send_sysex(const uint8_t *sysex, uint16_t len); -int wifi_get_client_count(void); +int wifi_transport_init(void); +int wifi_send_sysex(const uint8_t *sysex, uint16_t len); +int wifi_get_client_count(void); +esp_err_t wifi_transport_reconnect_sta(const char *ssid, const char *pass); +void wifi_transport_get_sta_state(uint8_t *state, uint32_t *ip); #endif