Files

140 lines
4.7 KiB
C

#include "sys_wifi.h"
#include "web_server.h"
#include "sys_time.h"
#include "os_event.h"
#include "os_status.h"
#include "sdkconfig.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "nvs.h"
#include "nvs_flash.h"
#include <stdio.h>
#include <string.h>
static const char *TAG = "SYS_WIFI";
static esp_netif_t *s_sta_netif;
static esp_netif_t *s_ap_netif;
static char s_sta_ssid[33];
static char s_sta_password[65];
static void copy_wifi_string(uint8_t *destination, size_t destination_size, const char *source)
{
size_t length = strlen(source);
if (length >= destination_size) length = destination_size - 1;
memcpy(destination, source, length);
destination[length] = '\0';
}
static void set_status(wifi_state_t state, int8_t rssi)
{
sys_status_set_wifi(state, rssi);
sys_event_post(SYS_EVENT_WIFI_STATUS_CHANGED, (int32_t)state, NULL);
}
static esp_err_t load_credentials(void)
{
nvs_handle_t nvs;
size_t ssid_len = sizeof(s_sta_ssid);
size_t password_len = sizeof(s_sta_password);
esp_err_t err = nvs_open("wifi", NVS_READONLY, &nvs);
if (err != ESP_OK) return err;
err = nvs_get_str(nvs, "ssid", s_sta_ssid, &ssid_len);
if (err == ESP_OK) err = nvs_get_str(nvs, "password", s_sta_password, &password_len);
nvs_close(nvs);
return err;
}
static void start_softap(void)
{
wifi_config_t ap_config = {0};
copy_wifi_string(ap_config.ap.ssid, sizeof(ap_config.ap.ssid), CONFIG_SYS_WIFI_AP_SSID);
copy_wifi_string(ap_config.ap.password, sizeof(ap_config.ap.password), CONFIG_SYS_WIFI_AP_PASSWORD);
ap_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
ap_config.ap.max_connection = 2;
esp_wifi_set_mode(WIFI_MODE_APSTA);
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
esp_wifi_start();
set_status(WIFI_STATE_AP_MODE, 0);
web_server_start();
ESP_LOGI(TAG, "Provisioning AP '%s', browse to http://192.168.4.1", CONFIG_SYS_WIFI_AP_SSID);
}
static void start_station(void)
{
wifi_config_t config = {0};
copy_wifi_string(config.sta.ssid, sizeof(config.sta.ssid), s_sta_ssid);
copy_wifi_string(config.sta.password, sizeof(config.sta.password), s_sta_password);
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_config(WIFI_IF_STA, &config);
esp_wifi_start();
set_status(WIFI_STATE_CONNECTING, 0);
esp_wifi_connect();
ESP_LOGI(TAG, "Connecting to Wi-Fi network '%s'", s_sta_ssid);
}
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_STA_DISCONNECTED) {
set_status(WIFI_STATE_CONNECTING, 0);
esp_wifi_connect();
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
wifi_ap_record_t record;
int8_t rssi = 0;
if (esp_wifi_sta_get_ap_info(&record) == ESP_OK) rssi = record.rssi;
set_status(WIFI_STATE_CONNECTED, rssi);
web_server_start();
sys_time_start_sntp();
const ip_event_got_ip_t *got_ip = (const ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "Wi-Fi connected, web server at http://" IPSTR, IP2STR(&got_ip->ip_info.ip));
}
}
esp_err_t sys_wifi_clear_credentials(void)
{
nvs_handle_t nvs;
esp_err_t err = nvs_open("wifi", NVS_READWRITE, &nvs);
if (err != ESP_OK) return err;
err = nvs_erase_all(nvs);
if (err == ESP_OK) err = nvs_commit(nvs);
nvs_close(nvs);
return err;
}
esp_err_t sys_wifi_init(void)
{
#if !CONFIG_SYS_WIFI_ENABLED
set_status(WIFI_STATE_OFF, 0);
return ESP_OK;
#else
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
if (err != ESP_OK) return err;
err = esp_netif_init();
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) return err;
err = esp_event_loop_create_default();
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) return err;
s_sta_netif = esp_netif_create_default_wifi_sta();
s_ap_netif = esp_netif_create_default_wifi_ap();
if (!s_sta_netif || !s_ap_netif) return ESP_ERR_NO_MEM;
wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT();
err = esp_wifi_init(&wifi_config);
if (err != ESP_OK) return err;
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));
if (load_credentials() == ESP_OK && s_sta_ssid[0] != '\0' && s_sta_password[0] != '\0') {
start_station();
} else {
start_softap();
}
return ESP_OK;
#endif
}