diff --git a/CMakeLists.txt b/CMakeLists.txt index a4b97ff..33f7aa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.16.0) project(pipedal - VERSION 1.1.20 + VERSION 1.1.21 DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi" HOMEPAGE_URL "https://rerdavies.github.io/pipedal" ) -set (DISPLAY_VERSION "v1.1.20") +set (DISPLAY_VERSION "v1.1.21") set (CMAKE_INSTALL_PREFIX "/usr/") diff --git a/README.md b/README.md index caee372..cf87873 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@
-Download: v1.1.20 +Download: v1.1.21 Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal). diff --git a/debian/control b/debian/control index 604fd2c..16b3439 100644 --- a/debian/control +++ b/debian/control @@ -9,6 +9,6 @@ Package: pipedal Pre-Depends: hostapd;authbind;dnsmasq Priority: optional Section: sound -Version: 1.1.20 +Version: 1.1.21 Installed-Size: 15147 diff --git a/docs/Installing.md b/docs/Installing.md index d07c32a..4d9376f 100644 --- a/docs/Installing.md +++ b/docs/Installing.md @@ -13,14 +13,14 @@ page_icon: img/Install4.jpg Download the most recent Debian (.deb) package for your platform: -- [Ubuntu/Raspberry Pi OS (64-bit) v1.1.20](https://github.com/rerdavies/pipedal/releases/download/v1.1.20/pipedal_1.1.20_arm64.deb) +- [Ubuntu/Raspberry Pi OS (64-bit) v1.1.21](https://github.com/rerdavies/pipedal/releases/download/v1.1.21/pipedal_1.1.21_arm64.deb) Install the package by running ``` sudo apt update cd ~/Downloads - sudo apt-get install ./pipedal_1.1.20_arm64.deb + sudo apt-get install ./pipedal_1.1.21_arm64.deb ``` On Raspberry Pi OS, if you have a graphical desktop installed, you can also install the package by double-clicking on the downloaded package in the File Manager. diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 324cb12..4f11608 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -1,6 +1,6 @@ # Release Notes -## PiPedal 1.1.20 +## PiPedal 1.1.21 Features: diff --git a/docs/download.md b/docs/download.md index 9f46c4d..5ff8dea 100644 --- a/docs/download.md +++ b/docs/download.md @@ -4,14 +4,14 @@ Download the most recent Debian (.deb) package for your platform: -- [Ubuntu or Raspberry Pi OS (64-bit)](https://github.com/rerdavies/pipedal/releases/download/v1.1.20/pipedal_1.1.20_arm64.deb) v1.1.20 +- [Ubuntu or Raspberry Pi OS (64-bit)](https://github.com/rerdavies/pipedal/releases/download/v1.1.21/pipedal_1.1.21_arm64.deb) v1.1.21 Install the package by running ``` sudo apt update cd ~/Downloads - sudo apt-get install ./pipedal_1.1.20_arm64.deb + sudo apt-get install ./pipedal_1.1.21_arm64.deb ``` Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation. diff --git a/docs/index.md b/docs/index.md index 74f4dd9..502f6f8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ -v1.1.20 +v1.1.21   diff --git a/lv2/aarch64/ToobAmp.lv2/ToobAmp.so.0 b/lv2/aarch64/ToobAmp.lv2/ToobAmp.so.0 index de69364..0e249c4 120000 --- a/lv2/aarch64/ToobAmp.lv2/ToobAmp.so.0 +++ b/lv2/aarch64/ToobAmp.lv2/ToobAmp.so.0 @@ -1 +1 @@ -ToobAmp.so.1.0.8 \ No newline at end of file +ToobAmp.so.1.0.9 \ No newline at end of file diff --git a/lv2/aarch64/ToobAmp.lv2/ToobAmp.so.1.0.9 b/lv2/aarch64/ToobAmp.lv2/ToobAmp.so.1.0.9 new file mode 100644 index 0000000..b7d1ef3 Binary files /dev/null and b/lv2/aarch64/ToobAmp.lv2/ToobAmp.so.1.0.9 differ diff --git a/react/src/AppThemed.tsx b/react/src/AppThemed.tsx index d7fa9fc..144e8d1 100644 --- a/react/src/AppThemed.tsx +++ b/react/src/AppThemed.tsx @@ -318,6 +318,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< }; this.errorChangeHandler_ = this.setErrorMessage.bind(this); + this.unmountListener = this.unmountListener.bind(this); this.stateChangeHandler_ = this.setDisplayState.bind(this); this.presetChangedHandler = this.presetChangedHandler.bind(this); this.alertMessageChangedHandler = this.alertMessageChangedHandler.bind(this); @@ -427,12 +428,10 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< this.setState({ isDrawerOpen: false, }); - if (this.model_.isAndroidHosted()) - { + if (this.model_.isAndroidHosted()) { this.model_.showAndroidDonationActivity(); } else { - if (window) - { + if (window) { window.open("https://github.com/sponsors/rerdavies", '_blank'); } } @@ -488,17 +487,18 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< setFullScreen(this.state.isFullScreen); this.setState({ isFullScreen: !this.state.isFullScreen }); } + + private unmountListener(e: Event) { + e.preventDefault(); + if (this.model_.state.get() === State.Ready && !this.model_.isAndroidHosted()) { + (e as any).returnValue = "Are you sure you want to leave this page?"; + return "Are you sure you want to leave this page?"; + } + } componentDidMount() { super.componentDidMount(); - - window.addEventListener("beforeunload", (e) => { - e.preventDefault(); - if (this.model_.state.get() === State.Ready) { - e.returnValue = "Are you sure you want to leave this page?"; - return "Are you sure you want to leave this page?"; - } - }); + window.addEventListener("beforeunload",this.unmountListener); this.model_.errorMessage.addOnChangedHandler(this.errorChangeHandler_); this.model_.state.addOnChangedHandler(this.stateChangeHandler_); @@ -510,193 +510,168 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< } - updateOverscroll(): void { - if (this.model_.serverVersion) { - // no pull-down refresh on android devices once we're ready (unless we're debug) - let preventOverscroll = - this.model_.state.get() === State.Ready - && !this.model_.debug; +updateOverscroll(): void { + if(this.model_.serverVersion) { + // no pull-down refresh on android devices once we're ready (unless we're debug) + let preventOverscroll = + this.model_.state.get() === State.Ready + && !this.model_.debug; - let overscrollBehavior = preventOverscroll ? "none" : "auto"; - document.body.style.overscrollBehavior = overscrollBehavior; - } + let overscrollBehavior = preventOverscroll ? "none" : "auto"; + document.body.style.overscrollBehavior = overscrollBehavior; +} } - componentDidUpdate() { - } +componentDidUpdate() { +} - componentWillUnmount() { - super.componentWillUnmount(); - this.model_.errorMessage.removeOnChangedHandler(this.errorChangeHandler_); - this.model_.state.removeOnChangedHandler(this.stateChangeHandler_); - this.model_.pedalboard.removeOnChangedHandler(this.presetChangedHandler); - this.model_.banks.removeOnChangedHandler(this.banksChangedHandler); - this.model_.banks.removeOnChangedHandler(this.showStatusMonitorHandler); +componentWillUnmount() { + super.componentWillUnmount(); + window.removeEventListener("beforeunload",this.unmountListener); - } + this.model_.errorMessage.removeOnChangedHandler(this.errorChangeHandler_); + this.model_.state.removeOnChangedHandler(this.stateChangeHandler_); + this.model_.pedalboard.removeOnChangedHandler(this.presetChangedHandler); + this.model_.banks.removeOnChangedHandler(this.banksChangedHandler); + this.model_.banks.removeOnChangedHandler(this.showStatusMonitorHandler); - alertMessageChangedHandler() { - let message = this.model_.alertMessage.get(); - if (message === "") { - this.setState({ alertDialogOpen: false }); - // leave the message intact so the dialog can fade. - } else { - this.setState({ - alertDialogOpen: true, - alertDialogMessage: message - }); - } - - } - updateResponsive() { - // functional, but disabled. - // let tinyToolBar_ = this.windowSize.height < 600; - // this.setState({ tinyToolBar: tinyToolBar_ }); - - let height = this.windowSize.height; - - const ENTRY_HEIGHT = 48; - // ENTRY_HEIGHT*6 +K = 727 from observation. - const K = 450; - - let bankEntries = Math.floor((height - K) / ENTRY_HEIGHT); - if (bankEntries < 1) bankEntries = 1; - if (bankEntries > 7) bankEntries = 7; - this.setState({ bankDisplayItems: bankEntries }); - - } - onWindowSizeChanged(width: number, height: number): void { - super.onWindowSizeChanged(width, height); - this.updateResponsive(); - } - - - setErrorMessage(message: string): void { - this.setState({ errorMessage: message }); - } - - - setDisplayState(newState: State): void { - this.updateOverscroll(); +} +alertMessageChangedHandler() { + let message = this.model_.alertMessage.get(); + if (message === "") { + this.setState({ alertDialogOpen: false }); + // leave the message intact so the dialog can fade. + } else { this.setState({ - displayState: newState, - canFullScreen: supportsFullScreen() && !this.model_.isAndroidHosted() + alertDialogOpen: true, + alertDialogMessage: message }); - if (newState === State.Ready) - { - if (this.model_.isOnboarding()) - { - this.handleDisplayOnboarding(); - } - } } - showDrawer() { - this.setState({ isDrawerOpen: true }) - } - hideDrawer() { - this.setState({ isDrawerOpen: false }) - } - shortBankList(banks: BankIndex): BankIndexEntry[] { - let n = this.state.bankDisplayItems; - let entries = banks.entries; - if (entries.length < n + 1) { // +1 for the .... entry. - return entries; - } - let result: BankIndexEntry[] = []; - let selectedIndex = -1; - for (let i = 0; i < entries.length; ++i) { - if (entries[i].instanceId === banks.selectedBank) { - selectedIndex = i; - break; - } - } - if (n > entries.length) n = entries.length; - if (selectedIndex > n) { - for (let i = 0; i < n - 1; ++i) { - result.push(entries[i]); - } - result.push(entries[selectedIndex]); - } else { - for (let i = 0; i < n; ++i) { - result.push(entries[i]); - } - } - return result; - } - handleReload() { - if (this.model_.isAndroidHosted()) { - this.model_.chooseNewDevice(); - } else { - window.location.reload(); - } - } - render() { +} +updateResponsive() { + // functional, but disabled. + // let tinyToolBar_ = this.windowSize.height < 600; + // this.setState({ tinyToolBar: tinyToolBar_ }); - const { classes } = this.props; + let height = this.windowSize.height; - let shortBankList = this.shortBankList(this.state.banks); - let showBankSelectDialog = shortBankList.length !== this.state.banks.entries.length; + const ENTRY_HEIGHT = 48; + // ENTRY_HEIGHT*6 +K = 727 from observation. + const K = 450; + + let bankEntries = Math.floor((height - K) / ENTRY_HEIGHT); + if (bankEntries < 1) bankEntries = 1; + if (bankEntries > 7) bankEntries = 7; + this.setState({ bankDisplayItems: bankEntries }); + +} +onWindowSizeChanged(width: number, height: number): void { + super.onWindowSizeChanged(width, height); + this.updateResponsive(); +} - return ( -
entries.length) n = entries.length; + if (selectedIndex > n) { + for (let i = 0; i < n - 1; ++i) { + result.push(entries[i]); + } + result.push(entries[selectedIndex]); + } else { + for (let i = 0; i < n; ++i) { + result.push(entries[i]); + } + } + return result; +} +handleReload() { + if (this.model_.isAndroidHosted()) { + this.model_.chooseNewDevice(); + } else { + window.location.reload(); + } +} +render() { + + const { classes } = this.props; + + let shortBankList = this.shortBankList(this.state.banks); + let showBankSelectDialog = shortBankList.length !== this.state.banks.entries.length; + + + return ( +
{ + if (!this.model_.debug) { + e.preventDefault(); e.stopPropagation(); + } }} - onContextMenu={(e) => { - if (!this.model_.debug) { - e.preventDefault(); e.stopPropagation(); - } - }} - > - - {(!this.state.tinyToolBar) ? - ( - - - { this.showDrawer() }} - size="large"> - - -
- -
-
- {this.state.canFullScreen && - { this.toggleFullScreen(); }} - size="large"> - {this.state.isFullScreen ? ( - - ) : ( - - - )} - - - } - - - ) : ( -
+ > + + {(!this.state.tinyToolBar) ? + ( + + { this.showDrawer() }} size="large"> - {this.state.canFullScreen && ( +
+ +
+
+ {this.state.canFullScreen && { this.toggleFullScreen(); }} size="large"> @@ -708,208 +683,234 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent< )} - )} -
- )} - { this.hideDrawer(); }} > - Banks - }> - { - shortBankList.map((bank) => { - return ( - this.onOpenBank(bank.instanceId)} - > + } +
+
+ ) : ( +
+ { this.showDrawer() }} + size="large"> + + + {this.state.canFullScreen && ( + { this.toggleFullScreen(); }} + size="large"> + {this.state.isFullScreen ? ( + + ) : ( + - - + )} - ); - }) - } - { - showBankSelectDialog && ( - this.handleDrawerSelectBank()} + + )} +
+ )} + { this.hideDrawer(); }} > + Banks + }> + { + shortBankList.map((bank) => { + return ( + this.onOpenBank(bank.instanceId)} > - + - - ) - } - - - - { this.handleDrawerRenameBank() }}> - - - - { this.handleDrawerSaveBankAs() }} > - - - - - - { this.handleDrawerManageBanks(); }}> - - - - - - - - - { this.handleDrawerSettingsClick() }}> - - - - - - { this.handleDrawerAboutClick() }}> - - - - - - { this.handleDrawerDonationClick() }}> - - - - - - - - - {!this.state.tinyToolBar && ( - - )} -
-
-
- {(this.state.displayState !== State.Loading) && ( - - )} -
- -
-
- this.setState({ bankDialogOpen: false })} /> - this.setState({ aboutDialogOpen: false })} /> - this.handleSettingsDialogClose()} /> - { - this.setState({ - renameBankDialogOpen: false, - saveBankAsDialogOpen: false + ); }) - }} - onOk={(text: string) => { - if (this.state.renameBankDialogOpen) { - this.handleBankRenameOk(text); - } else if (this.state.saveBankAsDialogOpen) { - this.handleSaveBankAsOk(text); - } } - } - /> + { + showBankSelectDialog && ( + this.handleDrawerSelectBank()} + > - { this.setState({ zoomedControlOpen: false }); }} - onDialogClosed={() => { this.model_.zoomedUiControl.set(undefined); } - } - /> - - - - - { - this.state.alertDialogMessage - } - - - - - - - - { this.state.showStatusMonitor && () } + + -
+ + + { this.handleDrawerRenameBank() }}> + + + + { this.handleDrawerSaveBankAs() }} > + + + + + + { this.handleDrawerManageBanks(); }}> + + + + + + + + + { this.handleDrawerSettingsClick() }}> + + + + + + { this.handleDrawerAboutClick() }}> + + + + + + { this.handleDrawerDonationClick() }}> + + + + + + + + + {!this.state.tinyToolBar && ( + + )} +
+
+
+ {(this.state.displayState !== State.Loading) && ( + + )} +
+ +
+
+ this.setState({ bankDialogOpen: false })} /> + this.setState({ aboutDialogOpen: false })} /> + this.handleSettingsDialogClose()} /> + { + this.setState({ + renameBankDialogOpen: false, + saveBankAsDialogOpen: false + }) }} - > -
+ onOk={(text: string) => { + if (this.state.renameBankDialogOpen) { + this.handleBankRenameOk(text); + } else if (this.state.saveBankAsDialogOpen) { + this.handleSaveBankAsOk(text); + } + } + } + /> -
-
- -
- - {this.state.displayState === State.ApplyingChanges ? "Applying\u00A0changes..." : "Reconnecting..."} + { this.setState({ zoomedControlOpen: false }); }} + onDialogClosed={() => { this.model_.zoomedUiControl.set(undefined); } + } + /> + + + + + { + this.state.alertDialogMessage + } -
-
-
-
-
 
