124 lines
2.9 KiB
C++
124 lines
2.9 KiB
C++
/// © MiroZ 2024
|
|
#include "Wifi.h"
|
|
#include "errors.h"
|
|
#include "Settings.h"
|
|
|
|
#include <WiFi.h>
|
|
#include <functional>
|
|
#include "utilities.h"
|
|
|
|
static const char *TAG = "Wifi";
|
|
#define IGNORE_SSID_MINS 10
|
|
|
|
using namespace std::placeholders;
|
|
|
|
|
|
Wifi::Wifi()
|
|
{
|
|
esp_log_level_set("wifi", ESP_LOG_WARN);
|
|
esp_log_level_set("wifi_init", ESP_LOG_INFO);
|
|
|
|
memset(m_ignored, 0, SETTINGS_NUM_WIFI_ENTRIES);
|
|
WiFi.onEvent(std::bind(&Wifi::wifi_event, this, _1, _2));
|
|
|
|
esp_timer_create_args_t timer;
|
|
timer.arg = this;
|
|
timer.callback = &timerCallback;
|
|
timer.dispatch_method = ESP_TIMER_TASK;
|
|
timer.skip_unhandled_events = true;
|
|
timer.name = "wifi countdown timer";
|
|
|
|
ESP_ERROR_CHECK(esp_timer_create(&timer, &m_timer));
|
|
ESP_ERROR_CHECK(esp_timer_start_periodic(m_timer, 60000000)); // 1 min
|
|
|
|
}
|
|
|
|
void Wifi::timerCallback(void* arg)
|
|
{
|
|
for(int n = 0; n < SETTINGS_NUM_WIFI_ENTRIES; n++)
|
|
{
|
|
if(((Wifi*)arg)->m_ignored[n] > 0)
|
|
((Wifi*)arg)->m_ignored[n]--;
|
|
}
|
|
}
|
|
|
|
void Wifi::wifi_event(arduino_event_id_t event, arduino_event_info_t info)
|
|
{
|
|
ESP_LOGI(TAG, "event: %s (%d)", WiFi.eventName(event), (int)event);
|
|
if(event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED)
|
|
{
|
|
wifi_err_reason_t reason = (wifi_err_reason_t)info.wifi_sta_disconnected.reason;
|
|
ESP_LOGI(TAG, "reason: %s", WiFi.disconnectReasonName(reason));
|
|
}
|
|
}
|
|
|
|
uint32_t Wifi::connect()
|
|
{
|
|
if(SETTINGS.wifi.num == 0)
|
|
{
|
|
ESP_LOGE(TAG, "Not provisioned!");
|
|
return WH_ERR_WIFI_NOT_PROVISIONED;
|
|
}
|
|
|
|
if(WiFi.isConnected())
|
|
return WH_OK;
|
|
|
|
int ssid_ix = SETTINGS.wifi.selected;
|
|
|
|
if((SETTINGS.wifi.always_scan_before_connect && SETTINGS.wifi.num > 1) || SETTINGS.wifi.selected >= SETTINGS_NUM_WIFI_ENTRIES)
|
|
ssid_ix = scan();
|
|
|
|
if(ssid_ix < 0)
|
|
{
|
|
// ESP_LOGE(TAG, "")
|
|
}
|
|
|
|
ESP_LOGI(TAG, "Connecting to %s...", SETTINGS.wifi.entry[ssid_ix].ssid);
|
|
WiFi.begin(SETTINGS.wifi.entry[ssid_ix].ssid, SETTINGS.wifi.entry[ssid_ix].pwd);
|
|
int status = WiFi.waitForConnectResult(15000);
|
|
|
|
if(status == WL_CONNECTED)
|
|
{
|
|
ESP_LOGI(TAG, "Connected");
|
|
return WH_OK;
|
|
}
|
|
|
|
WiFi.disconnect();
|
|
m_ignored[ssid_ix] = IGNORE_SSID_MINS;
|
|
SETTINGS.wifi.selected = 0xff;
|
|
|
|
ESP_LOGE(TAG, "connect %d", status);
|
|
return WH_ERR_WIFI_NOT_CONNECTED;
|
|
}
|
|
|
|
int Wifi::scan()
|
|
{
|
|
ESP_LOGI(TAG, "Scanning wifi networks...");
|
|
|
|
int num_networks = WiFi.scanNetworks(false, false, false, 500);
|
|
ESP_LOGI(TAG, "found %d networks", num_networks);
|
|
|
|
int rssi = -500;
|
|
int selected_index = -1;
|
|
|
|
// crossref scanned and saved networks
|
|
for(int n = 0; n < num_networks; n++)
|
|
{
|
|
for(int p = 0; p < SETTINGS.wifi.num; p++)
|
|
{
|
|
if(strcmp(SETTINGS.wifi.entry[p].ssid, WiFi.SSID(n).c_str()) == 0)
|
|
{
|
|
// found saved network
|
|
ESP_LOGI(TAG, "Found provisioned network '%s' with RSSI %d dBm", SETTINGS.wifi.entry[p].ssid, WiFi.RSSI(n));
|
|
if(WiFi.RSSI(n) > rssi && m_ignored[p] == 0)
|
|
{
|
|
rssi = WiFi.RSSI(n);
|
|
selected_index = p;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ESP_LOGI(TAG, "Chosen network: '%s' based on RSSI", SETTINGS.wifi.entry[selected_index].ssid);
|
|
|
|
return selected_index;
|
|
} |