Use DBUS to detect presence of Wi-Fi devices.

This commit is contained in:
Robin E. R. Davies
2024-11-20 14:50:05 -05:00
parent ca87658f90
commit 0dfe7b8080
8 changed files with 316 additions and 313 deletions
+114 -212
View File
@@ -56,6 +56,18 @@ export enum State {
HotspotChanging,
};
function getErrorMessage(error: any)
{
if (error instanceof Error)
{
return (error as Error).message;
}
if (!error)
{
return "";
}
return error.toString();
}
class UpdatedError extends Error {
};
export function wantsReloadingScreen(state: State) {
@@ -742,6 +754,10 @@ export class PiPedalModel //implements PiPedalModel
} else if (message === "onNetworkChanging") {
this.onNetworkChanging(body as boolean);
}
else if (message === "onHasWifiChanged") {
let hasWifi = body as boolean;
this.hasWifiDevice.set(hasWifi);
}
}
@@ -912,7 +928,7 @@ export class PiPedalModel //implements PiPedalModel
}
}
}
onSocketReconnected() {
async onSocketReconnected(): Promise<void> {
this.cancelOnNetworkChanging();
this.cancelAndroidReconnectTimer();
@@ -920,97 +936,20 @@ export class PiPedalModel //implements PiPedalModel
this.androidHost?.setDisconnected(false);
}
this.expectDisconnect(ReconnectReason.Disconnected); // the next expected disconnect will be an actual disconnect.
if (this.visibilityState.get() === VisibilityState.Hidden) return;
// reload state, but not configuration.
this.getWebSocket().request<number>("hello")
.then(clientId => {
this.clientId = clientId;
return this.getUpdateStatus(); // detects whether server has been upgraded.
})
.then((updateStatus) => {
this.clientId = await this.getWebSocket().request<number>("hello");
return this.getWebSocket().request<any>("plugins");
})
.then(data => {
this.ui_plugins.set(UiPlugin.deserialize_array(data));
return this.getWebSocket().request<Pedalboard>("currentPedalboard");
})
.then(data => {
this.setModelPedalboard(new Pedalboard().deserialize(data));
return this.getWebSocket().request<boolean>("getShowStatusMonitor");
})
.then(data => {
this.showStatusMonitor.set(data);
return this.getWebSocket().request<any>("getWifiConfigSettings");
})
.then(data => {
this.wifiConfigSettings.set(new WifiConfigSettings().deserialize(data));
return this.getWebSocket().request<any>("getWifiDirectConfigSettings");
})
.then(data => {
this.wifiDirectConfigSettings.set(new WifiDirectConfigSettings().deserialize(data));
return this.getWebSocket().request<any>("getGovernorSettings");
})
.then(data => {
this.governorSettings.set(new GovernorSettings().deserialize(data));
return this.getWebSocket().request<any>("getJackServerSettings");
})
.then(data => {
this.jackServerSettings.set(new JackServerSettings().deserialize(data));
return this.getWebSocket().request<PresetIndex>("getPresets");
})
.then((data) => {
this.presets.set(new PresetIndex().deserialize(data));
return this.getWebSocket().request<JackConfiguration>("getJackConfiguration");
})
.then((data) => {
// data.isValid = false;
// data.errorState = "Jack Audio server not running."
this.jackConfiguration.set(new JackConfiguration().deserialize(data));
return this.getWebSocket().request<any>("getJackSettings");
})
.then((data) => {
this.jackSettings.set(new JackChannelSelection().deserialize(data));
return this.getWebSocket().request<any>("getBankIndex");
})
.then((data) => {
this.banks.set(new BankIndex().deserialize(data));
return this.getWebSocket().request<FavoritesList>("getFavorites");
})
.then((data) => {
this.favorites.set(data);
return this.getWebSocket().request<MidiBinding[]>("getSystemMidiBindings");
})
.then((data) => {
let bindings = MidiBinding.deserialize_array(data);
this.systemMidiBindings.set(bindings);
this.setState(State.Ready);
})
.catch((what) => {
if (what instanceof UpdatedError) {
// do nothing. a page reload is imminent and unavoidable as soon as we return to the dispatcher.
} else {
this.onError(what.toString());
let newServerVersion = this.serverVersion = await this.getWebSocket().request<PiPedalVersion>("version");
if (newServerVersion.serverVersion !== this.serverVersion.serverVersion)
{
this.reloadPage();
return;
}
})
// anything could have changed while we were disconnected.
await this.loadServerState();
}
makeSocketServerUrl(hostName: string, port: number): string {
return "ws://" + hostName + ":" + port + "/pipedal";
@@ -1026,15 +965,14 @@ export class PiPedalModel //implements PiPedalModel
debug: boolean = false;
enableAutoUpdate: boolean = false;
requestConfig(): Promise<boolean> {
async requestConfig(): Promise<boolean> {
try {
const myRequest = new Request(this.varRequest('config.json'));
return fetch(myRequest)
.then(
(response) => {
return response.json();
}
)
.then(data => {
let response: Response = await fetch(myRequest);
let data = await response.json();
this.enableAutoUpdate = !!data.enable_auto_update;
this.hasWifiDevice.set(!!data.has_wifi_device);
if (data.max_upload_size) {
@@ -1052,10 +990,14 @@ export class PiPedalModel //implements PiPedalModel
let socket_server = this.makeSocketServerUrl(socket_server_address, socket_server_port);
let var_server_url = this.makeVarServerUrl("http", socket_server_address, socket_server_port);
this.socketServerUrl = socket_server;
this.varServerUrl = var_server_url;
this.maxFileUploadSize = parseInt(max_upload_size);
} catch (error: any)
{
this.setError("Can't connect to server. " + getErrorMessage(error));
return false;
}
this.webSocket = new PiPedalSocket(
this.socketServerUrl,
@@ -1067,138 +1009,98 @@ export class PiPedalModel //implements PiPedalModel
onReconnecting: this.onSocketReconnecting
}
);
return this.webSocket.connect();
})
.catch((error) => {
this.setError("Failed to connect to server. (" + this.socketServerUrl + ")");
try {
await this.webSocket.connect();
} catch (error) {
this.setError("Failed to connect to server. (" + getErrorMessage(error));
return false;
})
.then(() => {
return this.getUpdateStatus();
})
.then((updateStatus) => {
const isoRequest = new Request('iso_codes.json');
return fetch(isoRequest);
})
.then((response) => {
return response.json();
})
.then((countryCodes) => {
this.countryCodes = countryCodes as { [Name: string]: string };
return this.getWebSocket().request<number>("hello");
})
.then((clientId) => {
this.clientId = clientId;
}
try {
let isoFetch = await fetch(new Request('iso_codes.json'));
this.countryCodes = (await isoFetch.json()) as { [Name: string]: string };
return this.getWebSocket().request<string>("imageList");
})
.then((data) => {
this.preloadImages(data);
return true;
})
.catch((error) => {
this.setError("Failed to connect to server. " + error.toString());
this.clientId = (await this.getWebSocket().request<number>("hello")) as number;
this.preloadImages( (await this.getWebSocket().request<string>("imageList")));
} catch (error) {
this.setError("Failed to establish connection. " + getErrorMessage(error));
return false;
})
.then((succeeded) => {
if (!succeeded) return false;
return this.getWebSocket().request<PiPedalVersion>("version").then(data => {
this.serverVersion = data;
return this.getWebSocket().request<any>("plugins");
})
.then(data => {
this.ui_plugins.set(UiPlugin.deserialize_array(data));
}
return await this.loadServerState();
}
async loadServerState() : Promise<boolean>
{
try
{
this.serverVersion = await this.getWebSocket().request<PiPedalVersion>("version");
return this.getWebSocket().request<Pedalboard>("currentPedalboard");
})
.then(data => {
this.setModelPedalboard(new Pedalboard().deserialize(data));
this.updateStatus.set(new UpdateStatus().deserialize(await this.getUpdateStatus()));
return this.getWebSocket().request<any>("pluginClasses");
})
.then((data) => {
this.hasWifiDevice.set(await this.getWebSocket().request<boolean>("getHasWifi"));
this.plugin_classes.set(new PluginClass().deserialize(data));
this.ui_plugins.set(
UiPlugin.deserialize_array(await this.getWebSocket().request<any>("plugins"))
);
this.setModelPedalboard(
new Pedalboard().deserialize(
await this.getWebSocket().request<Pedalboard>("currentPedalboard")
)
);
this.plugin_classes.set(new PluginClass().deserialize(
await this.getWebSocket().request<any>("pluginClasses")
));
this.validatePluginClasses(this.plugin_classes.get());
return this.getWebSocket().request<PresetIndex>("getPresets");
})
.then((data) => {
this.presets.set(new PresetIndex().deserialize(data));
this.presets.set(
new PresetIndex().deserialize(
await this.getWebSocket().request<PresetIndex>("getPresets")
)
);
this.wifiConfigSettings.set(
new WifiConfigSettings().deserialize(
await this.getWebSocket().request<any>("getWifiConfigSettings")
));
this.wifiDirectConfigSettings.set(
new WifiDirectConfigSettings().deserialize(
await this.getWebSocket().request<any>("getWifiDirectConfigSettings")
));
this.governorSettings.set(new GovernorSettings().deserialize(
await this.getWebSocket().request<any>("getGovernorSettings")
));
this.showStatusMonitor.set(
await this.getWebSocket().request<boolean>("getShowStatusMonitor")
);
this.jackServerSettings.set(
new JackServerSettings().deserialize(
await this.getWebSocket().request<any>("getJackServerSettings")
)
);
this.jackConfiguration.set(new JackConfiguration().deserialize(
await this.getWebSocket().request<JackConfiguration>("getJackConfiguration")
));
this.jackSettings.set(new JackChannelSelection().deserialize(
await this.getWebSocket().request<any>("getJackSettings")
));
this.banks.set(new BankIndex().deserialize(await this.getWebSocket().request<any>("getBankIndex")));
return this.getWebSocket().request<any>("getWifiConfigSettings");
})
.then(data => {
this.wifiConfigSettings.set(new WifiConfigSettings().deserialize(data));
this.favorites.set(await this.getWebSocket().request<FavoritesList>("getFavorites"));
return this.getWebSocket().request<any>("getWifiDirectConfigSettings");
})
.then(data => {
this.wifiDirectConfigSettings.set(new WifiDirectConfigSettings().deserialize(data));
this.systemMidiBindings.set(MidiBinding.deserialize_array(await this.getWebSocket().request<MidiBinding[]>("getSystemMidiBindings")));
return this.getWebSocket().request<any>("getGovernorSettings");
})
.then(data => {
this.governorSettings.set(new GovernorSettings().deserialize(data));
// load at lest once before we allow a reconnect.
this.getWebSocket().canReconnect = true;
return this.getWebSocket().request<boolean>("getShowStatusMonitor");
})
.then(data => {
this.showStatusMonitor.set(data);
return this.getWebSocket().request<any>("getJackServerSettings");
})
.then(data => {
this.jackServerSettings.set(new JackServerSettings().deserialize(data));
return this.getWebSocket().request<JackConfiguration>("getJackConfiguration");
})
.then((data) => {
// data.isValid = false;
// data.errorState = "Jack Audio server not running."
this.jackConfiguration.set(new JackConfiguration().deserialize(data));
return this.getWebSocket().request<any>("getJackSettings");
})
.then((data) => {
this.jackSettings.set(new JackChannelSelection().deserialize(data));
return this.getWebSocket().request<any>("getBankIndex");
})
.then((data) => {
this.banks.set(new BankIndex().deserialize(data));
if (this.webSocket) {
// MUST not allow reconnect until at least one complete load has finished.
this.webSocket.canReconnect = true;
}
return this.getWebSocket().request<FavoritesList>("getFavorites");
})
.then((data) => {
this.favorites.set(data);
return this.getWebSocket().request<MidiBinding[]>("getSystemMidiBindings");
})
.then((data) => {
let bindings = MidiBinding.deserialize_array(data);
this.systemMidiBindings.set(bindings);
if (this.webSocket) {
// MUST not allow reconnect until at least one complete load has finished.
this.webSocket.canReconnect = true;
}
this.setState(State.Ready);
return true;
})
.catch((error) => {
this.setError("Failed to fetch server state.\n\n" + error.toString());
}
catch(error) {
this.setError("Failed to fetch server state.\n\n" + getErrorMessage(error));
return false;
});
})
;
}
}
+8 -1
View File
@@ -212,9 +212,13 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
this.handleGovernorSettingsChanged = this.handleGovernorSettingsChanged.bind(this);
this.handleConnectionStateChanged = this.handleConnectionStateChanged.bind(this);
this.handleShowStatusMonitorChanged = this.handleShowStatusMonitorChanged.bind(this);
this.handleHasWifiChanged = this.handleHasWifiChanged.bind(this);
}
handleHasWifiChanged(newValue: boolean) {
this.setState({hasWifiDevice: newValue});
}
handleShowStatusMonitorChanged(): void {
this.setState({ showStatusMonitor: this.model.showStatusMonitor.get() });
@@ -322,6 +326,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
if (active !== this.active) {
this.active = active;
if (active) {
this.model.hasWifiDevice.addOnChangedHandler(this.handleHasWifiChanged);
this.model.state.addOnChangedHandler(this.handleConnectionStateChanged);
this.model.showStatusMonitor.addOnChangedHandler(this.handleShowStatusMonitorChanged);
this.model.jackSettings.addOnChangedHandler(this.handleJackSettingsChanged);
@@ -350,6 +355,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
this.handleJackServerSettingsChanged();
this.handleWifiConfigSettingsChanged();
this.handleWifiDirectConfigSettingsChanged();
this.setState({hasWifiDevice: this.model.hasWifiDevice.get()});
this.timerHandle = setInterval(() => this.tick(), 1000);
} else {
if (this.timerHandle) {
@@ -364,7 +371,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
this.model.wifiConfigSettings.removeOnChangedHandler(this.handleWifiConfigSettingsChanged);
this.model.wifiDirectConfigSettings.removeOnChangedHandler(this.handleWifiDirectConfigSettingsChanged);
this.model.governorSettings.removeOnChangedHandler(this.handleGovernorSettingsChanged);
this.model.hasWifiDevice.removeOnChangedHandler(this.handleHasWifiChanged);
}
}
+51 -7
View File
@@ -60,6 +60,7 @@ namespace pipedal::impl
virtual bool CancelPost(PostHandle handle) override;
virtual void SetNetworkChangingListener(NetworkChangingListener &&listener) override;
virtual void SetHasWifiListener(HasWifiListener &&listener) override;
private:
enum class State
@@ -75,6 +76,11 @@ namespace pipedal::impl
void SetState(State state);
State state = State::Initial;
bool hasWifi = false;
HasWifiListener hasWifiListener;
void SetHasWifi(bool hasWifi);
virtual bool GetHasWifi() override ;
void onClose();
void onError(const std::string &message);
void onInitialize();
@@ -224,6 +230,7 @@ void HotspotManagerImpl::onInitialize()
}
void HotspotManagerImpl::onDisconnect()
{
SetHasWifi(false);
if (state != State::Initial && state != State::WaitingForNetworkManager)
{
WaitForNetworkManager();
@@ -242,6 +249,8 @@ void HotspotManagerImpl::UpdateNetworkManagerStatus()
auto ethernetDevice = GetDevice(NM_DEVICE_TYPE_ETHERNET);
auto wlanDevice = GetDevice(NM_DEVICE_TYPE_WIFI);
SetHasWifi(!!wlanDevice);
if (ethernetDevice && wlanDevice)
{
if (state == State::Initial || state == State::WaitingForNetworkManager)
@@ -291,6 +300,7 @@ void HotspotManagerImpl::ReleaseNetworkManager()
this->onDeviceRemovedHandle = INVALID_DBUS_EVENT_HANDLE;
this->onDeviceAddedHandle = INVALID_DBUS_EVENT_HANDLE;
SetHasWifi(false);
}
void HotspotManagerImpl::onDevicesChanged()
@@ -401,6 +411,8 @@ void HotspotManagerImpl::onStartMonitoring()
OnEthernetStateChanged(ethernetDevice->State());
OnWlanStateChanged(wlanDevice->State());
SetHasWifi(true);
StartScanTimer();
onAccessPointChanged();
}
@@ -1014,6 +1026,32 @@ bool HotspotManagerImpl::CancelPost(PostHandle handle)
return dbusDispatcher.CancelPost(handle);
}
void HotspotManagerImpl::SetHasWifiListener(HasWifiListener &&listener)
{
std::lock_guard<std::recursive_mutex> lock{this->networkChangingListenerMutex};
this->hasWifiListener = listener;
if (!this->closed && this->hasWifiListener)
{
this->hasWifiListener(this->hasWifi);
}
}
bool HotspotManagerImpl::GetHasWifi() {
std::lock_guard<std::recursive_mutex> lock{this->networkChangingListenerMutex};
return hasWifi;
}
void HotspotManagerImpl::SetHasWifi(bool hasWifi)
{
std::lock_guard<std::recursive_mutex> lock{this->networkChangingListenerMutex};
if (hasWifi != this->hasWifi)
{
this->hasWifi = hasWifi;
if (this->hasWifiListener)
{
this->hasWifiListener(this->hasWifi);
}
}
}
void HotspotManagerImpl::SetNetworkChangingListener(NetworkChangingListener &&listener)
{
std::lock_guard<std::recursive_mutex> lock{this->networkChangingListenerMutex};
@@ -1034,23 +1072,29 @@ std::vector<std::string> HotspotManagerImpl::GetKnownWifiNetworks()
return this->knownWifiNetworks;
}
static bool is_wireless_sysfs(const std::string& ifname) {
static bool is_wireless_sysfs(const std::string &ifname)
{
return fs::exists("/sys/class/net/" + ifname + "/wireless");
}
static std::vector<std::string> get_wireless_interfaces_sysfs() {
static std::vector<std::string> get_wireless_interfaces_sysfs()
{
std::vector<std::string> wireless_interfaces;
const std::string net_path = "/sys/class/net";
try {
for (const auto& entry : fs::directory_iterator(net_path)) {
try
{
for (const auto &entry : fs::directory_iterator(net_path))
{
std::string ifname = entry.path().filename();
if (is_wireless_sysfs(ifname)) {
if (is_wireless_sysfs(ifname))
{
wireless_interfaces.push_back(ifname);
}
}
} catch (const fs::filesystem_error& e) {
}
catch (const fs::filesystem_error &e)
{
std::cerr << "Error accessing " << net_path << ": " << e.what() << std::endl;
}
+5
View File
@@ -55,6 +55,11 @@ namespace pipedal {
virtual void SetNetworkChangingListener(NetworkChangingListener &&listener) = 0;
using HasWifiListener = std::function<void(bool hasWifi)>;
virtual void SetHasWifiListener(HasWifiListener &&listener) = 0;
virtual bool GetHasWifi() = 0;
using PostHandle = uint64_t;
using PostCallback = std::function<void()>;
+51 -27
View File
@@ -99,29 +99,33 @@ PiPedalModel::PiPedalModel()
{
OnNetworkChanging(ethernetConnected, hotspotEnabling);
});
hotspotManager->SetHasWifiListener(
[this](bool hasWifi)
{
this->SetHasWifi(hasWifi);
});
// don't actuall start the hotspotManager until after LV2 is initialized (in order to avoid logging oddities)
}
void PrepareSnapshostsForSave(Pedalboard &pedalboard)
{
if (pedalboard.selectedSnapshot() != -1) {
if (pedalboard.selectedSnapshot() != -1)
{
auto &currentSnapshot = pedalboard.snapshots()[pedalboard.selectedSnapshot()];
if (!currentSnapshot || currentSnapshot->isModified_)
{
pedalboard.selectedSnapshot(-1);
}
}
for (auto &snapshot : pedalboard.snapshots())
{
if (snapshot) {
if (snapshot)
{
snapshot->isModified_ = false;
}
}
}
void PiPedalModel::Close()
{
std::unique_ptr<AudioHost> oldAudioHost;
@@ -351,7 +355,8 @@ void PiPedalModel::RemoveNotificationSubsription(std::shared_ptr<IPiPedalModelSu
void PiPedalModel::PreviewControl(int64_t clientId, int64_t pedalItemId, const std::string &symbol, float value)
{
IEffect *effect = lv2Pedalboard->GetEffect(pedalItemId);
if (!effect) {
if (!effect)
{
return;
}
if (effect->IsVst3())
@@ -384,7 +389,8 @@ void PiPedalModel::OnNotifyMaybeLv2StateChanged(uint64_t instanceId)
PedalboardItem *item = pedalboard.GetItem(instanceId);
if (item != nullptr)
{
if (!audioHost) {
if (!audioHost)
{
return;
}
bool changed = this->audioHost->UpdatePluginState(*item);
@@ -481,7 +487,6 @@ void PiPedalModel::FireJackConfigurationChanged(const JackConfiguration &jackCon
{
// noify subscribers.
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
@@ -531,8 +536,6 @@ void PiPedalModel::SetPedalboard(int64_t clientId, Pedalboard &pedalboard)
}
}
void PiPedalModel::SetSnapshot(int64_t selectedSnapshot)
{
std::lock_guard<std::recursive_mutex> lock(mutex);
@@ -554,7 +557,6 @@ void PiPedalModel::SetSnapshots(std::vector<std::shared_ptr<Snapshot>> &snapshot
{
std::lock_guard<std::recursive_mutex> lock(mutex);
UpdateVst3Settings(pedalboard);
this->pedalboard.snapshots(std::move(snapshots));
@@ -575,7 +577,6 @@ void PiPedalModel::SetSnapshots(std::vector<std::shared_ptr<Snapshot>> &snapshot
// this means that all clients get an up-to-date copy of the snapshots AND the currently selected snapshot if that applies
// (and a fresh copy of the pedalboard settings as well, which is harmless, since they have not changed)
this->SetPresetChanged(-1, true, false);
}
void PiPedalModel::UpdateCurrentPedalboard(int64_t clientId, Pedalboard &pedalboard)
@@ -639,7 +640,8 @@ void PiPedalModel::SetPresetChanged(int64_t clientId, bool value, bool changeSna
if (changeSnapshotSelect && value && this->pedalboard.selectedSnapshot() != -1)
{
auto &snapshot = this->pedalboard.snapshots()[pedalboard.selectedSnapshot()];
if (snapshot) {
if (snapshot)
{
if (!snapshot->isModified_)
{
snapshot->isModified_ = true;
@@ -667,7 +669,6 @@ void PiPedalModel::FireSnapshotModified(int64_t snapshotIndex, bool modified)
subscriber->OnSnapshotModified(snapshotIndex, modified);
}
}
}
void PiPedalModel::FireSelectedSnapshotChanged(int64_t selectedSnapshot)
@@ -752,7 +753,8 @@ void PiPedalModel::UpdateVst3Settings(Pedalboard &pedalboard)
#endif
}
void PiPedalModel::FireLv2StateChanged(int64_t instanceId, const Lv2PluginState &lv2State) {
void PiPedalModel::FireLv2StateChanged(int64_t instanceId, const Lv2PluginState &lv2State)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
@@ -760,7 +762,6 @@ void PiPedalModel::FireLv2StateChanged(int64_t instanceId, const Lv2PluginState
{
subscriber->OnLv2StateChanged(instanceId, lv2State);
}
}
// referesh the plugin state for all plugins.
@@ -780,7 +781,6 @@ bool PiPedalModel::SyncLv2State()
}
}
return changed;
}
void PiPedalModel::SaveCurrentPreset(int64_t clientId)
{
@@ -790,7 +790,6 @@ void PiPedalModel::SaveCurrentPreset(int64_t clientId)
SyncLv2State();
PrepareSnapshostsForSave(pedalboard);
storage.SaveCurrentPreset(this->pedalboard);
this->SetPresetChanged(clientId, false);
}
@@ -819,7 +818,6 @@ int64_t PiPedalModel::SavePluginPresetAs(int64_t instanceId, const std::string &
return presetId;
}
int64_t PiPedalModel::SaveCurrentPresetAs(int64_t clientId, const std::string &name, int64_t saveAfterInstanceId)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
@@ -888,11 +886,15 @@ void PiPedalModel::NextBank(Direction direction)
{
index = 0;
}
} else {
}
else
{
if (index == 0)
{
index = bankIndex.entries().size() - 1;
} else {
}
else
{
--index;
}
}
@@ -968,9 +970,11 @@ void PiPedalModel::OnNotifyNextMidiProgram(const RealtimeNextMidiProgramRequest
void PiPedalModel::OnNotifyMidiRealtimeSnapshotRequest(int32_t snapshotIndex, int64_t snapshotRequestId)
{
try {
try
{
SetSnapshot((int64_t)snapshotIndex);
} catch (const std::exception&e)
}
catch (const std::exception &e)
{
Lv2Log::error(SS("SetSnapshot failed. " << e.what()));
}
@@ -1006,7 +1010,6 @@ void PiPedalModel::OnNotifyNextMidiBank(const RealtimeNextMidiProgramRequest &re
}
}
void PiPedalModel::OnNotifyMidiProgramChange(RealtimeMidiProgramRequest &midiProgramRequest)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
@@ -2054,7 +2057,9 @@ void PiPedalModel::OnPatchSetReply(uint64_t instanceId, LV2_URID patchSetPropert
if (properties.contains(propertyUri) && properties[propertyUri] == atomObject)
{
// do noting.
} else {
}
else
{
properties[propertyUri] = std::move(atomObject);
}
@@ -2234,7 +2239,6 @@ std::vector<AlsaDeviceInfo> PiPedalModel::GetAlsaDevices()
result.push_back(MakeDummyDeviceInfo(8));
#endif
return result;
}
const std::filesystem::path &PiPedalModel::GetWebRoot() const
@@ -2617,7 +2621,6 @@ void PiPedalModel::OnNetworkChanged(bool ethernetConnected, bool hotspotConnecte
FireNetworkChanged();
}
void PiPedalModel::OnNotifyMidiRealtimeEvent(RealtimeMidiEventType eventType)
{
try
@@ -2698,3 +2701,24 @@ void PiPedalModel::RequestShutdown(bool restart)
}
}
}
void PiPedalModel::SetHasWifi(bool hasWifi)
{
std::lock_guard<std::recursive_mutex> lock(mutex);
if (this->hasWifi != hasWifi)
{
this->hasWifi = hasWifi;
std::vector<IPiPedalModelSubscriber::ptr> t{subscribers.begin(), subscribers.end()};
for (auto &subscriber : t)
{
subscriber->OnHasWifiChanged(hasWifi);
}
}
}
bool PiPedalModel::GetHasWifi()
{
std::lock_guard<std::recursive_mutex> lock(mutex);
return hasWifi;
}
+7
View File
@@ -92,6 +92,7 @@ namespace pipedal
virtual void OnErrorMessage(const std::string &message) = 0;
virtual void OnLv2PluginsChanging() = 0;
virtual void OnNetworkChanging(bool hotspotConnected) = 0;
virtual void OnHasWifiChanged(bool hasWifi) = 0;
virtual void Close() = 0;
};
@@ -107,6 +108,9 @@ namespace pipedal
using NetworkChangedListener = std::function<void(void)>;
private:
bool hasWifi = false;
void SetHasWifi(bool hasWifi);
std::unique_ptr<HotspotManager> hotspotManager;
std::unique_ptr<Updater> updater;
@@ -257,6 +261,9 @@ namespace pipedal
Increase,
Decrease
};
bool GetHasWifi();
void NextBank(Direction direction = Direction::Increase);
void PreviousBank() { NextBank(Direction::Decrease); }
void NextPreset(Direction direction = Direction::Increase);
+11
View File
@@ -1080,6 +1080,11 @@ public:
UpdateStatus updateStatus = model.GetUpdateStatus();
this->Reply(replyTo, "getUpdateStatus", updateStatus);
}
else if (message == "getHasWifi")
{
bool result = model.GetHasWifi();
this->Reply(replyTo, "getHasWifi",result);
}
else if (message == "updateNow")
{
std::string updateUrl;
@@ -1727,6 +1732,12 @@ private:
Send("onLv2PluginsChanging", true);
Flush();
}
virtual void OnHasWifiChanged(bool hasWifi){
Send("onHasWifiChanged", hasWifi);
Flush();
}
virtual void OnNetworkChanging(bool hotspotConnected) override
{
try
+3
View File
@@ -1,3 +1,6 @@
Hotspot monitoring - fails when WiFi network is disabled.
Not all country codes are valid (e.g. Antarctica)