mirror of
https://github.com/MrUnknownDE/OpenIris-ESPIDF.git
synced 2026-04-14 04:03:44 +02:00
Merge pull request #33 from EyeTrackVR/feature/support-for-bssid
Add PoC support for BSSID
This commit is contained in:
@@ -588,6 +588,7 @@ CONFIG_CAMERA_WIFI_XCLK_FREQ=16500000
|
||||
#
|
||||
CONFIG_WIFI_MDNS_HOSTNAME="openiristracker"
|
||||
CONFIG_WIFI_SSID=""
|
||||
CONFIG_WIFI_BSSID=""
|
||||
CONFIG_WIFI_PASSWORD=""
|
||||
CONFIG_WIFI_AP_SSID="EyeTrackVR"
|
||||
CONFIG_WIFI_AP_PASSWORD="12345678"
|
||||
|
||||
@@ -1,8 +1,33 @@
|
||||
#include "CommandSchema.hpp"
|
||||
|
||||
void to_json(nlohmann::json& j, const WifiPayload& payload)
|
||||
{
|
||||
j = nlohmann::json{
|
||||
{"name", payload.name}, {"ssid", payload.ssid}, {"bssid", payload.bssid},
|
||||
{"password", payload.password}, {"channel", payload.channel}, {"power", payload.power},
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json& j, WifiPayload& payload)
|
||||
{
|
||||
payload.name = j.at("name").get<std::string>();
|
||||
payload.ssid = j.at("ssid").get<std::string>();
|
||||
payload.password = j.at("password").get<std::string>();
|
||||
payload.channel = j.at("channel").get<uint8_t>();
|
||||
payload.power = j.at("power").get<uint8_t>();
|
||||
|
||||
if (j.contains("bssid"))
|
||||
{
|
||||
payload.bssid = j.at("bssid").get<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json& j, const UpdateWifiPayload& payload)
|
||||
{
|
||||
j = nlohmann::json{{"name", payload.name}, {"ssid", payload.ssid}, {"password", payload.password}, {"channel", payload.channel}, {"power", payload.power}};
|
||||
j = nlohmann::json{
|
||||
{"name", payload.name}, {"ssid", payload.ssid}, {"bssid", payload.bssid},
|
||||
{"password", payload.password}, {"channel", payload.channel}, {"power", payload.power},
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json& j, UpdateWifiPayload& payload)
|
||||
@@ -13,6 +38,11 @@ void from_json(const nlohmann::json& j, UpdateWifiPayload& payload)
|
||||
payload.ssid = j.at("ssid").get<std::string>();
|
||||
}
|
||||
|
||||
if (j.contains("bssid"))
|
||||
{
|
||||
payload.bssid = j.at("bssid").get<std::string>();
|
||||
}
|
||||
|
||||
if (j.contains("password"))
|
||||
{
|
||||
payload.password = j.at("password").get<std::string>();
|
||||
@@ -54,7 +84,8 @@ void from_json(const nlohmann::json& j, UpdateAPWiFiPayload& payload)
|
||||
void to_json(nlohmann::json& j, const UpdateCameraConfigPayload& payload)
|
||||
{
|
||||
j = nlohmann::json{
|
||||
{"vflip", payload.vflip}, {"href", payload.href}, {"framesize", payload.framesize}, {"quality", payload.quality}, {"brightness", payload.brightness}};
|
||||
{"vflip", payload.vflip}, {"href", payload.href}, {"framesize", payload.framesize}, {"quality", payload.quality}, {"brightness", payload.brightness},
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json& j, UpdateCameraConfigPayload& payload)
|
||||
|
||||
@@ -10,17 +10,20 @@ struct WifiPayload : BasePayload
|
||||
{
|
||||
std::string name;
|
||||
std::string ssid;
|
||||
std::optional<std::string> bssid;
|
||||
std::string password;
|
||||
uint8_t channel;
|
||||
uint8_t power;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(WifiPayload, name, ssid, password, channel, power)
|
||||
void to_json(nlohmann::json& j, const WifiPayload& payload);
|
||||
void from_json(const nlohmann::json& j, WifiPayload& payload);
|
||||
|
||||
struct UpdateWifiPayload : BasePayload
|
||||
{
|
||||
std::string name;
|
||||
std::optional<std::string> ssid;
|
||||
std::optional<std::string> bssid;
|
||||
std::optional<std::string> password;
|
||||
std::optional<uint8_t> channel;
|
||||
std::optional<uint8_t> power;
|
||||
|
||||
@@ -19,8 +19,16 @@ CommandResult setWiFiCommand(std::shared_ptr<DependencyRegistry> registry, const
|
||||
return CommandResult::getErrorResult("Invalid payload: missing SSID");
|
||||
}
|
||||
|
||||
// format is XX:XX:XX:XX:XX:XX
|
||||
const std::string bssid = payload.bssid.has_value() ? payload.bssid.value() : "";
|
||||
const auto bssid_len = bssid.length();
|
||||
if (bssid_len > 0 && bssid_len != 17)
|
||||
{
|
||||
return CommandResult::getErrorResult("BSSID is malformed");
|
||||
}
|
||||
|
||||
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
|
||||
projectConfig->setWifiConfig(payload.name, payload.ssid, payload.password, payload.channel, payload.power);
|
||||
projectConfig->setWifiConfig(payload.name, payload.ssid, bssid, payload.password, payload.channel, payload.power);
|
||||
|
||||
return CommandResult::getSuccessResult("Config updated");
|
||||
}
|
||||
@@ -53,12 +61,22 @@ CommandResult updateWiFiCommand(std::shared_ptr<DependencyRegistry> registry, co
|
||||
return CommandResult::getErrorResult("Invalid payload - missing network name");
|
||||
}
|
||||
|
||||
if (payload.bssid.has_value())
|
||||
{
|
||||
auto bssid_len = payload.bssid.value().length();
|
||||
if (bssid_len > 0 && bssid_len != 11)
|
||||
{
|
||||
return CommandResult::getErrorResult("BSSID is malformed");
|
||||
}
|
||||
}
|
||||
|
||||
auto projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
|
||||
auto storedNetworks = projectConfig->getWifiConfigs();
|
||||
if (const auto networkToUpdate = std::ranges::find_if(storedNetworks, [&](auto& network) { return network.name == payload.name; });
|
||||
networkToUpdate != storedNetworks.end())
|
||||
{
|
||||
projectConfig->setWifiConfig(payload.name, payload.ssid.has_value() ? payload.ssid.value() : networkToUpdate->ssid,
|
||||
payload.bssid.has_value() ? payload.bssid.value() : networkToUpdate->bssid,
|
||||
payload.password.has_value() ? payload.password.value() : networkToUpdate->password,
|
||||
payload.channel.has_value() ? payload.channel.value() : networkToUpdate->channel,
|
||||
payload.power.has_value() ? payload.power.value() : networkToUpdate->power);
|
||||
|
||||
@@ -170,14 +170,23 @@ struct WiFiConfig_t : BaseConfigModel
|
||||
// default constructor used for loading
|
||||
WiFiConfig_t(Preferences* pref) : BaseConfigModel(pref) {}
|
||||
|
||||
WiFiConfig_t(Preferences* pref, const uint8_t index, std::string name, std::string ssid, std::string password, const uint8_t channel, const uint8_t power)
|
||||
: BaseConfigModel(pref), index(index), name(std::move(name)), ssid(std::move(ssid)), password(std::move(password)), channel(channel), power(power)
|
||||
WiFiConfig_t(Preferences* pref, const uint8_t index, std::string name, std::string ssid, std::string bssid, std::string password, const uint8_t channel,
|
||||
const uint8_t power)
|
||||
: BaseConfigModel(pref),
|
||||
index(index),
|
||||
name(std::move(name)),
|
||||
ssid(std::move(ssid)),
|
||||
bssid(std::move(bssid)),
|
||||
password(std::move(password)),
|
||||
channel(channel),
|
||||
power(power)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t index;
|
||||
std::string name;
|
||||
std::string ssid;
|
||||
std::string bssid;
|
||||
std::string password;
|
||||
uint8_t channel;
|
||||
uint8_t power;
|
||||
@@ -190,6 +199,7 @@ struct WiFiConfig_t : BaseConfigModel
|
||||
auto const iter_str = std::string(Helpers::itoa(index, buffer, 10));
|
||||
this->name = this->pref->getString(("name" + iter_str).c_str(), "");
|
||||
this->ssid = this->pref->getString(("ssid" + iter_str).c_str(), "");
|
||||
this->bssid = this->pref->getString(("bssid" + iter_str).c_str(), "");
|
||||
this->password = this->pref->getString(("password" + iter_str).c_str(), "");
|
||||
this->channel = this->pref->getUInt(("channel" + iter_str).c_str());
|
||||
this->power = this->pref->getUInt(("power" + iter_str).c_str());
|
||||
@@ -204,6 +214,7 @@ struct WiFiConfig_t : BaseConfigModel
|
||||
|
||||
this->pref->putString(("name" + iter_str).c_str(), this->name.c_str());
|
||||
this->pref->putString(("ssid" + iter_str).c_str(), this->ssid.c_str());
|
||||
this->pref->putString(("bssid" + iter_str).c_str(), this->bssid.c_str());
|
||||
this->pref->putString(("password" + iter_str).c_str(), this->password.c_str());
|
||||
this->pref->putUInt(("channel" + iter_str).c_str(), this->channel);
|
||||
this->pref->putUInt(("power" + iter_str).c_str(), this->power);
|
||||
@@ -213,8 +224,8 @@ struct WiFiConfig_t : BaseConfigModel
|
||||
|
||||
std::string toRepresentation()
|
||||
{
|
||||
return Helpers::format_string("{\"name\": \"%s\", \"ssid\": \"%s\", \"password\": \"%s\", \"channel\": %u, \"power\": %u}", this->name.c_str(),
|
||||
this->ssid.c_str(), this->password.c_str(), this->channel, this->power);
|
||||
return Helpers::format_string("{\"name\": \"%s\", \"ssid\": \"%s\", \"bssid\": \"%s\", \"password\": \"%s\", \"channel\": %u, \"power\": %u}",
|
||||
this->name.c_str(), this->ssid.c_str(), this->bssid.c_str(), this->password.c_str(), this->channel, this->power);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -127,7 +127,8 @@ void ProjectConfig::setCameraConfig(const uint8_t vflip, const uint8_t framesize
|
||||
ESP_LOGD(CONFIGURATION_TAG, "Updating Camera config");
|
||||
}
|
||||
|
||||
void ProjectConfig::setWifiConfig(const std::string& networkName, const std::string& ssid, const std::string& password, uint8_t channel, uint8_t power)
|
||||
void ProjectConfig::setWifiConfig(const std::string& networkName, const std::string& ssid, const std::string& bssid, const std::string& password,
|
||||
uint8_t channel, uint8_t power)
|
||||
{
|
||||
const auto size = this->config.networks.size();
|
||||
|
||||
@@ -139,6 +140,7 @@ void ProjectConfig::setWifiConfig(const std::string& networkName, const std::str
|
||||
|
||||
it->name = networkName;
|
||||
it->ssid = ssid;
|
||||
it->bssid = bssid;
|
||||
it->password = password;
|
||||
it->channel = channel;
|
||||
it->power = power;
|
||||
@@ -150,7 +152,7 @@ void ProjectConfig::setWifiConfig(const std::string& networkName, const std::str
|
||||
if (size == 0)
|
||||
{
|
||||
ESP_LOGI(CONFIGURATION_TAG, "No networks, We're adding a new network");
|
||||
this->config.networks.emplace_back(this->pref, static_cast<uint8_t>(0), networkName, ssid, password, channel, power);
|
||||
this->config.networks.emplace_back(this->pref, static_cast<uint8_t>(0), networkName, ssid, bssid, password, channel, power);
|
||||
// Save the new network immediately
|
||||
this->config.networks.back().save();
|
||||
saveNetworkCount(this->pref, 1);
|
||||
@@ -162,10 +164,10 @@ void ProjectConfig::setWifiConfig(const std::string& networkName, const std::str
|
||||
{
|
||||
ESP_LOGI(CONFIGURATION_TAG, "We're adding a new network");
|
||||
// we don't have that network yet, we can add it as we still have some
|
||||
// space we're using emplace_back as push_back will create a copy of it,
|
||||
// space, we're using emplace_back as push_back will create a copy of it,
|
||||
// we want to avoid that
|
||||
uint8_t last_index = getNetworkCount(this->pref);
|
||||
this->config.networks.emplace_back(this->pref, last_index, networkName, ssid, password, channel, power);
|
||||
this->config.networks.emplace_back(this->pref, last_index, networkName, ssid, bssid, password, channel, power);
|
||||
// Save the new network immediately
|
||||
this->config.networks.back().save();
|
||||
saveNetworkCount(this->pref, static_cast<int>(this->config.networks.size()));
|
||||
|
||||
@@ -37,7 +37,8 @@ class ProjectConfig
|
||||
void setLEDDUtyCycleConfig(int led_external_pwm_duty_cycle);
|
||||
void setMDNSConfig(const std::string& hostname);
|
||||
void setCameraConfig(uint8_t vflip, uint8_t framesize, uint8_t href, uint8_t quality, uint8_t brightness);
|
||||
void setWifiConfig(const std::string& networkName, const std::string& ssid, const std::string& password, uint8_t channel, uint8_t power);
|
||||
void setWifiConfig(const std::string& networkName, const std::string& ssid, const std::string& bssid, const std::string& password, uint8_t channel,
|
||||
uint8_t power);
|
||||
|
||||
void deleteWifiConfig(const std::string& networkName);
|
||||
|
||||
|
||||
@@ -6,42 +6,6 @@ static const char* TAG = "WiFiScanner";
|
||||
|
||||
WiFiScanner::WiFiScanner() {}
|
||||
|
||||
void WiFiScanner::scanResultCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
||||
{
|
||||
auto* scanner = static_cast<WiFiScanner*>(arg);
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE)
|
||||
{
|
||||
uint16_t ap_count = 0;
|
||||
esp_wifi_scan_get_ap_num(&ap_count);
|
||||
|
||||
if (ap_count == 0)
|
||||
{
|
||||
ESP_LOGI(TAG, "No access points found");
|
||||
return;
|
||||
}
|
||||
|
||||
wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count];
|
||||
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_records));
|
||||
|
||||
scanner->networks.clear();
|
||||
for (uint16_t i = 0; i < ap_count; i++)
|
||||
{
|
||||
WiFiNetwork network;
|
||||
network.ssid = std::string(reinterpret_cast<char*>(ap_records[i].ssid));
|
||||
network.channel = ap_records[i].primary;
|
||||
network.rssi = ap_records[i].rssi;
|
||||
memcpy(network.mac, ap_records[i].bssid, 6);
|
||||
network.auth_mode = ap_records[i].authmode;
|
||||
|
||||
scanner->networks.push_back(network);
|
||||
}
|
||||
|
||||
delete[] ap_records;
|
||||
ESP_LOGI(TAG, "Found %d access points", ap_count);
|
||||
}
|
||||
}
|
||||
|
||||
// todo this is garbage
|
||||
std::vector<WiFiNetwork> WiFiScanner::scanNetworks(int timeout_ms)
|
||||
{
|
||||
std::vector<WiFiNetwork> scan_results;
|
||||
@@ -61,176 +25,67 @@ std::vector<WiFiNetwork> WiFiScanner::scanNetworks(int timeout_ms)
|
||||
// Stop any ongoing scan
|
||||
esp_wifi_scan_stop();
|
||||
|
||||
// Try sequential channel scanning as a workaround
|
||||
bool try_sequential_scan = true; // Enable sequential scan
|
||||
|
||||
if (!try_sequential_scan)
|
||||
{
|
||||
// Normal all-channel scan
|
||||
wifi_scan_config_t scan_config = {
|
||||
.ssid = nullptr,
|
||||
.bssid = nullptr,
|
||||
.channel = 0, // 0 means scan all channels
|
||||
.show_hidden = true,
|
||||
.scan_type = WIFI_SCAN_TYPE_ACTIVE, // Active scan
|
||||
.scan_time = {.active =
|
||||
{
|
||||
.min = 120, // Min per channel
|
||||
.max = 300 // Max per channel
|
||||
},
|
||||
.passive = 360},
|
||||
.home_chan_dwell_time = 0, // 0 for default
|
||||
.channel_bitmap = 0 // 0 for all channels
|
||||
};
|
||||
|
||||
err = esp_wifi_scan_start(&scan_config, false);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to start scan: %s", esp_err_to_name(err));
|
||||
return scan_results;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sequential channel scan - scan each channel individually with timeout tracking
|
||||
std::vector<wifi_ap_record_t> all_records;
|
||||
int64_t start_time = esp_timer_get_time() / 1000; // Convert to ms
|
||||
|
||||
for (uint8_t ch = 1; ch <= 13; ch++)
|
||||
{
|
||||
// Check if we've exceeded the timeout
|
||||
int64_t current_time = esp_timer_get_time() / 1000;
|
||||
int64_t elapsed = current_time - start_time;
|
||||
|
||||
if (elapsed >= timeout_ms)
|
||||
{
|
||||
ESP_LOGW(TAG, "Sequential scan timeout after %lld ms at channel %d", elapsed, ch);
|
||||
break;
|
||||
}
|
||||
|
||||
wifi_scan_config_t scan_config = {.ssid = nullptr,
|
||||
.bssid = nullptr,
|
||||
.channel = ch,
|
||||
.show_hidden = true,
|
||||
.scan_type = WIFI_SCAN_TYPE_ACTIVE,
|
||||
.scan_time = {.active = {.min = 100, .max = 200}, .passive = 300},
|
||||
.home_chan_dwell_time = 0,
|
||||
.channel_bitmap = 0};
|
||||
|
||||
err = esp_wifi_scan_start(&scan_config, true); // Blocking scan
|
||||
if (err == ESP_OK)
|
||||
{
|
||||
uint16_t ch_count = 0;
|
||||
esp_wifi_scan_get_ap_num(&ch_count);
|
||||
if (ch_count > 0)
|
||||
{
|
||||
wifi_ap_record_t* ch_records = new wifi_ap_record_t[ch_count];
|
||||
if (esp_wifi_scan_get_ap_records(&ch_count, ch_records) == ESP_OK)
|
||||
{
|
||||
for (uint16_t i = 0; i < ch_count; i++)
|
||||
{
|
||||
all_records.push_back(ch_records[i]);
|
||||
}
|
||||
}
|
||||
delete[] ch_records;
|
||||
}
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
|
||||
// Process all collected records
|
||||
for (const auto& record : all_records)
|
||||
{
|
||||
WiFiNetwork network;
|
||||
network.ssid = std::string(reinterpret_cast<const char*>(record.ssid));
|
||||
network.channel = record.primary;
|
||||
network.rssi = record.rssi;
|
||||
memcpy(network.mac, record.bssid, 6);
|
||||
network.auth_mode = record.authmode;
|
||||
scan_results.push_back(network);
|
||||
}
|
||||
|
||||
int64_t total_time = (esp_timer_get_time() / 1000) - start_time;
|
||||
ESP_LOGI(TAG, "Sequential scan completed in %lld ms, found %d APs", total_time, scan_results.size());
|
||||
|
||||
// Skip the normal result processing
|
||||
return scan_results;
|
||||
}
|
||||
|
||||
// Wait for scan completion with timeout
|
||||
// Sequential channel scan - scan each channel individually with timeout tracking
|
||||
std::vector<wifi_ap_record_t> all_records;
|
||||
int64_t start_time = esp_timer_get_time() / 1000; // Convert to ms
|
||||
int64_t elapsed_ms = 0;
|
||||
bool scan_done = false;
|
||||
|
||||
while (elapsed_ms < timeout_ms)
|
||||
for (uint8_t ch = 1; ch <= 13; ch++)
|
||||
{
|
||||
// Check if scan is actually complete by trying to get AP count
|
||||
// When scan is done, this will return ESP_OK with a valid count
|
||||
uint16_t temp_count = 0;
|
||||
esp_err_t count_err = esp_wifi_scan_get_ap_num(&temp_count);
|
||||
// Check if we've exceeded the timeout
|
||||
int64_t current_time = esp_timer_get_time() / 1000;
|
||||
int64_t elapsed = current_time - start_time;
|
||||
|
||||
// If we can successfully get the AP count, the scan is likely complete
|
||||
// However, we should still wait for the scan to fully finish
|
||||
if (count_err == ESP_OK && temp_count > 0)
|
||||
if (elapsed >= timeout_ms)
|
||||
{
|
||||
// Give it a bit more time to ensure all channels are scanned
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
scan_done = true;
|
||||
ESP_LOGW(TAG, "Sequential scan timeout after %lld ms at channel %d", elapsed, ch);
|
||||
break;
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
elapsed_ms = (esp_timer_get_time() / 1000) - start_time;
|
||||
wifi_scan_config_t scan_config = {.ssid = nullptr,
|
||||
.bssid = nullptr,
|
||||
.channel = ch,
|
||||
.show_hidden = true,
|
||||
.scan_type = WIFI_SCAN_TYPE_ACTIVE,
|
||||
.scan_time = {.active = {.min = 100, .max = 200}, .passive = 300},
|
||||
.home_chan_dwell_time = 0,
|
||||
.channel_bitmap = 0};
|
||||
|
||||
err = esp_wifi_scan_start(&scan_config, true); // Blocking scan
|
||||
if (err == ESP_OK)
|
||||
{
|
||||
uint16_t ch_count = 0;
|
||||
esp_wifi_scan_get_ap_num(&ch_count);
|
||||
if (ch_count > 0)
|
||||
{
|
||||
wifi_ap_record_t* ch_records = new wifi_ap_record_t[ch_count];
|
||||
if (esp_wifi_scan_get_ap_records(&ch_count, ch_records) == ESP_OK)
|
||||
{
|
||||
for (uint16_t i = 0; i < ch_count; i++)
|
||||
{
|
||||
all_records.push_back(ch_records[i]);
|
||||
}
|
||||
}
|
||||
delete[] ch_records;
|
||||
}
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
|
||||
if (!scan_done && elapsed_ms >= timeout_ms)
|
||||
{
|
||||
ESP_LOGE(TAG, "Scan timeout after %lld ms", elapsed_ms);
|
||||
esp_wifi_scan_stop();
|
||||
return scan_results;
|
||||
}
|
||||
|
||||
// Get scan results
|
||||
uint16_t ap_count = 0;
|
||||
esp_wifi_scan_get_ap_num(&ap_count);
|
||||
|
||||
if (ap_count == 0)
|
||||
{
|
||||
ESP_LOGI(TAG, "No access points found");
|
||||
return scan_results;
|
||||
}
|
||||
|
||||
wifi_ap_record_t* ap_records = new wifi_ap_record_t[ap_count];
|
||||
err = esp_wifi_scan_get_ap_records(&ap_count, ap_records);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to get scan records: %s", esp_err_to_name(err));
|
||||
delete[] ap_records;
|
||||
return scan_results;
|
||||
}
|
||||
|
||||
// Build the results vector and track channels found
|
||||
bool channels_found[15] = {false}; // Track channels 0-14
|
||||
|
||||
for (uint16_t i = 0; i < ap_count; i++)
|
||||
// Process all collected records
|
||||
for (const auto& record : all_records)
|
||||
{
|
||||
WiFiNetwork network;
|
||||
network.ssid = std::string(reinterpret_cast<char*>(ap_records[i].ssid));
|
||||
network.channel = ap_records[i].primary;
|
||||
network.rssi = ap_records[i].rssi;
|
||||
memcpy(network.mac, ap_records[i].bssid, 6);
|
||||
network.auth_mode = ap_records[i].authmode;
|
||||
|
||||
if (network.channel <= 14)
|
||||
{
|
||||
channels_found[network.channel] = true;
|
||||
}
|
||||
|
||||
network.ssid = std::string(reinterpret_cast<const char*>(record.ssid));
|
||||
network.channel = record.primary;
|
||||
network.rssi = record.rssi;
|
||||
memcpy(network.mac, record.bssid, 6);
|
||||
network.auth_mode = record.authmode;
|
||||
scan_results.push_back(network);
|
||||
}
|
||||
|
||||
delete[] ap_records;
|
||||
ESP_LOGI(TAG, "Found %d access points", ap_count);
|
||||
int64_t total_time = (esp_timer_get_time() / 1000) - start_time;
|
||||
ESP_LOGI(TAG, "Sequential scan completed in %lld ms, found %d APs", total_time, scan_results.size());
|
||||
|
||||
// Skip the normal result processing
|
||||
return scan_results;
|
||||
}
|
||||
@@ -21,7 +21,6 @@ class WiFiScanner
|
||||
public:
|
||||
WiFiScanner();
|
||||
std::vector<WiFiNetwork> scanNetworks(int timeout_ms = 15000);
|
||||
static void scanResultCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||
|
||||
private:
|
||||
std::vector<WiFiNetwork> networks;
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
#include "wifiManager.hpp"
|
||||
#include <charconv>
|
||||
#include <cstdint>
|
||||
#include <ranges>
|
||||
#include <string_view>
|
||||
|
||||
static auto WIFI_MANAGER_TAG = "[WIFI_MANAGER]";
|
||||
|
||||
@@ -47,7 +51,25 @@ WiFiManager::WiFiManager(std::shared_ptr<ProjectConfig> deviceConfig, QueueHandl
|
||||
{
|
||||
}
|
||||
|
||||
void WiFiManager::SetCredentials(const char* ssid, const char* password)
|
||||
std::vector<uint8_t> WiFiManager::ParseBSSID(std::string_view bssid_string)
|
||||
{
|
||||
return bssid_string
|
||||
// We format the bssid/mac address as XX:XX:XX:XX:XX:XX
|
||||
| std::views::split(':')
|
||||
// Once we have that, we can convert each sub range into a proper uint8_t value
|
||||
| std::views::transform(
|
||||
[](auto&& subrange) -> uint8_t
|
||||
{
|
||||
auto view = std::string_view(subrange);
|
||||
uint8_t result{};
|
||||
std::from_chars(view.begin(), view.end(), result, 16);
|
||||
return result;
|
||||
})
|
||||
// and now group them into the vector we need
|
||||
| std::ranges::to<std::vector<uint8_t>>();
|
||||
}
|
||||
|
||||
void WiFiManager::SetCredentials(const char* ssid, const std::vector<uint8_t> bssid, const char* password, bool use_bssid)
|
||||
{
|
||||
// Clear the config first
|
||||
memset(&_wifi_cfg, 0, sizeof(_wifi_cfg));
|
||||
@@ -62,6 +84,13 @@ void WiFiManager::SetCredentials(const char* ssid, const char* password)
|
||||
memcpy(_wifi_cfg.sta.password, password, pass_len);
|
||||
_wifi_cfg.sta.password[pass_len] = '\0';
|
||||
|
||||
// if we can use bssid, just copy it. Parser makes sure we do not exceed 6 elements so we should be safe here
|
||||
// if we fail to parse, the vec will be empty, so use_bssid won't be set
|
||||
if (use_bssid)
|
||||
{
|
||||
std::copy(bssid.begin(), bssid.end(), _wifi_cfg.sta.bssid);
|
||||
}
|
||||
|
||||
// Set other required fields
|
||||
// Use open auth if no password, otherwise allow any WPA variant
|
||||
if (strlen(password) == 0)
|
||||
@@ -81,8 +110,8 @@ void WiFiManager::SetCredentials(const char* ssid, const char* password)
|
||||
|
||||
// OPTIMIZATION: Use fast scan instead of all channel scan for quicker connection
|
||||
_wifi_cfg.sta.scan_method = WIFI_FAST_SCAN;
|
||||
_wifi_cfg.sta.bssid_set = 0; // Don't use specific BSSID
|
||||
_wifi_cfg.sta.channel = 0; // Auto channel detection
|
||||
_wifi_cfg.sta.bssid_set = use_bssid; // Don't use specific BSSID
|
||||
_wifi_cfg.sta.channel = 0; // Auto channel detection
|
||||
|
||||
// Additional settings that might help with compatibility
|
||||
_wifi_cfg.sta.listen_interval = 0; // Default listen interval
|
||||
@@ -101,7 +130,8 @@ void WiFiManager::SetCredentials(const char* ssid, const char* password)
|
||||
void WiFiManager::ConnectWithHardcodedCredentials()
|
||||
{
|
||||
SystemEvent event = {EventSource::WIFI, WiFiState_e::WiFiState_ReadyToConnect};
|
||||
this->SetCredentials(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD);
|
||||
const auto bssid = this->ParseBSSID(std::string_view(CONFIG_WIFI_BSSID));
|
||||
this->SetCredentials(CONFIG_WIFI_SSID, bssid, CONFIG_WIFI_PASSWORD, bssid.size());
|
||||
|
||||
wifi_mode_t mode;
|
||||
if (esp_wifi_get_mode(&mode) == ESP_OK)
|
||||
@@ -170,7 +200,8 @@ void WiFiManager::ConnectWithStoredCredentials()
|
||||
// Reset retry counter for each network attempt
|
||||
s_retry_num = 0;
|
||||
xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_CONNECTED_BIT);
|
||||
this->SetCredentials(network.ssid.c_str(), network.password.c_str());
|
||||
auto bssid = this->ParseBSSID(std::string_view(network.bssid));
|
||||
this->SetCredentials(network.ssid.c_str(), bssid, network.password.c_str(), bssid.size());
|
||||
|
||||
// Update config without stopping WiFi again
|
||||
ESP_LOGI(WIFI_MANAGER_TAG, "Attempting to connect to SSID: '%s'", network.ssid.c_str());
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "WiFiScanner.hpp"
|
||||
|
||||
#include "esp_event.h"
|
||||
@@ -40,10 +41,11 @@ class WiFiManager
|
||||
|
||||
int8_t power;
|
||||
|
||||
void SetCredentials(const char* ssid, const char* password);
|
||||
void SetCredentials(const char* ssid, const std::vector<uint8_t> bssid, const char* password, bool use_bssid);
|
||||
void ConnectWithHardcodedCredentials();
|
||||
void ConnectWithStoredCredentials();
|
||||
void SetupAccessPoint();
|
||||
std::vector<uint8_t> ParseBSSID(std::string_view bssid_string);
|
||||
|
||||
public:
|
||||
WiFiManager(std::shared_ptr<ProjectConfig> deviceConfig, QueueHandle_t eventQueue, StateManager* stateManager);
|
||||
|
||||
@@ -93,6 +93,10 @@ menu "OpenIris: WiFi Configuration"
|
||||
string "WiFi network name (SSID)"
|
||||
default ""
|
||||
|
||||
config WIFI_BSSID
|
||||
string "WiFi network MAC Address (BSSID), completely optional, used in special cases"
|
||||
default ""
|
||||
|
||||
config WIFI_PASSWORD
|
||||
string "WiFi password"
|
||||
default ""
|
||||
|
||||
@@ -590,6 +590,7 @@ CONFIG_CAMERA_WIFI_XCLK_FREQ=16500000
|
||||
# OpenIris: WiFi Configuration
|
||||
#
|
||||
CONFIG_WIFI_SSID=""
|
||||
CONFIG_WIFI_BSSID=""
|
||||
CONFIG_WIFI_PASSWORD=""
|
||||
CONFIG_WIFI_AP_SSID="EyeTrackVR"
|
||||
CONFIG_WIFI_AP_PASSWORD="12345678"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
WIFI_SSID=
|
||||
WIFI_BSSID=
|
||||
WIFI_PASS=
|
||||
SWITCH_MODE_REBOOT_TIME=5
|
||||
WIFI_CONNECTION_TIMEOUT=5
|
||||
|
||||
@@ -37,7 +37,8 @@ def pytest_addoption(parser):
|
||||
|
||||
def pytest_configure(config):
|
||||
config.addinivalue_line(
|
||||
"markers", "has_capability(caps): skip if the board does not have the capability"
|
||||
"markers",
|
||||
"has_capability(caps): skip if the board does not have the capability",
|
||||
)
|
||||
config.addinivalue_line(
|
||||
"markers", "lacks_capability(caps): skip if the board DOES have the capability"
|
||||
@@ -60,7 +61,7 @@ def check_capability_marker(request, board_lacks_capability):
|
||||
"has_capability marker must be provided with a capability to check"
|
||||
)
|
||||
|
||||
for capability in marker.args:
|
||||
for capability in marker.args:
|
||||
if board_lacks_capability(capability):
|
||||
pytest.skip(f"Board does not have capability {capability}")
|
||||
|
||||
@@ -72,7 +73,7 @@ def check_lacks_capability_marker(request, board_lacks_capability):
|
||||
raise ValueError(
|
||||
"lacks_capability marker must be provided with a capability to check"
|
||||
)
|
||||
|
||||
|
||||
for capability in lacks_capability_marker.args:
|
||||
if not board_lacks_capability(capability):
|
||||
pytest.skip(
|
||||
@@ -119,6 +120,7 @@ def board_connection(request):
|
||||
@dataclass
|
||||
class TestConfig:
|
||||
WIFI_SSID: str
|
||||
WIFI_BSSID: str
|
||||
WIFI_PASS: str
|
||||
SWITCH_MODE_REBOOT_TIME: int
|
||||
WIFI_CONNECTION_TIMEOUT: int
|
||||
@@ -127,12 +129,14 @@ class TestConfig:
|
||||
def __init__(
|
||||
self,
|
||||
WIFI_SSID: str,
|
||||
WIFI_BSSID: str,
|
||||
WIFI_PASS: str,
|
||||
SWITCH_MODE_REBOOT_TIME: int,
|
||||
WIFI_CONNECTION_TIMEOUT: int,
|
||||
INVALID_WIFI_CONNECTION_TIMEOUT: int,
|
||||
):
|
||||
self.WIFI_SSID = WIFI_SSID
|
||||
self.WIFI_BSSID = WIFI_BSSID
|
||||
self.WIFI_PASS = WIFI_PASS
|
||||
self.SWITCH_MODE_REBOOT_TIME = int(SWITCH_MODE_REBOOT_TIME)
|
||||
self.WIFI_CONNECTION_TIMEOUT = int(WIFI_CONNECTION_TIMEOUT)
|
||||
|
||||
@@ -255,8 +255,39 @@ def test_reset_config(get_openiris_device, config):
|
||||
|
||||
|
||||
@pytest.mark.has_capability("wireless")
|
||||
def test_set_wifi(get_openiris_device, ensure_board_in_mode, config):
|
||||
# since we want to test actual connection to the network, let's reset the device and reboot it
|
||||
def test_set_wifi_no_bssid_in_payload(
|
||||
get_openiris_device, ensure_board_in_mode, config
|
||||
):
|
||||
device = get_openiris_device()
|
||||
reset_command = device.send_command("reset_config", {"section": "all"})
|
||||
assert not has_command_failed(reset_command)
|
||||
|
||||
with DetectPortChange():
|
||||
device.send_command("restart_device")
|
||||
time.sleep(config.SWITCH_MODE_REBOOT_TIME)
|
||||
|
||||
device = ensure_board_in_mode("wifi", device)
|
||||
params = {
|
||||
"name": "main",
|
||||
"ssid": config.WIFI_SSID,
|
||||
"password": config.WIFI_PASS,
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
}
|
||||
set_wifi_result = device.send_command("set_wifi", params)
|
||||
assert not has_command_failed(set_wifi_result)
|
||||
|
||||
connect_wifi_result = device.send_command("connect_wifi")
|
||||
assert not -has_command_failed(connect_wifi_result)
|
||||
time.sleep(config.WIFI_CONNECTION_TIMEOUT) # and let it try to for some time
|
||||
|
||||
wifi_status_command = device.send_command("get_wifi_status")
|
||||
assert not has_command_failed(wifi_status_command)
|
||||
assert wifi_status_command["results"][0]["result"]["data"]["status"] == "connected"
|
||||
|
||||
|
||||
@pytest.mark.has_capability("wireless")
|
||||
def test_set_wifi_no_bssid(get_openiris_device, ensure_board_in_mode, config):
|
||||
device = get_openiris_device()
|
||||
reset_command = device.send_command("reset_config", {"section": "all"})
|
||||
assert not has_command_failed(reset_command)
|
||||
@@ -270,6 +301,7 @@ def test_set_wifi(get_openiris_device, ensure_board_in_mode, config):
|
||||
params = {
|
||||
"name": "main",
|
||||
"ssid": config.WIFI_SSID,
|
||||
"bssid": "",
|
||||
"password": config.WIFI_PASS,
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
@@ -287,12 +319,76 @@ def test_set_wifi(get_openiris_device, ensure_board_in_mode, config):
|
||||
assert wifi_status_command["results"][0]["result"]["data"]["status"] == "connected"
|
||||
|
||||
|
||||
@pytest.mark.has_capability("wireless")
|
||||
def test_set_wifi_correct_bssid(get_openiris_device, ensure_board_in_mode, config):
|
||||
device = get_openiris_device()
|
||||
reset_command = device.send_command("reset_config", {"section": "all"})
|
||||
assert not has_command_failed(reset_command)
|
||||
|
||||
with DetectPortChange():
|
||||
device.send_command("restart_device")
|
||||
time.sleep(config.SWITCH_MODE_REBOOT_TIME)
|
||||
|
||||
device = ensure_board_in_mode("wifi", device)
|
||||
params = {
|
||||
"name": "main",
|
||||
"ssid": config.WIFI_SSID,
|
||||
"bssid": config.WIFI_BSSID,
|
||||
"password": config.WIFI_PASS,
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
}
|
||||
set_wifi_result = device.send_command("set_wifi", params)
|
||||
assert not has_command_failed(set_wifi_result)
|
||||
|
||||
connect_wifi_result = device.send_command("connect_wifi")
|
||||
assert not -has_command_failed(connect_wifi_result)
|
||||
time.sleep(config.WIFI_CONNECTION_TIMEOUT)
|
||||
|
||||
wifi_status_command = device.send_command("get_wifi_status")
|
||||
assert not has_command_failed(wifi_status_command)
|
||||
assert wifi_status_command["results"][0]["result"]["data"]["status"] == "connected"
|
||||
|
||||
|
||||
@pytest.mark.has_capability("wireless")
|
||||
def test_set_wifi_nonexitant_bssid(get_openiris_device, ensure_board_in_mode, config):
|
||||
device = get_openiris_device()
|
||||
reset_command = device.send_command("reset_config", {"section": "all"})
|
||||
assert not has_command_failed(reset_command)
|
||||
|
||||
with DetectPortChange():
|
||||
device.send_command("restart_device")
|
||||
time.sleep(config.SWITCH_MODE_REBOOT_TIME)
|
||||
|
||||
device = ensure_board_in_mode("wifi", device)
|
||||
params = {
|
||||
"name": "main",
|
||||
"ssid": config.WIFI_SSID,
|
||||
"bssid": "99:99:99:99:99:99", # a completely wrong BSSID, just to test that we fail to connect
|
||||
"password": config.WIFI_PASS,
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
}
|
||||
|
||||
set_wifi_result = device.send_command("set_wifi", params)
|
||||
assert not has_command_failed(set_wifi_result)
|
||||
|
||||
connect_wifi_result = device.send_command("connect_wifi")
|
||||
assert not -has_command_failed(connect_wifi_result)
|
||||
time.sleep(config.WIFI_CONNECTION_TIMEOUT)
|
||||
|
||||
wifi_status_command = device.send_command("get_wifi_status")
|
||||
assert not has_command_failed(wifi_status_command)
|
||||
assert wifi_status_command["results"][0]["result"]["data"]["status"] == "error"
|
||||
|
||||
|
||||
@pytest.mark.has_capability("wireless")
|
||||
def test_set_wifi_invalid_network(get_openiris_device, ensure_board_in_mode, config):
|
||||
device = ensure_board_in_mode("wifi", get_openiris_device())
|
||||
params = {
|
||||
"name": "main",
|
||||
"ssid": "PleaseDontBeARealNetwork",
|
||||
"bssid": "",
|
||||
"password": "AndThePasswordIsFake",
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
@@ -351,6 +447,7 @@ def test_update_main_wifi_network(ensure_board_in_mode, get_openiris_device, con
|
||||
params1 = {
|
||||
"name": "main",
|
||||
"ssid": "Nada",
|
||||
"bssid": "",
|
||||
"password": "Nuuh",
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
@@ -377,6 +474,7 @@ def test_set_wifi_add_another_network(ensure_board_in_mode, get_openiris_device)
|
||||
params = {
|
||||
"name": "anotherNetwork",
|
||||
"ssid": "PleaseDontBeARealNetwork",
|
||||
"bssid": "",
|
||||
"password": "AndThePassowrdIsFake",
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
@@ -475,6 +573,7 @@ def test_update_wifi_command(ensure_board_in_mode, get_openiris_device, payload)
|
||||
params = {
|
||||
"name": "anotherNetwork",
|
||||
"ssid": "PleaseDontBeARealNetwork",
|
||||
"bssid": "",
|
||||
"password": "AndThePasswordIsFake",
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
|
||||
@@ -82,6 +82,7 @@ class Menu(SubMenu):
|
||||
@dataclass
|
||||
class WiFiNetwork:
|
||||
ssid: str
|
||||
bssid: str
|
||||
channel: int
|
||||
rssi: int
|
||||
mac_address: str
|
||||
@@ -119,7 +120,7 @@ class WiFiScanner:
|
||||
"scan_networks", params={"timeout_ms": timeout_ms}, timeout=timeout
|
||||
)
|
||||
if has_command_failed(response):
|
||||
print(f"❌ Scan failed: {response['error']}")
|
||||
print(f"❌ Scan failed: {get_response_error(response)}")
|
||||
return
|
||||
|
||||
channels_found = set()
|
||||
@@ -130,6 +131,7 @@ class WiFiScanner:
|
||||
for net in networks:
|
||||
network = WiFiNetwork(
|
||||
ssid=net["ssid"],
|
||||
bssid=net["mac_address"],
|
||||
channel=net["channel"],
|
||||
rssi=net["rssi"],
|
||||
mac_address=net["mac_address"],
|
||||
@@ -144,7 +146,7 @@ class WiFiScanner:
|
||||
f"✅ Found {len(self.networks)} networks on channels: {sorted(channels_found)}"
|
||||
)
|
||||
|
||||
def get_networks(self) -> list:
|
||||
def get_networks(self) -> list[WiFiNetwork]:
|
||||
return self.networks
|
||||
|
||||
|
||||
@@ -152,6 +154,10 @@ def has_command_failed(result) -> bool:
|
||||
return "error" in result or result["results"][0]["result"]["status"] != "success"
|
||||
|
||||
|
||||
def get_response_error(result) -> str:
|
||||
return result["results"][0]["result"]["data"]
|
||||
|
||||
|
||||
def get_device_mode(device: OpenIrisDevice) -> dict:
|
||||
command_result = device.send_command("get_device_mode")
|
||||
if has_command_failed(command_result):
|
||||
@@ -181,7 +187,7 @@ def get_led_duty_cycle(device: OpenIrisDevice) -> dict:
|
||||
def get_mdns_name(device: OpenIrisDevice) -> dict:
|
||||
response = device.send_command("get_mdns_name")
|
||||
if "error" in response:
|
||||
print(f"❌ Failed to get device name: {response['error']}")
|
||||
print(f"❌ Failed to get device name: {get_response_error(response)}")
|
||||
return {"name": "unknown"}
|
||||
|
||||
return {"name": response["results"][0]["result"]["data"]["hostname"]}
|
||||
@@ -190,7 +196,7 @@ def get_mdns_name(device: OpenIrisDevice) -> dict:
|
||||
def get_serial_info(device: OpenIrisDevice) -> dict:
|
||||
response = device.send_command("get_serial")
|
||||
if has_command_failed(response):
|
||||
print(f"❌ Failed to get serial/MAC: {response['error']}")
|
||||
print(f"❌ Failed to get serial/MAC: {get_response_error(response)}")
|
||||
return {"serial": None, "mac": None}
|
||||
|
||||
return {
|
||||
@@ -203,7 +209,7 @@ def get_device_info(device: OpenIrisDevice) -> dict:
|
||||
response = device.send_command("get_who_am_i")
|
||||
|
||||
if has_command_failed(response):
|
||||
print(f"❌ Failed to get device info: {response['error']}")
|
||||
print(f"❌ Failed to get device info: {get_response_error(response)}")
|
||||
return {"who_am_i": None, "version": None}
|
||||
|
||||
return {
|
||||
@@ -215,7 +221,7 @@ def get_device_info(device: OpenIrisDevice) -> dict:
|
||||
def get_wifi_status(device: OpenIrisDevice) -> dict:
|
||||
response = device.send_command("get_wifi_status")
|
||||
if has_command_failed(response):
|
||||
print(f"❌ Failed to get wifi status: {response['error']}")
|
||||
print(f"❌ Failed to get wifi status: {get_response_error(response)}")
|
||||
return {"wifi_status": {"status": "unknown"}}
|
||||
|
||||
return {"wifi_status": response["results"][0]["result"]["data"]}
|
||||
@@ -267,7 +273,7 @@ def configure_device_name(device: OpenIrisDevice, *args, **kwargs):
|
||||
|
||||
response = device.send_command("set_mdns", {"hostname": name_choice})
|
||||
if "error" in response:
|
||||
print(f"❌ MDNS name setup failed: {response['error']}")
|
||||
print(f"❌ MDNS name setup failed: {get_response_error(response)}")
|
||||
return
|
||||
|
||||
print("✅ MDNS name set successfully")
|
||||
@@ -278,7 +284,7 @@ def start_streaming(device: OpenIrisDevice, *args, **kwargs):
|
||||
response = device.send_command("start_streaming")
|
||||
|
||||
if "error" in response:
|
||||
print(f"❌ Failed to start streaming: {response['error']}")
|
||||
print(f"❌ Failed to start streaming: {get_response_error(response)}")
|
||||
return
|
||||
|
||||
print("✅ Streaming mode started")
|
||||
@@ -336,7 +342,7 @@ def set_led_duty_cycle(device: OpenIrisDevice, *args, **kwargs):
|
||||
"set_led_duty_cycle", {"dutyCycle": duty_cycle}
|
||||
)
|
||||
if has_command_failed(response):
|
||||
print(f"❌ Failed to set LED duty cycle: {response['error']}")
|
||||
print(f"❌ Failed to set LED duty cycle: {get_response_error(response)}")
|
||||
return False
|
||||
|
||||
print("✅ LED duty cycle set successfully")
|
||||
@@ -400,7 +406,7 @@ def restart_device_command(device: OpenIrisDevice, *args, **kwargs):
|
||||
print("🔄 Restarting device...")
|
||||
response = device.send_command("restart_device")
|
||||
if has_command_failed(response):
|
||||
print(f"❌ Failed to restart device: {response['error']}")
|
||||
print(f"❌ Failed to restart device: {get_response_error(response)}")
|
||||
return
|
||||
|
||||
print("✅ Device restart command sent successfully")
|
||||
@@ -439,9 +445,9 @@ def display_networks(wifi_scanner: WiFiScanner, *args, **kwargs):
|
||||
return
|
||||
|
||||
print("\n📡 Available WiFi Networks:")
|
||||
print("-" * 85)
|
||||
print(f"{'#':<3} {'SSID':<32} {'Channel':<8} {'Signal':<20} {'Security':<15}")
|
||||
print("-" * 85)
|
||||
print("-" * 110)
|
||||
print(f"{'#':<3} {'SSID':<32} {'Channel':<8} {'Signal':<20} {'BSSID':<22} {'Security':<15}")
|
||||
print("-" * 110)
|
||||
|
||||
channels = {}
|
||||
for idx, network in enumerate(networks, 1):
|
||||
@@ -452,10 +458,10 @@ def display_networks(wifi_scanner: WiFiScanner, *args, **kwargs):
|
||||
ssid_display = network.ssid if network.ssid else "<hidden>"
|
||||
|
||||
print(
|
||||
f"{idx:<3} {ssid_display:<32} {network.channel:<8} {signal_str:<20} {network.security_type:<15}"
|
||||
f"{idx:<3} {ssid_display:<32} {network.channel:<8} {signal_str:<20} {network.bssid:<22} {network.security_type:<15}"
|
||||
)
|
||||
|
||||
print("-" * 85)
|
||||
print("-" * 110)
|
||||
|
||||
print("\n📊 Channel distribution: ", end="")
|
||||
for channel in sorted(channels.keys()):
|
||||
@@ -483,7 +489,7 @@ def configure_wifi(device: OpenIrisDevice, wifi_scanner: WiFiScanner, *args, **k
|
||||
|
||||
sorted_networks = wifi_scanner.get_networks()
|
||||
if 0 <= net_idx < len(sorted_networks):
|
||||
selected_network = sorted_networks[net_idx]
|
||||
selected_network = sorted_networks[net_idx]
|
||||
ssid = selected_network.ssid
|
||||
|
||||
print(f"\n🔐 Selected: {ssid}")
|
||||
@@ -502,6 +508,7 @@ def configure_wifi(device: OpenIrisDevice, wifi_scanner: WiFiScanner, *args, **k
|
||||
params = {
|
||||
"name": "main",
|
||||
"ssid": ssid,
|
||||
"bssid": selected_network.bssid,
|
||||
"password": password,
|
||||
"channel": 0,
|
||||
"power": 0,
|
||||
@@ -509,7 +516,7 @@ def configure_wifi(device: OpenIrisDevice, wifi_scanner: WiFiScanner, *args, **k
|
||||
|
||||
response = device.send_command("set_wifi", params)
|
||||
if has_command_failed(response):
|
||||
print(f"❌ WiFi setup failed: {response['error']}")
|
||||
print(f"❌ WiFi setup failed: {get_response_error(response)}")
|
||||
break
|
||||
|
||||
print("✅ WiFi configured successfully!")
|
||||
@@ -557,7 +564,7 @@ def attempt_wifi_connection(device: OpenIrisDevice, *args, **kwargs):
|
||||
print("🔗 Attempting WiFi connection...")
|
||||
response = device.send_command("connect_wifi")
|
||||
if has_command_failed(response):
|
||||
print(f"❌ WiFi connection failed: {response['error']}")
|
||||
print(f"❌ WiFi connection failed: {get_response_error(response)}")
|
||||
return
|
||||
|
||||
print("✅ WiFi connection attempt started")
|
||||
|
||||
Reference in New Issue
Block a user