Skip to content

Commit

Permalink
More progress i guess
Browse files Browse the repository at this point in the history
  • Loading branch information
hhvrc committed Nov 12, 2024
1 parent 2b67c80 commit c2ce261
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 143 deletions.
267 changes: 179 additions & 88 deletions src/wifi/WiFiManagerNew.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

const char* const TAG = "WiFiManager";

#include <freertos/queue.h>
#include <freertos/task.h>

#include <esp_wifi.h>
Expand All @@ -29,6 +30,16 @@ const uint32_t OPENSHOCK_WIFI_SCAN_MIN_MS_PER_CHANNEL = 100;
const uint32_t OPENSHOCK_WIFI_SCAN_MAX_MS_PER_CHANNEL = 300; // Adjusting this value will affect the scan rate, but may also affect the scan results
const uint32_t OPENSHOCK_WIFI_SCAN_TIMEOUT_MS = 10 * 1000;

const uint32_t OPENSHOCK_DNS_MAIN = 0x01010101; // 1.1.1.1
const uint32_t OPENSHOCK_DNS_BACKUP = 0x08080808; // 8.8.8.8
const uint32_t OPENSHOCK_DNS_FALLBACK = 0x09090909; // 9.9.9.9

enum class WiFiTaskNotification : uint8_t {
None,
ScanFailed,
ScanCompleted
}

