Files
2025-12-05 12:19:20 +09:00

169 lines
4.7 KiB
C

//
// Created by shinys on 25. 9. 1.
//
#include <string.h>
#include "esp_event.h"
#include "esp_log.h"
#include "esp_mac.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nconfig.h"
#include "priv_wifi.h"
#include "wifi.h"
#include "indicator.h"
static bool s_auto_reconnect = true;
static const char* TAG = "WIFI";
void wifi_set_auto_reconnect(bool enable) { s_auto_reconnect = enable; }
static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED)
{
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*)event_data;
ESP_LOGI(TAG, "Station " MACSTR " joined, AID=%d", MAC2STR(event->mac), event->aid);
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED)
{
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*)event_data;
ESP_LOGI(TAG, "Station " MACSTR " left, AID=%d", MAC2STR(event->mac), event->aid);
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
ESP_LOGI(TAG, "Station mode started");
// Only try to connect if SSID is configured
if (!nconfig_value_is_not_set(WIFI_SSID))
{
esp_wifi_connect();
}
else
{
ESP_LOGI(TAG, "STA SSID not configured, not connecting.");
}
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
led_set(LED_BLU, BLINK_TRIPLE);
wifi_event_sta_disconnected_t* event = (wifi_event_sta_disconnected_t*)event_data;
ESP_LOGW(TAG, "Disconnected from AP, reason: %s", wifi_reason_str(event->reason));
if (event->reason != WIFI_REASON_ASSOC_LEAVE)
{
if (s_auto_reconnect && !nconfig_value_is_not_set(WIFI_SSID))
{
ESP_LOGI(TAG, "Connection lost, attempting to reconnect...");
esp_wifi_connect();
}
}
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
led_set(LED_BLU, BLINK_SOLID);
ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data;
ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip));
sync_time();
}
}
void wifi_init(void)
{
// Create network interfaces for both AP and STA.
// This is done unconditionally to allow for dynamic mode switching.
esp_netif_create_default_wifi_ap();
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));
initialize_sntp();
char mode_str[10] = {0};
wifi_mode_t mode = WIFI_MODE_APSTA;
const char* started_mode_str = "APSTA";
if (nconfig_read(WIFI_MODE, mode_str, sizeof(mode_str)) == ESP_OK)
{
if (strcmp(mode_str, "sta") == 0)
{
mode = WIFI_MODE_STA;
started_mode_str = "STA";
}
else if (strcmp(mode_str, "apsta") != 0)
{
ESP_LOGW(TAG, "Invalid Wi-Fi mode in nconfig: '%s'. Defaulting to APSTA.", mode_str);
}
}
else
{
ESP_LOGW(TAG, "Failed to read Wi-Fi mode from nconfig. Defaulting to APSTA.");
}
ESP_ERROR_CHECK(esp_wifi_set_mode(mode));
if (mode == WIFI_MODE_APSTA)
{
wifi_init_ap();
wifi_init_sta();
}
else if (mode == WIFI_MODE_STA)
{
wifi_init_sta();
}
ESP_ERROR_CHECK(esp_wifi_start());
led_set(LED_BLU, BLINK_TRIPLE);
ESP_LOGI(TAG, "wifi_init_all finished. Started in %s mode.", started_mode_str);
}
esp_err_t wifi_switch_mode(const char* mode)
{
ESP_LOGI(TAG, "Switching Wi-Fi mode to %s", mode);
wifi_mode_t new_mode;
if (strcmp(mode, "sta") == 0)
{
new_mode = WIFI_MODE_STA;
}
else if (strcmp(mode, "apsta") == 0)
{
new_mode = WIFI_MODE_APSTA;
}
else
{
ESP_LOGE(TAG, "Unsupported mode: %s", mode);
return ESP_ERR_INVALID_ARG;
}
nconfig_write(WIFI_MODE, mode);
ESP_ERROR_CHECK(esp_wifi_stop());
ESP_ERROR_CHECK(esp_wifi_set_mode(new_mode));
if (new_mode == WIFI_MODE_APSTA)
{
wifi_init_ap();
wifi_init_sta();
}
else if (new_mode == WIFI_MODE_STA)
{
wifi_init_sta();
}
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "Wi-Fi mode switched to %s", mode);
return ESP_OK;
}