Skip to content

Commit

Permalink
wifi: allow to set bssid and channel from settings
Browse files Browse the repository at this point in the history
For when scanning is disabled. Remove uniqueness requirement, since
settings may contain multiple SSID with different BSSID values.

wifi::Mac conversion helpers for both xxxxxxxxxx and xx:xx:xx:xx:xx:xx
  • Loading branch information
mcspr committed Aug 6, 2021
1 parent 4be2d37 commit c5f7028
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 13 deletions.
40 changes: 40 additions & 0 deletions code/espurna/config/general.h
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,14 @@
#define WIFI1_DNS ""
#endif

#ifndef WIFI1_BSSID
#define WIFI1_BSSID ""
#endif

#ifndef WIFI1_CHANNEL
#define WIFI1_CHANNEL 0
#endif

#ifndef WIFI2_SSID
#define WIFI2_SSID ""
#endif
Expand All @@ -664,6 +672,14 @@
#define WIFI2_DNS ""
#endif

#ifndef WIFI2_BSSID
#define WIFI2_BSSID ""
#endif

#ifndef WIFI2_CHANNEL
#define WIFI2_CHANNEL 0
#endif

#ifndef WIFI3_SSID
#define WIFI3_SSID ""
#endif
Expand All @@ -688,6 +704,14 @@
#define WIFI3_DNS ""
#endif

#ifndef WIFI3_BSSID
#define WIFI3_BSSID ""
#endif

#ifndef WIFI3_CHANNEL
#define WIFI3_CHANNEL 0
#endif

#ifndef WIFI4_SSID
#define WIFI4_SSID ""
#endif
Expand All @@ -712,6 +736,14 @@
#define WIFI4_DNS ""
#endif

#ifndef WIFI4_BSSID
#define WIFI4_BSSID ""
#endif

#ifndef WIFI4_CHANNEL
#define WIFI4_CHANNEL 0
#endif

#ifndef WIFI5_SSID
#define WIFI5_SSID ""
#endif
Expand All @@ -736,6 +768,14 @@
#define WIFI5_DNS ""
#endif

#ifndef WIFI5_BSSID
#define WIFI5_BSSID ""
#endif

#ifndef WIFI5_CHANNEL
#define WIFI5_CHANNEL 0
#endif

// ref: https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html#config-lwip-esp-gratuitous-arp
// ref: https://github.com/xoseperez/espurna/pull/1877#issuecomment-525612546
//
Expand Down
88 changes: 75 additions & 13 deletions code/espurna/wifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ extern "C" void netif_set_addr(netif* netif, ip4_addr_t*, ip4_addr_t*, ip4_addr_

namespace wifi {
namespace {

using Mac = std::array<uint8_t, 6>;

namespace build {

constexpr size_t NetworksMax { WIFI_MAX_NETWORKS };
Expand Down Expand Up @@ -211,6 +214,26 @@ const __FlashStringHelper* dns(size_t index) {
);
}

const __FlashStringHelper* bssid(size_t index) {
return (
(index == 0) ? F(WIFI1_BSSID) :
(index == 1) ? F(WIFI2_BSSID) :
(index == 2) ? F(WIFI3_BSSID) :
(index == 3) ? F(WIFI4_BSSID) :
(index == 4) ? F(WIFI5_BSSID) : nullptr
);
}

constexpr uint8_t channel(size_t index) {
return (
(index == 0) ? WIFI1_CHANNEL :
(index == 1) ? WIFI2_CHANNEL :
(index == 2) ? WIFI3_CHANNEL :
(index == 3) ? WIFI4_CHANNEL :
(index == 4) ? WIFI5_CHANNEL : 0
);
}

} // namespace build
} // namespace
} // namespace wifi
Expand Down Expand Up @@ -260,6 +283,36 @@ IPAddress convert(const String& value) {
return out;
}

template <>
wifi::Mac convert(const String& value) {
wifi::Mac out { 0u, 0u, 0u, 0u, 0u, 0u };

switch (value.length()) {
// xxxxxxxxxx
case 12:
hexDecode(value.c_str(), value.length(), out.data(), out.size());
break;

// xx:xx:xx:xx:xx:xx
case 17: {
String buffer;
buffer.reserve(value.length());

for (auto it = value.begin(); it != value.end(); ++it) {
if ((*it) != ':') {
buffer += *it;
}
}

hexDecode(buffer.c_str(), buffer.length(), out.data(), out.size());
break;
}

}

return out;
}

// XXX: "(IP unset)" when not set, no point saving these :/
// XXX: both 0.0.0.0 and 255.255.255.255 will be saved as empty string

Expand All @@ -281,9 +334,6 @@ constexpr uint8_t OpmodeSta { STATION_MODE };
constexpr uint8_t OpmodeAp { SOFTAP_MODE };
constexpr uint8_t OpmodeApSta { OpmodeSta | OpmodeAp };

using Mac = std::array<uint8_t, 6>;
using Macs = std::vector<Mac>;

enum class ScanError {
None,
AlreadyScanning,
Expand Down Expand Up @@ -586,6 +636,15 @@ IPAddress staDns(size_t index) {
getSetting({"dns", index}, wifi::build::dns(index)));
}

wifi::Mac staBssid(size_t index) {
return ::settings::internal::convert<wifi::Mac>(
getSetting({"bssid", index}, wifi::build::bssid(index)));
}

int8_t staChannel(size_t index) {
return getSetting({"chan", index}, wifi::build::channel(index));
}

bool softApCaptive() {
return getSetting("wifiApCaptive", wifi::build::softApCaptive());
}
Expand All @@ -610,7 +669,7 @@ String softApPassphrase() {
: getAdminPass());
}

int8_t softApChannel() {
uint8_t softApChannel() {
return getSetting("wifiApChannel", wifi::build::softApChannel());
}

Expand Down Expand Up @@ -1827,20 +1886,21 @@ wifi::Networks networks() {
}

auto pass = wifi::settings::staPassphrase(id);

auto ip = staIp(id);
if (ip.isSet()) {
out.emplace_back(std::move(ssid), std::move(pass),
wifi::IpSettings{std::move(ip), staMask(id), staGateway(id), staDns(id)});
auto ipSettings = ip.isSet()
? wifi::IpSettings{std::move(ip), staMask(id), staGateway(id), staDns(id)}
: wifi::IpSettings{};

Network network(std::move(ssid), staPassphrase(id), std::move(ipSettings));
auto channel = staChannel(id);
if (channel) {
out.emplace_back(std::move(network), staBssid(id), channel);
} else {
out.emplace_back(std::move(ssid), std::move(pass));
out.push_back(std::move(network));
}
}

auto duplicates = std::unique(out.begin(), out.end(), [](const wifi::Network& lhs, const wifi::Network& rhs) {
return lhs.ssid() == rhs.ssid();
});
out.erase(duplicates, out.end());

return out;
}

Expand Down Expand Up @@ -2036,6 +2096,8 @@ bool onKeyCheck(const char * key, JsonVariant& value) {
if (strncmp(key, "gw", 2) == 0) return true;
if (strncmp(key, "mask", 4) == 0) return true;
if (strncmp(key, "dns", 3) == 0) return true;
if (strncmp(key, "bssid", 5) == 0) return true;
if (strncmp(key, "chan", 4) == 0) return true;
return false;
}

Expand Down

0 comments on commit c5f7028

Please sign in to comment.