Wi-Fi Hotspot UI
This commit is contained in:
@@ -116,12 +116,6 @@ public:
|
||||
|
||||
static std::vector<std::unique_ptr<IDBusLogger>> loggers;
|
||||
|
||||
void SetDBusLogger(std::unique_ptr<IDBusLogger> && logger)
|
||||
{
|
||||
loggers.clear();
|
||||
loggers.push_back(std::move(logger));
|
||||
}
|
||||
|
||||
|
||||
void SetDBusLogLevel(DBusLogLevel level)
|
||||
{
|
||||
@@ -231,11 +225,17 @@ void LogTrace(const std::string&path,const char*method,const std::string&message
|
||||
}
|
||||
}
|
||||
|
||||
void SetDBusLogger(std::unique_ptr<IDBusLogger> && logger)
|
||||
{
|
||||
loggers.clear();
|
||||
loggers.push_back(std::move(logger));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SetDBusConsoleLogger()
|
||||
{
|
||||
loggers.clear();
|
||||
loggers.push_back(std::make_unique<ConsoleDBusLogger>());
|
||||
SetDBusLogger(std::make_unique<ConsoleDBusLogger>());
|
||||
}
|
||||
void AddDBusConsoleLogger()
|
||||
{
|
||||
@@ -243,13 +243,11 @@ void AddDBusConsoleLogger()
|
||||
}
|
||||
void SetDBusSystemdLogger()
|
||||
{
|
||||
loggers.clear();
|
||||
loggers.push_back(std::make_unique<SystemdDBusLogger>());
|
||||
SetDBusLogger(std::make_unique<SystemdDBusLogger>());
|
||||
|
||||
}
|
||||
void SetDBusFileLogger(const std::filesystem::path &path)
|
||||
{
|
||||
loggers.clear();
|
||||
loggers.push_back(std::make_unique<FileDBusLogger>(path));
|
||||
SetDBusLogger(std::make_unique<FileDBusLogger>(path));
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,8 @@ void WifiConfigSettings::Load()
|
||||
reader.read(this);
|
||||
}
|
||||
this->countryCode_ = getWifiCountryCode();
|
||||
this->enable_ = this->autoStartMode_ != (uint16_t)HotspotAutoStartMode::Never;
|
||||
this->mdnsName_ = this->hotspotName_;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
@@ -143,12 +145,27 @@ static void openWithPerms(
|
||||
|
||||
void WifiConfigSettings::Save()
|
||||
{
|
||||
WifiConfigSettings newSettings {*this};
|
||||
|
||||
// sync legacy settings, just in case i don't know what.
|
||||
newSettings.mdnsName_ = newSettings.hotspotName_;
|
||||
newSettings.enable_ = newSettings.IsEnabled();
|
||||
// fill in the password, if required.
|
||||
if (!newSettings.hasPassword_)
|
||||
{
|
||||
WifiConfigSettings oldSettings;
|
||||
oldSettings.Load();
|
||||
newSettings.hasPassword_ = oldSettings.hasPassword_;
|
||||
newSettings.password_ = oldSettings.password_;
|
||||
}
|
||||
newSettings.hasSavedPassword_ = newSettings.hasPassword_;
|
||||
|
||||
try
|
||||
{
|
||||
ofstream_synced f;
|
||||
openWithPerms(f,CONFIG_PATH);
|
||||
json_writer writer(f);
|
||||
writer.write(this);
|
||||
writer.write(&newSettings);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
@@ -398,6 +415,7 @@ namespace pipedal::priv
|
||||
|
||||
|
||||
JSON_MAP_BEGIN(WifiConfigSettings)
|
||||
// v0
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, valid)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, wifiWarningGiven)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, rebootRequired)
|
||||
@@ -408,8 +426,13 @@ JSON_MAP_REFERENCE(WifiConfigSettings, hasPassword)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, password)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, countryCode)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, channel)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, alwaysOn)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, homeNetworks)
|
||||
|
||||
// v1: Auto-hotspot
|
||||
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, autoStartMode)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, homeNetwork)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, hasSavedPassword)
|
||||
|
||||
JSON_MAP_END()
|
||||
|
||||
int32_t pipedal::ChannelToChannelNumber(const std::string &channel)
|
||||
@@ -646,22 +669,33 @@ static std::vector<WifiConfigSettings::ssid_t> stringToSsidArray(const std::stri
|
||||
return result;
|
||||
|
||||
}
|
||||
void WifiConfigSettings::ParseArguments(const std::vector<std::string> &argv)
|
||||
void WifiConfigSettings::ParseArguments(
|
||||
const std::vector<std::string> &argv,
|
||||
HotspotAutoStartMode startMode,
|
||||
const std::string homeNetworkSsid
|
||||
|
||||
)
|
||||
{
|
||||
this->valid_ = false;
|
||||
if (argv.size() < 4 || argv.size() > 6)
|
||||
if (argv.size() != 4)
|
||||
{
|
||||
throw invalid_argument("Invalid number of arguments.");
|
||||
}
|
||||
this->enable_ = true;
|
||||
WifiConfigSettings oldSettings;
|
||||
oldSettings.Load();
|
||||
this->valid_ = false;
|
||||
|
||||
this->autoStartMode_ = (int16_t)startMode;
|
||||
this->enable_ = startMode != HotspotAutoStartMode::Never;
|
||||
this->homeNetwork_ = homeNetworkSsid;
|
||||
|
||||
this->countryCode_ = argv[0];
|
||||
this->hotspotName_ = argv[1];
|
||||
this->mdnsName_ = this->hotspotName_;
|
||||
this->password_ = argv[2];
|
||||
this->channel_ = argv[3];
|
||||
this->hasPassword_ = this->password_.length() != 0;
|
||||
this->homeNetworks_ = std::vector<ssid_t>();
|
||||
this->alwaysOn_ = false;
|
||||
this->hasSavedPassword_ = oldSettings.hasSavedPassword_;
|
||||
|
||||
|
||||
if (!ValidateCountryCode(this->countryCode_))
|
||||
@@ -672,26 +706,20 @@ void WifiConfigSettings::ParseArguments(const std::vector<std::string> &argv)
|
||||
throw invalid_argument("Hotspot name is too long.");
|
||||
if (this->hotspotName_.length() < 1)
|
||||
throw invalid_argument("Hotspot name is too short.");
|
||||
|
||||
if (this->password_.size() != 0 && this->password_.size() < 8)
|
||||
throw invalid_argument("Passphrase must be at least 8 characters long.");
|
||||
|
||||
if (this->password_.size() == 0 && !this->hasSavedPassword_)
|
||||
{
|
||||
throw invalid_argument("Passphrase required.");
|
||||
}
|
||||
|
||||
if (!ValidateChannel(this->countryCode_, this->channel_))
|
||||
{
|
||||
throw invalid_argument("Channel is not valid.");
|
||||
}
|
||||
|
||||
if (argv.size() >= 5)
|
||||
{
|
||||
if (!TryStringToBool(argv[4],&this->alwaysOn_))
|
||||
{
|
||||
throw std::runtime_error(SS("Invalid boolean value: " << argv[4]));
|
||||
}
|
||||
}
|
||||
if (argv.size() >= 6)
|
||||
{
|
||||
this->homeNetworks_ = stringToSsidArray(argv[5]);
|
||||
}
|
||||
|
||||
// validate that the channel number is supported for the given country code.
|
||||
|
||||
this->valid_ = true;
|
||||
@@ -701,15 +729,17 @@ bool WifiConfigSettings::ConfigurationChanged(const WifiConfigSettings&other) co
|
||||
{
|
||||
return !(
|
||||
this->valid_ == other.valid_ &&
|
||||
this->rebootRequired_ == other.rebootRequired_ &&
|
||||
this->enable_ == other.enable_ &&
|
||||
//this->rebootRequired_ == other.rebootRequired_ &&
|
||||
//this->enable_ == other.enable_ &&
|
||||
this->countryCode_ == other.countryCode_ &&
|
||||
this->mdnsName_ == other.mdnsName_ &&
|
||||
this->hotspotName_ == other.hotspotName_ &&
|
||||
this->hasPassword_ == other.hasPassword_ &&
|
||||
this->password_ == other.password_ &&
|
||||
this->channel_ == other.channel_ &&
|
||||
this->homeNetworks_ == other.homeNetworks_ &&
|
||||
this->alwaysOn_ == other.alwaysOn_
|
||||
|
||||
this->homeNetwork_ == other.homeNetwork_ &&
|
||||
this->autoStartMode_ == other.autoStartMode_ &&
|
||||
this->hasSavedPassword_ == other.hasSavedPassword_
|
||||
);
|
||||
|
||||
}
|
||||
@@ -718,33 +748,75 @@ bool WifiConfigSettings::operator==(const WifiConfigSettings&other) const
|
||||
return !ConfigurationChanged(other) && this->wifiWarningGiven_ == other.wifiWarningGiven_;
|
||||
}
|
||||
|
||||
|
||||
bool WifiConfigSettings::WantsHotspot(bool ethernetConnected, const std::vector<ssid_t> &availableNetworks)
|
||||
static bool CanSeeHomeNetwork(const std::string&home, const std::vector<std::string>&availableNetworks)
|
||||
{
|
||||
if ((!this->valid_) || (!this->enable_))
|
||||
return false;
|
||||
if (ethernetConnected)
|
||||
for (const auto &availableNetwork: availableNetworks)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!homeNetworks_.empty())
|
||||
{
|
||||
for (auto &network: availableNetworks)
|
||||
if (availableNetwork == home)
|
||||
{
|
||||
for (auto&homeNetwork: homeNetworks_)
|
||||
{
|
||||
if (network == homeNetwork)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (alwaysOn_)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WifiConfigSettings::WantsHotspot(
|
||||
bool ethernetConnected,
|
||||
const std::vector<std::string> &availableRememberedNetworks,
|
||||
const std::vector<std::string> &availableNetworks)
|
||||
{
|
||||
if ((!this->valid_))
|
||||
return false;
|
||||
|
||||
HotspotAutoStartMode autoStartMode = (HotspotAutoStartMode)this->autoStartMode_;
|
||||
|
||||
switch (autoStartMode)
|
||||
{
|
||||
return true;
|
||||
case HotspotAutoStartMode::Never:
|
||||
default:
|
||||
return false;
|
||||
|
||||
case HotspotAutoStartMode::NoEthernetConnection:
|
||||
return !ethernetConnected;
|
||||
case HotspotAutoStartMode::NotAtHome:
|
||||
return !CanSeeHomeNetwork(this->homeNetwork_, availableNetworks);
|
||||
case HotspotAutoStartMode::NoRememberedWifiConections:
|
||||
return availableRememberedNetworks.size() == 0;
|
||||
case HotspotAutoStartMode::Always:
|
||||
return true;
|
||||
}
|
||||
return availableNetworks.size() == 0;
|
||||
}
|
||||
|
||||
std::string pipedal::ssidToString(const std::vector<uint8_t> &ssid)
|
||||
{
|
||||
std::stringstream s;
|
||||
for (auto v: ssid)
|
||||
{
|
||||
if (v == 0) break; // breaks for some arguably legal ssids, but I can live with that.
|
||||
s << (char)v;
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
std::vector<std::string> pipedal::ssidToStringVector(const std::vector<std::vector<uint8_t>> &ssids)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
result.reserve(ssids.size());
|
||||
for (const std::vector<uint8_t> &ssid: ssids)
|
||||
{
|
||||
result.push_back(ssidToString(ssid));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool WifiConfigSettings::WantsHotspot(
|
||||
bool ethernetConnected,
|
||||
const std::vector<std::vector<uint8_t>> &availableRememberedNetworks, // remembered networks that are currently visible
|
||||
const std::vector<std::vector<uint8_t>> &availableNetworks // all visible networks.
|
||||
)
|
||||
{
|
||||
std::vector<std::string> sAvailableRememberedNetworks = ssidToStringVector(availableRememberedNetworks);
|
||||
std::vector<std::string> sAvailableNetworks = ssidToStringVector(availableNetworks);
|
||||
return WantsHotspot(ethernetConnected,sAvailableRememberedNetworks,sAvailableNetworks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "json.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
#ifndef NEW_WIFI_CONFIG
|
||||
@@ -39,12 +41,23 @@
|
||||
#endif
|
||||
|
||||
namespace pipedal {
|
||||
std::string ssidToString(const std::vector<uint8_t> &ssid);
|
||||
std::vector<std::string> ssidToStringVector(const std::vector<std::vector<uint8_t>> &ssids);
|
||||
|
||||
|
||||
uint32_t ChannelToWifiFrequency(const std::string &channel);
|
||||
uint32_t ChannelToWifiFrequency(uint32_t channel);
|
||||
int32_t ChannelToChannelNumber(const std::string&channel);
|
||||
|
||||
|
||||
enum class HotspotAutoStartMode {
|
||||
// saved to file. Do not remove or renumber enums.
|
||||
Never = 0,
|
||||
NoEthernetConnection = 1,
|
||||
NotAtHome = 2,
|
||||
NoRememberedWifiConections = 3,
|
||||
Always = 4
|
||||
};
|
||||
class WifiConfigSettings {
|
||||
public:
|
||||
using ssid_t = std::vector<uint8_t>;
|
||||
@@ -53,26 +66,45 @@ namespace pipedal {
|
||||
void Load();
|
||||
void Save();
|
||||
|
||||
bool valid_ = false;
|
||||
bool wifiWarningGiven_ = false;
|
||||
bool rebootRequired_ = false;
|
||||
bool enable_ = false;
|
||||
int16_t autoStartMode_ = 0; // see HotspotAutoStartMode
|
||||
bool hasSavedPassword_ = false;
|
||||
std::string homeNetwork_;
|
||||
|
||||
std::string countryCode_ = "US"; // iso 3661
|
||||
std::string hotspotName_ = "pipedal";
|
||||
std::string mdnsName_ = "pipedal";
|
||||
std::vector<ssid_t> homeNetworks_;
|
||||
bool hasPassword_ = false;
|
||||
std::string password_;
|
||||
std::string channel_ = "";
|
||||
bool alwaysOn_ = false;
|
||||
|
||||
void ParseArguments(const std::vector<std::string> &arguments);
|
||||
bool wifiWarningGiven_ = false; // Do not use. Present only for backward compatibility.
|
||||
bool valid_ = false; // Do not use. Present only for backward compatibility.
|
||||
private:
|
||||
bool rebootRequired_ = false; // Do not use. Present only for backward compatibility.
|
||||
std::string mdnsName_ = "pipedal";
|
||||
bool enable_ = false; // Do not use. Present only for backward compatibility.
|
||||
public:
|
||||
bool IsEnabled() const { return autoStartMode_ != 0; }
|
||||
// Initialize from commandline arguments (see ConfigMain.cpp)
|
||||
void ParseArguments(
|
||||
const std::vector<std::string> &argv,
|
||||
HotspotAutoStartMode startMode,
|
||||
const std::string homeNetworkSsid
|
||||
);
|
||||
static bool ValidateCountryCode(const std::string&value);
|
||||
static bool ValidateChannel(const std::string&countryCode,const std::string&value);
|
||||
|
||||
bool operator==(const WifiConfigSettings&other) const;
|
||||
bool ConfigurationChanged(const WifiConfigSettings&other) const;
|
||||
bool WantsHotspot(bool ethernetConnected,const std::vector<ssid_t> &availableNetworks);
|
||||
bool WantsHotspot(
|
||||
bool ethernetConnected,
|
||||
const std::vector<std::string> &availableRememberedNetworks, // remembered networks that are currently visible
|
||||
const std::vector<std::string> &availableNetworks // all visible networks.
|
||||
);
|
||||
bool WantsHotspot(
|
||||
bool ethernetConnected,
|
||||
const std::vector<std::vector<uint8_t>> &availableRememberedNetworks, // remembered networks that are currently visible
|
||||
const std::vector<std::vector<uint8_t>> &availableNetworks // all visible networks.
|
||||
);
|
||||
|
||||
public:
|
||||
DECLARE_JSON_MAP(WifiConfigSettings);
|
||||
|
||||
@@ -335,6 +335,14 @@ namespace pipedal
|
||||
{
|
||||
os << value;
|
||||
}
|
||||
void write(short value)
|
||||
{
|
||||
os << value;
|
||||
}
|
||||
void write(unsigned short value)
|
||||
{
|
||||
os << value;
|
||||
}
|
||||
void write(long long value)
|
||||
{
|
||||
os << value;
|
||||
@@ -897,6 +905,22 @@ namespace pipedal
|
||||
if (is_.fail())
|
||||
throw JsonException("Invalid format.");
|
||||
}
|
||||
void read(short * value)
|
||||
{
|
||||
skip_whitespace();
|
||||
is_ >> *value;
|
||||
if (is_.fail())
|
||||
throw JsonException("Invalid format.");
|
||||
}
|
||||
|
||||
void read(unsigned short * value)
|
||||
{
|
||||
skip_whitespace();
|
||||
is_ >> *value;
|
||||
if (is_.fail())
|
||||
throw JsonException("Invalid format.");
|
||||
}
|
||||
|
||||
void read(int *value)
|
||||
{
|
||||
skip_whitespace();
|
||||
|
||||
Reference in New Issue
Block a user