Skip to content

Commit 2b67c80

Browse files
committed
More scanning logic
1 parent b198c25 commit 2b67c80

File tree

3 files changed

+147
-76
lines changed

3 files changed

+147
-76
lines changed

src/wifi/WiFiManager.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#include "wifi/WiFiManager.h"
2-
3-
const char* const TAG = "WiFiManager";
41

52
#include "CaptivePortal.h"
63
#include "config/Config.h"
@@ -28,7 +25,6 @@ static uint8_t s_connectedCredentialsID = 0;
2825
static uint8_t s_preferredCredentialsID = 0;
2926
static std::vector<WiFiNetwork> s_wifiNetworks;
3027

31-
3228
bool _attractivityComparer(const WiFiNetwork& a, const WiFiNetwork& b)
3329
{
3430
if (a.credentialsID == 0) {
@@ -72,7 +68,6 @@ bool _markNetworkAsAttempted(const uint8_t (&bssid)[6])
7268
return true;
7369
}
7470

75-
7671
bool _connectHidden(const uint8_t (&bssid)[6], const std::string& password)
7772
{
7873
(void)password;
@@ -380,10 +375,6 @@ void WiFiManager::Disconnect()
380375
WiFi.disconnect(false);
381376
}
382377

383-
bool WiFiManager::IsConnected()
384-
{
385-
return s_wifiState == WiFiState::Connected;
386-
}
387378
bool WiFiManager::GetConnectedNetwork(OpenShock::WiFiNetwork& network)
388379
{
389380
if (s_connectedCredentialsID == 0) {

src/wifi/WiFiManagerNew.cpp

Lines changed: 146 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include <freertos/FreeRTOS.h>
22

3+
#include "wifi/WiFiManager.h"
4+
35
const char* const TAG = "WiFiManager";
46

57
#include <freertos/task.h>
@@ -14,23 +16,39 @@ const char* const TAG = "WiFiManager";
1416
#include "ReadWriteMutex.h"
1517
#include "Time.h"
1618
#include "util/TaskUtils.h"
19+
#include "wifi/WiFiNetwork.h"
1720

1821
// Temporary fix to ensure that CDC+JTAG stay on on ESP32-C3
1922
#if CONFIG_IDF_TARGET_ESP32C3
2023
extern "C" void phy_bbpll_en_usb(bool en);
2124
#endif
2225

26+
const uint8_t OPENSHOCK_WIFI_SCAN_MAX_CHANNEL = 13;
27+
const uint32_t OPENSHOCK_WIFI_SCAN_DWELL_PER_CHANNEL = 100;
28+
const uint32_t OPENSHOCK_WIFI_SCAN_MIN_MS_PER_CHANNEL = 100;
29+
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
30+
const uint32_t OPENSHOCK_WIFI_SCAN_TIMEOUT_MS = 10 * 1000;
31+
2332
enum class WiFiState : uint8_t {
2433
Disconnected = 0,
2534
Scanning = 1 << 0,
2635
Connecting = 1 << 1,
2736
Connected = 1 << 2,
2837
};
2938

30-
static esp_netif_t* s_wifi_sta = nullptr;
31-
static esp_netif_t* s_wifi_ap = nullptr;
32-
static WiFiState s_state = WiFiState::Disconnected;
33-
static uint8_t s_target_creds = 0;
39+
struct ScanResult {
40+
uint8_t scanId;
41+
uint8_t size;
42+
uint8_t capacity;
43+
wifi_ap_record_t* records;
44+
};
45+
46+
static esp_netif_t* s_wifi_sta = nullptr;
47+
static esp_netif_t* s_wifi_ap = nullptr;
48+
static WiFiState s_state = WiFiState::Disconnected;
49+
static uint8_t s_target_creds = 0;
50+
static uint8_t s_scan_current_ch = 0;
51+
static ScanResult s_scan_results[OPENSHOCK_WIFI_SCAN_MAX_CHANNEL] = {};
3452

3553
template<std::size_t N>
3654
static bool is_zero(const uint8_t (&array)[N])
@@ -117,7 +135,7 @@ static bool set_ap_enabled(bool enabled)
117135
return true;
118136
}
119137

120-
static bool is_connect_ratelimited(const WiFiNetwork& net)
138+
static bool is_connect_ratelimited(const OpenShock::WiFiNetwork& net)
121139
{
122140
if (net.lastConnectAttempt == 0) {
123141
return false;
@@ -132,17 +150,95 @@ static bool is_connect_ratelimited(const WiFiNetwork& net)
132150
return false;
133151
}
134152

135-
static std::vector<WiFiNetwork>::iterator find_network(std::function<bool(WiFiNetwork&)> predicate, bool sortByAttractivity = true)
153+
static std::vector<OpenShock::WiFiNetwork>::iterator find_network(std::function<bool(OpenShock::WiFiNetwork&)> predicate, bool sortByAttractivity = true)
136154
{
137155
if (sortByAttractivity) {
138156
std::sort(s_wifiNetworks.begin(), s_wifiNetworks.end(), _attractivityComparer);
139157
}
140158
return std::find_if(s_wifiNetworks.begin(), s_wifiNetworks.end(), predicate);
141159
}
142160

161+
static bool mark_network_as_attempted(const uint8_t (&bssid)[6])
162+
{
163+
auto it = _findNetworkByBSSID(bssid);
164+
if (it == s_wifiNetworks.end()) {
165+
return false;
166+
}
167+
168+
it->connectAttempts++;
169+
it->lastConnectAttempt = OpenShock::millis();
170+
171+
return true;
172+
}
173+
174+
static void wifi_event_wifi_ready_handler(void* event_data)
175+
{
176+
OS_LOGV(TAG, "WiFi Ready!");
177+
}
178+
179+
static void wifi_event_scan_done_handler(void* event_data)
180+
{
181+
auto data = reinterpret_cast<wifi_event_sta_scan_done_t*>(event_data);
182+
183+
if (data->status == 1) {
184+
// TODO: what to do?
185+
OS_LOGE(TAG, "WiFi Scan failed!");
186+
return;
187+
}
188+
189+
if (s_scan_current_ch <= 0 || s_scan_current_ch >= OPENSHOCK_WIFI_SCAN_MAX_CHANNEL) {
190+
// TODO: what to do?
191+
OS_LOGE(TAG, "WiFi Scanned channel is invalid!");
192+
return;
193+
}
194+
195+
OS_LOGD(TAG, "WiFi scan completed, results: %hhu scan id: %hhu", data->number, data->scan_id);
196+
197+
ScanResult* result = s_scan_results[s_scan_current_ch];
198+
199+
result->scanId = data->scan_id;
200+
result->size = data->number;
201+
202+
if (result->records == nullptr || result->capacity < data->number) {
203+
OS_LOGD(TAG, "Initializing scan results at %hhu to %hhu elements", s_scan_current_ch, data->number);
204+
result->capacity = data->number;
205+
result->records = reinterpret_cast<wifi_ap_record_t*>(malloc(data->number * sizeof(wifi_ap_record_t)));
206+
} else if (result->capacity < data->number) {
207+
OS_LOGD(TAG, "Resizing scan results at %hhu from %hhu to %hhu elements", s_scan_current_ch, data->number);
208+
free(result->records);
209+
result->capacity = data->number;
210+
result->records = reinterpret_cast<wifi_ap_record_t*>(malloc(data->number * sizeof(wifi_ap_record_t)));
211+
}
212+
213+
esp_err_t err = esp_wifi_scan_get_ap_records(result->size, result->records);
214+
if (err != nullptr) {
215+
OS_LOGE(TAG, "Failed to get scan results: %d", err);
216+
return;
217+
}
218+
219+
// TODO: Check if scan is finished, start next channel scan if not.
220+
}
221+
222+
static void wifi_event_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
223+
{
224+
(void)event_handler_arg;
225+
(void)event_base;
226+
227+
switch (event_id) {
228+
case WIFI_EVENT_WIFI_READY:
229+
wifi_event_wifi_ready_handler(event_data);
230+
break;
231+
case WIFI_EVENT_SCAN_DONE:
232+
wifi_event_scan_done_handler(event_data);
233+
break;
234+
default:
235+
break;
236+
}
237+
}
238+
143239
static bool get_next_network(OpenShock::Config::WiFiCredentials& creds)
144240
{
145-
return find_network([&creds](const WiFiNetwork& net) {
241+
return find_network([&creds](const OpenShock::WiFiNetwork& net) {
146242
if (net.credentialsID == 0) {
147243
return false;
148244
}
@@ -159,6 +255,32 @@ static bool get_next_network(OpenShock::Config::WiFiCredentials& creds)
159255
}) != s_wifiNetworks.end();
160256
}
161257

258+
static bool wifi_start_scan(uint8_t channel = OPENSHOCK_WIFI_SCAN_MAX_CHANNEL)
259+
{
260+
wifi_scan_config_t scan_cfg = {
261+
.ssid = nullptr,
262+
.bssid = nullptr,
263+
.channel = channel,
264+
.show_hidden = true,
265+
.scan_type = WIFI_SCAN_TYPE_ACTIVE,
266+
.scan_time = {
267+
.active = {
268+
.min = OPENSHOCK_WIFI_SCAN_MIN_MS_PER_CHANNEL,
269+
.max = OPENSHOCK_WIFI_SCAN_MAX_MS_PER_CHANNEL,
270+
},
271+
},
272+
.home_chan_dwell_time = OPENSHOCK_WIFI_SCAN_DWELL_PER_CHANNEL,
273+
};
274+
275+
esp_err_t err = esp_wifi_scan_start(&scan_cfg, /* block: */ false);
276+
if (err != ERR_OK) {
277+
OS_LOGE(TAG, "Failed to start scan: %d", err);
278+
return false;
279+
}
280+
281+
return true;
282+
}
283+
162284
static bool wifi_start_connect(std::string_view ssid, std::string_view password, uint8_t (&bssid)[6])
163285
{
164286
esp_err_t err;
@@ -175,7 +297,10 @@ static bool wifi_start_connect(std::string_view ssid, std::string_view password,
175297

176298
OS_LOGV(TAG, "Connecting to network %s (" BSSID_FMT ")", ssid, BSSID_ARG(bssid));
177299

178-
// TODO: Mark network as attempted
300+
if (!mark_network_as_attempted(bssid)) {
301+
OS_LOGE(TAG, "Network not recognized!");
302+
return false;
303+
}
179304

180305
// Create WiFi config
181306
wifi_config_t wifi_cfg;
@@ -185,7 +310,7 @@ static bool wifi_start_connect(std::string_view ssid, std::string_view password,
185310
wifi_cfg.sta.threshold.rssi = -127;
186311
if (try_str_copy_fixed(wifi_cfg.sta.ssid, ssid) > 0) {
187312
if (try_str_copy_fixed(wifi_cfg.sta.password, password) > 0) {
188-
wifi_cfg.sta.authmode = WIFI_AUTH_WEP;
313+
wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WEP;
189314
}
190315
if (!is_zero(bssid)) {
191316
wifi_cfg.sta.bssid_set = 1;
@@ -196,7 +321,7 @@ static bool wifi_start_connect(std::string_view ssid, std::string_view password,
196321
// Set config before connnect
197322
err = esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg);
198323
if (err != ERR_OK) {
199-
OS_LOGE("Failed to set config: %d", err);
324+
OS_LOGE(TAG, "Failed to set config: %d", err);
200325
return false;
201326
}
202327

@@ -205,7 +330,7 @@ static bool wifi_start_connect(std::string_view ssid, std::string_view password,
205330
err = esp_wifi_connect();
206331
if (err != ERR_OK) {
207332
s_state = WiFiState::Disconnected;
208-
OS_LOGE("Failed to stat wifi connect: %d", err);
333+
OS_LOGE(TAG, "Failed to stat wifi connect: %d", err);
209334
return false;
210335
}
211336

@@ -225,7 +350,7 @@ static bool wifi_connect_target_or_next()
225350
return false;
226351
}
227352

228-
if (wifi_start_connect(creds.ssid, creds.password, nullptr)) {
353+
if (wifi_start_connect(creds.ssid, creds.password, creds.)) {
229354
return true;
230355
}
231356

@@ -250,15 +375,15 @@ static void wifi_task(void*)
250375
lastScanRequest = now;
251376

252377
OS_LOGV(TAG, "No networks to connect to, starting scan...");
253-
start_scanning();
378+
wifi_start_scan();
254379
}
255380
}
256381
}
257382
vTaskDelay(pdMS_TO_TICKS(1000));
258383
}
259384
}
260385

261-
bool WiFiManager::Init()
386+
bool OpenShock::WiFiManager::Init()
262387
{
263388
// Initializtion guard
264389
static bool initialized = false;
@@ -267,7 +392,13 @@ bool WiFiManager::Init()
267392

268393
esp_err_t err;
269394

270-
// TODO: register event handlers
395+
memset(s_scan_results, 0, sizeof(ScanResult) * OPENSHOCK_WIFI_SCAN_MAX_CHANNEL);
396+
397+
err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, nullptr);
398+
if (err != ERR_OK) {
399+
OS_LOGE(TAG, "Failed to subscribe to WiFi events: %d", err);
400+
return false;
401+
}
271402

272403
// Get saved config
273404
std::string hostname;

src/wifi/WiFiScanManager.cpp

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ const char* const TAG = "WiFiScanManager";
1212

1313
#include <map>
1414

15-
const uint8_t OPENSHOCK_WIFI_SCAN_MAX_CHANNEL = 13;
16-
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
17-
const uint32_t OPENSHOCK_WIFI_SCAN_TIMEOUT_MS = 10 * 1000;
18-
1915
enum WiFiScanTaskNotificationFlags {
2016
CHANNEL_DONE = 1 << 0,
2117
ERROR = 1 << 1,
@@ -207,21 +203,6 @@ void _evSTAStopped(arduino_event_id_t event, arduino_event_info_t info)
207203
_notifyTask(WiFiScanTaskNotificationFlags::WIFI_DISABLED);
208204
}
209205

210-
bool WiFiScanManager::Init()
211-
{
212-
if (s_initialized) {
213-
OS_LOGW(TAG, "WiFiScanManager is already initialized");
214-
return true;
215-
}
216-
217-
WiFi.onEvent(_evScanCompleted, ARDUINO_EVENT_WIFI_SCAN_DONE);
218-
WiFi.onEvent(_evSTAStopped, ARDUINO_EVENT_WIFI_STA_STOP);
219-
220-
s_initialized = true;
221-
222-
return true;
223-
}
224-
225206
bool WiFiScanManager::IsScanning()
226207
{
227208
// Quick check
@@ -278,36 +259,4 @@ bool WiFiScanManager::AbortScan()
278259
}
279260

280261
return true;
281-
}
282-
283-
uint64_t WiFiScanManager::RegisterStatusChangedHandler(const WiFiScanManager::StatusChangedHandler& handler)
284-
{
285-
static uint64_t nextHandle = 0;
286-
uint64_t handle = nextHandle++;
287-
s_statusChangedHandlers[handle] = handler;
288-
return handle;
289-
}
290-
void WiFiScanManager::UnregisterStatusChangedHandler(uint64_t handle)
291-
{
292-
auto it = s_statusChangedHandlers.find(handle);
293-
294-
if (it != s_statusChangedHandlers.end()) {
295-
s_statusChangedHandlers.erase(it);
296-
}
297-
}
298-
299-
uint64_t WiFiScanManager::RegisterNetworksDiscoveredHandler(const WiFiScanManager::NetworksDiscoveredHandler& handler)
300-
{
301-
static uint64_t nextHandle = 0;
302-
uint64_t handle = nextHandle++;
303-
s_networksDiscoveredHandlers[handle] = handler;
304-
return handle;
305-
}
306-
void WiFiScanManager::UnregisterNetworksDiscoveredHandler(uint64_t handle)
307-
{
308-
auto it = s_networksDiscoveredHandlers.find(handle);
309-
310-
if (it != s_networksDiscoveredHandlers.end()) {
311-
s_networksDiscoveredHandlers.erase(it);
312-
}
313-
}
262+
}

0 commit comments

Comments
 (0)