pipedalconfig Wifi Direct configuration
This commit is contained in:
Vendored
+36
-1
@@ -4,6 +4,7 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "(gdb) pipedaltest Launch",
|
||||
"type": "cppdbg",
|
||||
@@ -111,7 +112,41 @@
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "(gdb) pipedalconfig",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
// Resolved by CMake Tools:
|
||||
"program": "${command:cmake.launchTargetPath}",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [
|
||||
{
|
||||
// add the directory where our target was built to the PATHs
|
||||
// it gets resolved by CMake Tools:
|
||||
"name": "PATH",
|
||||
"value": "$PATH:${command:cmake.launchTargetDirectory}"
|
||||
},
|
||||
{
|
||||
"name": "OTHER_VALUE",
|
||||
"value": "Something something"
|
||||
}
|
||||
],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
@@ -14,10 +14,14 @@ enable_testing()
|
||||
# Frameworks
|
||||
# catch
|
||||
|
||||
add_subdirectory("submodules/pipedal_p2pd")
|
||||
|
||||
add_subdirectory("react")
|
||||
|
||||
add_subdirectory("src")
|
||||
|
||||
install (TARGETS pipedal_p2pd DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
|
||||
)
|
||||
|
||||
# select LV2 source directory for the current build architecture
|
||||
|
||||
@@ -51,6 +55,9 @@ install (FILES ${PROJECT_SOURCE_DIR}/src/template.service
|
||||
${PROJECT_SOURCE_DIR}/src/templateAdmin.service
|
||||
${PROJECT_SOURCE_DIR}/src/templateJack.service
|
||||
${PROJECT_SOURCE_DIR}/src/defaultFavorites.json
|
||||
${PROJECT_SOURCE_DIR}/src/templateP2pd.service
|
||||
${PROEJCT_SOURCE_DIR}/src/template_p2pd.conf
|
||||
|
||||
DESTINATION /etc/pipedal/config )
|
||||
|
||||
install (DIRECTORY ${LV2_SOURCE_DIRECTORY}
|
||||
|
||||
+11
-1
@@ -102,6 +102,7 @@ add_custom_command(
|
||||
|
||||
|
||||
set (PIPEDAL_SOURCES
|
||||
P2pConfigFiles.hpp
|
||||
StdErrorCapture.hpp StdErrorCapture.cpp
|
||||
Ipv6Helpers.cpp Ipv6Helpers.hpp
|
||||
PluginPreset.cpp PluginPreset.hpp
|
||||
@@ -110,6 +111,7 @@ set (PIPEDAL_SOURCES
|
||||
SysExec.cpp SysExec.hpp
|
||||
BeastServer.cpp BeastServer.hpp HtmlHelper.cpp HtmlHelper.hpp pch.h Uri.cpp Uri.hpp
|
||||
WifiConfigSettings.hpp WifiConfigSettings.cpp
|
||||
WifiDirectConfigSettings.hpp WifiDirectConfigSettings.cpp
|
||||
RequestHandler.hpp json.cpp json.hpp Scratch.cpp Lv2Host.hpp Lv2Host.cpp
|
||||
PluginType.hpp PluginType.cpp
|
||||
Lv2Log.hpp Lv2Log.cpp
|
||||
@@ -219,19 +221,24 @@ add_test(NAME DevTest COMMAND pipedaltest "[Dev]")
|
||||
#################################
|
||||
|
||||
|
||||
add_executable(pipedalconfig json.cpp json.hpp
|
||||
add_executable(pipedalconfig
|
||||
PrettyPrinter.hpp
|
||||
json.cpp json.hpp
|
||||
HtmlHelper.cpp HtmlHelper.hpp
|
||||
CommandLineParser.hpp
|
||||
WriteTemplateFile.hpp WriteTemplateFile.cpp
|
||||
PiPedalException.hpp
|
||||
ConfigMain.cpp
|
||||
WifiConfigSettings.cpp WifiConfigSettings.hpp
|
||||
WifiDirectConfigSettings.cpp WifiDirectConfigSettings.hpp
|
||||
JackServerSettings.hpp JackServerSettings.cpp
|
||||
SetWifiConfig.hpp SetWifiConfig.cpp
|
||||
SystemConfigFile.hpp SystemConfigFile.cpp
|
||||
SysExec.hpp SysExec.cpp
|
||||
asan_options.cpp
|
||||
Lv2Log.cpp Lv2Log.hpp
|
||||
P2pConfigFiles.hpp
|
||||
|
||||
)
|
||||
|
||||
target_link_libraries(pipedalconfig PRIVATE pthread atomic stdc++fs
|
||||
@@ -242,11 +249,14 @@ add_executable(pipedaladmind ShutdownMain.cpp CommandLineParser.hpp
|
||||
json.hpp json.cpp HtmlHelper.hpp HtmlHelper.cpp Lv2Log.hpp Lv2Log.cpp
|
||||
Lv2SystemdLogger.hpp Lv2SystemdLogger.cpp
|
||||
WifiConfigSettings.cpp WifiConfigSettings.hpp
|
||||
WifiDirectConfigSettings.cpp WifiDirectConfigSettings.hpp
|
||||
SetWifiConfig.hpp SetWifiConfig.cpp
|
||||
SystemConfigFile.hpp SystemConfigFile.cpp
|
||||
SysExec.hpp SysExec.cpp
|
||||
CpuGovernor.cpp CpuGovernor.hpp
|
||||
asan_options.cpp
|
||||
P2pConfigFiles.hpp
|
||||
|
||||
)
|
||||
target_link_libraries(pipedaladmind PRIVATE pthread atomic stdc++fs systemd)
|
||||
|
||||
|
||||
+205
-103
@@ -31,8 +31,10 @@
|
||||
#include <sys/wait.h>
|
||||
#include <pwd.h>
|
||||
#include "JackServerSettings.hpp"
|
||||
#include "P2pConfigFiles.hpp"
|
||||
#include "PrettyPrinter.hpp"
|
||||
|
||||
#define SS(x) ( ((std::stringstream&)(std::stringstream() << x )).str())
|
||||
#define SS(x) (((std::stringstream &)(std::stringstream() << x)).str())
|
||||
|
||||
using namespace std;
|
||||
using namespace pipedal;
|
||||
@@ -54,6 +56,7 @@ using namespace pipedal;
|
||||
#define SERVICE_PATH "/usr/lib/systemd/system"
|
||||
#define NATIVE_SERVICE "pipedald"
|
||||
#define ADMIN_SERVICE "pipedaladmind"
|
||||
#define PIPEDAL_P2PD_SERVICE "pipedal_p2pd"
|
||||
#define JACK_SERVICE "jack"
|
||||
|
||||
#define REMOVE_OLD_SERVICE 1 // Grandfathering: whether to remove the old shutdown service (now pipedaladmind)
|
||||
@@ -110,12 +113,12 @@ void DisableService()
|
||||
{
|
||||
cout << "Error: Failed to disable the " ADMIN_SERVICE " service.";
|
||||
}
|
||||
#if REMOVE_OLD_SERVICE
|
||||
#if REMOVE_OLD_SERVICE
|
||||
if (sysExec(SYSTEMCTL_BIN " disable " OLD_SHUTDOWN_SERVICE ".service") != EXIT_SUCCESS)
|
||||
{
|
||||
cout << "Error: Failed to disable the " OLD_SHUTDOWN_SERVICE " service.";
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void StopService(bool excludeShutdownService = false)
|
||||
@@ -130,12 +133,12 @@ void StopService(bool excludeShutdownService = false)
|
||||
{
|
||||
cout << "Error: Failed to stop the " ADMIN_SERVICE " service.";
|
||||
}
|
||||
#if REMOVE_OLD_SERVICE
|
||||
#if REMOVE_OLD_SERVICE
|
||||
if (sysExec(SYSTEMCTL_BIN " stop " OLD_SHUTDOWN_SERVICE ".service") != EXIT_SUCCESS)
|
||||
{
|
||||
cout << "Error: Failed to stop the " OLD_SHUTDOWN_SERVICE " service.";
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if (sysExec(SYSTEMCTL_BIN " stop " JACK_SERVICE ".service") != EXIT_SUCCESS)
|
||||
{
|
||||
@@ -202,7 +205,7 @@ static bool userExists(const char *userName)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RemoveLine(const std::string&path, const std::string lineToRemove)
|
||||
static void RemoveLine(const std::string &path, const std::string lineToRemove)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
try
|
||||
@@ -234,16 +237,16 @@ static void RemoveLine(const std::string&path, const std::string lineToRemove)
|
||||
{
|
||||
throw PiPedalException(SS("Can't write to " << path));
|
||||
}
|
||||
for (auto&line: lines)
|
||||
for (auto &line : lines)
|
||||
{
|
||||
f << line << endl;
|
||||
f << line << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cout << "Failed to update " << path << ". " << e.what();
|
||||
cout << "Failed to update " << path << ". " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,8 +255,7 @@ void UninstallPamEnv()
|
||||
{
|
||||
RemoveLine(
|
||||
"/etc/security/pam_env.conf",
|
||||
PAM_LINE
|
||||
);
|
||||
PAM_LINE);
|
||||
}
|
||||
void InstallPamEnv()
|
||||
{
|
||||
@@ -295,16 +297,16 @@ void InstallPamEnv()
|
||||
{
|
||||
throw PiPedalException(SS("Can't write to " << path));
|
||||
}
|
||||
for (auto&line: lines)
|
||||
for (auto &line : lines)
|
||||
{
|
||||
f << line << endl;
|
||||
f << line << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cout << "Failed to update " << path << ". " << e.what();
|
||||
cout << "Failed to update " << path << ". " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,9 +322,9 @@ void InstallLimits()
|
||||
if (!std::filesystem::exists(limitsConfig))
|
||||
{
|
||||
ofstream output(limitsConfig);
|
||||
output << "# Realtime priority group used by pipedal/jack daemon" << endl;
|
||||
output << "@audio - rtprio 95" << endl;
|
||||
output << "@audio - memlock unlimited" << endl;
|
||||
output << "# Realtime priority group used by pipedal/jack daemon" << "\n";
|
||||
output << "@audio - rtprio 95" << "\n";
|
||||
output << "@audio - memlock unlimited" << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,15 +367,15 @@ void InstallJackService()
|
||||
}
|
||||
// lock account for login.
|
||||
silentSysExec("passwd -l " JACK_SERVICE_ACCOUNT_NAME);
|
||||
}
|
||||
}
|
||||
// Add to audio groups.
|
||||
// sysExec(USERMOD_BIN " -a -G " JACK_SERVICE_GROUP_NAME " " JACK_SERVICE_ACCOUNT_NAME);
|
||||
sysExec(USERMOD_BIN " -a -G" AUDIO_SERVICE_GROUP_NAME " " JACK_SERVICE_ACCOUNT_NAME);
|
||||
|
||||
// If ONBOARDING, add to bluetooth group.
|
||||
#ifdef ONBOARDING
|
||||
sysExec(USERMOD_BIN " -a -G bluetooth " JACK_SERVICE_ACCOUNT_NAME);
|
||||
#endif
|
||||
// If ONBOARDING, add to bluetooth group.
|
||||
#ifdef ONBOARDING
|
||||
sysExec(USERMOD_BIN " -a -G bluetooth " JACK_SERVICE_ACCOUNT_NAME);
|
||||
#endif
|
||||
|
||||
// deploy the systemd service file
|
||||
std::map<std::string, std::string> map; // nothing to customize.
|
||||
@@ -383,7 +385,6 @@ void InstallJackService()
|
||||
MaybeStartJackService();
|
||||
}
|
||||
|
||||
|
||||
int SudoExec(char **argv)
|
||||
{
|
||||
int pbPid;
|
||||
@@ -404,21 +405,25 @@ int SudoExec(char **argv)
|
||||
|
||||
void Uninstall()
|
||||
{
|
||||
|
||||
OnWifiUninstall();
|
||||
|
||||
StopService();
|
||||
DisableService();
|
||||
silentSysExec(SYSTEMCTL_BIN " stop jack");
|
||||
silentSysExec(SYSTEMCTL_BIN " disable jack");
|
||||
OnWifiUninstall();
|
||||
|
||||
std::filesystem::remove("/usr/bin/systemd/system/" OLD_SHUTDOWN_SERVICE ".service");
|
||||
std::filesystem::remove("/usr/bin/systemd/system/" ADMIN_SERVICE ".service");
|
||||
std::filesystem::remove("/usr/bin/systemd/system/" PIPEDAL_P2PD_SERVICE ".service");
|
||||
std::filesystem::remove("/usr/bin/systemd/system/" NATIVE_SERVICE ".service");
|
||||
std::filesystem::remove("/usr/bin/systemd/system/" JACK_SERVICE ".service");
|
||||
UninstallPamEnv();
|
||||
UninstallLimits();
|
||||
sysExec(SYSTEMCTL_BIN " daemon-reload");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Install(const std::filesystem::path &programPrefix, const std::string endpointAddress)
|
||||
{
|
||||
if (sysExec(GROUPADD_BIN " -f " AUDIO_SERVICE_GROUP_NAME) != EXIT_SUCCESS)
|
||||
@@ -470,7 +475,7 @@ void Install(const std::filesystem::path &programPrefix, const std::string endpo
|
||||
}
|
||||
// lock account for login.
|
||||
silentSysExec("passwd -l " SERVICE_ACCOUNT_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
// Add to audio groups.
|
||||
sysExec(USERMOD_BIN " -a -G " AUDIO_SERVICE_GROUP_NAME " " SERVICE_ACCOUNT_NAME);
|
||||
@@ -512,7 +517,8 @@ void Install(const std::filesystem::path &programPrefix, const std::string endpo
|
||||
{
|
||||
// create it.
|
||||
std::ofstream f(portAuthFile);
|
||||
if (!f.is_open()) {
|
||||
if (!f.is_open())
|
||||
{
|
||||
throw PiPedalException("Failed to create " + portAuthFile.string());
|
||||
}
|
||||
}
|
||||
@@ -535,7 +541,7 @@ void Install(const std::filesystem::path &programPrefix, const std::string endpo
|
||||
}
|
||||
}
|
||||
|
||||
cout << "Creating Systemd file." << endl;
|
||||
cout << "Creating Systemd file." << "\n";
|
||||
|
||||
std::map<string, string> map;
|
||||
|
||||
@@ -568,15 +574,147 @@ void Install(const std::filesystem::path &programPrefix, const std::string endpo
|
||||
}
|
||||
WriteTemplateFile(map, std::filesystem::path("/etc/pipedal/config/templateAdmin.service"), GetServiceFileName(ADMIN_SERVICE));
|
||||
|
||||
// /usr/bin/pipedal_p2pd --config-file /etc/pipedal/config/template_p2pd.conf
|
||||
|
||||
std::string pipedal_p2pd_cmd = SS(
|
||||
(programPrefix / "bin" / "pipedal_p2pd").string()
|
||||
<< " --config-file " << PIPEDAL_P2PD_CONF_PATH);
|
||||
map["COMMAND"] = pipedal_p2pd_cmd;
|
||||
|
||||
WriteTemplateFile(map, std::filesystem::path("/etc/pipedal/config/templateP2pd.service"), GetServiceFileName(PIPEDAL_P2PD_SERVICE));
|
||||
|
||||
sysExec(SYSTEMCTL_BIN " daemon-reload");
|
||||
|
||||
cout << "Starting services" << endl;
|
||||
cout << "Starting services" << "\n";
|
||||
RestartService(false);
|
||||
EnableService();
|
||||
|
||||
cout << "Complete" << endl;
|
||||
|
||||
cout << "Complete" << "\n";
|
||||
}
|
||||
|
||||
static void PrintHelp()
|
||||
{
|
||||
PrettyPrinter pp;
|
||||
pp << "pipedalconfig - Command-line post-install configuration for PiPedal" << "\n"
|
||||
<< "Copyright (c) 2022 Robin Davies. All rights reserved." << "\n"
|
||||
<< "\n"
|
||||
<< "See https://rerdavies.github.io/pipedal/Documentation.html for "
|
||||
<< "online documentation." << "\n"
|
||||
<< "\n"
|
||||
<< "Syntax:" << "\n";
|
||||
pp << Indent(4)
|
||||
<< "pipedalconfig [Options...]" << "\n"
|
||||
<< "\n";
|
||||
pp.Indent(0)
|
||||
<< "Options: " << "\n\n";
|
||||
pp.Indent(20);
|
||||
|
||||
pp
|
||||
<< HangingIndent() << " -h --help\t"
|
||||
<< "Display this message." << "\n"
|
||||
<< "\n"
|
||||
|
||||
<< HangingIndent() << " --install [--port <port#>]\t"
|
||||
<< "Install or re-install services and service accounts." << "\n"
|
||||
<< "\n"
|
||||
<< "The --port option controls which port the web server uses."
|
||||
<< "\n\n"
|
||||
|
||||
<< HangingIndent() << " --uninstall\t"
|
||||
<< "Remove installed services." << "\n"
|
||||
<< "\n"
|
||||
|
||||
<< HangingIndent() << " --enable\t"
|
||||
<< "Start the pipedal service at boot time." << "\n"
|
||||
<< "\n"
|
||||
|
||||
<< HangingIndent() << " --disable\tDo not start the pipedal service at boot time." << "\n"
|
||||
<< "\n"
|
||||
<< HangingIndent() << " --start\tStart the pipedal services." << "\n"
|
||||
<< "\n"
|
||||
<< HangingIndent() << " --stop\tStop the pipedal services." << "\n"
|
||||
<< "\n"
|
||||
<< HangingIndent() << " --restart\tRestart the pipedal services." << "\n"
|
||||
<< "\n"
|
||||
|
||||
<< HangingIndent() << " --enable-p2p <country_code> <ssid> [[<pin>] <channel>]\t"
|
||||
<< "Enable the P2P (Wi-Fi Direct) hotspot." << "\n\n"
|
||||
<< "<country_code> is the 2-letter ISO-3166 country code for "
|
||||
"the country you are in. see below for further notes."
|
||||
<< "\n\n"
|
||||
<< "<ssid> is the name you see when connecting. "
|
||||
<< "\n\n"
|
||||
<< "<pin> is an exactly-eight-digit pin number that you must "
|
||||
<< "enter when connecting to the hotspot. If you don't "
|
||||
<< "provide a pin, pipedalconfig will generate and "
|
||||
<< "display a random pin for you. The pin is a "
|
||||
<< "so-called \"label\" pin, which is the same every "
|
||||
<< "time you are asked to enter it (unlike a keypad pin "
|
||||
<< "which changes every time you need to enter it."
|
||||
<< "\n\n"
|
||||
<< "Consider attaching a label to the bottom of your device "
|
||||
<< "so you can can remember the pin if you wan't to connect a new "
|
||||
<< "device to PiPedal. (It's also available on the Settings page of PiPedal, if you have access to PiPedal UI on another device.)"
|
||||
<< "\n\n"
|
||||
<< "For best performance, the channel number should be 1, 6, or 11 (the Wifi Direct \"social\" channels). "
|
||||
<< "If you don't supply a channel number, PiPedal will select the least-busy of channels 1, 6 and 11."
|
||||
<< "\n\n"
|
||||
|
||||
<< HangingIndent() << " --disable-p2p\tDisabled Wi-Fi Direct access."
|
||||
<< "\n\n"
|
||||
|
||||
<< HangingIndent() << " --enable-legacy-ap\t <country_code> <ssid> <wep_password> <channel>\tEnable a legacy Wi-Fi access point."
|
||||
<< "\n\n"
|
||||
<< "Enable a legacy Wi-Fi access point. \n\n"
|
||||
<< "country_code is the 2-letter ISO-3166 country code for "
|
||||
<< "the country you are in. see below for further notes."
|
||||
<< "\n\n"
|
||||
<< "See below for an explanation of when you might want to use a legacy Wi-Fi access point instead of Wifi-Direct access."
|
||||
<< "an explanation of when you might want to use a legacy Access Point instead of "
|
||||
<< "a P2P (Wi-Fi Direct) connection. Generally, you should prefer a P2p connection "
|
||||
<< "to an ordinary Hotspot connection."
|
||||
<< "\n\n"
|
||||
|
||||
<< HangingIndent() << " --disable-legacy-ap\tDisabled the legacy Wi-Fi access point."
|
||||
<< "\n\n"
|
||||
|
||||
|
||||
<< Indent(0) << "Country codes:"
|
||||
<< "\n\n"
|
||||
<< Indent(4)
|
||||
<< "Country codes are used to determine Wi-Fi-regulatory regime - the "
|
||||
<< "channels you are legally allowed to use, and the features which must "
|
||||
<< "be enabled or disabled on the channels you can use. "
|
||||
<< "\n\n"
|
||||
<< "Without a country code, Wi-Fi must be restricted to channels 1 through 11 "
|
||||
<< "with reduced amplitude and feature sets."
|
||||
<< "\n\n"
|
||||
<< "For the most part, Wi-Fi country codes are taken from the list of ISO 3661 "
|
||||
<< "2-letter country codes; although there are a handful of exceptions for small "
|
||||
<< "countries and islands. See the Alpha-2 code column of "
|
||||
<< "\n\n"
|
||||
<< Indent(8) << "https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes."
|
||||
<< "\n\n"
|
||||
|
||||
<< Indent(0) << "Legacy Wi-Fi Access Points:"
|
||||
<< "\n\n"
|
||||
<< Indent(4)
|
||||
<< "Some older devices may not be able to connect to PiPedal using Wi-Fi Direct connections. "
|
||||
"Old Apple devices, for example, do not support Wi-Fi Direct. In theory, Wi-Fi Direct should "
|
||||
"allow legacy Wi-Fi devices to connect to a Wi-Fi Direct access points as if it were an "
|
||||
"ordinary Access Point. If this turns out "
|
||||
"not to be the case, you can configure PiPedal to provide a legacy Wi-Fi access point instead. "
|
||||
"\n\n"
|
||||
"Unlike Wi-Fi Direct connections, legacy Access Points will prevent both the connecting device "
|
||||
"and the PiPedal host machine from connecting to the Internet over a simultanous Wi-Fi connection Access "
|
||||
"Point. On a connecting Android device, you won't be able to use the data connection either when a legacy "
|
||||
"Wi-Fi connection is active."
|
||||
"\n\n"
|
||||
"Wi-Fi Direct connections are "
|
||||
"therefore preferrable under almost all circumstances.\n\n"
|
||||
;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@@ -588,6 +726,7 @@ int main(int argc, char **argv)
|
||||
bool stop = false, start = false;
|
||||
bool enable = false, disable = false, restart = false;
|
||||
bool enable_ap = false, disable_ap = false;
|
||||
bool enable_p2p = false, disable_p2p = false;
|
||||
bool nopkexec = false;
|
||||
bool excludeShutdownService = false;
|
||||
std::string prefixOption;
|
||||
@@ -605,14 +744,17 @@ int main(int argc, char **argv)
|
||||
parser.AddOption("--help", &help);
|
||||
parser.AddOption("--prefix", &prefixOption);
|
||||
parser.AddOption("--port", &portOption);
|
||||
parser.AddOption("--enable_ap", &enable_ap);
|
||||
parser.AddOption("--disable_ap", &disable_ap);
|
||||
parser.AddOption("--enable-ap", &enable_ap);
|
||||
parser.AddOption("--disable-ap", &disable_ap);
|
||||
parser.AddOption("--enable-p2p", &enable_p2p);
|
||||
parser.AddOption("--disable-p2p", &disable_p2p);
|
||||
|
||||
parser.AddOption("--excludeShutdownService", &excludeShutdownService); // private (unstable) option used by shutdown service.
|
||||
try
|
||||
{
|
||||
parser.Parse(argc, (const char **)argv);
|
||||
|
||||
int actionCount = install + uninstall + stop + start + enable + disable + enable_ap + disable_ap + restart;
|
||||
int actionCount = install + uninstall + stop + start + enable + disable + enable_ap + disable_ap + restart + enable_p2p + disable_p2p;
|
||||
if (actionCount > 1)
|
||||
{
|
||||
throw PiPedalException("Please provide only one action.");
|
||||
@@ -621,20 +763,11 @@ int main(int argc, char **argv)
|
||||
{
|
||||
help = true;
|
||||
}
|
||||
if (enable_ap)
|
||||
{
|
||||
if (parser.Arguments().size() != 4)
|
||||
{
|
||||
cout << "Error: "
|
||||
<< "Incorrect number of arguments supplied for --enable_ap option." << endl;
|
||||
helpError = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
if ((!enable_p2p) && (!enable_ap))
|
||||
{
|
||||
if (parser.Arguments().size() != 0)
|
||||
{
|
||||
cout << "Error: Unexpected argument : " << parser.Arguments()[0] << endl;
|
||||
cout << "Error: Unexpected argument : " << parser.Arguments()[0] << "\n";
|
||||
helpError = true;
|
||||
}
|
||||
}
|
||||
@@ -642,64 +775,23 @@ int main(int argc, char **argv)
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::string s = e.what();
|
||||
cout << "Error: " << s << endl;
|
||||
cout << "Error: " << s << "\n";
|
||||
helpError = true;
|
||||
}
|
||||
|
||||
if (help || helpError)
|
||||
if (helpError)
|
||||
{
|
||||
if (helpError)
|
||||
cout << endl;
|
||||
cout << "\n";
|
||||
return EXIT_FAILURE; // don't scroll the error off the screen.
|
||||
}
|
||||
|
||||
cout << "pipedalconfig - Post-install configuration for pipdeal" << endl
|
||||
<< "Copyright (c) 2022 Robin Davies. All rights reserved." << endl
|
||||
<< endl
|
||||
<< "Syntax:" << endl
|
||||
<< " pipedalconfig [Options...]" << endl
|
||||
<< "Options: " << endl
|
||||
<< " -h --help Display this message." << endl
|
||||
<< endl
|
||||
<< " --install Install services and service accounts." << endl
|
||||
<< endl
|
||||
<< " --prefix Either /usr/local or /usr as appropriate for the install" << endl
|
||||
<< " (only valid with the -install option). Usually determined " << endl
|
||||
<< " automatically." << endl
|
||||
<< endl
|
||||
<< " --uninstall Remove installed services." << endl
|
||||
<< endl
|
||||
<< " --enable Start the pipedal service at boot time." << endl
|
||||
<< endl
|
||||
<< " --disable Do not start the pipedal service at boot time." << endl
|
||||
<< endl
|
||||
<< " --stop Stop the pipedal services." << endl
|
||||
<< endl
|
||||
<< " --start Start the pipedal services." << endl
|
||||
<< endl
|
||||
<< " --restart Restart the pipedal services." << endl
|
||||
<< endl
|
||||
<< " --port Port for the web server (only with -install option)." << endl
|
||||
<< " Either a port (e.g. '81'), or a full endpoint (e.g.: " << endl
|
||||
<< " '127.0.0.1:8080'). If no address is specified, the " << endl
|
||||
<< " web server will listen on 0.0.0.0 (any)." << endl
|
||||
<< endl
|
||||
<< " --enable_ap <country_code> <ssid> <wep_password> <channel>" << endl
|
||||
<< " Enable the Wi-Fi access point. <country_code> is the " << endl
|
||||
<< " 2-letter ISO-3166 country code for the country in " << endl
|
||||
<< " which you are currently located. The country code " << endl
|
||||
<< " determines which channels may be legally used in (and " << endl
|
||||
<< " which features need to be enabled) in order to use a " << endl
|
||||
<< " Wi-Fi channel in your legislative regime." << endl
|
||||
<< endl
|
||||
<< " --disable_ap Disabled the Wi-Fi access point." << endl
|
||||
<< endl
|
||||
<< "Description:" << endl
|
||||
<< " pipedalconfig performs post-install configuration of pipedal." << endl
|
||||
<< endl;
|
||||
exit(helpError ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
if (help)
|
||||
{
|
||||
PrintHelp();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (portOption.size() != 0 && !install)
|
||||
{
|
||||
cout << "Error: -port option can only be specified with the -install option." << endl;
|
||||
cout << "Error: -port option can only be specified with the -install option." << "\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -780,17 +872,27 @@ int main(int argc, char **argv)
|
||||
{
|
||||
DisableService();
|
||||
}
|
||||
else if (enable_p2p)
|
||||
{
|
||||
auto argv = parser.Arguments();
|
||||
WifiDirectConfigSettings settings;
|
||||
settings.ParseArguments(argv);
|
||||
settings.valid_ = true;
|
||||
settings.enable_ = false;
|
||||
SetWifiDirectConfig(settings);
|
||||
}
|
||||
else if (disable_p2p)
|
||||
{
|
||||
WifiDirectConfigSettings settings;
|
||||
settings.valid_ = true;
|
||||
settings.enable_ = false;
|
||||
SetWifiDirectConfig(settings);
|
||||
}
|
||||
else if (enable_ap)
|
||||
{
|
||||
auto argv = parser.Arguments();
|
||||
WifiConfigSettings settings;
|
||||
settings.valid_ = true;
|
||||
settings.enable_ = true;
|
||||
settings.countryCode_ = argv[0];
|
||||
settings.hotspotName_ = argv[1];
|
||||
settings.password_ = argv[2];
|
||||
settings.channel_ = argv[3];
|
||||
settings.hasPassword_ = settings.password_.length() != 0;
|
||||
settings.ParseArguments(argv);
|
||||
|
||||
SetWifiConfig(settings);
|
||||
}
|
||||
@@ -804,7 +906,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
cout << "Error: " << e.what() << endl;
|
||||
cout << "Error: " << e.what() << "\n";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define DEVICE_GUID_FILE "/etc/pipedal/config/device_uuid"
|
||||
|
||||
#define PIPEDAL_P2PD_CONF_PATH "/etc/pipedal/config/template_p2pd.conf"
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace pipedal
|
||||
{
|
||||
|
||||
using namespace std;
|
||||
|
||||
class PrettyPrinter
|
||||
{
|
||||
private:
|
||||
std::ostream &s;
|
||||
size_t lineWidth = 80;
|
||||
std::vector<char> lineBuffer;
|
||||
size_t column = 0;
|
||||
size_t indent = 0;
|
||||
size_t tabSize = 4;
|
||||
bool hangingIndent = false;
|
||||
bool hungIndent = false;
|
||||
|
||||
public:
|
||||
PrettyPrinter()
|
||||
: s(std::cout)
|
||||
{
|
||||
lineBuffer.resize(lineWidth * 2);
|
||||
}
|
||||
std::ostream&Stream() const { return s;}
|
||||
|
||||
PrettyPrinter& Indent(size_t indent)
|
||||
{
|
||||
this->indent = indent;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void WriteLine() {
|
||||
lineBuffer.push_back('\n');
|
||||
s.write(&lineBuffer[0],lineBuffer.size());
|
||||
lineBuffer.clear();
|
||||
column = 0;
|
||||
}
|
||||
|
||||
PrettyPrinter& HangingIndent()
|
||||
{
|
||||
hangingIndent = true;
|
||||
return *this;
|
||||
}
|
||||
void Write(const std::string &text)
|
||||
{
|
||||
for (char c : text)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
WriteLine();
|
||||
hungIndent = false;
|
||||
hangingIndent = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (column <= indent)
|
||||
{
|
||||
if (hangingIndent)
|
||||
{
|
||||
hangingIndent = false;
|
||||
hungIndent = true;
|
||||
|
||||
} else if (!hungIndent) {
|
||||
if (c == ' ')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
while (column < indent)
|
||||
{
|
||||
lineBuffer.push_back(' ');
|
||||
++column;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c == '\t')
|
||||
{
|
||||
if (hungIndent)
|
||||
{
|
||||
if (column < indent-1)
|
||||
{
|
||||
while (column < indent)
|
||||
{
|
||||
lineBuffer.push_back(' ');
|
||||
++column;
|
||||
}
|
||||
} else {
|
||||
WriteLine();
|
||||
column = 0;
|
||||
while (column < indent)
|
||||
{
|
||||
lineBuffer.push_back(' ');
|
||||
++column;
|
||||
}
|
||||
}
|
||||
hungIndent = false;
|
||||
} else {
|
||||
lineBuffer.push_back(' ');
|
||||
++column;
|
||||
while ((column % tabSize) != 0)
|
||||
{
|
||||
lineBuffer.push_back(' ');
|
||||
++column;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((c & 0x80) == 0)
|
||||
{
|
||||
lineBuffer.push_back(c);
|
||||
++column;
|
||||
}
|
||||
else
|
||||
{
|
||||
//utf-8 sequence.
|
||||
lineBuffer.push_back(c);
|
||||
if ((c & 0xC0) == 0x80)
|
||||
{
|
||||
++column;
|
||||
}
|
||||
}
|
||||
|
||||
if (column >= lineWidth - 1)
|
||||
{
|
||||
|
||||
size_t breakPos = FindBreak();
|
||||
|
||||
size_t startOfOverflow = breakPos;
|
||||
while (startOfOverflow < lineBuffer.size() && lineBuffer[startOfOverflow] == ' ')
|
||||
{
|
||||
++startOfOverflow;
|
||||
}
|
||||
std::string overflow = string(&lineBuffer[startOfOverflow], lineBuffer.size() - startOfOverflow);
|
||||
lineBuffer.resize(breakPos);
|
||||
|
||||
WriteLine();
|
||||
|
||||
this->Write(overflow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
size_t FindBreak()
|
||||
{
|
||||
size_t i = lineBuffer.size();
|
||||
while (i > indent && lineBuffer[i-1] != ' ')
|
||||
{
|
||||
--i;
|
||||
}
|
||||
if (i > indent)
|
||||
return i;
|
||||
return lineBuffer.size();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
PrettyPrinter& operator<< (PrettyPrinter &p, T &v)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << v;
|
||||
p.Write(s.str());
|
||||
return p;
|
||||
}
|
||||
|
||||
inline PrettyPrinter& operator << (PrettyPrinter& p,const std::string&s)
|
||||
{
|
||||
p.Write(s);
|
||||
return p;
|
||||
}
|
||||
|
||||
// iomanip
|
||||
|
||||
// template<typename _CharT, typename _Traits>
|
||||
// inline basic_ostream<_CharT, _Traits>&
|
||||
// endl(basic_ostream<_CharT, _Traits>& __os)
|
||||
// { return flush(__os.put(__os.widen('\n'))); }
|
||||
|
||||
inline PrettyPrinter& operator << (PrettyPrinter& p,PrettyPrinter& (*iomanip)(PrettyPrinter&os))
|
||||
{
|
||||
return (*iomanip)(p);
|
||||
}
|
||||
|
||||
using pp_manip = std::function<PrettyPrinter& (PrettyPrinter&)>;
|
||||
|
||||
inline
|
||||
PrettyPrinter& operator << (PrettyPrinter&pp,pp_manip manip)
|
||||
{
|
||||
return manip(pp);
|
||||
}
|
||||
|
||||
pp_manip Indent(int n)
|
||||
{
|
||||
return [n] (PrettyPrinter&pp) ->PrettyPrinter& {
|
||||
pp.Indent(n);
|
||||
return pp;
|
||||
};
|
||||
}
|
||||
pp_manip HangingIndent()
|
||||
{
|
||||
return [] (PrettyPrinter&pp) ->PrettyPrinter&{
|
||||
pp.HangingIndent();
|
||||
return pp;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+333
-23
@@ -18,22 +18,91 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "pch.h"
|
||||
#include "ss.hpp"
|
||||
|
||||
#include "P2pConfigFiles.hpp"
|
||||
#include "SetWifiConfig.hpp"
|
||||
#include "PiPedalException.hpp"
|
||||
#include "SystemConfigFile.hpp"
|
||||
#include "SysExec.hpp"
|
||||
#include "WriteTemplateFile.hpp"
|
||||
|
||||
|
||||
using namespace pipedal;
|
||||
using namespace std;
|
||||
|
||||
#define IP_RANGE "172.22.0"
|
||||
#define PIPEDAL_IP IP_RANGE ".1"
|
||||
#define APD_IP_PREFIX "172.22.0"
|
||||
#define APD_IP_ADDRESS APD_IP_PREFIX ".1"
|
||||
#define APD_INTERFACE_ADDR APD_IP_ADDRESS "/24"
|
||||
|
||||
#define PIPEDAL_NETWORK PIPEDAL_IP "/24"
|
||||
#define P2P_IP_PREFIX "172.23.0"
|
||||
#define P2P_IP_ADDRESS P2P_IP_PREFIX ".2" // no gateway!
|
||||
#define P2P_INTERFACE_ADDR P2P_IP_ADDRESS "/24"
|
||||
|
||||
#define SYSTEMCTL_BIN "/usr/bin/systemctl"
|
||||
|
||||
static void restoreDhcpcdConfFile()
|
||||
|
||||
static char DNSMASQ_APD_PATH[] = "/etc/dnsmasq.d/30-pipedal-apd.conf";
|
||||
static char DNSMASQ_P2P_PATH[] = "/etc/dnsmasqdnsmaqsq.d/30-pipedal-p2p.conf";
|
||||
|
||||
|
||||
static bool IsApdInstalled() {
|
||||
return std::filesystem::exists(DNSMASQ_APD_PATH);
|
||||
}
|
||||
static bool IsP2pInstalled() {
|
||||
return std::filesystem::exists(DNSMASQ_P2P_PATH);
|
||||
}
|
||||
|
||||
|
||||
uint32_t pipedal::ChannelToWifiFrequency(const std::string &channel)
|
||||
{
|
||||
std::string t = channel;
|
||||
// remove dprecated band specs.
|
||||
if (t.size() > 1 && t[0] == 'a' || t[0] == 'g')
|
||||
{
|
||||
t = t.substr(1);
|
||||
}
|
||||
size_t size = t.length();
|
||||
|
||||
unsigned long long lChannel = std::stoull(t,&size);
|
||||
if (size != t.length())
|
||||
{
|
||||
throw invalid_argument("Expecting a number: '" + t + "'.");
|
||||
}
|
||||
return ChannelToWifiFrequency((uint32_t)lChannel);
|
||||
}
|
||||
|
||||
uint32_t pipedal::ChannelToWifiFrequency(uint32_t channel)
|
||||
{
|
||||
// 2.4GHz.
|
||||
if (channel >= 1 && channel <= 13)
|
||||
{
|
||||
return 2412 + 5*(channel-1);
|
||||
}
|
||||
if (channel == 14)
|
||||
{
|
||||
return 2484;
|
||||
}
|
||||
// 802.11y
|
||||
if (channel >= 131 && channel < 137)
|
||||
{
|
||||
return 3660 + (channel-131)*5;
|
||||
}
|
||||
if (channel >= 32 && channel <= 68 && (channel & 1) == 0)
|
||||
{
|
||||
return 5160 + (channel-32)/2*10;
|
||||
}
|
||||
if (channel == 96) return 5480;
|
||||
|
||||
if (channel >= 100 && channel <= 196)
|
||||
{
|
||||
return 5500 + (channel-100)/5;
|
||||
}
|
||||
throw invalid_argument(SS("Invalid channel: " << channel));
|
||||
|
||||
}
|
||||
|
||||
static void restoreApdDhcpdConfFile()
|
||||
{
|
||||
// remove the interface wlan0 section.
|
||||
std::filesystem::path dhcpcdConfig("/etc/dhcpcd.conf");
|
||||
@@ -71,35 +140,48 @@ static void restoreDhcpcdConfFile()
|
||||
}
|
||||
}
|
||||
|
||||
static void restoreDnsmasqConfFile()
|
||||
|
||||
static void restoreApdDnsmasqConfFile()
|
||||
{
|
||||
std::filesystem::path path("/etc/dnsmasq.c/pipedal.conf");
|
||||
std::filesystem::path path(DNSMASQ_APD_PATH);
|
||||
if (std::filesystem::exists(path))
|
||||
{
|
||||
std::filesystem::remove(path);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
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();
|
||||
|
||||
void pipedal::SetWifiConfig(const WifiConfigSettings &settings)
|
||||
{
|
||||
char band;
|
||||
if (!settings.enable_)
|
||||
{
|
||||
sysExec(SYSTEMCTL_BIN " stop hostapd");
|
||||
sysExec(SYSTEMCTL_BIN " disable hostapd");
|
||||
|
||||
sysExec(SYSTEMCTL_BIN " stop dnsmasq");
|
||||
sysExec(SYSTEMCTL_BIN " disable dnsmasq");
|
||||
|
||||
restoreDhcpcdConfFile();
|
||||
restoreDnsmasqConfFile();
|
||||
|
||||
sysExec(SYSTEMCTL_BIN " unmask wpa_supplicant");
|
||||
sysExec(SYSTEMCTL_BIN " enable wpa_supplicant");
|
||||
sysExec(SYSTEMCTL_BIN " start wpa_supplicant");
|
||||
UninstallHostApd();
|
||||
}
|
||||
else
|
||||
{
|
||||
UninstallP2p();
|
||||
|
||||
std::filesystem::path path("/etc/hostapd/hostapd.conf");
|
||||
SystemConfigFile apdConfig;
|
||||
if (std::filesystem::exists(path))
|
||||
@@ -160,7 +242,7 @@ void pipedal::SetWifiConfig(const WifiConfigSettings &settings)
|
||||
apdConfig.Set("channel", channel);
|
||||
|
||||
// ******************** dsnmasq ******
|
||||
std::filesystem::path dnsMasqPath("/etc/dnsmasq.d/pipedal.conf");
|
||||
std::filesystem::path dnsMasqPath(DNSMASQ_APD_PATH);
|
||||
SystemConfigFile dnsMasq;
|
||||
|
||||
try
|
||||
@@ -173,12 +255,12 @@ void pipedal::SetWifiConfig(const WifiConfigSettings &settings)
|
||||
}
|
||||
|
||||
dnsMasq.Set("interface", "wlan0", "Name of the Wi-Fi interface");
|
||||
dnsMasq.Set("listen-address", PIPEDAL_IP);
|
||||
dnsMasq.Set("listen-address", APD_IP_ADDRESS);
|
||||
|
||||
dnsMasq.SetDefault("dhcp-range", IP_RANGE ".3," IP_RANGE ".127,12h", "dhcp configuration");
|
||||
dnsMasq.SetDefault("dhcp-range", APD_IP_PREFIX ".3," APD_IP_PREFIX ".127,12h", "dhcp configuration");
|
||||
dnsMasq.SetDefault("domain", "local");
|
||||
std::stringstream sAddress;
|
||||
sAddress << "/" << settings.mdnsName_ << ".local/" IP_RANGE << ".1";
|
||||
sAddress << "/" << settings.mdnsName_ << ".local/" APD_IP_PREFIX << ".1";
|
||||
dnsMasq.Set("address", sAddress.str());
|
||||
|
||||
// ****** dhcpd.conf ***/
|
||||
@@ -228,7 +310,7 @@ void pipedal::SetWifiConfig(const WifiConfigSettings &settings)
|
||||
line = dhcpcd.GetLineCount();
|
||||
}
|
||||
dhcpcd.InsertLine(line++, "interface wlan0");
|
||||
dhcpcd.InsertLine(line++, " static ip_address=" PIPEDAL_NETWORK);
|
||||
dhcpcd.InsertLine(line++, " static ip_address=" APD_INTERFACE_ADDR);
|
||||
dhcpcd.InsertLine(line++, " nohook wpa_supplicant");
|
||||
dhcpcd.Save(dhcpcdConfig);
|
||||
}
|
||||
@@ -263,3 +345,231 @@ void pipedal::SetWifiConfig(const WifiConfigSettings &settings)
|
||||
sysExec(SYSTEMCTL_BIN " enable dnsmasq");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************
|
||||
|
||||
p2p configuration:
|
||||
|
||||
|
||||
dnsmaqsq.d/30-pipedal-p2p.conf:
|
||||
|
||||
interface=p2p-wlan0-0
|
||||
dhcp-range=p2p-wlan0,172.24.0.3,172.24.0.127,1h
|
||||
domain=local
|
||||
address=/pipedal.local/172.24.0.1 # do this through DNS-SD?
|
||||
|
||||
except-interface=eth0
|
||||
except-interface=wlan0
|
||||
except-interface=lo
|
||||
|
||||
|
||||
dhcpcd.conf:
|
||||
======
|
||||
interface p2p-wlan0-0
|
||||
static ip_address=172.24.0.1/16
|
||||
domain_name_server=172.24.0.1
|
||||
|
||||
Watch resolv.conf to make sure we don't lose DNS servers.
|
||||
************************************************************************************/
|
||||
|
||||
|
||||
void UninstallP2p()
|
||||
{
|
||||
if (IsP2pInstalled())
|
||||
{
|
||||
sysExec(SYSTEMCTL_BIN " stop pipidal_p2pd");
|
||||
sysExec(SYSTEMCTL_BIN " disable pipidal_p2pd");
|
||||
|
||||
sysExec(SYSTEMCTL_BIN " stop dnsmasq");
|
||||
sysExec(SYSTEMCTL_BIN " disable dnsmasq");
|
||||
|
||||
restoreApdDhcpdConfFile();
|
||||
restoreApdDnsmasqConfFile();
|
||||
|
||||
sysExec(SYSTEMCTL_BIN " enable wpa_supplicant");
|
||||
sysExec(SYSTEMCTL_BIN " start wpa_supplicant");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings)
|
||||
{
|
||||
char band;
|
||||
if (!settings.enable_)
|
||||
{
|
||||
UninstallP2p();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// ******************* pipedal_p2pd ******
|
||||
{
|
||||
// ${COUNTRY_CODE}
|
||||
//${PIN}
|
||||
// ${DEVICE_NAME}
|
||||
// ${WIFI_GROUP_FREQUENCY}
|
||||
// ${INSTANCE_ID_FILE} /var/pipedal/instance_id
|
||||
|
||||
std::map<string, string> map;
|
||||
map["COUNTRY_CODE"] = settings.countryCode_;
|
||||
map["PIN"] = settings.pin_;
|
||||
map["DEVICE_NAME"] = settings.hotspotName_;
|
||||
map["WIFI_GROUP_FREQUENCY"] = SS(ChannelToWifiFrequency(settings.channel_));
|
||||
map["INSTANCE_ID_FILE"] = DEVICE_GUID_FILE;
|
||||
|
||||
|
||||
WriteTemplateFile(map, std::filesystem::path("/etc/pipedal/config/template_p2pd.conf"), PIPEDAL_P2PD_CONF_PATH);
|
||||
|
||||
}
|
||||
|
||||
// ******************** dsnmasq ******
|
||||
std::filesystem::path dnsMasqPath(DNSMASQ_P2P_PATH);
|
||||
SystemConfigFile dnsMasq;
|
||||
|
||||
try
|
||||
{
|
||||
dnsMasq.Load(dnsMasqPath);
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
// ignore.
|
||||
}
|
||||
// interface=p2p-wlan0-0
|
||||
// dhcp-range=172.24.0.3,172.24.0.127,1h
|
||||
// domain=local
|
||||
// address=/pipedal.local/172.24.0.1 # do this through DNS-SD?
|
||||
|
||||
// except-interface=eth0
|
||||
// except-interface=wlan0
|
||||
// except-interface=lo
|
||||
|
||||
|
||||
|
||||
dnsMasq.Set("interface", "p2p-wlan0-0", "Name of the Wi-Fi interface");
|
||||
dnsMasq.Set("listen-address", APD_IP_ADDRESS);
|
||||
|
||||
dnsMasq.SetDefault("dhcp-range", P2P_IP_PREFIX ".3," P2P_IP_PREFIX ".127,1h", "dhcp configuration");
|
||||
dnsMasq.SetDefault("domain", "local");
|
||||
std::string strAddress = SS("/" << settings.mdnsName_ << ".local/" P2P_IP_PREFIX << ".2");
|
||||
dnsMasq.Set("address", strAddress);
|
||||
dnsMasq.AppendLine("except-interface=eth0");
|
||||
dnsMasq.AppendLine("except-interface=wlan0");
|
||||
|
||||
|
||||
// ****** dhcpd.conf ***/
|
||||
std::filesystem::path dhcpcdConfig("/etc/dhcpcd.conf");
|
||||
if (std::filesystem::exists(dhcpcdConfig))
|
||||
{
|
||||
SystemConfigFile dhcpcd(dhcpcdConfig);
|
||||
|
||||
// dhcpcd.conf:
|
||||
// ======
|
||||
// interface p2p-wlan0-0
|
||||
// static ip_address=172.24.0.1/16
|
||||
// domain_name_server=172.24.0.1
|
||||
|
||||
|
||||
int line = dhcpcd.GetLineThatStartsWith("hostname");
|
||||
std::string hostNameLine;
|
||||
if (settings.mdnsName_ != "")
|
||||
{
|
||||
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())
|
||||
{
|
||||
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++, " domain_name_servier=" P2P_IP_ADDRESS);
|
||||
dhcpcd.Save(dhcpcdConfig);
|
||||
}
|
||||
|
||||
// ***** save the config files ***
|
||||
|
||||
dnsMasq.Save(dnsMasqPath);
|
||||
|
||||
// **************** start services ************
|
||||
sysExec("rfkill unblock wlan");
|
||||
sysExec(SYSTEMCTL_BIN " daemon-reload");
|
||||
|
||||
sysExec(SYSTEMCTL_BIN " restart wpa_supplicant");
|
||||
|
||||
sysExec(SYSTEMCTL_BIN " unmask pipedal_p2pd");
|
||||
if (sysExec(SYSTEMCTL_BIN " restart pipedal_p2pd") != 0)
|
||||
{
|
||||
throw PiPedalException("Unable to start the pipedal_p2pd.");
|
||||
}
|
||||
if (sysExec("systemctl is-active --quiet pipedal_p2pd") != 0)
|
||||
{
|
||||
throw PiPedalException("Unable to start the access point.");
|
||||
}
|
||||
sysExec(SYSTEMCTL_BIN " enable pipedal_p2pd");
|
||||
|
||||
sysExec(SYSTEMCTL_BIN " restart dnsmasq");
|
||||
sysExec(SYSTEMCTL_BIN " enable dnsmasq");
|
||||
}
|
||||
}
|
||||
|
||||
void pipedal::OnWifiUninstall()
|
||||
{
|
||||
// intaller hook
|
||||
if (IsApdInstalled())
|
||||
{
|
||||
UninstallHostApd();
|
||||
} else if (IsP2pInstalled())
|
||||
{
|
||||
UninstallP2p();
|
||||
}
|
||||
|
||||
}
|
||||
void pipedal::OnWifiInstallComplete()
|
||||
{
|
||||
// install has already done a daemon-reload.
|
||||
// I can't think of anything that needs to be done.
|
||||
// if (IsApdInstalled())
|
||||
// {
|
||||
// sysExec(SYSTEMCTL_BIN " daemon-reload");
|
||||
// } else if (IsP2pInstalled())
|
||||
// {
|
||||
// sysExec(SYSTEMCTL_BIN " daemon-reload");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,16 @@
|
||||
|
||||
#pragma once
|
||||
#include "WifiConfigSettings.hpp"
|
||||
#include "WifiDirectConfigSettings.hpp"
|
||||
|
||||
namespace pipedal {
|
||||
|
||||
uint32_t ChannelToWifiFrequency(const std::string &channel);
|
||||
uint32_t ChannelToWifiFrequency(uint32_t channel);
|
||||
void SetWifiConfig(const WifiConfigSettings&settings);
|
||||
void SetWifiDirectConfig(const WifiDirectConfigSettings&settings);
|
||||
|
||||
void OnWifiUninstall();
|
||||
void OnWifiInstallComplete();
|
||||
|
||||
} // namespace.
|
||||
@@ -19,8 +19,10 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "WifiConfigSettings.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace pipedal;
|
||||
using namespace std;
|
||||
|
||||
JSON_MAP_BEGIN(WifiConfigSettings)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,valid)
|
||||
@@ -35,3 +37,48 @@ JSON_MAP_BEGIN(WifiConfigSettings)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,channel)
|
||||
JSON_MAP_END()
|
||||
|
||||
bool WifiConfigSettings::ValidateCountryCode(const std::string&value)
|
||||
{
|
||||
if (value.size() < 2 || value.size() > 3) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WifiConfigSettings::ValidateChannel(const std::string&arguments)
|
||||
{
|
||||
// 1) frequency in khz.
|
||||
// 2) unadorned channel number 1, 2,3 &c.
|
||||
// 3) With band annotated: g1, a51.
|
||||
// come back to this.
|
||||
return true;
|
||||
}
|
||||
|
||||
void WifiConfigSettings::ParseArguments(const std::vector<std::string> &argv)
|
||||
{
|
||||
this->valid_ = false;
|
||||
if (argv.size() != 4) {
|
||||
throw invalid_argument("Invalid number of arguments.");
|
||||
}
|
||||
this->enable_ = true;
|
||||
this->countryCode_ = argv[0];
|
||||
this->hotspotName_ = argv[1];
|
||||
this->mdnsName_ = this->hotspotName_;
|
||||
this->password_ = argv[2];
|
||||
this->channel_ = argv[3];
|
||||
this->hasPassword_ = this->password_.length() != 0;
|
||||
|
||||
if (!ValidateCountryCode(this->countryCode_))
|
||||
{
|
||||
throw invalid_argument("Invalid country code.");
|
||||
}
|
||||
if (this->hotspotName_.length() > 31) throw invalid_argument("Hotspot name is too long.");
|
||||
if (this->hotspotName_.length() < 1) throw invalid_argument("Hotspot name is too short.");
|
||||
if (this->password_.size() != 0 && this->password_.size() < 8) throw invalid_argument("Passphrase must be at least 8 characters long.");
|
||||
|
||||
if (!ValidateChannel(this->channel_))
|
||||
{
|
||||
throw invalid_argument("Channel is not valid.");
|
||||
}
|
||||
this->valid_ = true;
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ namespace pipedal {
|
||||
bool hasPassword_ = false;
|
||||
std::string password_;
|
||||
std::string channel_ = "g6";
|
||||
|
||||
void ParseArguments(const std::vector<std::string> &arguments);
|
||||
static bool ValidateChannel(const std::string&value);
|
||||
static bool ValidateCountryCode(const std::string&value);
|
||||
public:
|
||||
DECLARE_JSON_MAP(WifiConfigSettings);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
// 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 "pch.h"
|
||||
#include "WifiDirectConfigSettings.hpp"
|
||||
#include "WifiConfigSettings.hpp"
|
||||
#include <stdexcept>
|
||||
#include <random>
|
||||
|
||||
using namespace pipedal;
|
||||
using namespace std;
|
||||
|
||||
JSON_MAP_BEGIN(WifiDirectConfigSettings)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,valid)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,rebootRequired)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,enable)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,hotspotName)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,hasPin)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,pin)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,countryCode)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,channel)
|
||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,mdnsName)
|
||||
JSON_MAP_END()
|
||||
|
||||
static std::string MakePin()
|
||||
{
|
||||
std::random_device rand_dev;
|
||||
|
||||
std::mt19937 gen(rand_dev());
|
||||
std::uniform_int_distribution<int> dist { 0,9};
|
||||
|
||||
std::stringstream s;
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
int r = dist(gen);
|
||||
s << (char)('0' + r);
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
static void ValidatePin(const std::string&pin)
|
||||
{
|
||||
for (char c : pin)
|
||||
{
|
||||
if (c < '0' || c > '9')
|
||||
{
|
||||
throw invalid_argument("Pin must consist of digits only.");
|
||||
}
|
||||
}
|
||||
if (pin.length() != 8)
|
||||
{
|
||||
throw invalid_argument("Pin must have exctly 8 digits.");
|
||||
}
|
||||
}
|
||||
|
||||
void WifiDirectConfigSettings::ParseArguments(const std::vector<std::string> &arguments)
|
||||
{
|
||||
this->valid_ = false;
|
||||
if (arguments.size() < 2 || arguments.size() > 4)
|
||||
{
|
||||
throw invalid_argument("Incorrect number of arguments supplied");
|
||||
}
|
||||
|
||||
this->enable_ = true;
|
||||
|
||||
this->countryCode_ = arguments[0];
|
||||
this->hotspotName_ = arguments[1];
|
||||
this->pin_ = arguments.size() >= 3 ? arguments[2] : "";
|
||||
this->channel_ = arguments.size() >= 4? arguments[3]: "";
|
||||
size_t maxLength = 32-string("DIRECT-XX-").length();
|
||||
if (hotspotName_.size() >= maxLength) { throw invalid_argument("Device name is too long."); }
|
||||
if (hotspotName_.size() < 1) { throw invalid_argument("Device name is too short."); }
|
||||
if (!WifiConfigSettings::ValidateCountryCode(countryCode_))
|
||||
{
|
||||
throw invalid_argument("Invalid country code.");
|
||||
}
|
||||
if (pin_.size() == 0)
|
||||
{
|
||||
pin_ = MakePin();
|
||||
}
|
||||
ValidatePin(pin_); // throws.
|
||||
if (!WifiConfigSettings::ValidateChannel(channel_))
|
||||
{
|
||||
throw invalid_argument("Invalid channel.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "json.hpp"
|
||||
|
||||
namespace pipedal {
|
||||
|
||||
class WifiDirectConfigSettings {
|
||||
public:
|
||||
bool valid_ = false;
|
||||
bool rebootRequired_ = false;
|
||||
bool enable_ = false;
|
||||
std::string countryCode_ = "US"; // iso 3661
|
||||
std::string hotspotName_ = "pipedal";
|
||||
std::string mdnsName_ = "pipedal";
|
||||
bool hasPin_ = false;
|
||||
std::string pin_;
|
||||
std::string channel_ = "g6";
|
||||
void ParseArguments(const std::vector<std::string> &arguments);
|
||||
|
||||
public:
|
||||
DECLARE_JSON_MAP(WifiDirectConfigSettings);
|
||||
};
|
||||
}
|
||||
@@ -10,4 +10,4 @@ WorkingDirectory=/var/pipedal
|
||||
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
[Unit]
|
||||
Description=PiPedal P2P Session Manager
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=${COMMAND}
|
||||
Type=notify
|
||||
Restart=always
|
||||
RestartSec=60
|
||||
WorkingDirectory=/var/pipedal
|
||||
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,48 @@
|
||||
${COUNTRY_CODE}
|
||||
${PIN}
|
||||
${DEVICE_NAME}
|
||||
${WIFI_GROUP_FREQUENCY}
|
||||
${INSTANCE_ID_FILE} /var/pipedal/instance_id
|
||||
# WiFi regdomain 2-letter country code.
|
||||
# see: http://www.davros.org/misc/iso3166.txt
|
||||
country_code=${COUNTRY_CODE}
|
||||
|
||||
# keypad/label pin
|
||||
p2p_pin=${PIN}
|
||||
|
||||
# Name that appears when you connect.
|
||||
p2p_device_name=${DEVICE_NAME}
|
||||
|
||||
# DIRECT-XX-postfix (appears on Android p2p Group names)
|
||||
p2p_ssid_postfix=${DEVICE_NAME}
|
||||
|
||||
# Wifi frequency (kHz).
|
||||
# Should almost always be 2412 (ch1),2437 (ch6), or 2462 (ch11).
|
||||
wifiGroupFrequency=${WIFI_GROUP_FREQUENCY}
|
||||
|
||||
# P2P Device info
|
||||
p2p_model_name=PiPedal
|
||||
p2p_model_number=1
|
||||
p2p_manufacturer="The PiPedal Project"
|
||||
p2p_serial_number=1
|
||||
p2p_device_type=1-0050F204-1
|
||||
|
||||
# Wi-Fi configuration
|
||||
wlanInterface=wlan0
|
||||
p2pInterface=p2p-dev-wlan0
|
||||
p2p_go_ht40=0
|
||||
p2p_go_vht=0
|
||||
p2p_go_he=0
|
||||
|
||||
# Ipv4 address for the P2P group interface
|
||||
p2p_ip_address=172.24.0.2/16
|
||||
|
||||
# File containing the a globally-unique id identifying the service on this machine.
|
||||
# Syntax: 0a6045b0-1753-4104-b3e4-b9713b9cc356
|
||||
#
|
||||
service_guid_file=${INSTANCE_ID_FILE}
|
||||
|
||||
|
||||
# GUID identifying the PiPedal service
|
||||
# (if service_guid_file is not provided.)
|
||||
service_guid=
|
||||
Reference in New Issue
Block a user