enum class WiFiState : uint8_t {
Disconnected = 0,
Scanning = 1 << 0,
Expand All @@ -38,17 +49,18 @@ enum class WiFiState : uint8_t {

struct ScanResult {
uint8_t scanId;
uint8_t size;
uint8_t capacity;
uint16_t size;
uint16_t capacity;
wifi_ap_record_t* records;
};

static QueueHandle_t s_event_queue = nullptr;
static esp_netif_t* s_wifi_sta = nullptr;
static esp_netif_t* s_wifi_ap = nullptr;
static WiFiState s_state = WiFiState::Disconnected;
static uint8_t s_target_creds = 0;
static uint8_t s_scan_current_ch = 0;
static ScanResult s_scan_results[OPENSHOCK_WIFI_SCAN_MAX_CHANNEL] = {};
static uint8_t s_scan_channel_current = 0;
static ScanResult s_scan_channel[OPENSHOCK_WIFI_SCAN_MAX_CHANNEL] = {};

template<std::size_t N>
static bool is_zero(const uint8_t (&array)[N])
Expand Down Expand Up @@ -83,23 +95,23 @@ static bool configure_sta_dns()
esp_netif_dns_info_t dns;
dns.ip.type = ESP_IPADDR_TYPE_V4;

dns.ip.u_addr.ip4.addr = 0x01010101; // 1.1.1.1
dns.ip.u_addr.ip4.addr = OPENSHOCK_DNS_MAIN;

err = esp_netif_set_dns_info(s_wifi_sta, ESP_NETIF_DNS_MAIN, &dns);
if (err != ERR_OK) {
OS_LOGE(TAG, "Failed to set Main DNS: %d", err);
return false;
}

dns.ip.u_addr.ip4.addr = 0x08080808; // 8.8.8.8
dns.ip.u_addr.ip4.addr = OPENSHOCK_DNS_BACKUP;

err = esp_netif_set_dns_info(s_wifi_sta, ESP_NETIF_DNS_BACKUP, &dns);
if (err != ERR_OK) {
OS_LOGE(TAG, "Failed to set Backup DNS: %d", err);
return false;
}

dns.ip.u_addr.ip4.addr = 0x09090909; // 9.9.9.9
dns.ip.u_addr.ip4.addr = OPENSHOCK_DNS_FALLBACK;

err = esp_netif_set_dns_info(s_wifi_sta, ESP_NETIF_DNS_FALLBACK, &dns);
if (err != ERR_OK) {
Expand Down Expand Up @@ -171,71 +183,6 @@ static bool mark_network_as_attempted(const uint8_t (&bssid)[6])
return true;
}

static void wifi_event_wifi_ready_handler(void* event_data)
{
OS_LOGV(TAG, "WiFi Ready!");
}

static void wifi_event_scan_done_handler(void* event_data)
{
auto data = reinterpret_cast<wifi_event_sta_scan_done_t*>(event_data);

if (data->status == 1) {
// TODO: what to do?
OS_LOGE(TAG, "WiFi Scan failed!");
return;
}

if (s_scan_current_ch <= 0 || s_scan_current_ch >= OPENSHOCK_WIFI_SCAN_MAX_CHANNEL) {
// TODO: what to do?
OS_LOGE(TAG, "WiFi Scanned channel is invalid!");
return;
}

OS_LOGD(TAG, "WiFi scan completed, results: %hhu scan id: %hhu", data->number, data->scan_id);

ScanResult* result = s_scan_results[s_scan_current_ch];

result->scanId = data->scan_id;
result->size = data->number;

if (result->records == nullptr || result->capacity < data->number) {
OS_LOGD(TAG, "Initializing scan results at %hhu to %hhu elements", s_scan_current_ch, data->number);
result->capacity = data->number;
result->records = reinterpret_cast<wifi_ap_record_t*>(malloc(data->number * sizeof(wifi_ap_record_t)));
} else if (result->capacity < data->number) {
OS_LOGD(TAG, "Resizing scan results at %hhu from %hhu to %hhu elements", s_scan_current_ch, data->number);
free(result->records);
result->capacity = data->number;
result->records = reinterpret_cast<wifi_ap_record_t*>(malloc(data->number * sizeof(wifi_ap_record_t)));
}

esp_err_t err = esp_wifi_scan_get_ap_records(result->size, result->records);
if (err != nullptr) {
OS_LOGE(TAG, "Failed to get scan results: %d", err);
return;
}

// TODO: Check if scan is finished, start next channel scan if not.
}

static void wifi_event_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
(void)event_handler_arg;
(void)event_base;

switch (event_id) {
case WIFI_EVENT_WIFI_READY:
wifi_event_wifi_ready_handler(event_data);
break;
case WIFI_EVENT_SCAN_DONE:
wifi_event_scan_done_handler(event_data);
break;
default:
break;
}
}

static bool get_next_network(OpenShock::Config::WiFiCredentials& creds)
{
return find_network([&creds](const OpenShock::WiFiNetwork& net) {
Expand All @@ -255,7 +202,7 @@ static bool get_next_network(OpenShock::Config::WiFiCredentials& creds)
}) != s_wifiNetworks.end();
}

static bool wifi_start_scan(uint8_t channel = OPENSHOCK_WIFI_SCAN_MAX_CHANNEL)
static bool wifi_scan_start(uint8_t channel = OPENSHOCK_WIFI_SCAN_MAX_CHANNEL)
{
wifi_scan_config_t scan_cfg = {
.ssid = nullptr,
Expand All @@ -272,9 +219,16 @@ static bool wifi_start_scan(uint8_t channel = OPENSHOCK_WIFI_SCAN_MAX_CHANNEL)
.home_chan_dwell_time = OPENSHOCK_WIFI_SCAN_DWELL_PER_CHANNEL,
};

uint8_t lastChannel = s_scan_channel_current;
s_scan_channel_current = channel;

esp_err_t err = esp_wifi_scan_start(&scan_cfg, /* block: */ false);
if (err != ERR_OK) {
// Restore previous variable ASAP
s_scan_channel_current = lastChannel;

OS_LOGE(TAG, "Failed to start scan: %d", err);

return false;
}

Expand Down Expand Up @@ -330,7 +284,7 @@ static bool wifi_start_connect(std::string_view ssid, std::string_view password,
err = esp_wifi_connect();
if (err != ERR_OK) {
s_state = WiFiState::Disconnected;
OS_LOGE(TAG, "Failed to stat wifi connect: %d", err);
OS_LOGE(TAG, "Failed to stat wifi conhuhnect: %d", err);
return false;
}

Expand Down Expand Up @@ -364,22 +318,154 @@ static bool wifi_connect_target_or_next()
return wifi_start_connect(creds.ssid, creds.password, nullptr);
}

static void wifi_task(void*)
static void task_handle_scan_failed()
{
// TODO: Wtf to do here?
}

static void task_handle_scan_completed()
{
}

static void task_handle_disconnected()
{
static int64_t lastScanRequest = 0;
if (wifi_connect_target_or_next()) return;

int64_t now = OpenShock::millis();

if (lastScanRequest == 0 || now - lastScanRequest > 30'000) {
lastScanRequest = now;

OS_LOGV(TAG, "No networks to connect to, starting scan...");
wifi_scan_start();
}
}

static void task_main(void*)
{
int64_t lastScanRequest = 0;
bool isScanning = false;
while (true) {
if (s_state == WiFiState::Disconnected) {
if (!wifi_connect_target_or_next()) {
int64_t now = OpenShock::millis();
if (lastScanRequest == 0 || now - lastScanRequest > 30'000) {
lastScanRequest = now;

OS_LOGV(TAG, "No networks to connect to, starting scan...");
wifi_start_scan();
}
WiFiTaskNotification eventType;
if (xQueueReceive(s_event_queue, &eventType, portMAX_DELAY) == pdTRUE) {
switch (eventType) {
case WiFiTaskNotification::ScanFailed:
task_handle_scan_failed();
break;
case WiFiTaskNotification::ScanCompleted:
task_handle_scan_completed();
break;
default:
break;
}
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

static void event_notify_task(WiFiTaskNotification notification)
{
if (xQueueSend(s_event_queue, &notification, portMAX_DELAY) != pdTRUE) {
OS_PANIC(TAG, "Unable to queue wifi event!");
}
}

static void event_wifi_ready_handler(void* event_data)
{
OS_LOGV(TAG, "WiFi Ready!");
}

static void event_wifi_scan_done_handler(void* event_data)
{
auto data = reinterpret_cast<wifi_event_sta_scan_done_t*>(event_data);

if (data->status == 1) {
OS_LOGE(TAG, "WiFi Scan failed!");
event_notify_task(WiFiTaskNotification::ScanFailed);
return;
}

if (s_scan_channel_current <= 0 || s_scan_channel_current > OPENSHOCK_WIFI_SCAN_MAX_CHANNEL) {
OS_LOGE(TAG, "WiFi Scanned channel is invalid!");
event_notify_task(WiFiTaskNotification::ScanFailed);
return;
}

OS_LOGD(TAG, "WiFi scan completed, results: %hhu scan id: %hhu", data->number, data->scan_id);

ScanResult& result = s_scan_channel[s_scan_channel_current];

esp_err_t err;

uint16_t numRecords;
err = esp_wifi_scan_get_ap_num(&numRecords);
if (err != ERR_OK) {
OS_LOGE(TAG, "Failed to get scan result count: %d", err);
event_notify_task(WiFiTaskNotification::ScanFailed);
return;
}

OS_LOGI(TAG, "Values: %hhu <-> %hu", data->number, numRecords);

result.scanId = data->scan_id;
result.size = numRecords;

if (result.records == nullptr || result.capacity < numRecords) {
OS_LOGD(TAG, "Initializing scan results at %hhu to %hhu elements", s_scan_channel_current, numRecords);
result.capacity = numRecords;
result.records = reinterpret_cast<wifi_ap_record_t*>(malloc(numRecords * sizeof(wifi_ap_record_t)));
} else if (result.capacity < numRecords) {
OS_LOGD(TAG, "Resizing scan results at %hhu from %hhu to %hhu elements", s_scan_channel_current, numRecords);
free(result.records);
result.capacity = numRecords;
result.records = reinterpret_cast<wifi_ap_record_t*>(malloc(numRecords * sizeof(wifi_ap_record_t)));
}

err = esp_wifi_scan_get_ap_records(&result.size, result.records);
if (err != ERR_OK) {
OS_LOGE(TAG, "Failed to get scan results: %d", err);
event_notify_task(WiFiTaskNotification::ScanFailed);
return;
}

if (--s_scan_channel_current == 0) {
event_notify_task(WiFiTaskNotification::ScanCompleted);
return;
}

wifi_scan_start(s_scan_channel_current);
}

static void event_wifi_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
(void)event_handler_arg;
(void)event_base;

switch (event_id) {
case WIFI_EVENT_WIFI_READY:
event_wifi_ready_handler(event_data);
break;
case WIFI_EVENT_SCAN_DONE:
event_wifi_scan_done_handler(event_data);
break;
case WIFI_EVENT_STA_START:
break;
case WIFI_EVENT_STA_STOP:
break;
case WIFI_EVENT_STA_CONNECTED:
break;
case WIFI_EVENT_STA_DISCONNECTED:
break;
case WIFI_EVENT_AP_START:
break;
case WIFI_EVENT_AP_STOP:
break;
case WIFI_EVENT_AP_STACONNECTED:
break;
case WIFI_EVENT_AP_STADISCONNECTED:
break;
default:
OS_LOGW(TAG, "Received unknown event with ID: %i", event_id);
break;
}
}

Expand All @@ -392,9 +478,14 @@ bool OpenShock::WiFiManager::Init()

esp_err_t err;

memset(s_scan_results, 0, sizeof(ScanResult) * OPENSHOCK_WIFI_SCAN_MAX_CHANNEL);
s_event_queue = xQueueCreate(32, sizeof(WiFiTaskNotification));
if (s_event_queue == nullptr) {
OS_PANIC(TAG, "Failed to allocate event queue, probably out of memory!");
}

memset(s_scan_channel, 0, sizeof(ScanResult) * OPENSHOCK_WIFI_SCAN_MAX_CHANNEL);

err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, nullptr);
err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_wifi_handler, nullptr);
if (err != ERR_OK) {
OS_LOGE(TAG, "Failed to subscribe to WiFi events: %d", err);
return false;
Expand Down
Loading

1 comment on commit c2ce261

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cpp-Linter Report ⚠️

Some files did not pass the configured checks!

clang-format (v18.1.8) reports: 1 file(s) not formatted
  • src/wifi/WiFiScanManager.cpp

Have any feedback or feature suggestions? Share it here.

Please sign in to comment.