From 3057d78efe27e7416f63b18c07aca997b9ec239a Mon Sep 17 00:00:00 2001 From: Robin Davies Date: Fri, 13 Sep 2024 06:13:57 -0400 Subject: [PATCH] Refuse to install on buster. --- PiPedalCommon/src/CMakeLists.txt | 2 +- PiPedalCommon/src/Lv2Log.cpp | 116 ++++++++++++++++ PiPedalCommon/src/WifiConfigSettings.cpp | 3 +- PiPedalCommon/src/include/Lv2Log.hpp | 167 +++++++++++++++++++++++ react/src/SettingsDialog.tsx | 3 +- src/CMakeLists.txt | 7 +- src/ConfigMain.cpp | 106 ++++++++++---- 7 files changed, 367 insertions(+), 37 deletions(-) create mode 100644 PiPedalCommon/src/Lv2Log.cpp create mode 100644 PiPedalCommon/src/include/Lv2Log.hpp diff --git a/PiPedalCommon/src/CMakeLists.txt b/PiPedalCommon/src/CMakeLists.txt index 154e8ce..f95dc77 100644 --- a/PiPedalCommon/src/CMakeLists.txt +++ b/PiPedalCommon/src/CMakeLists.txt @@ -59,7 +59,7 @@ add_library(PiPedalCommon STATIC NetworkManagerInterfaces.cpp include/NetworkManagerInterfaces.hpp - + Lv2Log.cpp include/Lv2Log.hpp DBusEvent.cpp DBusVariantHelper.cpp DBusLog.cpp diff --git a/PiPedalCommon/src/Lv2Log.cpp b/PiPedalCommon/src/Lv2Log.cpp new file mode 100644 index 0000000..7b43bec --- /dev/null +++ b/PiPedalCommon/src/Lv2Log.cpp @@ -0,0 +1,116 @@ +// Copyright (c) 2022 Robin 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. + +#include +#include +#include "Lv2Log.hpp" +#include +#include +#include + +using namespace pipedal; + +#include + + + + +static auto timeZero = std::chrono::system_clock::now(); +bool Lv2Log::show_time_ = true; + +std::string timeTag() +{ + if (!Lv2Log::show_time()) return ""; + + using namespace std::chrono; + + auto now = std::chrono::system_clock::now(); + std::time_t now_c = std::chrono::system_clock::to_time_t(now); + + auto milliseconds = std::chrono::duration_cast(now.time_since_epoch()) % 1000; + + + std::stringstream s; + + using namespace std; + s << std::put_time(std::localtime(&now_c), "%Y-%m-%d %H:%M:%S") << "." << std::setw(3) << std::setfill('0') << milliseconds.count() << " "; + return s.str(); + +} +class StdErrLogger : public Lv2Logger +{ + std::mutex m; + + + public : virtual ~StdErrLogger() {} + + virtual void onError(const char* message) + { + std::lock_guard lock(m); + std::cerr << timeTag() << "ERR: " << message << std::endl; + } + virtual void onWarning(const char* message) + { + std::lock_guard lock(m); + std::cerr << timeTag() << "WRN: " << message << std::endl; + } + + virtual void onDebug(const char* message) + { + std::lock_guard lock(m); + std::cerr << timeTag() << "DBG: " << message << std::endl; + } + virtual void onInfo(const char* message) + { + std::lock_guard lock(m); + std::cerr << timeTag() << "INF: " << message << std::endl; + } +}; + +Lv2Logger *Lv2Log::logger_ = new StdErrLogger(); + +LogLevel Lv2Log::log_level_ = LogLevel::Debug; + +void Lv2Log::v_error(const char *format, va_list arglist) +{ + char buffer[512]; + vsnprintf(buffer,sizeof(buffer),format,arglist); + logger_->onError(buffer); +} +void Lv2Log::v_warning(const char *format, va_list arglist) +{ + char buffer[512]; + vsnprintf(buffer,sizeof(buffer),format,arglist); + logger_->onWarning(buffer); +} +void Lv2Log::v_debug(const char *format, va_list arglist) +{ + char buffer[512]; + vsnprintf(buffer,sizeof(buffer),format,arglist); + logger_->onDebug(buffer); +} +void Lv2Log::v_info(const char *format, va_list arglist) +{ + char buffer[512]; + vsnprintf(buffer,sizeof(buffer),format,arglist); + logger_->onInfo(buffer); + +} + + diff --git a/PiPedalCommon/src/WifiConfigSettings.cpp b/PiPedalCommon/src/WifiConfigSettings.cpp index c6a364b..ae525c3 100644 --- a/PiPedalCommon/src/WifiConfigSettings.cpp +++ b/PiPedalCommon/src/WifiConfigSettings.cpp @@ -26,7 +26,7 @@ #include #include #include "SysExec.hpp" - +#include "Lv2Log.hpp" #include #include #include @@ -136,6 +136,7 @@ static void openWithPerms( perms, std::filesystem::perm_options::replace); } catch (const std::exception&) { + Lv2Log::warning(SS("Failed to set permissions on" << path << ".")); } } diff --git a/PiPedalCommon/src/include/Lv2Log.hpp b/PiPedalCommon/src/include/Lv2Log.hpp new file mode 100644 index 0000000..721c1a5 --- /dev/null +++ b/PiPedalCommon/src/include/Lv2Log.hpp @@ -0,0 +1,167 @@ +// Copyright (c) 2022 Robin 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. + +#pragma once +#include +#include + +namespace pipedal +{ + + class Lv2Logger + { + public: + virtual ~Lv2Logger() = default; + + virtual void onError(const char *message) = 0; + virtual void onWarning(const char *message) = 0; + virtual void onDebug(const char *message) = 0; + virtual void onInfo(const char *message) = 0; + }; + + enum class LogLevel + { + None = 0, + Error = 1, + Warning = 2, + Info = 3, + Debug = 4 + }; + + class Lv2Log + { + private: + + static Lv2Logger *logger_; + static LogLevel log_level_; + static bool show_time_; + + static void v_error(const char *format, va_list arglist); + static void v_warning(const char *format, va_list arglist); + static void v_debug(const char *format, va_list arglist); + static void v_info(const char *format, va_list arglist); + + public: + static void set_logger(Lv2Logger *logger) + { + Lv2Log::logger_ = logger; + } + static void log_level(LogLevel level) + { + Lv2Log::log_level_ = level; + } + static LogLevel log_level() + { + return Lv2Log::log_level_; + } + static void show_time(bool show) + { + show_time_ = show; + } + static bool show_time() { + return show_time_; + } + + // static void error(const char* message) { + // if (Lv2Log::log_level_ >= LogLevel::Error) + // { + // logger_->onError(message); + // } + // } + // static void warning(const char* message) { + // if (Lv2Log::log_level_ >= LogLevel::Warning) + // { + // logger_->onWarning(message); + // } + // } + // static void debug(const char* message) { + // if (Lv2Log::log_level_ >= LogLevel::Debug) + // { + // logger_->onDebug(message); + // } + // } + // static void info(const char* message) { + // if (Lv2Log::log_level_ >= LogLevel::Info) + // { + // logger_->onInfo(message); + // } + // } + + static void info(const char *format, ...) + { + if (Lv2Log::log_level_ >= LogLevel::Info) + { + va_list arglist; + va_start(arglist, format); + v_info(format, arglist); + va_end(arglist); + } + } + static void info(const std::string &str) + { + info("%s", str.c_str()); + } + + static void debug(const char *format, ...) + { + if (Lv2Log::log_level_ >= LogLevel::Debug) + { + va_list arglist; + va_start(arglist, format); + v_debug(format, arglist); + va_end(arglist); + } + } + static void debug(const std::string &str) + { + debug("%s", str.c_str()); + } + + static void warning(const char *format, ...) + { + if (Lv2Log::log_level_ >= LogLevel::Warning) + { + va_list arglist; + va_start(arglist, format); + v_warning(format, arglist); + va_end(arglist); + } + } + static void warning(const std::string &str) + { + warning("%s", str.c_str()); + } + + static void error(const char *format, ...) + { + if (Lv2Log::log_level_ >= LogLevel::Warning) + { + va_list arglist; + va_start(arglist, format); + v_error(format, arglist); + va_end(arglist); + } + } + static void error(const std::string &str) + { + error("%s", str.c_str()); + } + }; + +} // namespace pipedal \ No newline at end of file diff --git a/react/src/SettingsDialog.tsx b/react/src/SettingsDialog.tsx index 929951e..43500c0 100644 --- a/react/src/SettingsDialog.tsx +++ b/react/src/SettingsDialog.tsx @@ -571,7 +571,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })( (
- Select and configure an audio device. You may optionally configure MIDI inputs, and set up a Wi-Fi Direct Hotspot now as well. + Select and configure an audio device. You may optionally configure MIDI inputs, and configure up a Wi-Fi Auto-Hotspot as well. + The Auto-Hotspot feature allows you to connect to Pipedal even if you don't have access to a Wi-Fi router. Access and modify these settings later by selecting the Settings menu item on the main menu. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 66e305f..e9b5047 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -194,7 +194,6 @@ set (PIPEDAL_SOURCES RequestHandler.hpp Scratch.cpp PluginHost.hpp PluginHost.cpp PluginType.hpp PluginType.cpp - Lv2Log.hpp Lv2Log.cpp PiPedalSocket.hpp PiPedalSocket.cpp PiPedalVersion.hpp PiPedalVersion.cpp PiPedalModel.hpp PiPedalModel.cpp @@ -297,7 +296,7 @@ target_link_libraries(pipedald PRIVATE PiPedalCommon ################################# add_executable(hotspotManagerTest hotspotManagerTestMain.cpp - HotspotManager.cpp HotspotManager.hpp Lv2Log.cpp Lv2Log.hpp) + HotspotManager.cpp HotspotManager.hpp) target_link_libraries(hotspotManagerTest PRIVATE ${PIPEDAL_LIBS}) @@ -608,7 +607,6 @@ add_executable(pipedalconfig SystemConfigFile.hpp SystemConfigFile.cpp WifiChannelSelectors.cpp WifiChannelSelectors.hpp asan_options.cpp - Lv2Log.cpp Lv2Log.hpp ) @@ -621,7 +619,6 @@ add_executable(pipedal_latency_test PiLatencyMain.cpp PiPedalAlsa.hpp PiPedalAlsa.cpp asan_options.cpp - Lv2Log.cpp Lv2Log.hpp AlsaDriver.cpp AlsaDriver.hpp JackConfiguration.hpp JackConfiguration.cpp JackServerSettings.hpp JackServerSettings.cpp @@ -648,7 +645,6 @@ target_link_libraries(capturepresets ${PIPEDAL_LIBS}) add_executable(pipedal_update UpdateMain.cpp UpdateResults.cpp UpdateResults.hpp - Lv2Log.hpp Lv2Log.cpp Lv2SystemdLogger.cpp Lv2SystemdLogger.hpp UpdateResults.cpp UpdateResults.hpp AdminInstallUpdate.cpp AdminInstallUpdate.hpp @@ -664,7 +660,6 @@ add_executable(pipedaladmind AdminMain.cpp CommandLineParser.hpp JackServerSettings.hpp JackServerSettings.cpp Lv2SystemdLogger.hpp Lv2SystemdLogger.cpp - Lv2Log.cpp Lv2Log.hpp SystemConfigFile.hpp SystemConfigFile.cpp CpuGovernor.cpp CpuGovernor.hpp asan_options.cpp diff --git a/src/ConfigMain.cpp b/src/ConfigMain.cpp index 806c4ba..bb26e61 100644 --- a/src/ConfigMain.cpp +++ b/src/ConfigMain.cpp @@ -552,6 +552,11 @@ static bool IsP2pServiceEnabled() void Uninstall() { + // if NetworkManager isn't installed, Install will have failed. + // Do cleanup as if the Isntall had not failed. + + PretendNetworkManagerIsInstalled(); + try { OnWifiUninstall(true); @@ -897,6 +902,11 @@ void InstallPgpKey() void Install(const fs::path &programPrefix, const std::string endpointAddress) { cout << "Configuring pipedal" << endl; + + if (!UsingNetworkManager()) + { + throw std::runtime_error("The current OS is not using NetworkManager. Services not configured."); + } try { DeployVarConfig(); @@ -1275,6 +1285,13 @@ static int ListP2PChannels(const std::vector &arguments) return EXIT_SUCCESS; } +void RequireNetworkManager() +{ + if (!UsingNetworkManager()) + { + throw std::runtime_error("The current OS is not using NetworkManager."); + } +} int main(int argc, char **argv) { CommandLineParser parser; @@ -1407,68 +1424,92 @@ int main(int argc, char **argv) } if (install) { - fs::path prefix; - if (prefixOption.length() != 0) - { - prefix = fs::path(prefixOption); - } - else - { - prefix = fs::path(argv[0]).parent_path().parent_path(); - - fs::path pipedalPath = prefix / "sbin" / "pipedald"; - if (!fs::exists(pipedalPath)) + try { + fs::path prefix; + if (prefixOption.length() != 0) { - std::stringstream s; - s << "Can't find pipedald executable at " << pipedalPath << ". Try again using the -prefix option."; - throw std::runtime_error(s.str()); + prefix = fs::path(prefixOption); + } + else + { + prefix = fs::path(argv[0]).parent_path().parent_path(); + + fs::path pipedalPath = prefix / "sbin" / "pipedald"; + if (!fs::exists(pipedalPath)) + { + std::stringstream s; + s << "Can't find pipedald executable at " << pipedalPath << ". Try again using the -prefix option."; + throw std::runtime_error(s.str()); + } } - } - if (portOption == "") - { - portOption = GetCurrentWebServicePort(); if (portOption == "") { - portOption = "80"; + portOption = GetCurrentWebServicePort(); + if (portOption == "") + { + portOption = "80"; + } } - } - if (portOption.find(':') == string::npos) + if (portOption.find(':') == string::npos) + { + portOption = "0.0.0.0:" + portOption; + } + Install(prefix, portOption); + FileSystemSync(); + + } catch (const std::exception&e) { - portOption = "0.0.0.0:" + portOption; + cout << "ERROR: " << e.what() << endl; + FileSystemSync(); + return EXIT_SUCCESS; // say we succeeded so we don't put APT into a hellish state. } - Install(prefix, portOption); - FileSystemSync(); } else if (uninstall) { - Uninstall(); - FileSystemSync(); + try { + Uninstall(); + FileSystemSync(); + } catch (const std::exception &e) + { + cout << "ERROR: " << e.what() << endl; + FileSystemSync(); + return EXIT_SUCCESS; // Say we succeeds so that we don't put APT into a hellish state. + } } else if (stop) { + RequireNetworkManager(); StopService(); + } else if (start) { + RequireNetworkManager(); StartService(); } else if (restart) { + RequireNetworkManager(); RestartService(excludeShutdownService); } else if (enable) { + RequireNetworkManager(); EnableService(); + FileSystemSync(); + } else if (disable) { + RequireNetworkManager(); DisableService(); + FileSystemSync(); + } else if (enable_p2p) { - cout << "ERROR: Wi-Fi p2p connections are no longer supported. Use hotspots instead." << endl; - return EXIT_FAILURE; + throw std::runtime_error("Wi-Fi p2p connections are no longer supported. Use hotspots instead."); // try // { // auto argv = parser.Arguments(); @@ -1487,15 +1528,20 @@ int main(int argc, char **argv) } else if (disable_p2p) { + RequireNetworkManager(); WifiDirectConfigSettings settings; settings.Load(); settings.enable_ = false; SetWifiDirectConfig(settings); + + RestartService(true); return EXIT_SUCCESS; } else if (enable_hotspot) { + RequireNetworkManager(); + auto argv = parser.Arguments(); WifiConfigSettings settings; @@ -1522,9 +1568,12 @@ int main(int argc, char **argv) { throw std::runtime_error("Failed to restart the " PIPEDALD_SERVICE " service."); } + FileSystemSync(); } else if (disable_hotspot) { + RequireNetworkManager(); + WifiConfigSettings settings; settings.valid_ = true; settings.autoStartMode_ = (uint16_t)HotspotAutoStartMode::Never; @@ -1533,6 +1582,7 @@ int main(int argc, char **argv) { throw std::runtime_error("Failed to restart the " PIPEDALD_SERVICE " service."); } + FileSystemSync(); } } catch (const std::exception &e)