Hotspot: no scanning if not required.
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
#include "Finally.hpp"
|
||||
#include "Lv2Log.hpp"
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
// enumerate alsa sequencer ports
|
||||
|
||||
@@ -96,6 +97,26 @@ namespace pipedal
|
||||
int queueId = -1; // Queue for real-time timestamps
|
||||
};
|
||||
|
||||
class AlsaSequencerDeviceMonitorImpl : public AlsaSequencerDeviceMonitor
|
||||
{
|
||||
|
||||
public:
|
||||
virtual ~AlsaSequencerDeviceMonitorImpl() override;
|
||||
|
||||
virtual void StartMonitoring(
|
||||
Callback &&onChangeCallback) override;
|
||||
virtual void StopMonitoring() override;
|
||||
|
||||
private:
|
||||
int CreateInputQueue(snd_seq_t *seqHandle, int inPort);
|
||||
|
||||
bool started = false;
|
||||
void ServiceProc();
|
||||
std::unique_ptr<std::jthread> serviceThread;
|
||||
std::atomic<bool> terminateThread{false};
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
};
|
||||
using namespace impl;
|
||||
|
||||
@@ -247,9 +268,10 @@ namespace pipedal
|
||||
size_t inputBufferSize = snd_seq_get_input_buffer_size(seqHandle);
|
||||
(void)inputBufferSize;
|
||||
|
||||
rc = snd_seq_set_input_buffer_size(seqHandle, 128*1024);
|
||||
if (rc < 0) {
|
||||
Lv2Log::warning("Failed resize the ALSA sequencer input buffer: %s",snd_strerror(rc));
|
||||
rc = snd_seq_set_input_buffer_size(seqHandle, 128 * 1024);
|
||||
if (rc < 0)
|
||||
{
|
||||
Lv2Log::warning("Failed resize the ALSA sequencer input buffer: %s", snd_strerror(rc));
|
||||
}
|
||||
snd_seq_set_client_name(seqHandle, "PiPedal");
|
||||
|
||||
@@ -584,12 +606,12 @@ namespace pipedal
|
||||
message.Set(0xF8); // MIDI Real Time Clock Tick
|
||||
break;
|
||||
#ifndef NDEBUG
|
||||
#define MSG_DEBUG_LOG(x) \
|
||||
case x:\
|
||||
Lv2Log::debug("ALSA Sequencer Message" #x);\
|
||||
break;
|
||||
#define MSG_DEBUG_LOG(x) \
|
||||
case x: \
|
||||
Lv2Log::debug("ALSA Sequencer Message" #x); \
|
||||
break;
|
||||
#else
|
||||
#define MSG_DEBUG_LOG(x)
|
||||
#define MSG_DEBUG_LOG(x)
|
||||
#endif
|
||||
MSG_DEBUG_LOG(SND_SEQ_EVENT_CLIENT_START)
|
||||
MSG_DEBUG_LOG(SND_SEQ_EVENT_CLIENT_EXIT)
|
||||
@@ -733,6 +755,7 @@ namespace pipedal
|
||||
Finally seq_finally([seq]()
|
||||
{ snd_seq_close(seq); });
|
||||
|
||||
|
||||
snd_seq_addr_t sender, dest;
|
||||
dest.client = myClientId;
|
||||
dest.port = 0;
|
||||
@@ -797,6 +820,208 @@ namespace pipedal
|
||||
}
|
||||
}
|
||||
|
||||
AlsaSequencerDeviceMonitor::ptr AlsaSequencerDeviceMonitor::Create()
|
||||
{
|
||||
return std::make_shared<AlsaSequencerDeviceMonitorImpl>();
|
||||
}
|
||||
|
||||
void AlsaSequencerDeviceMonitorImpl::StartMonitoring(
|
||||
Callback &&onChangeCallback)
|
||||
{
|
||||
started = true;
|
||||
this->callback = std::move(onChangeCallback);
|
||||
this->serviceThread = std::make_unique<std::jthread>(
|
||||
[this]()
|
||||
{
|
||||
ServiceProc();
|
||||
});
|
||||
}
|
||||
void AlsaSequencerDeviceMonitorImpl::ServiceProc()
|
||||
{
|
||||
int err;
|
||||
snd_seq_t *seqHandle;
|
||||
|
||||
err = snd_seq_open(&seqHandle, "default", SND_SEQ_OPEN_DUPLEX, 0);
|
||||
|
||||
Finally seq_finally(
|
||||
[seqHandle]()
|
||||
{
|
||||
snd_seq_close(seqHandle);
|
||||
});
|
||||
if (err < 0)
|
||||
{
|
||||
Lv2Log::error("Error opening ALSA Device Monitor sequencer: %s", snd_strerror(err));
|
||||
return;
|
||||
}
|
||||
snd_seq_set_client_name(seqHandle, "Device Monitor");
|
||||
|
||||
int inPort = snd_seq_create_simple_port(
|
||||
seqHandle, "PiPedal:portMonitor",
|
||||
SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
|
||||
SND_SEQ_PORT_TYPE_APPLICATION);
|
||||
if (inPort < 0)
|
||||
{
|
||||
Lv2Log::error("Error creating ALSA Device Monitor port: %s", snd_strerror(inPort));
|
||||
return;
|
||||
}
|
||||
Finally inPort_finaly {
|
||||
[seqHandle, inPort]()
|
||||
{
|
||||
snd_seq_delete_port(seqHandle, inPort);
|
||||
}
|
||||
};
|
||||
|
||||
// Set client name
|
||||
|
||||
int queueId = CreateInputQueue(seqHandle,inPort);
|
||||
if (queueId < 0)
|
||||
{
|
||||
Lv2Log::error("Error creating ALSA Device Monitor queue: %s", snd_strerror(queueId));
|
||||
return;
|
||||
}
|
||||
Finally queue_finally(
|
||||
[seqHandle, queueId]()
|
||||
{
|
||||
snd_seq_free_queue(seqHandle, queueId);
|
||||
});
|
||||
|
||||
// Subscribe to system announcements
|
||||
snd_seq_port_subscribe_t *subscription;
|
||||
snd_seq_port_subscribe_alloca(&subscription);
|
||||
snd_seq_addr_t sender, dest;
|
||||
|
||||
sender.client = SND_SEQ_CLIENT_SYSTEM;
|
||||
sender.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
|
||||
dest.client = snd_seq_client_id(seqHandle);
|
||||
dest.port = inPort;
|
||||
|
||||
snd_seq_port_subscribe_set_sender(subscription, &sender);
|
||||
snd_seq_port_subscribe_set_dest(subscription, &dest);
|
||||
err = snd_seq_subscribe_port(seqHandle, subscription);
|
||||
if (err < 0)
|
||||
{
|
||||
Lv2Log::error("Failed to subscribe to ALSA sequencer announcements: %s", snd_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// Create poll descriptors
|
||||
std::vector<struct pollfd> pollFds;
|
||||
|
||||
snd_seq_nonblock(seqHandle, 1); // Set sequencer to non-blocking mode
|
||||
while (!terminateThread)
|
||||
{
|
||||
int nPollFds = snd_seq_poll_descriptors_count(seqHandle, POLLIN);
|
||||
pollFds.resize(nPollFds);
|
||||
snd_seq_poll_descriptors(seqHandle, pollFds.data(), nPollFds, POLLIN);
|
||||
|
||||
// Poll for events
|
||||
if (poll(pollFds.data(), nPollFds, 100) > 0)
|
||||
{
|
||||
snd_seq_event_t *event;
|
||||
while (snd_seq_event_input(seqHandle, &event) > 0)
|
||||
{
|
||||
if (event->type == SND_SEQ_EVENT_CLIENT_START)
|
||||
{
|
||||
// Get the client name for logging/debugging
|
||||
snd_seq_client_info_t *client_info;
|
||||
snd_seq_client_info_alloca(&client_info);
|
||||
if (snd_seq_get_any_client_info(seqHandle, event->data.addr.client, client_info) >= 0) {
|
||||
std::string clientName = snd_seq_client_info_get_name(client_info);
|
||||
callback(MonitorAction::DeviceAdded, event->data.addr.client, clientName);
|
||||
}
|
||||
}
|
||||
else if (event->type == SND_SEQ_EVENT_CLIENT_EXIT)
|
||||
{
|
||||
callback(MonitorAction::DeviceRemoved, event->data.addr.client,"");
|
||||
}
|
||||
snd_seq_free_event(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void AlsaSequencerDeviceMonitorImpl::StopMonitoring()
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
started = false;
|
||||
terminateThread = true;
|
||||
serviceThread = nullptr; // (joins)
|
||||
}
|
||||
}
|
||||
|
||||
AlsaSequencerDeviceMonitorImpl::~AlsaSequencerDeviceMonitorImpl()
|
||||
{
|
||||
StopMonitoring();
|
||||
}
|
||||
|
||||
int AlsaSequencerDeviceMonitorImpl::CreateInputQueue(snd_seq_t *seqHandle, int inPort)
|
||||
{
|
||||
if (!seqHandle)
|
||||
{
|
||||
throw std::runtime_error("ALSA sequencer not initialized");
|
||||
}
|
||||
|
||||
// Create a new queue if we don't have one yet
|
||||
int queueId = -1;
|
||||
{
|
||||
queueId = snd_seq_alloc_named_queue(seqHandle, "PiPedal Device Monitor Queue");
|
||||
if (queueId < 0)
|
||||
{
|
||||
throw std::runtime_error(SS("Failed to create ALSA queue: " << snd_strerror(queueId)));
|
||||
}
|
||||
|
||||
// Set queue timing to real-time mode
|
||||
snd_seq_queue_tempo_t *tempo;
|
||||
snd_seq_queue_tempo_alloca(&tempo);
|
||||
snd_seq_queue_tempo_set_tempo(tempo, 120); // 120 BPM default
|
||||
snd_seq_queue_tempo_set_ppq(tempo, 96); // 96 ticks per quarter note
|
||||
|
||||
int rc = snd_seq_set_queue_tempo(seqHandle, queueId, tempo);
|
||||
if (rc < 0)
|
||||
{
|
||||
snd_seq_free_queue(seqHandle, queueId);
|
||||
throw std::runtime_error(SS("Failed to set queue tempo: " << snd_strerror(rc)));
|
||||
}
|
||||
|
||||
// Start the queue
|
||||
rc = snd_seq_start_queue(seqHandle, queueId, nullptr);
|
||||
if (rc < 0)
|
||||
{
|
||||
snd_seq_free_queue(seqHandle, queueId);
|
||||
throw std::runtime_error(SS("Failed to start queue: " << snd_strerror(rc)));
|
||||
}
|
||||
|
||||
// Set the queue for input timestamping
|
||||
snd_seq_port_info_t *port_info;
|
||||
snd_seq_port_info_alloca(&port_info);
|
||||
|
||||
rc = snd_seq_get_port_info(seqHandle, inPort, port_info);
|
||||
if (rc < 0)
|
||||
{
|
||||
snd_seq_free_queue(seqHandle, queueId);
|
||||
throw std::runtime_error(SS("Failed to get port info: " << snd_strerror(rc)));
|
||||
}
|
||||
|
||||
// Enable timestamping on the input port
|
||||
snd_seq_port_info_set_timestamping(port_info, 1);
|
||||
snd_seq_port_info_set_timestamp_real(port_info, 1);
|
||||
snd_seq_port_info_set_timestamp_queue(port_info, queueId);
|
||||
|
||||
rc = snd_seq_set_port_info(seqHandle, inPort, port_info);
|
||||
if (rc < 0)
|
||||
{
|
||||
snd_seq_free_queue(seqHandle, queueId);
|
||||
throw std::runtime_error(SS("Failed to set port timestamping: " << snd_strerror(rc)));
|
||||
}
|
||||
return queueId;
|
||||
}
|
||||
|
||||
return queueId;
|
||||
}
|
||||
|
||||
JSON_MAP_BEGIN(AlsaSequencerPortSelection)
|
||||
JSON_MAP_REFERENCE(AlsaSequencerPortSelection, id)
|
||||
JSON_MAP_REFERENCE(AlsaSequencerPortSelection, name)
|
||||
|
||||
@@ -89,7 +89,6 @@ bool WifiConfigSettings::ValidateCountryCode(const std::string &text)
|
||||
return std::isalpha(text[0]) && std::isalpha(text[1]);
|
||||
}
|
||||
|
||||
|
||||
void WifiConfigSettings::Load()
|
||||
{
|
||||
try
|
||||
@@ -115,9 +114,9 @@ void WifiConfigSettings::Load()
|
||||
}
|
||||
|
||||
static void openWithPerms(
|
||||
pipedal::ofstream_synced &f,
|
||||
const std::filesystem::path &path,
|
||||
std::filesystem::perms perms =
|
||||
pipedal::ofstream_synced &f,
|
||||
const std::filesystem::path &path,
|
||||
std::filesystem::perms perms =
|
||||
std::filesystem::perms::owner_read | std::filesystem::perms::owner_write |
|
||||
std::filesystem::perms::group_read | std::filesystem::perms::group_write)
|
||||
{
|
||||
@@ -132,13 +131,16 @@ static void openWithPerms(
|
||||
f.open(path);
|
||||
f.close();
|
||||
}
|
||||
try {
|
||||
try
|
||||
{
|
||||
// set the perms.
|
||||
std::filesystem::permissions(
|
||||
path,
|
||||
perms,
|
||||
std::filesystem::perm_options::replace);
|
||||
} catch (const std::exception&) {
|
||||
std::filesystem::perm_options::replace);
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
Lv2Log::warning(SS("Failed to set permissions on" << path << "."));
|
||||
}
|
||||
}
|
||||
@@ -147,10 +149,10 @@ static void openWithPerms(
|
||||
f.open(path);
|
||||
}
|
||||
|
||||
void WifiConfigSettings::Save()
|
||||
void WifiConfigSettings::Save()
|
||||
{
|
||||
WifiConfigSettings newSettings {*this};
|
||||
|
||||
WifiConfigSettings newSettings{*this};
|
||||
|
||||
// sync legacy settings, just in case i don't know what.
|
||||
newSettings.mdnsName_ = newSettings.hotspotName_;
|
||||
newSettings.enable_ = newSettings.IsEnabled();
|
||||
@@ -163,12 +165,12 @@ void WifiConfigSettings::Save()
|
||||
newSettings.password_ = oldSettings.password_;
|
||||
}
|
||||
newSettings.hasSavedPassword_ = newSettings.hasPassword_;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
ofstream_synced f;
|
||||
openWithPerms(f,CONFIG_PATH);
|
||||
json_writer writer(f,false);
|
||||
openWithPerms(f, CONFIG_PATH);
|
||||
json_writer writer(f, false);
|
||||
writer.write(&newSettings);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
@@ -300,17 +302,14 @@ namespace pipedal::priv
|
||||
connection["ipv4"]["method"] = sdbus::Variant(std::string("shared"));
|
||||
connection["ipv6"]["method"] = sdbus::Variant(std::string("ignore"));
|
||||
|
||||
|
||||
connection["ipv4"]["address-data"] = sdbus::Variant(std::vector<std::map<std::string, sdbus::Variant>>{{
|
||||
{"address", sdbus::Variant("192.168.4.1")},
|
||||
{"prefix", sdbus::Variant(uint32_t(24))}
|
||||
}});
|
||||
connection["ipv4"]["address-data"] = sdbus::Variant(std::vector<std::map<std::string, sdbus::Variant>>{{{"address", sdbus::Variant("192.168.4.1")},
|
||||
{"prefix", sdbus::Variant(uint32_t(24))}}});
|
||||
connection["ipv4"]["dhcp-send-hostname"] = sdbus::Variant(true);
|
||||
connection["ipv4"]["dhcp-hostname"] = sdbus::Variant("raspberrypi");
|
||||
connection["ipv4"]["dhcp-options"] = sdbus::Variant(std::vector<std::string>{
|
||||
"option:classless-static-route,192.168.4.0/24,0.0.0.0,0.0.0.0/0,192.168.4.1"
|
||||
//"option:classless-static-route,192.168.4.0/24,192.168.4.1"
|
||||
});
|
||||
});
|
||||
|
||||
auto connection_path = AddConnection(connection);
|
||||
return connection_path;
|
||||
@@ -326,7 +325,6 @@ namespace pipedal::priv
|
||||
return active_connection_path;
|
||||
}
|
||||
|
||||
|
||||
void RemoveConnection(const std::string &connection)
|
||||
{
|
||||
auto connection_proxy = sdbus::createProxy(
|
||||
@@ -429,7 +427,6 @@ namespace pipedal::priv
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
JSON_MAP_BEGIN(WifiConfigSettings)
|
||||
// v0
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings, valid)
|
||||
@@ -560,52 +557,51 @@ bool WifiConfigSettings::ValidateChannel(const std::string &countryCode, const s
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char* trueValues[] {
|
||||
static const char *trueValues[]{
|
||||
"true",
|
||||
"on",
|
||||
"yes"
|
||||
"1",
|
||||
nullptr
|
||||
};
|
||||
static const char* falseValues[] {
|
||||
nullptr};
|
||||
static const char *falseValues[]{
|
||||
"false",
|
||||
"off",
|
||||
"no",
|
||||
"0",
|
||||
nullptr
|
||||
};
|
||||
nullptr};
|
||||
|
||||
static bool Matches(const std::string&value, const char**matches)
|
||||
static bool Matches(const std::string &value, const char **matches)
|
||||
{
|
||||
while(*matches)
|
||||
while (*matches)
|
||||
{
|
||||
if (value == *matches) return true;
|
||||
if (value == *matches)
|
||||
return true;
|
||||
++matches;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool TryStringToBool(const std::string &value, bool*outputValue)
|
||||
static bool TryStringToBool(const std::string &value, bool *outputValue)
|
||||
{
|
||||
if (Matches(value,trueValues))
|
||||
if (Matches(value, trueValues))
|
||||
{
|
||||
*outputValue = true;
|
||||
return true;
|
||||
}
|
||||
if (Matches(value, falseValues)) {
|
||||
if (Matches(value, falseValues))
|
||||
{
|
||||
*outputValue = false;
|
||||
return true;
|
||||
}
|
||||
*outputValue = false;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
static WifiConfigSettings::ssid_t readSsid(std::istream&ss)
|
||||
static WifiConfigSettings::ssid_t readSsid(std::istream &ss)
|
||||
{
|
||||
using ssid_t = WifiConfigSettings::ssid_t;
|
||||
char c;
|
||||
|
||||
|
||||
ssid_t result;
|
||||
while (ss.peek() == ' ')
|
||||
{
|
||||
@@ -624,28 +620,33 @@ static WifiConfigSettings::ssid_t readSsid(std::istream&ss)
|
||||
break;
|
||||
}
|
||||
ss >> c;
|
||||
switch (c) {
|
||||
case 'n':
|
||||
result.push_back((uint8_t)'\n');
|
||||
break;
|
||||
case 'r':
|
||||
result.push_back((uint8_t)'\r');
|
||||
break;
|
||||
case 't':
|
||||
result.push_back((uint8_t)'\t');
|
||||
break;
|
||||
case 'b':
|
||||
result.push_back((uint8_t)'\b');
|
||||
break;
|
||||
default:
|
||||
result.push_back((uint8_t)c);
|
||||
break;
|
||||
switch (c)
|
||||
{
|
||||
case 'n':
|
||||
result.push_back((uint8_t)'\n');
|
||||
break;
|
||||
case 'r':
|
||||
result.push_back((uint8_t)'\r');
|
||||
break;
|
||||
case 't':
|
||||
result.push_back((uint8_t)'\t');
|
||||
break;
|
||||
case 'b':
|
||||
result.push_back((uint8_t)'\b');
|
||||
break;
|
||||
default:
|
||||
result.push_back((uint8_t)c);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back((uint8_t)c);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!ss.eof())
|
||||
{
|
||||
if (c == ':')
|
||||
@@ -662,7 +663,7 @@ static WifiConfigSettings::ssid_t readSsid(std::istream&ss)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static std::vector<WifiConfigSettings::ssid_t> stringToSsidArray(const std::string&value)
|
||||
static std::vector<WifiConfigSettings::ssid_t> stringToSsidArray(const std::string &value)
|
||||
{
|
||||
using ssid_t = WifiConfigSettings::ssid_t;
|
||||
std::istringstream ss(value);
|
||||
@@ -671,7 +672,7 @@ static std::vector<WifiConfigSettings::ssid_t> stringToSsidArray(const std::stri
|
||||
while (true)
|
||||
{
|
||||
ssid_t ssid = readSsid(ss);
|
||||
if (ssid.size() == 0)
|
||||
if (ssid.size() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -683,16 +684,15 @@ static std::vector<WifiConfigSettings::ssid_t> stringToSsidArray(const std::stri
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
void WifiConfigSettings::ParseArguments(
|
||||
const std::vector<std::string> &argv,
|
||||
HotspotAutoStartMode startMode,
|
||||
const std::string homeNetworkSsid
|
||||
|
||||
)
|
||||
)
|
||||
{
|
||||
this->valid_ = false ;
|
||||
this->valid_ = false;
|
||||
if (argv.size() != 4)
|
||||
{
|
||||
throw invalid_argument("Invalid number of arguments.");
|
||||
@@ -714,7 +714,6 @@ void WifiConfigSettings::ParseArguments(
|
||||
this->hasPassword_ = this->password_.length() != 0;
|
||||
this->hasSavedPassword_ = oldSettings.hasSavedPassword_;
|
||||
|
||||
|
||||
if (!ValidateCountryCode(this->countryCode_))
|
||||
{
|
||||
throw invalid_argument("Invalid country code.");
|
||||
@@ -723,7 +722,7 @@ void WifiConfigSettings::ParseArguments(
|
||||
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.");
|
||||
|
||||
@@ -742,12 +741,12 @@ void WifiConfigSettings::ParseArguments(
|
||||
this->valid_ = true;
|
||||
}
|
||||
|
||||
bool WifiConfigSettings::ConfigurationChanged(const WifiConfigSettings&other) const
|
||||
bool WifiConfigSettings::ConfigurationChanged(const WifiConfigSettings &other) const
|
||||
{
|
||||
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->hotspotName_ == other.hotspotName_ &&
|
||||
this->hasPassword_ == other.hasPassword_ &&
|
||||
@@ -756,20 +755,18 @@ bool WifiConfigSettings::ConfigurationChanged(const WifiConfigSettings&other) co
|
||||
|
||||
this->homeNetwork_ == other.homeNetwork_ &&
|
||||
this->autoStartMode_ == other.autoStartMode_ &&
|
||||
this->hasSavedPassword_ == other.hasSavedPassword_
|
||||
);
|
||||
|
||||
this->hasSavedPassword_ == other.hasSavedPassword_);
|
||||
}
|
||||
bool WifiConfigSettings::operator==(const WifiConfigSettings&other) const
|
||||
bool WifiConfigSettings::operator==(const WifiConfigSettings &other) const
|
||||
{
|
||||
return !ConfigurationChanged(other) && this->wifiWarningGiven_ == other.wifiWarningGiven_;
|
||||
}
|
||||
|
||||
static bool CanSeeHomeNetwork(const std::string&home, const std::vector<std::string>&availableNetworks)
|
||||
static bool CanSeeHomeNetwork(const std::string &home, const std::vector<std::string> &availableNetworks)
|
||||
{
|
||||
for (const auto &availableNetwork: availableNetworks)
|
||||
for (const auto &availableNetwork : availableNetworks)
|
||||
{
|
||||
if (availableNetwork == home)
|
||||
if (availableNetwork == home)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -778,38 +775,39 @@ static bool CanSeeHomeNetwork(const std::string&home, const std::vector<std::str
|
||||
}
|
||||
|
||||
bool WifiConfigSettings::WantsHotspot(
|
||||
bool ethernetConnected,
|
||||
bool ethernetConnected,
|
||||
const std::vector<std::string> &availableRememberedNetworks,
|
||||
const std::vector<std::string> &availableNetworks)
|
||||
{
|
||||
if ((!this->valid_))
|
||||
if ((!this->valid_))
|
||||
return false;
|
||||
|
||||
|
||||
HotspotAutoStartMode autoStartMode = (HotspotAutoStartMode)this->autoStartMode_;
|
||||
|
||||
switch (autoStartMode)
|
||||
{
|
||||
case HotspotAutoStartMode::Never:
|
||||
default:
|
||||
return false;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
std::string pipedal::ssidToString(const std::vector<uint8_t> &ssid)
|
||||
{
|
||||
std::stringstream s;
|
||||
for (auto v: ssid)
|
||||
for (auto v : ssid)
|
||||
{
|
||||
if (v == 0) break; // breaks for some arguably legal ssids, but I can live with that.
|
||||
if (v == 0)
|
||||
break; // breaks for some arguably legal ssids, but I can live with that.
|
||||
s << (char)v;
|
||||
}
|
||||
return s.str();
|
||||
@@ -819,21 +817,43 @@ std::vector<std::string> pipedal::ssidToStringVector(const std::vector<std::vect
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
result.reserve(ssids.size());
|
||||
for (const std::vector<uint8_t> &ssid: ssids)
|
||||
for (const std::vector<uint8_t> &ssid : ssids)
|
||||
{
|
||||
result.push_back(ssidToString(ssid));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool WifiConfigSettings::WantsHotspot(
|
||||
bool ethernetConnected,
|
||||
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.
|
||||
)
|
||||
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);
|
||||
return WantsHotspot(ethernetConnected, sAvailableRememberedNetworks, sAvailableNetworks);
|
||||
}
|
||||
|
||||
bool WifiConfigSettings::NeedsWifi() const
|
||||
{
|
||||
HotspotAutoStartMode autoStartMode = (HotspotAutoStartMode)this->autoStartMode_;
|
||||
return autoStartMode != HotspotAutoStartMode::Never;
|
||||
}
|
||||
|
||||
|
||||
bool WifiConfigSettings::NeedsScan() const
|
||||
{
|
||||
HotspotAutoStartMode autoStartMode = (HotspotAutoStartMode)this->autoStartMode_;
|
||||
switch (autoStartMode)
|
||||
{
|
||||
case HotspotAutoStartMode::Never:
|
||||
case HotspotAutoStartMode::NoEthernetConnection:
|
||||
case HotspotAutoStartMode::Always:
|
||||
default:
|
||||
return false;
|
||||
|
||||
case HotspotAutoStartMode::NotAtHome:
|
||||
case HotspotAutoStartMode::NoRememberedWifiConections:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include "json.hpp"
|
||||
|
||||
namespace pipedal
|
||||
@@ -331,6 +332,26 @@ namespace pipedal
|
||||
virtual void RemoveAllConnections() = 0;
|
||||
};
|
||||
|
||||
|
||||
class AlsaSequencerDeviceMonitor {
|
||||
protected:
|
||||
AlsaSequencerDeviceMonitor() {}
|
||||
public:
|
||||
virtual ~AlsaSequencerDeviceMonitor() {}
|
||||
|
||||
using self = AlsaSequencerDeviceMonitor;
|
||||
using ptr = std::shared_ptr<self>;
|
||||
static ptr Create();
|
||||
enum class MonitorAction {
|
||||
DeviceAdded,
|
||||
DeviceRemoved
|
||||
};
|
||||
using Callback = std::function<void(MonitorAction action, int client, const std::string& clientName)>;
|
||||
virtual void StartMonitoring(Callback &&onChangeCallback) = 0;
|
||||
virtual void StopMonitoring() = 0;
|
||||
|
||||
};
|
||||
|
||||
std::string RawMidiIdToSequencerId(const std::vector<AlsaSequencerPort> &seqDevices, const std::string &rawMidiId);
|
||||
|
||||
}
|
||||
@@ -95,6 +95,10 @@ namespace pipedal {
|
||||
|
||||
bool operator==(const WifiConfigSettings&other) const;
|
||||
bool ConfigurationChanged(const WifiConfigSettings&other) const;
|
||||
bool WantsHotspot(bool ethernetConnected)
|
||||
{
|
||||
return WantsHotspot(ethernetConnected, std::vector<std::string>{}, std::vector<std::string>{});
|
||||
}
|
||||
bool WantsHotspot(
|
||||
bool ethernetConnected,
|
||||
const std::vector<std::string> &availableRememberedNetworks, // remembered networks that are currently visible
|
||||
@@ -105,7 +109,8 @@ namespace pipedal {
|
||||
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.
|
||||
);
|
||||
|
||||
bool NeedsScan() const;
|
||||
bool NeedsWifi() const;
|
||||
public:
|
||||
DECLARE_JSON_MAP(WifiConfigSettings);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user