-
-
- -
-
-

- Error: {this.state.errorMessage} -

-
-
- + + + + + + + {this.state.showStatusMonitor && ()} -
+
+
+ +
+
+ +
+ + {this.state.displayState === State.ApplyingChanges ? "Applying\u00A0changes..." : "Reconnecting..."} + +
+
+
+
+
 
+
+
+ +
+
+

+ Error: {this.state.errorMessage} +

+
+
+
-
 
-
-
-
-
-
- -
- - Loading... - + +
 
+ +
+
+
+
+
+
+ + Loading... +
+
-
- ); - } +
+ ); +} } ); diff --git a/react/src/Lv2Plugin.tsx b/react/src/Lv2Plugin.tsx index af174da..8f24139 100644 --- a/react/src/Lv2Plugin.tsx +++ b/react/src/Lv2Plugin.tsx @@ -161,7 +161,7 @@ export class UiFileType { } else { // chrome desktop thinks "application/octet-stream" is .exe, .com, or .bat. // Feed it file extensions isntead. - if (result = "application/octet-stream") + if (result === "application/octet-stream") { result = ""; for (let i = 0; i < fileTypes.length; ++i) diff --git a/react/src/PiPedalModel.tsx b/react/src/PiPedalModel.tsx index a5c8e1e..32c571f 100644 --- a/react/src/PiPedalModel.tsx +++ b/react/src/PiPedalModel.tsx @@ -957,8 +957,8 @@ export class PiPedalModel //implements PiPedalModel } enterBackgroundState() { - // on Android, delay entering background state by 3 seconds, - // so that screen-flips don't trigger disconnects. + // on Android, delay entering background state by 180 seconds, + // since background management is more complicated. e.g. screen flips, and system upload dialogs. if (this.isAndroidHosted()) { if (this.backgroundStateTimeout) { @@ -967,7 +967,7 @@ export class PiPedalModel //implements PiPedalModel this.backgroundStateTimeout = setTimeout(() => { this.backgroundStateTimeout = undefined; this.enterBackgroundState_(); - }, 3000); + }, 180000); } else { this.enterBackgroundState_(); } diff --git a/src/PluginHost.cpp b/src/PluginHost.cpp index 49fe770..181dc5e 100644 --- a/src/PluginHost.cpp +++ b/src/PluginHost.cpp @@ -71,26 +71,6 @@ namespace pipedal static const char *LV2_MIDI_PLUGIN = "http://lv2plug.in/ns/lv2core#MIDIPlugin"; - // static const char *LV2_AUDIO_PORT = P_LV2_CORE_URI "AudioPort"; - // static const char *LV2_PLUGIN = P_LV2_CORE_URI "Plugin"; - // static const char *LV2_CONTROL_PORT = P_LV2_CORE_URI "ControlPort"; - // static const char *LV2_INPUT_PORT = P_LV2_CORE_URI "InputPort"; - // static const char *LV2_OUTPUT_PORT = P_LV2_CORE_URI "OutputPort"; - // static const char *LV2_INTEGER = P_LV2_CORE_URI "integer"; - // static const char *LV2_ENUMERATION = P_LV2_CORE_URI "enumeration"; - // static const char *LV2_PORT_LOGARITHMIC = P_LV2_PPROPS "logarithmic"; - // static const char *LV2_PORT_RANGE_STEPS = P_LV2_PPROPS "rangeSteps"; - // static const char *LV2_PORT_TRIGGER = P_LV2_PPROPS "trigger"; - // static const char *LV2_PORT_DISPLAY_PRIORITY = P_LV2_PPROPS "displayPriority"; - - - // static const char *LV2_ATOM_PORT = "http://lv2plug.in/ns/ext/atom#AtomPort"; - // static const char *LV2_ATOM_SEQUENCE = "http://lv2plug.in/ns/ext/atom#Sequence"; - // static const char *LV2_ATOM_SOUND = "http://lv2plug.in/ns/ext/atom#Sound"; - // static const char *LV2_ATOM_VECTOR = "http://lv2plug.in/ns/ext/atom#Vector"; - // static const char *LV2_ATOM_STRING = "http://lv2plug.in/ns/ext/atom#String"; - // static const char *LV2_MIDI_EVENT = "http://lv2plug.in/ns/ext/midi#MidiEvent"; - // static const char *LV2_DESIGNATION = "http://lv2plug.in/ns/lv2core#Designation"; class PluginHost::Urids { diff --git a/src/SetWifiConfig.cpp b/src/SetWifiConfig.cpp index 409fd03..4070e53 100644 --- a/src/SetWifiConfig.cpp +++ b/src/SetWifiConfig.cpp @@ -28,7 +28,6 @@ #include "SysExec.hpp" #include "WriteTemplateFile.hpp" - using namespace pipedal; using namespace std; @@ -42,23 +41,22 @@ using namespace std; #define SYSTEMCTL_BIN "/usr/bin/systemctl" - static char DNSMASQ_APD_PATH[] = "/etc/dnsmasq.d/30-pipedal-apd.conf"; static char DNSMASQ_P2P_SOURCE_PATH[] = "/etc/pipedal/config/templates/30-pipedal-p2p.conf"; static char DNSMASQ_P2P_PATH[] = "/etc/dnsmasq.d/30-pipedal-p2p.conf"; - -static bool IsApdInstalled() { +static bool IsApdInstalled() +{ + return std::filesystem::exists(DNSMASQ_APD_PATH); } -static bool IsP2pInstalled() { +static bool IsP2pInstalled() +{ return std::filesystem::exists(DNSMASQ_P2P_PATH); } - - static void restoreApdDhcpdConfFile() { // remove the interface wlan0 section. @@ -135,7 +133,6 @@ static void restoreP2pDhcpdConfFile() } } - static void restoreApdDnsmasqConfFile() { std::filesystem::path path(DNSMASQ_APD_PATH); @@ -155,21 +152,20 @@ static void restoreP2pDnsmasqConfFile() static void UninstallHostApd() { - if (IsApdInstalled()) - { - sysExec(SYSTEMCTL_BIN " stop hostapd"); - sysExec(SYSTEMCTL_BIN " disable hostapd"); - sysExec(SYSTEMCTL_BIN " stop dnsmasq"); - sysExec(SYSTEMCTL_BIN " disable dnsmasq"); + if (IsApdInstalled()) + { + sysExec(SYSTEMCTL_BIN " stop hostapd"); + sysExec(SYSTEMCTL_BIN " disable hostapd"); + sysExec(SYSTEMCTL_BIN " stop dnsmasq"); + sysExec(SYSTEMCTL_BIN " disable dnsmasq"); - restoreApdDhcpdConfFile(); - restoreApdDnsmasqConfFile(); - - sysExec(SYSTEMCTL_BIN " unmask wpa_supplicant"); // TODO: Do we need this now we have no_hook line. - sysExec(SYSTEMCTL_BIN " enable wpa_supplicant"); - sysExec(SYSTEMCTL_BIN " start wpa_supplicant"); - } + restoreApdDhcpdConfFile(); + restoreApdDnsmasqConfFile(); + sysExec(SYSTEMCTL_BIN " unmask wpa_supplicant"); // TODO: Do we need this now we have no_hook line. + sysExec(SYSTEMCTL_BIN " enable wpa_supplicant"); + sysExec(SYSTEMCTL_BIN " start wpa_supplicant"); + } } static void UninstallP2p(); @@ -327,29 +323,28 @@ void pipedal::SetWifiConfig(const WifiConfigSettings &settings) sysExec("rfkill unblock wlan"); sysExec(SYSTEMCTL_BIN " daemon-reload"); -// sysExec(SYSTEMCTL_BIN " mask wpa_supplicant"); + // sysExec(SYSTEMCTL_BIN " mask wpa_supplicant"); sysExec(SYSTEMCTL_BIN " stop wpa_supplicant"); - sysExec(SYSTEMCTL_BIN " unmask hostapd"); - if (sysExec(SYSTEMCTL_BIN " restart hostapd") != 0) - { - throw PiPedalException("Unable to start the access point."); - } - if (sysExec("systemctl is-active --quiet hostapd") != 0) - { - throw PiPedalException("Unable to start the access point."); - } - sysExec(SYSTEMCTL_BIN " enable hostapd"); + // sysExec(SYSTEMCTL_BIN " unmask hostapd"); + // if (sysExec(SYSTEMCTL_BIN " restart hostapd") != 0) + // { + // throw PiPedalException("Unable to start the access point."); + // } + // if (sysExec("systemctl is-active --quiet hostapd") != 0) + // { + // throw PiPedalException("Unable to start the access point."); + // } + // sysExec(SYSTEMCTL_BIN " enable hostapd"); sysExec(SYSTEMCTL_BIN " stop wpa_supplicant"); -// sysExec(SYSTEMCTL_BIN " mask wpa_supplicant"); + // sysExec(SYSTEMCTL_BIN " mask wpa_supplicant"); sysExec(SYSTEMCTL_BIN " restart dnsmasq"); sysExec(SYSTEMCTL_BIN " enable dnsmasq"); } } - /********************************************************************************* p2p configuration: @@ -359,9 +354,9 @@ dnsmaqsq.d/30-pipedal-p2p.conf: interface=p2p-wlan0-0 dhcp-range=p2p-wlan0,173.24.0.3,172.23.0.127,1h - domain=local - address=/pipedal.local/172.23.0.2 - + domain=local + address=/pipedal.local/172.23.0.2 + except-interface=eth0 except-interface=wlan0 except-interface=lo @@ -376,7 +371,6 @@ interface p2p-wlan0-0 Watch resolv.conf to make sure we don't lose DNS servers. ************************************************************************************/ - void UninstallP2p() { if (IsP2pInstalled()) @@ -390,141 +384,143 @@ void UninstallP2p() restoreP2pDhcpdConfFile(); restoreP2pDnsmasqConfFile(); - sysExec(SYSTEMCTL_BIN " restart dhcpcd"); WifiDirectConfigSettings wifiDirectConfigSettings; wifiDirectConfigSettings.Load(); wifiDirectConfigSettings.enable_ = false; wifiDirectConfigSettings.Save(); - } } - void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings) { - char band; - if (!settings.enable_) + try { - cout << "Disabling P2P" << endl; - UninstallP2p(); - - ServiceConfiguration deviceIdFile; - deviceIdFile.Load(); - deviceIdFile.deviceName = settings.hotspotName_; - deviceIdFile.Save(); - - - // Announce new mDNS service with potentially new deviceName. - sysExec(SYSTEMCTL_BIN " restart pipedald"); - - } - else - { - - settings.Save(); - // ******************* device_uuid - - ServiceConfiguration deviceIdFile; - deviceIdFile.Load(); - deviceIdFile.deviceName = settings.hotspotName_; - deviceIdFile.Save(); - - // ******************** dsnmasq ****** - - std::filesystem::remove(DNSMASQ_P2P_PATH); - std::filesystem::copy_file(DNSMASQ_P2P_SOURCE_PATH, DNSMASQ_P2P_PATH); - - // ****** dhcpd.conf ***/ - std::filesystem::path dhcpcdConfig("/etc/dhcpcd.conf"); - if (std::filesystem::exists(dhcpcdConfig)) + char band; + if (!settings.enable_) { - SystemConfigFile dhcpcd(dhcpcdConfig); + cout << "Disabling P2P" << endl; + UninstallP2p(); - // dhcpcd.conf: - // ====== - // interface p2p-wlan0-0 - // static ip_address=172.24.0.1/24 - // domain_name_server=172.24.0.1 + ServiceConfiguration deviceIdFile; + deviceIdFile.Load(); + deviceIdFile.deviceName = settings.hotspotName_; + deviceIdFile.Save(); + // Announce new mDNS service with potentially new deviceName. + sysExec(SYSTEMCTL_BIN " restart pipedald"); + } + else + { + cout << "Enabling P2P" << endl; - int line = dhcpcd.GetLineThatStartsWith("hostname"); - std::string hostNameLine; - if (false) - { - // hostNameLine = "hostname " + settings.mdnsName_; - } - else - { - hostNameLine = "hostname"; // the default value. - } - if (line != -1) - { - dhcpcd.SetLineValue(line, hostNameLine); - } - else - { - dhcpcd.AppendLine(hostNameLine); - } + settings.Save(); + // ******************* device_uuid - // erase any existing interface for p2p-wlan0-0 - line = dhcpcd.GetLineNumber("interface p2p-wlan0-0"); - if (line != -1) + ServiceConfiguration deviceIdFile; + deviceIdFile.Load(); + deviceIdFile.deviceName = settings.hotspotName_; + deviceIdFile.Save(); + + // ******************** dsnmasq ****** + + std::filesystem::remove(DNSMASQ_P2P_PATH); + std::filesystem::copy_file(DNSMASQ_P2P_SOURCE_PATH, DNSMASQ_P2P_PATH); + + // ****** dhcpd.conf ***/ + std::filesystem::path dhcpcdConfig("/etc/dhcpcd.conf"); + if (std::filesystem::exists(dhcpcdConfig)) { - dhcpcd.EraseLine(line); - while (line < dhcpcd.GetLineCount()) + cout << "Updating /etc/dhcpcd.conf" << endl; + SystemConfigFile dhcpcd(dhcpcdConfig); + + // dhcpcd.conf: + // ====== + // interface p2p-wlan0-0 + // static ip_address=172.24.0.1/24 + // domain_name_server=172.24.0.1 + + int line = dhcpcd.GetLineThatStartsWith("hostname"); + std::string hostNameLine; + if (false) { - const std::string &lineValue = dhcpcd.GetLineValue(line); - if (lineValue.length() > 0 && (lineValue[0] == ' ' || lineValue[0] == '\t')) + // hostNameLine = "hostname " + settings.mdnsName_; + } + else + { + hostNameLine = "hostname"; // the default value. + } + if (line != -1) + { + dhcpcd.SetLineValue(line, hostNameLine); + } + else + { + dhcpcd.AppendLine(hostNameLine); + } + + // erase any existing interface for p2p-wlan0-0 + line = dhcpcd.GetLineNumber("interface p2p-wlan0-0"); + if (line != -1) + { + dhcpcd.EraseLine(line); + while (line < dhcpcd.GetLineCount()) { - dhcpcd.EraseLine(line); - } - else - { - break; + const std::string &lineValue = dhcpcd.GetLineValue(line); + if (lineValue.length() > 0 && (lineValue[0] == ' ' || lineValue[0] == '\t')) + { + dhcpcd.EraseLine(line); + } + else + { + break; + } } } + if (line == -1) + { + dhcpcd.AppendLine(""); + line = dhcpcd.GetLineCount(); + } + // interface p2p-wlan0-0 + // static ip_address=172.24.0.1/16 (trying int on .1.) + // domain_name_server=172.24.0.1 + + dhcpcd.InsertLine(line++, "interface p2p-wlan0-0"); + dhcpcd.InsertLine(line++, " static ip_address=" P2P_INTERFACE_ADDR); + dhcpcd.InsertLine(line++, " nohook wpa_supplicant"); + // dhcpcd.InsertLine(line++, " domain_name_servers=" P2P_IP_ADDRESS); + dhcpcd.Save(dhcpcdConfig); } - if (line == -1) + + // **************** start services ************ + + cout << "Starting P2P services." << endl; + sysExec("rfkill unblock wlan"); + + sysExec(SYSTEMCTL_BIN " daemon-reload"); + + sysExec(SYSTEMCTL_BIN " stop pipedal_p2pd"); + sysExec(SYSTEMCTL_BIN " restart dhcpcd"); + sysExec(SYSTEMCTL_BIN " start wpa_supplicant"); + sysExec(SYSTEMCTL_BIN " enable wpa_supplicant"); // ?? Not sure that's still right. :-/ + sysExec(SYSTEMCTL_BIN " start dnsmasq"); + sysExec(SYSTEMCTL_BIN " enable dnsmasq"); + sysExec(SYSTEMCTL_BIN " start pipedal_p2pd"); + if (sysExec(SYSTEMCTL_BIN " start pipedal_p2pd") != 0) { - dhcpcd.AppendLine(""); - line = dhcpcd.GetLineCount(); + throw PiPedalException("Unable to start the Wi-Fi Direct access point."); } - // interface p2p-wlan0-0 - // static ip_address=172.24.0.1/16 (trying int on .1.) - // domain_name_server=172.24.0.1 - dhcpcd.InsertLine(line++, "interface p2p-wlan0-0"); - dhcpcd.InsertLine(line++, " static ip_address=" P2P_INTERFACE_ADDR); - dhcpcd.InsertLine(line++, " nohook wpa_supplicant"); - //dhcpcd.InsertLine(line++, " domain_name_servers=" P2P_IP_ADDRESS); - dhcpcd.Save(dhcpcdConfig); + sysExec(SYSTEMCTL_BIN " enable pipedal_p2pd"); + sysExec(SYSTEMCTL_BIN " restart pipedald"); } - - - // **************** start services ************ - - cout << "Starting services." << endl; - sysExec("rfkill unblock wlan"); - - sysExec(SYSTEMCTL_BIN " daemon-reload"); - - sysExec(SYSTEMCTL_BIN " stop pipedal_p2pd"); - sysExec(SYSTEMCTL_BIN " restart dhcpcd"); - sysExec(SYSTEMCTL_BIN " start wpa_supplicant"); - sysExec(SYSTEMCTL_BIN " enable wpa_supplicant"); // ?? Not sure that's still right. :-/ - sysExec(SYSTEMCTL_BIN " start dnsmasq"); - sysExec(SYSTEMCTL_BIN " enable dnsmasq"); - sysExec(SYSTEMCTL_BIN " start pipedal_p2pd"); - if (sysExec(SYSTEMCTL_BIN " start pipedal_p2pd") != 0) - { - throw PiPedalException("Unable to start the Wi-Fi Direct access point."); - } - - sysExec(SYSTEMCTL_BIN " enable pipedal_p2pd"); - sysExec(SYSTEMCTL_BIN " restart pipedald"); + } + catch (const std::exception &e) + { + cout << e.what() << endl; } } @@ -534,11 +530,11 @@ void pipedal::OnWifiUninstall() if (IsApdInstalled()) { UninstallHostApd(); - } else if (IsP2pInstalled()) + } + else if (IsP2pInstalled()) { UninstallP2p(); } - } void pipedal::OnWifiInstallComplete() { @@ -551,5 +547,4 @@ void pipedal::OnWifiInstallComplete() // { // sysExec(SYSTEMCTL_BIN " daemon-reload"); // } - } diff --git a/src/main.cpp b/src/main.cpp index f019d0e..d9f386b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -825,11 +825,13 @@ int main(int argc, char *argv[]) } } - Lv2Log::info("Shutting down gracefully."); + Lv2Log::info("Closing audio session."); model.Close(); + Lv2Log::info("Stopping web server."); server->ShutDown(5000); server->Join(); + Lv2Log::info("Shutdown complete."); } catch (const std::exception &e) diff --git a/src/templates/30-pipedal-apd.conf b/src/templates/30-pipedal-apd.conf index fd8c808..e69de29 100644 --- a/src/templates/30-pipedal-apd.conf +++ b/src/templates/30-pipedal-apd.conf @@ -1,24 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022 Robin E. R. Davies - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - diff --git a/src/templates/pipedald.service.template b/src/templates/pipedald.service.template index 37ceaeb..3fe571a 100644 --- a/src/templates/pipedald.service.template +++ b/src/templates/pipedald.service.template @@ -3,7 +3,6 @@ Description=${DESCRIPTION} After=network.target After=sound.target After=local-fs.target -After=avahi-daemon