Wi-Fi Direct alpha
This commit is contained in:
Vendored
+34
@@ -37,6 +37,40 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "(gdb) pipedald",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
// Resolved by CMake Tools:
|
||||||
|
"program": "${command:cmake.launchTargetPath}",
|
||||||
|
"args": [ "/etc/pipedal/config", "/etc/pipedal/react", "-port", "0.0.0.0:8080" ],
|
||||||
|
"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": "ASAN_OPTIONS",
|
||||||
|
"value": "detect_leaks=0"
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "(gdb) pipedaltest Launch",
|
"name": "(gdb) pipedaltest Launch",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ install (
|
|||||||
DESTINATION /etc/pipedal/config/
|
DESTINATION /etc/pipedal/config/
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install (
|
||||||
|
DIRECTORY ${PROJECT_SOURCE_DIR}/default_presets
|
||||||
|
DESTINATION /etc/pipedal/config
|
||||||
|
)
|
||||||
|
|
||||||
install (DIRECTORY ${LV2_SOURCE_DIRECTORY}
|
install (DIRECTORY ${LV2_SOURCE_DIRECTORY}
|
||||||
DESTINATION /usr/lib/lv2
|
DESTINATION /usr/lib/lv2
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZaMaximX2","presets": [{"instanceId": 1,"label": "Zero","controlValues": {"ceil": 0,"rel": 25,"thresh": 0}}],"nextInstanceId": 2}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamGate","presets": [{"instanceId": 1,"label": "Default","controlValues": {"att": 50,"close": -50,"mak": 0,"mode": 0,"rel": 100,"sidechain": 0,"thr": -60}}],"nextInstanceId": 2}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamGateX2","presets": [{"instanceId": 1,"label": "Default","controlValues": {"att": 50,"close": -50,"mak": 0,"mode": 0,"rel": 100,"sidechain": 0,"thr": -60}}],"nextInstanceId": 2}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamGrains","presets": [ ],"nextInstanceId": 1}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamHeadX2","presets": [{"instanceId": 1,"label": "Zero","controlValues": {"az": 0,"elev": 0,"width": 1}}],"nextInstanceId": 2}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamPhono","presets": [ ],"nextInstanceId": 1}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamTube","presets": [ ],"nextInstanceId": 1}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamVerb","presets": [ ],"nextInstanceId": 1}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "http://two-play.com/plugins/toob-delay","presets": [{"instanceId": 1,"label": "Classic","controlValues": {"delay": 340,"feedback": 39.1666679,"level": 27}},{"instanceId": 2,"label": "Slapback","controlValues": {"delay": 94.6446991,"feedback": 39.1666679,"level": 42}}],"nextInstanceId": 3}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "http://two-play.com/plugins/toob-ml","presets": [{"instanceId": 1,"label": "Fender Clean","controlValues": {"bass": 0.783333361,"gain": 0,"master": 1.5,"mid": 0.5,"model": 8,"treble": 0.550000012,"trim": -3}},{"instanceId": 2,"label": "Mesa Crunch","controlValues": {"bass": 0.650000036,"gain": 0,"master": 1.5,"mid": 0.5,"model": 17,"treble": 0.550000012,"trim": -3}},{"instanceId": 3,"label": "Sparkling Clean","controlValues": {"bass": 0.650000036,"gain": 0,"master": 1.5,"mid": 0.5,"model": 19,"treble": 0.550000012,"trim": -3}}],"nextInstanceId": 4}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZaMultiComp","presets": [{"instanceId": 1,"label": "Presence","controlValues": {"att1": 10,"att2": 10,"att3": 10,"globalgain": 0,"kn1": 3,"kn2": 3,"kn3": 3,"listen1": 0,"listen2": 0,"listen3": 0,"mak1": 9,"mak2": 6,"mak3": 6,"rat1": 5,"rat2": 5,"rat3": 5,"rel1": 200,"rel2": 200,"rel3": 200,"thr1": -20,"thr2": -18,"thr3": -16,"toggle1": 1,"toggle2": 1,"toggle3": 1,"xover1": 160,"xover2": 1400}},{"instanceId": 2,"label": "Zero","controlValues": {"att1": 10,"att2": 10,"att3": 10,"globalgain": 0,"kn1": 0,"kn2": 0,"kn3": 0,"listen1": 0,"listen2": 0,"listen3": 0,"mak1": 0,"mak2": 0,"mak3": 0,"rat1": 4,"rat2": 4,"rat3": 4,"rel1": 80,"rel2": 80,"rel3": 80,"thr1": -20,"thr2": -18,"thr3": -16,"toggle1": 0,"toggle2": 0,"toggle3": 0,"xover1": 160,"xover2": 1400}}],"nextInstanceId": 3}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZaMultiCompX2","presets": [{"instanceId": 1,"label": "Zero","controlValues": {"att1": 10,"att2": 10,"att3": 10,"globalgain": 0,"kn1": 0,"kn2": 0,"kn3": 0,"listen1": 0,"listen2": 0,"listen3": 0,"mak1": 0,"mak2": 0,"mak3": 0,"rat1": 4,"rat2": 4,"rat3": 4,"rel1": 80,"rel2": 80,"rel3": 80,"stereodet": 1,"thr1": -20,"thr2": -18,"thr3": -16,"toggle1": 0,"toggle2": 0,"toggle3": 0,"xover1": 160,"xover2": 1400}},{"instanceId": 2,"label": "Presence","controlValues": {"att1": 10,"att2": 10,"att3": 10,"globalgain": 0,"kn1": 3,"kn2": 3,"kn3": 3,"listen1": 0,"listen2": 0,"listen3": 0,"mak1": 9,"mak2": 6,"mak3": 6,"rat1": 5,"rat2": 5,"rat3": 5,"rel1": 200,"rel2": 200,"rel3": 200,"stereodet": 1,"thr1": -20,"thr2": -18,"thr3": -16,"toggle1": 1,"toggle2": 1,"toggle3": 1,"xover1": 160,"xover2": 1400}}],"nextInstanceId": 3}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamComp","presets": [{"instanceId": 1,"label": "Zero","controlValues": {"att": 10,"kn": 0,"mak": 0,"rat": 4,"rel": 80,"sidech": 0,"slew": 1,"thr": 0}},{"instanceId": 2,"label": "VocalLeveller","controlValues": {"att": 50,"kn": 8,"mak": 9,"rat": 5,"rel": 400,"sidech": 0,"slew": 1,"thr": -16}},{"instanceId": 3,"label": "PoppySnare","controlValues": {"att": 10,"kn": 1,"mak": 6,"rat": 5,"rel": 10,"sidech": 0,"slew": 20,"thr": -18}}],"nextInstanceId": 4}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamCompX2","presets": [{"instanceId": 1,"label": "PoppySnare","controlValues": {"att": 10,"kn": 1,"mak": 6,"rat": 5,"rel": 10,"sidechain": 0,"slew": 20,"stereodet": 1,"thr": -18}},{"instanceId": 2,"label": "VocalLeveller","controlValues": {"att": 50,"kn": 8,"mak": 9,"rat": 5,"rel": 400,"sidechain": 0,"slew": 1,"stereodet": 1,"thr": -16}},{"instanceId": 3,"label": "Zero","controlValues": {"att": 10,"kn": 0,"mak": 0,"rat": 4,"rel": 80,"sidechain": 0,"slew": 1,"stereodet": 0,"thr": 0}}],"nextInstanceId": 4}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamDelay","presets": [ ],"nextInstanceId": 1}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamDynamicEQ","presets": [{"instanceId": 1,"label": "Zero","controlValues": {"att": 10,"boostcut": 0,"detectfreq": 1000,"kn": 0,"max": 10,"rat": 1.5,"rel": 80,"sidech": 0,"slew": 1,"targetfreq": 1000,"targetwidth": 1,"thr": 0,"togglehigh": 0,"togglelow": 0,"togglepeak": 1}},{"instanceId": 2,"label": "PoppySnare","controlValues": {"att": 10,"boostcut": 0,"detectfreq": 1000,"kn": 1,"max": 10,"rat": 1.5,"rel": 10,"sidech": 0,"slew": 20,"targetfreq": 1000,"targetwidth": 1,"thr": -18,"togglehigh": 0,"togglelow": 0,"togglepeak": 1}}],"nextInstanceId": 3}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamEQ2","presets": [{"instanceId": 1,"label": "Zero","controlValues": {"boost1": 0,"boost2": 0,"boosth": 0,"boostl": 0,"bw1": 1,"bw2": 1,"f1": 500,"f2": 3000,"fh": 8000,"fl": 250,"master": 0,"peaks": 0}},{"instanceId": 2,"label": "CarvedBass","controlValues": {"boost1": 0,"boost2": 0,"boosth": 0,"boostl": 6,"bw1": 1,"bw2": 1,"f1": 500,"f2": 3000,"fh": 8000,"fl": 60,"master": -6,"peaks": 0}},{"instanceId": 3,"label": "CarvedVox","controlValues": {"boost1": 0,"boost2": 0,"boosth": 6,"boostl": 6,"bw1": 1,"bw2": 1,"f1": 500,"f2": 3000,"fh": 330,"fl": 6600,"master": -12,"peaks": 0}},{"instanceId": 4,"label": "CarvedGuitar","controlValues": {"boost1": 5.5999999,"boost2": 0.699999988,"boosth": 0,"boostl": -1.04999995,"bw1": 1.46000004,"bw2": 1.33000004,"f1": 175,"f2": 500,"fh": 8000,"fl": 30,"master": -6,"peaks": 0}}],"nextInstanceId": 5}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"pluginUri": "urn:zamaudio:ZamGEQ31","presets": [{"instanceId": 1,"label": "Default","controlValues": {"band1": 0,"band10": 0,"band11": 0,"band12": 0,"band13": 0,"band14": 0,"band15": 0,"band16": 0,"band17": 0,"band18": 0,"band19": 0,"band2": 0,"band20": 0,"band21": 0,"band22": 0,"band23": 0,"band24": 0,"band25": 0,"band26": 0,"band27": 0,"band28": 0,"band29": 0,"band3": 0,"band4": 0,"band5": 0,"band6": 0,"band7": 0,"band8": 0,"band9": 0,"master": 0}}],"nextInstanceId": 2}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"entries": [{"pluginUri": "urn:zamaudio:ZaMaximX2","fileName": "1.json"},{"pluginUri": "urn:zamaudio:ZaMultiComp","fileName": "2.json"},{"pluginUri": "urn:zamaudio:ZaMultiCompX2","fileName": "3.json"},{"pluginUri": "urn:zamaudio:ZamComp","fileName": "4.json"},{"pluginUri": "urn:zamaudio:ZamCompX2","fileName": "5.json"},{"pluginUri": "urn:zamaudio:ZamDelay","fileName": "6.json"},{"pluginUri": "urn:zamaudio:ZamDynamicEQ","fileName": "7.json"},{"pluginUri": "urn:zamaudio:ZamEQ2","fileName": "8.json"},{"pluginUri": "urn:zamaudio:ZamGEQ31","fileName": "9.json"},{"pluginUri": "urn:zamaudio:ZamGate","fileName": "10.json"},{"pluginUri": "urn:zamaudio:ZamGateX2","fileName": "11.json"},{"pluginUri": "urn:zamaudio:ZamGrains","fileName": "12.json"},{"pluginUri": "urn:zamaudio:ZamHeadX2","fileName": "13.json"},{"pluginUri": "urn:zamaudio:ZamPhono","fileName": "14.json"},{"pluginUri": "urn:zamaudio:ZamTube","fileName": "15.json"},{"pluginUri": "urn:zamaudio:ZamVerb","fileName": "16.json"},{"pluginUri": "http://two-play.com/plugins/toob-delay","fileName": "17.json"},{"pluginUri": "http://two-play.com/plugins/toob-ml","fileName": "18.json"}],"nextInstanceId": 19}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
|||||||
|
{"selectedBank": 1,"nextInstanceId": 1,"entries": [{"instanceId": 1,"name": "Default Bank"}]}
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
{
|
{
|
||||||
"socket_server_port": 80,
|
"socket_server_port": 8080,
|
||||||
"socket_server_address": "*",
|
"socket_server_address": "*",
|
||||||
"debug": true,
|
"debug": true,
|
||||||
"max_upload_size": 1048576,
|
"max_upload_size": 1048576,
|
||||||
|
"fakeAndroid": true,
|
||||||
"ui_plugins": [
|
"ui_plugins": []
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface AndroidHostInterface {
|
||||||
|
isAndroidHosted(): boolean;
|
||||||
|
getHostVersion() : string;
|
||||||
|
chooseNewDevice() : void;
|
||||||
|
onLostConnection(): void;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export class FakeAndroidHost implements AndroidHostInterface
|
||||||
|
{
|
||||||
|
isAndroidHosted(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
getHostVersion(): string {
|
||||||
|
return "Fake Android 1.0";
|
||||||
|
}
|
||||||
|
chooseNewDevice(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
onLostConnection(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -36,7 +36,7 @@ declare module '@mui/styles/defaultTheme' {
|
|||||||
const theme = createTheme({
|
const theme = createTheme({
|
||||||
palette: {
|
palette: {
|
||||||
primary: {
|
primary: {
|
||||||
main: "#324c6c"
|
main: "#6750A4"
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
main: "#FF6060"
|
main: "#FF6060"
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
isDrawerOpen: false,
|
isDrawerOpen: false,
|
||||||
errorMessage: this.model_.errorMessage.get(),
|
errorMessage: this.model_.errorMessage.get(),
|
||||||
displayState: this.model_.state.get(),
|
displayState: this.model_.state.get(),
|
||||||
canFullScreen: supportsFullScreen(),
|
canFullScreen: supportsFullScreen() && !this.model_.isAndroidHosted(),
|
||||||
isFullScreen: !!document.fullscreenElement,
|
isFullScreen: !!document.fullscreenElement,
|
||||||
tinyToolBar: false,
|
tinyToolBar: false,
|
||||||
alertDialogOpen: false,
|
alertDialogOpen: false,
|
||||||
@@ -537,7 +537,10 @@ const AppThemed = withStyles(appStyles)(class extends ResizeResponsiveComponent<
|
|||||||
setDisplayState(newState: State): void {
|
setDisplayState(newState: State): void {
|
||||||
this.updateOverscroll();
|
this.updateOverscroll();
|
||||||
|
|
||||||
this.setState({ displayState: newState });
|
this.setState({
|
||||||
|
displayState: newState,
|
||||||
|
canFullScreen: supportsFullScreen() && !this.model_.isAndroidHosted()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showDrawer() {
|
showDrawer() {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ const styles = ({ palette }: Theme) => createStyles({
|
|||||||
controlContentSmall: {
|
controlContentSmall: {
|
||||||
flex: "0 0 162px", width: "100%", height: 162, overflowY: "hidden",
|
flex: "0 0 162px", width: "100%", height: 162, overflowY: "hidden",
|
||||||
},
|
},
|
||||||
title: { fontSize: "1.3em", fontWeight: 700, marginRight: 8 },
|
title: { fontSize: "1.1em", fontWeight: 700, marginRight: 8 },
|
||||||
author: { fontWeight: 500, marginRight: 8 }
|
author: { fontWeight: 500, marginRight: 8 }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -103,6 +103,7 @@ interface MainState {
|
|||||||
horizontalScrollLayout: boolean;
|
horizontalScrollLayout: boolean;
|
||||||
showMidiBindingsDialog: boolean;
|
showMidiBindingsDialog: boolean;
|
||||||
screenHeight: number;
|
screenHeight: number;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -126,7 +127,7 @@ export const MainPage =
|
|||||||
splitControlBar: this.windowSize.width < SPLIT_CONTROLBAR_THRESHHOLD,
|
splitControlBar: this.windowSize.width < SPLIT_CONTROLBAR_THRESHHOLD,
|
||||||
horizontalScrollLayout: this.windowSize.height < HORIZONTAL_CONTROL_SCROLL_HEIGHT_BREAK,
|
horizontalScrollLayout: this.windowSize.height < HORIZONTAL_CONTROL_SCROLL_HEIGHT_BREAK,
|
||||||
showMidiBindingsDialog: false,
|
showMidiBindingsDialog: false,
|
||||||
screenHeight: this.windowSize.height,
|
screenHeight: this.windowSize.height
|
||||||
|
|
||||||
};
|
};
|
||||||
this.onSelectionChanged = this.onSelectionChanged.bind(this);
|
this.onSelectionChanged = this.onSelectionChanged.bind(this);
|
||||||
@@ -465,6 +466,7 @@ export const MainPage =
|
|||||||
onClick={this.onLoadClick}
|
onClick={this.onLoadClick}
|
||||||
disabled={this.state.selectedPedal === -1 || (this.getSelectedPedalBoardItem()?.isSplit() ?? true)}
|
disabled={this.state.selectedPedal === -1 || (this.getSelectedPedalBoardItem()?.isSplit() ?? true)}
|
||||||
startIcon={<InputIcon />}
|
startIcon={<InputIcon />}
|
||||||
|
style={{ borderRadius: 24, paddingLeft: 18, paddingRight: 18, textTransform: "none"}}
|
||||||
>
|
>
|
||||||
Load
|
Load
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
+108
-22
@@ -33,9 +33,11 @@ import JackServerSettings from './JackServerSettings';
|
|||||||
import MidiBinding from './MidiBinding';
|
import MidiBinding from './MidiBinding';
|
||||||
import { PluginUiPresets } from './PluginPreset';
|
import { PluginUiPresets } from './PluginPreset';
|
||||||
import WifiConfigSettings from './WifiConfigSettings';
|
import WifiConfigSettings from './WifiConfigSettings';
|
||||||
|
import WifiDirectConfigSettings from './WifiDirectConfigSettings';
|
||||||
import GovernorSettings from './GovernorSettings';
|
import GovernorSettings from './GovernorSettings';
|
||||||
import WifiChannel from './WifiChannel';
|
import WifiChannel from './WifiChannel';
|
||||||
import AlsaDeviceInfo from './AlsaDeviceInfo';
|
import AlsaDeviceInfo from './AlsaDeviceInfo';
|
||||||
|
import { AndroidHostInterface, FakeAndroidHost } from './AndroidHost';
|
||||||
|
|
||||||
|
|
||||||
export enum State {
|
export enum State {
|
||||||
@@ -321,6 +323,7 @@ export interface PiPedalModel {
|
|||||||
banks: ObservableProperty<BankIndex>;
|
banks: ObservableProperty<BankIndex>;
|
||||||
jackServerSettings: ObservableProperty<JackServerSettings>;
|
jackServerSettings: ObservableProperty<JackServerSettings>;
|
||||||
wifiConfigSettings: ObservableProperty<WifiConfigSettings>;
|
wifiConfigSettings: ObservableProperty<WifiConfigSettings>;
|
||||||
|
wifiDirectConfigSettings: ObservableProperty<WifiDirectConfigSettings>;
|
||||||
governorSettings: ObservableProperty<GovernorSettings>;
|
governorSettings: ObservableProperty<GovernorSettings>;
|
||||||
favorites: ObservableProperty<FavoritesList>;
|
favorites: ObservableProperty<FavoritesList>;
|
||||||
|
|
||||||
@@ -418,6 +421,7 @@ export interface PiPedalModel {
|
|||||||
uploadBank(file: File, uploadAfter: number): Promise<number>;
|
uploadBank(file: File, uploadAfter: number): Promise<number>;
|
||||||
|
|
||||||
setWifiConfigSettings(wifiConfigSettings: WifiConfigSettings): Promise<void>;
|
setWifiConfigSettings(wifiConfigSettings: WifiConfigSettings): Promise<void>;
|
||||||
|
setWifiDirectConfigSettings(wifiDirectConfigSettings: WifiDirectConfigSettings): Promise<void>;
|
||||||
setGovernorSettings(governor: string): Promise<void>;
|
setGovernorSettings(governor: string): Promise<void>;
|
||||||
|
|
||||||
getWifiChannels(countryIso3661: string): Promise<WifiChannel[]>;
|
getWifiChannels(countryIso3661: string): Promise<WifiChannel[]>;
|
||||||
@@ -428,6 +432,10 @@ export interface PiPedalModel {
|
|||||||
clearZoomedControl(): void;
|
clearZoomedControl(): void;
|
||||||
|
|
||||||
setFavorite(pluginUrl: string, isFavorite: boolean): void;
|
setFavorite(pluginUrl: string, isFavorite: boolean): void;
|
||||||
|
|
||||||
|
isAndroidHosted(): boolean;
|
||||||
|
getAndroidHostVersion(): string;
|
||||||
|
chooseNewDevice(): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PiPedalModelImpl implements PiPedalModel {
|
class PiPedalModelImpl implements PiPedalModel {
|
||||||
@@ -457,6 +465,7 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
= new ObservableProperty<JackServerSettings>(new JackServerSettings());
|
= new ObservableProperty<JackServerSettings>(new JackServerSettings());
|
||||||
|
|
||||||
wifiConfigSettings: ObservableProperty<WifiConfigSettings> = new ObservableProperty<WifiConfigSettings>(new WifiConfigSettings());
|
wifiConfigSettings: ObservableProperty<WifiConfigSettings> = new ObservableProperty<WifiConfigSettings>(new WifiConfigSettings());
|
||||||
|
wifiDirectConfigSettings: ObservableProperty<WifiDirectConfigSettings> = new ObservableProperty<WifiDirectConfigSettings>(new WifiDirectConfigSettings());
|
||||||
governorSettings: ObservableProperty<GovernorSettings> = new ObservableProperty<GovernorSettings>(new GovernorSettings());
|
governorSettings: ObservableProperty<GovernorSettings> = new ObservableProperty<GovernorSettings>(new GovernorSettings());
|
||||||
|
|
||||||
favorites: ObservableProperty<FavoritesList> = new ObservableProperty<FavoritesList>({});
|
favorites: ObservableProperty<FavoritesList> = new ObservableProperty<FavoritesList>({});
|
||||||
@@ -484,8 +493,11 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
androidHost?: AndroidHostInterface;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.androidHost = (window as any).AndroidHost as AndroidHostInterface;
|
||||||
|
|
||||||
this.onSocketError = this.onSocketError.bind(this);
|
this.onSocketError = this.onSocketError.bind(this);
|
||||||
this.onSocketMessage = this.onSocketMessage.bind(this);
|
this.onSocketMessage = this.onSocketMessage.bind(this);
|
||||||
this.onSocketReconnecting = this.onSocketReconnecting.bind(this);
|
this.onSocketReconnecting = this.onSocketReconnecting.bind(this);
|
||||||
@@ -505,17 +517,14 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
this.onError(errorMessage);
|
this.onError(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
compareFavorites(left: FavoritesList, right: FavoritesList): boolean
|
compareFavorites(left: FavoritesList, right: FavoritesList): boolean {
|
||||||
{
|
for (let key of Object.keys(left)) {
|
||||||
for (let key of Object.keys(left))
|
|
||||||
{
|
|
||||||
if (!right[key]) {
|
if (!right[key]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let key of Object.keys(right))
|
for (let key of Object.keys(right)) {
|
||||||
{
|
|
||||||
if (!left[key]) {
|
if (!left[key]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -539,11 +548,9 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
if (header.replyTo) {
|
if (header.replyTo) {
|
||||||
this.webSocket?.reply(header.replyTo, "onMonitorPortOutput", true);
|
this.webSocket?.reply(header.replyTo, "onMonitorPortOutput", true);
|
||||||
}
|
}
|
||||||
} else if (message === "onFavoritesChanged")
|
} else if (message === "onFavoritesChanged") {
|
||||||
{
|
|
||||||
let favorites = body as FavoritesList;
|
let favorites = body as FavoritesList;
|
||||||
if (!this.compareFavorites(favorites,this.favorites.get()))
|
if (!this.compareFavorites(favorites, this.favorites.get())) {
|
||||||
{
|
|
||||||
this.favorites.set(favorites);
|
this.favorites.set(favorites);
|
||||||
}
|
}
|
||||||
} else if (message === "onChannelSelectionChanged") {
|
} else if (message === "onChannelSelectionChanged") {
|
||||||
@@ -613,6 +620,9 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
} else if (message === "onWifiConfigSettingsChanged") {
|
} else if (message === "onWifiConfigSettingsChanged") {
|
||||||
let wifiConfigSettings = new WifiConfigSettings().deserialize(body);
|
let wifiConfigSettings = new WifiConfigSettings().deserialize(body);
|
||||||
this.wifiConfigSettings.set(wifiConfigSettings);
|
this.wifiConfigSettings.set(wifiConfigSettings);
|
||||||
|
} else if (message === "onWifiDirectConfigSettingsChanged") {
|
||||||
|
let wifiDirectConfigSettings = new WifiDirectConfigSettings().deserialize(body);
|
||||||
|
this.wifiDirectConfigSettings.set(wifiDirectConfigSettings);
|
||||||
}
|
}
|
||||||
else if (message === "onGovernorSettingsChanged") {
|
else if (message === "onGovernorSettingsChanged") {
|
||||||
let governor = body as string;
|
let governor = body as string;
|
||||||
@@ -704,6 +714,13 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
this.wifiConfigSettings.set(new WifiConfigSettings().deserialize(data));
|
this.wifiConfigSettings.set(new WifiConfigSettings().deserialize(data));
|
||||||
|
|
||||||
|
|
||||||
|
return this.getWebSocket().request<any>("getWifiDirectConfigSettings");
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
this.wifiDirectConfigSettings.set(new WifiDirectConfigSettings().deserialize(data));
|
||||||
|
|
||||||
|
|
||||||
return this.getWebSocket().request<any>("getGovernorSettings");
|
return this.getWebSocket().request<any>("getGovernorSettings");
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@@ -773,6 +790,9 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
if (data.max_upload_size) {
|
if (data.max_upload_size) {
|
||||||
this.maxUploadSize = data.max_upload_size;
|
this.maxUploadSize = data.max_upload_size;
|
||||||
}
|
}
|
||||||
|
if (data.fakeAndroid) {
|
||||||
|
this.androidHost = new FakeAndroidHost();
|
||||||
|
}
|
||||||
this.debug = !!data.debug;
|
this.debug = !!data.debug;
|
||||||
let { socket_server_port, socket_server_address } = data;
|
let { socket_server_port, socket_server_address } = data;
|
||||||
if ((!socket_server_address) || socket_server_address === "*") {
|
if ((!socket_server_address) || socket_server_address === "*") {
|
||||||
@@ -843,11 +863,17 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.presets.set(new PresetIndex().deserialize(data));
|
this.presets.set(new PresetIndex().deserialize(data));
|
||||||
|
|
||||||
return this.getWebSocket().request<any>("getWifiConfigSettings");
|
return this.getWebSocket().request<any>("getWifiConfigSettings");
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.wifiConfigSettings.set(new WifiConfigSettings().deserialize(data));
|
this.wifiConfigSettings.set(new WifiConfigSettings().deserialize(data));
|
||||||
|
|
||||||
|
return this.getWebSocket().request<any>("getWifiDirectConfigSettings");
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
this.wifiDirectConfigSettings.set(new WifiDirectConfigSettings().deserialize(data));
|
||||||
|
|
||||||
return this.getWebSocket().request<any>("getGovernorSettings");
|
return this.getWebSocket().request<any>("getGovernorSettings");
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@@ -876,8 +902,7 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.banks.set(new BankIndex().deserialize(data));
|
this.banks.set(new BankIndex().deserialize(data));
|
||||||
if (this.webSocket)
|
if (this.webSocket) {
|
||||||
{
|
|
||||||
// MUST not allow reconnect until at least one complete load has finished.
|
// MUST not allow reconnect until at least one complete load has finished.
|
||||||
this.webSocket.canReconnect = true;
|
this.webSocket.canReconnect = true;
|
||||||
}
|
}
|
||||||
@@ -887,8 +912,7 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
.then((data) => {
|
.then((data) => {
|
||||||
this.favorites.set(data);
|
this.favorites.set(data);
|
||||||
|
|
||||||
if (this.webSocket)
|
if (this.webSocket) {
|
||||||
{
|
|
||||||
// MUST not allow reconnect until at least one complete load has finished.
|
// MUST not allow reconnect until at least one complete load has finished.
|
||||||
this.webSocket.canReconnect = true;
|
this.webSocket.canReconnect = true;
|
||||||
}
|
}
|
||||||
@@ -1901,6 +1925,57 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
setWifiDirectConfigSettings(wifiDirectConfigSettings: WifiDirectConfigSettings): Promise<void> {
|
||||||
|
let result = new Promise<void>((resolve, reject) => {
|
||||||
|
let oldSettings = this.wifiDirectConfigSettings.get();
|
||||||
|
wifiDirectConfigSettings = wifiDirectConfigSettings.clone();
|
||||||
|
|
||||||
|
if ((!oldSettings.enable) && (!wifiDirectConfigSettings.enable)) {
|
||||||
|
// no effective change.
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!wifiDirectConfigSettings.enable) {
|
||||||
|
wifiDirectConfigSettings = oldSettings.clone();
|
||||||
|
wifiDirectConfigSettings.enable = false;
|
||||||
|
} else {
|
||||||
|
if (wifiDirectConfigSettings.countryCode === oldSettings.countryCode
|
||||||
|
&& wifiDirectConfigSettings.channel === oldSettings.channel
|
||||||
|
&& wifiDirectConfigSettings.hotspotName === oldSettings.hotspotName
|
||||||
|
&& wifiDirectConfigSettings.enable == oldSettings.enable) {
|
||||||
|
if (wifiDirectConfigSettings.pin === oldSettings.pin) {
|
||||||
|
// no effective change.
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// save a version for the server (potentially carrying a password)
|
||||||
|
let serverConfigSettings = wifiDirectConfigSettings.clone();
|
||||||
|
this.wifiDirectConfigSettings.set(wifiDirectConfigSettings);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// notify the server.
|
||||||
|
let ws = this.webSocket;
|
||||||
|
if (!ws) {
|
||||||
|
reject("Not connected.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ws.request<void>(
|
||||||
|
"setWifiDirectConfigSettings",
|
||||||
|
serverConfigSettings
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
getWifiChannels(countryIso3661: string): Promise<WifiChannel[]> {
|
getWifiChannels(countryIso3661: string): Promise<WifiChannel[]> {
|
||||||
let result = new Promise<WifiChannel[]>((resolve, reject) => {
|
let result = new Promise<WifiChannel[]>((resolve, reject) => {
|
||||||
@@ -1939,23 +2014,19 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
this.zoomedUiControl.set(undefined);
|
this.zoomedUiControl.set(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
setFavorite(pluginUrl: string, isFavorite: boolean): void
|
setFavorite(pluginUrl: string, isFavorite: boolean): void {
|
||||||
{
|
|
||||||
let favorites = this.favorites.get();
|
let favorites = this.favorites.get();
|
||||||
let newFavorites: FavoritesList = {};
|
let newFavorites: FavoritesList = {};
|
||||||
Object.assign(newFavorites, favorites);
|
Object.assign(newFavorites, favorites);
|
||||||
if (isFavorite)
|
if (isFavorite) {
|
||||||
{
|
|
||||||
newFavorites[pluginUrl] = true;
|
newFavorites[pluginUrl] = true;
|
||||||
} else {
|
} else {
|
||||||
if (newFavorites[pluginUrl])
|
if (newFavorites[pluginUrl]) {
|
||||||
{
|
|
||||||
delete newFavorites[pluginUrl];
|
delete newFavorites[pluginUrl];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.favorites.set(newFavorites);
|
this.favorites.set(newFavorites);
|
||||||
if (this.webSocket)
|
if (this.webSocket) {
|
||||||
{
|
|
||||||
this.webSocket.send("setFavorites", newFavorites);
|
this.webSocket.send("setFavorites", newFavorites);
|
||||||
}
|
}
|
||||||
// stub: update server.
|
// stub: update server.
|
||||||
@@ -1971,6 +2042,21 @@ class PiPedalModelImpl implements PiPedalModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isAndroidHosted(): boolean { return this.androidHost !== undefined; }
|
||||||
|
|
||||||
|
getAndroidHostVersion(): string {
|
||||||
|
if (this.androidHost) {
|
||||||
|
return this.androidHost.getHostVersion();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
chooseNewDevice(): void {
|
||||||
|
if (this.androidHost) {
|
||||||
|
return this.androidHost.chooseNewDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let instance: PiPedalModel | undefined = undefined;
|
let instance: PiPedalModel | undefined = undefined;
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ import JackServerSettings from './JackServerSettings';
|
|||||||
import JackServerSettingsDialog from './JackServerSettingsDialog';
|
import JackServerSettingsDialog from './JackServerSettingsDialog';
|
||||||
import JackHostStatus from './JackHostStatus';
|
import JackHostStatus from './JackHostStatus';
|
||||||
import WifiConfigSettings from './WifiConfigSettings';
|
import WifiConfigSettings from './WifiConfigSettings';
|
||||||
|
import WifiDirectConfigSettings from './WifiDirectConfigSettings';
|
||||||
import WifiConfigDialog from './WifiConfigDialog';
|
import WifiConfigDialog from './WifiConfigDialog';
|
||||||
|
import WifiDirectConfigDialog from './WifiDirectConfigDialog';
|
||||||
import DialogEx from './DialogEx'
|
import DialogEx from './DialogEx'
|
||||||
import GovernorSettings from './GovernorSettings';
|
import GovernorSettings from './GovernorSettings';
|
||||||
|
|
||||||
@@ -60,8 +62,10 @@ interface SettingsDialogState {
|
|||||||
governorSettings: GovernorSettings;
|
governorSettings: GovernorSettings;
|
||||||
|
|
||||||
wifiConfigSettings: WifiConfigSettings;
|
wifiConfigSettings: WifiConfigSettings;
|
||||||
|
wifiDirectConfigSettings: WifiDirectConfigSettings;
|
||||||
|
|
||||||
showWifiConfigDialog: boolean;
|
showWifiConfigDialog: boolean;
|
||||||
|
showWifiDirectConfigDialog: boolean;
|
||||||
showGovernorSettingsDialog: boolean;
|
showGovernorSettingsDialog: boolean;
|
||||||
showInputSelectDialog: boolean;
|
showInputSelectDialog: boolean;
|
||||||
showOutputSelectDialog: boolean;
|
showOutputSelectDialog: boolean;
|
||||||
@@ -69,6 +73,7 @@ interface SettingsDialogState {
|
|||||||
showJackServerSettingsDialog: boolean;
|
showJackServerSettingsDialog: boolean;
|
||||||
shuttingDown: boolean;
|
shuttingDown: boolean;
|
||||||
restarting: boolean;
|
restarting: boolean;
|
||||||
|
isAndroidHosted: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -150,15 +155,19 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
jackStatus: undefined,
|
jackStatus: undefined,
|
||||||
jackSettings: this.model.jackSettings.get(),
|
jackSettings: this.model.jackSettings.get(),
|
||||||
wifiConfigSettings: this.model.wifiConfigSettings.get(),
|
wifiConfigSettings: this.model.wifiConfigSettings.get(),
|
||||||
|
wifiDirectConfigSettings: this.model.wifiDirectConfigSettings.get(),
|
||||||
governorSettings: this.model.governorSettings.get(),
|
governorSettings: this.model.governorSettings.get(),
|
||||||
showWifiConfigDialog: false,
|
showWifiConfigDialog: false,
|
||||||
|
showWifiDirectConfigDialog: false,
|
||||||
showGovernorSettingsDialog: false,
|
showGovernorSettingsDialog: false,
|
||||||
showInputSelectDialog: false,
|
showInputSelectDialog: false,
|
||||||
showOutputSelectDialog: false,
|
showOutputSelectDialog: false,
|
||||||
showMidiSelectDialog: false,
|
showMidiSelectDialog: false,
|
||||||
showJackServerSettingsDialog: false,
|
showJackServerSettingsDialog: false,
|
||||||
shuttingDown: false,
|
shuttingDown: false,
|
||||||
restarting: false
|
restarting: false,
|
||||||
|
isAndroidHosted: this.model.isAndroidHosted()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -166,6 +175,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
this.handleJackSettingsChanged = this.handleJackSettingsChanged.bind(this);
|
this.handleJackSettingsChanged = this.handleJackSettingsChanged.bind(this);
|
||||||
this.handleJackServerSettingsChanged = this.handleJackServerSettingsChanged.bind(this);
|
this.handleJackServerSettingsChanged = this.handleJackServerSettingsChanged.bind(this);
|
||||||
this.handleWifiConfigSettingsChanged = this.handleWifiConfigSettingsChanged.bind(this);
|
this.handleWifiConfigSettingsChanged = this.handleWifiConfigSettingsChanged.bind(this);
|
||||||
|
this.handleWifiDirectConfigSettingsChanged = this.handleWifiDirectConfigSettingsChanged.bind(this);
|
||||||
this.handleGovernorSettingsChanged = this.handleGovernorSettingsChanged.bind(this);
|
this.handleGovernorSettingsChanged = this.handleGovernorSettingsChanged.bind(this);
|
||||||
this.handleConnectionStateChanged = this.handleConnectionStateChanged.bind(this);
|
this.handleConnectionStateChanged = this.handleConnectionStateChanged.bind(this);
|
||||||
|
|
||||||
@@ -173,6 +183,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
handleConnectionStateChanged(): void {
|
handleConnectionStateChanged(): void {
|
||||||
if (this.model.state.get() === State.Ready) {
|
if (this.model.state.get() === State.Ready) {
|
||||||
|
this.setState({ isAndroidHosted: this.model.isAndroidHosted() });
|
||||||
if (this.state.shuttingDown || this.state.restarting) {
|
if (this.state.shuttingDown || this.state.restarting) {
|
||||||
this.setState({ shuttingDown: false, restarting: false });
|
this.setState({ shuttingDown: false, restarting: false });
|
||||||
}
|
}
|
||||||
@@ -189,6 +200,18 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
this.model.showAlert(err);
|
this.model.showAlert(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleApplyWifiDirectConfig(wifiDirectConfigSettings: WifiDirectConfigSettings): void {
|
||||||
|
this.setState({ showWifiDirectConfigDialog: false });
|
||||||
|
this.model.setWifiDirectConfigSettings(wifiDirectConfigSettings)
|
||||||
|
.then(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.model.showAlert(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
handleApplyGovernorSettings(governor: string): void {
|
handleApplyGovernorSettings(governor: string): void {
|
||||||
this.model.setGovernorSettings(governor)
|
this.model.setGovernorSettings(governor)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -206,6 +229,14 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
handleWifiDirectConfigSettingsChanged(): void {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
wifiDirectConfigSettings: this.model.wifiDirectConfigSettings.get()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
handleGovernorSettingsChanged(): void {
|
handleGovernorSettingsChanged(): void {
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
@@ -257,6 +288,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
this.model.jackConfiguration.addOnChangedHandler(this.handleJackConfigurationChanged);
|
this.model.jackConfiguration.addOnChangedHandler(this.handleJackConfigurationChanged);
|
||||||
this.model.jackServerSettings.addOnChangedHandler(this.handleJackServerSettingsChanged);
|
this.model.jackServerSettings.addOnChangedHandler(this.handleJackServerSettingsChanged);
|
||||||
this.model.wifiConfigSettings.addOnChangedHandler(this.handleWifiConfigSettingsChanged);
|
this.model.wifiConfigSettings.addOnChangedHandler(this.handleWifiConfigSettingsChanged);
|
||||||
|
this.model.wifiDirectConfigSettings.addOnChangedHandler(this.handleWifiDirectConfigSettingsChanged);
|
||||||
this.model.governorSettings.addOnChangedHandler(this.handleGovernorSettingsChanged);
|
this.model.governorSettings.addOnChangedHandler(this.handleGovernorSettingsChanged);
|
||||||
this.model.getJackStatus()
|
this.model.getJackStatus()
|
||||||
.then((jackStatus) =>
|
.then((jackStatus) =>
|
||||||
@@ -276,6 +308,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
this.handleJackSettingsChanged();
|
this.handleJackSettingsChanged();
|
||||||
this.handleJackServerSettingsChanged();
|
this.handleJackServerSettingsChanged();
|
||||||
this.handleWifiConfigSettingsChanged();
|
this.handleWifiConfigSettingsChanged();
|
||||||
|
this.handleWifiDirectConfigSettingsChanged();
|
||||||
this.timerHandle = setInterval(() => this.tick(), 1000);
|
this.timerHandle = setInterval(() => this.tick(), 1000);
|
||||||
} else {
|
} else {
|
||||||
if (this.timerHandle) {
|
if (this.timerHandle) {
|
||||||
@@ -286,7 +319,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
this.model.jackSettings.removeOnChangedHandler(this.handleJackSettingsChanged);
|
this.model.jackSettings.removeOnChangedHandler(this.handleJackSettingsChanged);
|
||||||
this.model.jackServerSettings.removeOnChangedHandler(this.handleJackServerSettingsChanged);
|
this.model.jackServerSettings.removeOnChangedHandler(this.handleJackServerSettingsChanged);
|
||||||
this.model.wifiConfigSettings.removeOnChangedHandler(this.handleWifiConfigSettingsChanged);
|
this.model.wifiConfigSettings.removeOnChangedHandler(this.handleWifiConfigSettingsChanged);
|
||||||
this.model.wifiConfigSettings.removeOnChangedHandler(this.handleGovernorSettingsChanged);
|
this.model.wifiDirectConfigSettings.removeOnChangedHandler(this.handleWifiDirectConfigSettingsChanged);
|
||||||
|
this.model.governorSettings.removeOnChangedHandler(this.handleGovernorSettingsChanged);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,6 +419,11 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
showWifiConfigDialog: true
|
showWifiConfigDialog: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
handleShowWifiDirectConfigDialog() {
|
||||||
|
this.setState({
|
||||||
|
showWifiDirectConfigDialog: true
|
||||||
|
});
|
||||||
|
}
|
||||||
handleShowGovernorSettingsDialogDialog() {
|
handleShowGovernorSettingsDialogDialog() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showGovernorSettingsDialog: true
|
showGovernorSettingsDialog: true
|
||||||
@@ -534,8 +573,42 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
</div>
|
</div>
|
||||||
<Divider />
|
<Divider />
|
||||||
<div >
|
<div >
|
||||||
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">SYSTEM</Typography>
|
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">CONNECTION</Typography>
|
||||||
|
|
||||||
|
{
|
||||||
|
this.state.isAndroidHosted &&
|
||||||
|
(
|
||||||
<ButtonBase className={classes.setting} disabled={!this.state.wifiConfigSettings.valid}
|
<ButtonBase className={classes.setting} disabled={!this.state.wifiConfigSettings.valid}
|
||||||
|
onClick={() => this.model.chooseNewDevice() } >
|
||||||
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Typography className={classes.primaryItem} display="block" variant="body2" color="textPrimary" noWrap>
|
||||||
|
Connect to a difference device</Typography>
|
||||||
|
<Typography display="block" variant="caption" noWrap color="textSecondary">
|
||||||
|
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</ButtonBase>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
<ButtonBase
|
||||||
|
className={classes.setting} disabled={!this.state.wifiConfigSettings.valid}
|
||||||
|
onClick={() => this.handleShowWifiDirectConfigDialog()} >
|
||||||
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Typography className={classes.primaryItem} display="block" variant="body2" color="textPrimary" noWrap>
|
||||||
|
Configure Wi-Fi Direct hotspot</Typography>
|
||||||
|
<Typography display="block" variant="caption" noWrap color="textSecondary">
|
||||||
|
{this.state.wifiDirectConfigSettings.getSummaryText()}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</ButtonBase>
|
||||||
|
|
||||||
|
<ButtonBase className={classes.setting} disabled={!this.state.wifiConfigSettings.valid}
|
||||||
|
style={{ display: "none" }}
|
||||||
onClick={() => this.handleShowWifiConfigDialog()} >
|
onClick={() => this.handleShowWifiConfigDialog()} >
|
||||||
<SelectHoverBackground selected={false} showHover={true} />
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
<div style={{ width: "100%" }}>
|
<div style={{ width: "100%" }}>
|
||||||
@@ -547,6 +620,11 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
</div>
|
||||||
|
<Divider />
|
||||||
|
<div >
|
||||||
|
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">SYSTEM</Typography>
|
||||||
|
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
style={{ display: "none" }}
|
style={{ display: "none" }}
|
||||||
className={classes.setting} disabled={!this.state.wifiConfigSettings.valid}
|
className={classes.setting} disabled={!this.state.wifiConfigSettings.valid}
|
||||||
@@ -562,6 +640,19 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
</div>
|
</div>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
|
<ButtonBase
|
||||||
|
className={classes.setting} disabled={!this.state.wifiConfigSettings.valid}
|
||||||
|
onClick={() => this.handleShowGovernorSettingsDialogDialog()} >
|
||||||
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
|
<div style={{ width: "100%" }}>
|
||||||
|
<Typography className={classes.primaryItem} display="block" variant="body2" color="textPrimary" noWrap>
|
||||||
|
Show status monitor on main screen.</Typography>
|
||||||
|
<Typography display="block" variant="caption" noWrap color="textSecondary">
|
||||||
|
Enabled
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</ButtonBase>
|
||||||
|
|
||||||
<ButtonBase className={classes.setting} disabled={disableShutdown}
|
<ButtonBase className={classes.setting} disabled={disableShutdown}
|
||||||
onClick={() => this.handleRestart()} >
|
onClick={() => this.handleRestart()} >
|
||||||
@@ -571,7 +662,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
this.state.restarting ? (
|
this.state.restarting ? (
|
||||||
<Typography className={classes.primaryItem} display="block" variant="body2" color="textSecondary" noWrap>Rebooting...</Typography>
|
<Typography className={classes.primaryItem} display="block" variant="body2" color="textSecondary" noWrap>Rebooting...</Typography>
|
||||||
) : (
|
) : (
|
||||||
<Typography className={classes.primaryItem} display="block" variant="body2" noWrap>Reboot</Typography>
|
<Typography className={classes.primaryItem} display="block" variant="body2" noWrap>Reboot PiPedal</Typography>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -648,6 +739,10 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
onClose={() => this.setState({ showWifiConfigDialog: false })}
|
onClose={() => this.setState({ showWifiConfigDialog: false })}
|
||||||
onOk={(wifiConfigSettings) => this.handleApplyWifiConfig(wifiConfigSettings)}
|
onOk={(wifiConfigSettings) => this.handleApplyWifiConfig(wifiConfigSettings)}
|
||||||
/>
|
/>
|
||||||
|
<WifiDirectConfigDialog wifiDirectConfigSettings={this.state.wifiDirectConfigSettings} open={this.state.showWifiDirectConfigDialog}
|
||||||
|
onClose={() => this.setState({ showWifiDirectConfigDialog: false })}
|
||||||
|
onOk={(wifiDirectConfigSettings: WifiDirectConfigSettings) => this.handleApplyWifiDirectConfig(wifiDirectConfigSettings)}
|
||||||
|
/>
|
||||||
|
|
||||||
</DialogEx >
|
</DialogEx >
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ const drawerStyles = (theme: Theme) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
drawer_header: {
|
drawer_header: {
|
||||||
color: 'white',
|
color: theme.palette.primary.main,
|
||||||
background: theme.palette.primary.main,
|
background: 'white',
|
||||||
|
|
||||||
}
|
}
|
||||||
})};
|
})};
|
||||||
|
|||||||
@@ -0,0 +1,400 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
import TextField from '@mui/material/TextField';
|
||||||
|
import DialogEx from './DialogEx';
|
||||||
|
import DialogActions from '@mui/material/DialogActions';
|
||||||
|
import DialogContent from '@mui/material/DialogContent';
|
||||||
|
import DialogTitle from '@mui/material/DialogTitle';
|
||||||
|
import Switch from '@mui/material/Switch';
|
||||||
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||||
|
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
|
||||||
|
import WifiDirectConfigSettings from './WifiDirectConfigSettings';
|
||||||
|
import { Theme } from '@mui/material/styles';
|
||||||
|
import { WithStyles } from '@mui/styles';
|
||||||
|
import withStyles from '@mui/styles/withStyles';
|
||||||
|
import createStyles from '@mui/styles/createStyles';
|
||||||
|
import Select from '@mui/material/Select';
|
||||||
|
import FormControl from '@mui/material/FormControl';
|
||||||
|
import InputLabel from '@mui/material/InputLabel';
|
||||||
|
import MenuItem from '@mui/material/MenuItem';
|
||||||
|
import WifiChannel from './WifiChannel';
|
||||||
|
import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
|
||||||
|
|
||||||
|
const styles = (theme: Theme) => createStyles({
|
||||||
|
pgraph: {
|
||||||
|
paddingBottom: 16
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
declare let crypto: any;
|
||||||
|
|
||||||
|
const NBSP = "\u00A0";
|
||||||
|
|
||||||
|
export interface WifiDirectConfigProps extends WithStyles<typeof styles> {
|
||||||
|
open: boolean,
|
||||||
|
wifiDirectConfigSettings: WifiDirectConfigSettings,
|
||||||
|
onOk: (wifiDirectConfigSettings: WifiDirectConfigSettings) => void,
|
||||||
|
onClose: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WifiDirectConfigState {
|
||||||
|
fullScreen: boolean;
|
||||||
|
enabled: boolean;
|
||||||
|
name: string;
|
||||||
|
pin: string;
|
||||||
|
nameError: boolean;
|
||||||
|
nameErrorMessage: string;
|
||||||
|
pinError: boolean;
|
||||||
|
pinErrorMessage: string;
|
||||||
|
countryCode: string;
|
||||||
|
channel: string;
|
||||||
|
wifiChannels: WifiChannel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const WifiDirectConfigDialog = withStyles(styles, { withTheme: true })(
|
||||||
|
class extends ResizeResponsiveComponent<WifiDirectConfigProps, WifiDirectConfigState> {
|
||||||
|
|
||||||
|
refName: React.RefObject<HTMLInputElement>;
|
||||||
|
refPassword: React.RefObject<HTMLInputElement>;
|
||||||
|
model: PiPedalModel;
|
||||||
|
|
||||||
|
constructor(props: WifiDirectConfigProps) {
|
||||||
|
super(props);
|
||||||
|
this.model = PiPedalModelFactory.getInstance();
|
||||||
|
this.state = {
|
||||||
|
fullScreen: false,
|
||||||
|
enabled: this.props.wifiDirectConfigSettings.enable,
|
||||||
|
name: this.props.wifiDirectConfigSettings.hotspotName,
|
||||||
|
pin: this.props.wifiDirectConfigSettings.pin,
|
||||||
|
nameError: false,
|
||||||
|
nameErrorMessage: NBSP,
|
||||||
|
pinError: false,
|
||||||
|
pinErrorMessage: NBSP,
|
||||||
|
countryCode: this.props.wifiDirectConfigSettings.countryCode,
|
||||||
|
channel: this.props.wifiDirectConfigSettings.channel,
|
||||||
|
wifiChannels: []
|
||||||
|
};
|
||||||
|
this.model.getWifiChannels(this.props.wifiDirectConfigSettings.countryCode)
|
||||||
|
.then((wifiChannels_) => {
|
||||||
|
this.setState({ wifiChannels: wifiChannels_ });
|
||||||
|
}).catch((err) => { });
|
||||||
|
|
||||||
|
this.refName = React.createRef<HTMLInputElement>();
|
||||||
|
this.refPassword = React.createRef<HTMLInputElement>();
|
||||||
|
}
|
||||||
|
mounted: boolean = false;
|
||||||
|
|
||||||
|
handleEnableChanged(e: any) {
|
||||||
|
this.setState({ enabled: e.target.checked });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onWindowSizeChanged(width: number, height: number): void {
|
||||||
|
this.setState({ fullScreen: height < 200 })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
super.componentDidMount();
|
||||||
|
this.mounted = true;
|
||||||
|
}
|
||||||
|
componentWillUnmount() {
|
||||||
|
super.componentWillUnmount();
|
||||||
|
this.mounted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: WifiDirectConfigProps) {
|
||||||
|
|
||||||
|
if (this.props.open && !prevProps.open) {
|
||||||
|
this.setState({
|
||||||
|
enabled: this.props.wifiDirectConfigSettings.enable,
|
||||||
|
name: this.props.wifiDirectConfigSettings.hotspotName,
|
||||||
|
pin: this.props.wifiDirectConfigSettings.pin,
|
||||||
|
countryCode: this.props.wifiDirectConfigSettings.countryCode,
|
||||||
|
channel: this.props.wifiDirectConfigSettings.channel
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.props.wifiDirectConfigSettings.countryCode !== this.state.countryCode) {
|
||||||
|
this.model.getWifiChannels(this.props.wifiDirectConfigSettings.countryCode)
|
||||||
|
.then((wifiChannels) => {
|
||||||
|
this.setState({ wifiChannels: wifiChannels });
|
||||||
|
})
|
||||||
|
.catch((error) => { });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
utf8Encode: TextEncoder = new TextEncoder();
|
||||||
|
|
||||||
|
validateName(name: string): void {
|
||||||
|
if (name.length === 0) {
|
||||||
|
throw new RangeError("Required.");
|
||||||
|
}
|
||||||
|
let bytes = this.utf8Encode.encode("DIRECT-XX-" + name);
|
||||||
|
if (bytes.length > 31) {
|
||||||
|
throw new RangeError("Too long.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validatePin(pin: string) {
|
||||||
|
if (pin.length === 0) throw new Error("Required.");
|
||||||
|
if (pin.length !== 8) {
|
||||||
|
throw new RangeError("Must be exactly 8 digits.");
|
||||||
|
}
|
||||||
|
for (let i = 0; i < pin.length; ++i) {
|
||||||
|
let c = pin.charCodeAt(i);
|
||||||
|
if (c < '0'.charCodeAt(0) || c > '9'.charCodeAt(0)) {
|
||||||
|
throw new RangeError("Must be exactly 8 digits.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOk() {
|
||||||
|
let nameError = false;
|
||||||
|
let nameErrorMessage = NBSP;
|
||||||
|
let pinError = false;
|
||||||
|
let pinErrorMessage = NBSP;
|
||||||
|
if (this.state.enabled) {
|
||||||
|
let name = this.state.name;
|
||||||
|
try {
|
||||||
|
this.validateName(name);
|
||||||
|
} catch (e: any) {
|
||||||
|
nameError = true; nameErrorMessage = "* " + e.message;
|
||||||
|
}
|
||||||
|
let pin = this.state.pin;
|
||||||
|
try {
|
||||||
|
this.validatePin(pin);
|
||||||
|
} catch (e: any) {
|
||||||
|
pinError = true; pinErrorMessage = "* " + e.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
let error = pinError || nameError || this.state.countryCode === "";
|
||||||
|
if (error) {
|
||||||
|
this.setState({ nameError: nameError, nameErrorMessage: nameErrorMessage, pinError: pinError, pinErrorMessage: pinErrorMessage });
|
||||||
|
} else {
|
||||||
|
let wifiDirectConfigSettings = new WifiDirectConfigSettings();
|
||||||
|
wifiDirectConfigSettings.valid = true;
|
||||||
|
|
||||||
|
wifiDirectConfigSettings.enable = this.state.enabled;
|
||||||
|
wifiDirectConfigSettings.hotspotName = this.state.name;
|
||||||
|
wifiDirectConfigSettings.countryCode = this.state.countryCode;
|
||||||
|
wifiDirectConfigSettings.channel = this.state.channel;
|
||||||
|
wifiDirectConfigSettings.pin = this.state.pin;
|
||||||
|
this.props.onOk(wifiDirectConfigSettings);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let wifiDirectConfigSettings = new WifiDirectConfigSettings();
|
||||||
|
wifiDirectConfigSettings.valid = true;
|
||||||
|
wifiDirectConfigSettings.enable = false;
|
||||||
|
this.props.onOk(wifiDirectConfigSettings);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
preventPasswordPrompt() {
|
||||||
|
}
|
||||||
|
handleChannelChange(e: any) {
|
||||||
|
let value = e.target.value as string;
|
||||||
|
this.setState({ channel: value });
|
||||||
|
}
|
||||||
|
handleCountryChanged(e: any) {
|
||||||
|
let value = e.target.value as string;
|
||||||
|
|
||||||
|
this.setState({ countryCode: value });
|
||||||
|
this.model.getWifiChannels(value)
|
||||||
|
.then(wifiChannels => {
|
||||||
|
this.setState({ wifiChannels: wifiChannels });
|
||||||
|
})
|
||||||
|
.catch((error) => { });
|
||||||
|
}
|
||||||
|
|
||||||
|
generateRandomPin(): string {
|
||||||
|
// prefer crypto if it's available.
|
||||||
|
let zero = "0".charCodeAt(0);
|
||||||
|
try {
|
||||||
|
let randomValue = new Int32Array(8);
|
||||||
|
crypto.getRandomValues(randomValue);
|
||||||
|
|
||||||
|
let s: string = "";
|
||||||
|
for (let i = 0; i < 8; ++i) {
|
||||||
|
let k = randomValue[i];
|
||||||
|
if (k < 0) k = -k;
|
||||||
|
k = k % 10;
|
||||||
|
|
||||||
|
s += String.fromCharCode(zero + k);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
let zero2 = "a".charCodeAt(0);
|
||||||
|
let s2 = "";
|
||||||
|
for (let i = 0; i < 8; ++i) {
|
||||||
|
let k = Math.floor(Math.random() * 10);
|
||||||
|
if (k < 0) k = -k;
|
||||||
|
k = k % 10;
|
||||||
|
|
||||||
|
s2 += String.fromCharCode(zero2 + k);
|
||||||
|
}
|
||||||
|
return s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
onGenerateRandomPin() {
|
||||||
|
let newPin = this.generateRandomPin();
|
||||||
|
this.setState({ pin: newPin, pinError: false, pinErrorMessage: NBSP });
|
||||||
|
if (this.refPassword.current) {
|
||||||
|
this.refPassword.current.value = newPin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let props = this.props;
|
||||||
|
let { open, onClose } = props;
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
this.preventPasswordPrompt();
|
||||||
|
// let preventPasswordPrompt changes settle (it's HARD to prevent a password prompt)
|
||||||
|
setTimeout(() => {
|
||||||
|
onClose();
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogEx tag="WifiDirectConfigDialog" open={open} fullWidth onClose={handleClose} style={{ userSelect: "none" }}
|
||||||
|
fullScreen={this.state.fullScreen}
|
||||||
|
>
|
||||||
|
{this.state.fullScreen && (
|
||||||
|
<DialogTitle>Wi-fi Hotspot</DialogTitle>
|
||||||
|
)}
|
||||||
|
<DialogContent>
|
||||||
|
|
||||||
|
<FormControlLabel
|
||||||
|
control={(
|
||||||
|
<Switch
|
||||||
|
checked={this.state.enabled}
|
||||||
|
onChange={(e: any) => this.handleEnableChanged(e)}
|
||||||
|
color="secondary"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
label="Enable Wi-Fi Direct Hotspot"
|
||||||
|
/>
|
||||||
|
<div style={{ marginTop: 16 }}>
|
||||||
|
<TextField
|
||||||
|
required
|
||||||
|
autoComplete="off"
|
||||||
|
id="name"
|
||||||
|
spellCheck="false"
|
||||||
|
label="SSID"
|
||||||
|
type="text"
|
||||||
|
fullWidth
|
||||||
|
error={this.state.nameError}
|
||||||
|
helperText={this.state.nameErrorMessage}
|
||||||
|
value={this.state.name}
|
||||||
|
onChange={(e) => this.setState({ name: e.target.value, nameError: false, nameErrorMessage: NBSP })}
|
||||||
|
inputRef={this.refName}
|
||||||
|
disabled={!this.state.enabled}
|
||||||
|
variant="filled"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ marginBottom: 0, verticalAlign: "baseline" }}>
|
||||||
|
<TextField
|
||||||
|
inputRef={this.refPassword}
|
||||||
|
autoComplete="off"
|
||||||
|
onChange={(e): void => { this.setState({ pin: e.target.value, pinError: false, pinErrorMessage: NBSP }); }}
|
||||||
|
label="Pin"
|
||||||
|
error={this.state.pinError}
|
||||||
|
helperText={this.state.pinErrorMessage}
|
||||||
|
defaultValue={this.state.pin}
|
||||||
|
disabled={!this.state.enabled}
|
||||||
|
variant="filled"
|
||||||
|
/>
|
||||||
|
<FormControl>
|
||||||
|
<div style={{ marginLeft: 16, marginTop: 18 }}>
|
||||||
|
<Button size="medium" disabled={!this.state.enabled}
|
||||||
|
onClick={() => this.onGenerateRandomPin()}
|
||||||
|
>Generate random pin</Button>
|
||||||
|
</div>
|
||||||
|
</FormControl>
|
||||||
|
</div>
|
||||||
|
<div style={{ marginBottom: 24 }}>
|
||||||
|
<FormControl variant="filled" sx={{ minWidth: 330 }}>
|
||||||
|
<InputLabel htmlFor="countryCodeSelect">Country</InputLabel>
|
||||||
|
<Select id="countryCodeSelect" label="Country" value={this.state.countryCode} disabled={!this.state.enabled}
|
||||||
|
onChange={(event) => this.handleCountryChanged(event)} >
|
||||||
|
{Object.entries(this.model.countryCodes).map(([key, value]) => {
|
||||||
|
return (
|
||||||
|
<MenuItem value={key}>{value}</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style={{ marginBottom: 24 }}>
|
||||||
|
<FormControl variant="filled" sx={{ minWidth: 330 }} >
|
||||||
|
<InputLabel htmlFor="channelSelect">Channel</InputLabel>
|
||||||
|
<Select id="channelSelect" label="Channel" value={this.state.channel} disabled={!this.state.enabled} onChange={(e) => {
|
||||||
|
this.handleChannelChange(e);
|
||||||
|
}}>
|
||||||
|
{this.state.wifiChannels.map((channel) => {
|
||||||
|
let t = channel.channelId;
|
||||||
|
if (t.startsWith("a")) t = t.substring(1);
|
||||||
|
if (t.startsWith("g")) t = t.substring(1);
|
||||||
|
let name = channel.channelName;
|
||||||
|
if (name.startsWith("1 ") || name.startsWith("6 ") || name.startsWith("11 ")) {
|
||||||
|
name += " *Recommended";
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<MenuItem value={t}>{name}</MenuItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleClose} color="primary" style={{ width: 120 }}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => this.handleOk()} color="secondary" style={{ width: 120 }} >
|
||||||
|
OK
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</DialogEx>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default WifiDirectConfigDialog;
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export default class WifiDirectConfigSettings {
|
||||||
|
deserialize(input: any) : WifiDirectConfigSettings{
|
||||||
|
this.valid = input.valid;
|
||||||
|
this.rebootRequired = input.rebootRequired;
|
||||||
|
this.enable = input.enable;
|
||||||
|
this.pinChanged = input.pinChanged;
|
||||||
|
this.hotspotName = input.hotspotName;
|
||||||
|
this.countryCode = input.countryCode;
|
||||||
|
this.pin = input.pin;
|
||||||
|
this.channel = input.channel;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
clone() : WifiDirectConfigSettings {
|
||||||
|
return new WifiDirectConfigSettings().deserialize(this);
|
||||||
|
}
|
||||||
|
valid: boolean = true;
|
||||||
|
enable: boolean = true;
|
||||||
|
rebootRequired = false;
|
||||||
|
hotspotName: string = "pipedal";
|
||||||
|
pinChanged: boolean = false;
|
||||||
|
pin: string = "";
|
||||||
|
countryCode: string = "US";
|
||||||
|
channel: string = "6";
|
||||||
|
|
||||||
|
getSummaryText() {
|
||||||
|
let result: string;
|
||||||
|
if (!this.valid) {
|
||||||
|
result = "Not available.";
|
||||||
|
} else if (!this.enable) {
|
||||||
|
result = "Disabled.";
|
||||||
|
} else {
|
||||||
|
result = this.hotspotName;
|
||||||
|
}
|
||||||
|
if (this.rebootRequired)
|
||||||
|
{
|
||||||
|
result += " (Restart required)";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -156,7 +156,7 @@ void AvahiService::create_group(AvahiClient *c)
|
|||||||
if ((ret = avahi_entry_group_add_service(
|
if ((ret = avahi_entry_group_add_service(
|
||||||
group,
|
group,
|
||||||
AVAHI_IF_UNSPEC,
|
AVAHI_IF_UNSPEC,
|
||||||
AVAHI_PROTO_UNSPEC,
|
AVAHI_PROTO_INET, // IPv4 for now, until we figure out why dnsqmasq borks IPv6 routing.)
|
||||||
(AvahiPublishFlags)0,
|
(AvahiPublishFlags)0,
|
||||||
name,
|
name,
|
||||||
PIPEDAL_SERVICE_TYPE,
|
PIPEDAL_SERVICE_TYPE,
|
||||||
|
|||||||
+36
-21
@@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.16.0)
|
|||||||
|
|
||||||
set (CMAKE_INSTALL_PREFIX "/usr/")
|
set (CMAKE_INSTALL_PREFIX "/usr/")
|
||||||
|
|
||||||
|
set (USE_PCH 1)
|
||||||
|
|
||||||
include(FindPkgConfig)
|
include(FindPkgConfig)
|
||||||
|
|
||||||
|
|
||||||
@@ -95,6 +97,7 @@ set (PIPEDAL_SOURCES
|
|||||||
P2pConfigFiles.hpp
|
P2pConfigFiles.hpp
|
||||||
AvahiService.cpp AvahiService.hpp
|
AvahiService.cpp AvahiService.hpp
|
||||||
DeviceIdFile.cpp DeviceIdFile.hpp
|
DeviceIdFile.cpp DeviceIdFile.hpp
|
||||||
|
WriteTemplateFile.cpp WriteTemplateFile.hpp
|
||||||
|
|
||||||
StdErrorCapture.hpp StdErrorCapture.cpp
|
StdErrorCapture.hpp StdErrorCapture.cpp
|
||||||
Ipv6Helpers.cpp Ipv6Helpers.hpp
|
Ipv6Helpers.cpp Ipv6Helpers.hpp
|
||||||
@@ -152,30 +155,45 @@ set (PIPEDAL_SOURCES
|
|||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
configure_file(config.hpp.in config.hpp)
|
configure_file(config.hpp.in config.hpp)
|
||||||
|
|
||||||
#################################
|
|
||||||
add_executable(pipedald ${PIPEDAL_SOURCES}
|
|
||||||
asan_options.cpp # disable leak checking for sanitize=address.
|
|
||||||
main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
include_directories( ${pipedald_SOURCE_DIR}/. ../build/src)
|
include_directories( ${pipedald_SOURCE_DIR}/. ../build/src)
|
||||||
|
|
||||||
target_precompile_headers(pipedald PRIVATE pch.h)
|
set (PIPEDAL_INCLUDES
|
||||||
|
|
||||||
|
|
||||||
target_include_directories(pipedald PRIVATE
|
|
||||||
${LV2DEV_INCLUDE_DIRS}
|
${LV2DEV_INCLUDE_DIRS}
|
||||||
${JACK_INCLUDE_DIRS} ${LILV_0_INCLUDE_DIRS} ${LIBNL3_INCLUDE_DIRS} ${LVDEV_INCLUDE_DIRS}
|
${JACK_INCLUDE_DIRS} ${LILV_0_INCLUDE_DIRS} ${LIBNL3_INCLUDE_DIRS} ${LVDEV_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(pipedald PRIVATE pthread atomic stdc++fs asound avahi-common avahi-client
|
set(PIPEDAL_LIBS libpipedald pthread atomic stdc++fs asound avahi-common avahi-client systemd
|
||||||
${LILV_0_LIBRARIES} ${JACK_LIBRARIES} ${LIBNL3_LIBRARIES} systemd SDBusCpp::sdbus-c++
|
${LILV_0_LIBRARIES} ${JACK_LIBRARIES} ${LIBNL3_LIBRARIES} )
|
||||||
|
|
||||||
|
|
||||||
|
##########################
|
||||||
|
|
||||||
|
add_library(libpipedald STATIC ${PIPEDAL_SOURCES})
|
||||||
|
|
||||||
|
target_include_directories(libpipedald PRIVATE ${PIPEDAL_INCLUDES}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(${USE_PCH})
|
||||||
|
target_precompile_headers(libpipedald PRIVATE pch.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
#################################
|
||||||
|
add_executable(pipedald
|
||||||
|
asan_options.cpp # disable leak checking for sanitize=address.
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(pipedald PRIVATE ${PIPEDAL_INCLUDES})
|
||||||
|
|
||||||
|
target_link_libraries(pipedald PRIVATE
|
||||||
|
|
||||||
|
${PIPEDAL_LIBS}
|
||||||
)
|
)
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
add_executable(pipedaltest ${PIPEDAL_SOURCES} testMain.cpp
|
add_executable(pipedaltest testMain.cpp
|
||||||
jsonTest.cpp
|
jsonTest.cpp
|
||||||
AvahiServiceTest.cpp
|
AvahiServiceTest.cpp
|
||||||
WifiChannelsTest.cpp
|
WifiChannelsTest.cpp
|
||||||
@@ -192,20 +210,17 @@ add_executable(pipedaltest ${PIPEDAL_SOURCES} testMain.cpp
|
|||||||
MemDebug.hpp
|
MemDebug.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file(config.hpp.in config.hpp)
|
|
||||||
include_directories( ${pipedald_SOURCE_DIR}/. ../build/src)
|
include_directories( ${pipedald_SOURCE_DIR}/. ../build/src)
|
||||||
|
|
||||||
|
if(${USE_PCH})
|
||||||
target_precompile_headers(pipedaltest PRIVATE pch.h)
|
target_precompile_headers(pipedaltest PRIVATE pch.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
target_include_directories(pipedaltest PRIVATE
|
target_include_directories(pipedaltest PRIVATE ${PIPEDAL_INCLUDES}
|
||||||
.
|
|
||||||
${LV2DEV_INCLUDE_DIRS}
|
|
||||||
${JACK_INCLUDE_DIRS} ${LILV_0_INCLUDE_DIRS} ${LIBNL3_INCLUDE_DIRS}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(pipedaltest PRIVATE pthread atomic stdc++fs asound avahi-common avahi-client
|
target_link_libraries(pipedaltest PRIVATE ${PIPEDAL_LIBS}
|
||||||
${LILV_0_LIBRARIES} ${JACK_LIBRARIES} ${LIBNL3_LIBRARIES} systemd SDBusCpp::sdbus-c++
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+26
-1
@@ -96,10 +96,35 @@ static std::string unquote(const std::string &value)
|
|||||||
}
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ConfigUtil::QuoteString(const std::string &value)
|
||||||
|
{
|
||||||
|
std::stringstream s;
|
||||||
|
|
||||||
|
s << '"';
|
||||||
|
for (char c : value)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '\n':
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
s << "\\\"";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
s << "\\\\";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s << c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s << '"';
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
bool ConfigUtil::GetConfigLine(const std::string &filePath, const std::string &key, std::string *pValue)
|
bool ConfigUtil::GetConfigLine(const std::string &filePath, const std::string &key, std::string *pValue)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -30,5 +30,8 @@ namespace pipedal {
|
|||||||
class ConfigUtil {
|
class ConfigUtil {
|
||||||
public:
|
public:
|
||||||
static bool GetConfigLine(const std::string & filePath,const std::string & key, std::string *pValue);
|
static bool GetConfigLine(const std::string & filePath,const std::string & key, std::string *pValue);
|
||||||
|
|
||||||
|
static std::string QuoteString(const std::string &value);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace pipedal {
|
namespace pipedal {
|
||||||
|
|
||||||
|
|||||||
@@ -678,11 +678,42 @@ void PiPedalModel::SetWifiConfigSettings(const WifiConfigSettings &wifiConfigSet
|
|||||||
delete[] t;
|
delete[] t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void PiPedalModel::SetWifiDirectConfigSettings(const WifiDirectConfigSettings &wifiDirectConfigSettings)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> guard(mutex);
|
||||||
|
|
||||||
|
adminClient.SetWifiDirectConfig(wifiDirectConfigSettings);
|
||||||
|
|
||||||
|
this->storage.SetWifiDirectConfigSettings(wifiDirectConfigSettings);
|
||||||
|
|
||||||
|
{
|
||||||
|
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
|
||||||
|
for (size_t i = 0; i < subscribers.size(); ++i)
|
||||||
|
{
|
||||||
|
t[i] = this->subscribers[i];
|
||||||
|
}
|
||||||
|
size_t n = this->subscribers.size();
|
||||||
|
|
||||||
|
WifiDirectConfigSettings tWifiDirectConfigSettings = storage.GetWifiDirectConfigSettings(); // (the passwordless version)
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
t[i]->OnWifiDirectConfigSettingsChanged(tWifiDirectConfigSettings);
|
||||||
|
}
|
||||||
|
delete[] t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WifiConfigSettings PiPedalModel::GetWifiConfigSettings()
|
WifiConfigSettings PiPedalModel::GetWifiConfigSettings()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> guard(mutex);
|
std::lock_guard<std::recursive_mutex> guard(mutex);
|
||||||
return this->storage.GetWifiConfigSettings();
|
return this->storage.GetWifiConfigSettings();
|
||||||
}
|
}
|
||||||
|
WifiDirectConfigSettings PiPedalModel::GetWifiDirectConfigSettings()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> guard(mutex);
|
||||||
|
return this->storage.GetWifiDirectConfigSettings();
|
||||||
|
}
|
||||||
|
|
||||||
JackConfiguration PiPedalModel::GetJackConfiguration()
|
JackConfiguration PiPedalModel::GetJackConfiguration()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "PiPedalConfiguration.hpp"
|
#include "PiPedalConfiguration.hpp"
|
||||||
#include "JackServerSettings.hpp"
|
#include "JackServerSettings.hpp"
|
||||||
#include "WifiConfigSettings.hpp"
|
#include "WifiConfigSettings.hpp"
|
||||||
|
#include "WifiDirectConfigSettings.hpp"
|
||||||
#include "AdminClient.hpp"
|
#include "AdminClient.hpp"
|
||||||
|
|
||||||
|
|
||||||
@@ -62,6 +63,7 @@ public:
|
|||||||
virtual void OnNotifyMidiListener(int64_t clientHandle, bool isNote, uint8_t noteOrControl) = 0;
|
virtual void OnNotifyMidiListener(int64_t clientHandle, bool isNote, uint8_t noteOrControl) = 0;
|
||||||
virtual void OnNotifyAtomOutput(int64_t clientModel,uint64_t instanceId,const std::string&atomType, const std::string&atomJson) = 0;
|
virtual void OnNotifyAtomOutput(int64_t clientModel,uint64_t instanceId,const std::string&atomType, const std::string&atomJson) = 0;
|
||||||
virtual void OnWifiConfigSettingsChanged(const WifiConfigSettings&wifiConfigSettings) = 0;
|
virtual void OnWifiConfigSettingsChanged(const WifiConfigSettings&wifiConfigSettings) = 0;
|
||||||
|
virtual void OnWifiDirectConfigSettingsChanged(const WifiDirectConfigSettings&wifiDirectConfigSettings) = 0;
|
||||||
virtual void OnGovernorSettingsChanged(const std::string &governor) = 0;
|
virtual void OnGovernorSettingsChanged(const std::string &governor) = 0;
|
||||||
virtual void OnFavoritesChanged(const std::map<std::string,bool> &favorites) = 0;
|
virtual void OnFavoritesChanged(const std::map<std::string,bool> &favorites) = 0;
|
||||||
virtual void Close() = 0;
|
virtual void Close() = 0;
|
||||||
@@ -207,6 +209,9 @@ public:
|
|||||||
void SetWifiConfigSettings(const WifiConfigSettings&wifiConfigSettings);
|
void SetWifiConfigSettings(const WifiConfigSettings&wifiConfigSettings);
|
||||||
WifiConfigSettings GetWifiConfigSettings();
|
WifiConfigSettings GetWifiConfigSettings();
|
||||||
|
|
||||||
|
void SetWifiDirectConfigSettings(const WifiDirectConfigSettings&wifiConfigSettings);
|
||||||
|
WifiDirectConfigSettings GetWifiDirectConfigSettings();
|
||||||
|
|
||||||
void SetGovernorSettings(const std::string& governor);
|
void SetGovernorSettings(const std::string& governor);
|
||||||
GovernorSettings GetGovernorSettings();
|
GovernorSettings GetGovernorSettings();
|
||||||
|
|
||||||
|
|||||||
+27
-1
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "AdminClient.hpp"
|
#include "AdminClient.hpp"
|
||||||
#include "WifiConfigSettings.hpp"
|
#include "WifiConfigSettings.hpp"
|
||||||
|
#include "WifiDirectConfigSettings.hpp"
|
||||||
#include "WifiChannels.hpp"
|
#include "WifiChannels.hpp"
|
||||||
#include "SysExec.hpp"
|
#include "SysExec.hpp"
|
||||||
#include "PiPedalAlsa.hpp"
|
#include "PiPedalAlsa.hpp"
|
||||||
@@ -812,6 +813,28 @@ public:
|
|||||||
this->Reply(replyTo, "getWifiConfigSettings", model.GetWifiConfigSettings());
|
this->Reply(replyTo, "getWifiConfigSettings", model.GetWifiConfigSettings());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (message == "setWifiDirectConfigSettings") {
|
||||||
|
WifiDirectConfigSettings wifiDirectConfigSettings;
|
||||||
|
pReader->read(&wifiDirectConfigSettings);
|
||||||
|
if (!GetAdminClient().CanUseShutdownClient())
|
||||||
|
{
|
||||||
|
throw PiPedalException("Can't change server settings when running interactively.");
|
||||||
|
}
|
||||||
|
std::string fromAddress = this->getFromAddress();
|
||||||
|
if (!IsOnLocalSubnet(fromAddress))
|
||||||
|
{
|
||||||
|
throw PiPedalException("Permission denied. Not on local subnet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this->model.SetWifiDirectConfigSettings(wifiDirectConfigSettings);
|
||||||
|
this->Reply(replyTo,"setWifiDirectConfigSettings");
|
||||||
|
}
|
||||||
|
else if (message == "getWifiDirectConfigSettings") {
|
||||||
|
this->Reply(replyTo, "getWifiDirectConfigSettings", model.GetWifiDirectConfigSettings());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
else if (message == "getGovernorSettings") {
|
else if (message == "getGovernorSettings") {
|
||||||
this->Reply(replyTo, "getGovernorSettings", model.GetGovernorSettings());
|
this->Reply(replyTo, "getGovernorSettings", model.GetGovernorSettings());
|
||||||
|
|
||||||
@@ -1462,10 +1485,13 @@ public:
|
|||||||
{
|
{
|
||||||
Send("onJackServerSettingsChanged",jackServerSettings);
|
Send("onJackServerSettingsChanged",jackServerSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnWifiConfigSettingsChanged(const WifiConfigSettings&wifiConfigSettings) {
|
virtual void OnWifiConfigSettingsChanged(const WifiConfigSettings&wifiConfigSettings) {
|
||||||
Send("onWifiConfigSettingsChanged",wifiConfigSettings);
|
Send("onWifiConfigSettingsChanged",wifiConfigSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void OnWifiDirectConfigSettingsChanged(const WifiDirectConfigSettings&wifiConfigSettings) {
|
||||||
|
Send("onWifiDirectConfigSettingsChanged",wifiConfigSettings);
|
||||||
|
}
|
||||||
virtual void OnGovernorSettingsChanged(const std::string& governor) {
|
virtual void OnGovernorSettingsChanged(const std::string& governor) {
|
||||||
Send("onGovernorSettingsChanged",governor);
|
Send("onGovernorSettingsChanged",governor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
#include "PiPedalException.hpp"
|
#include "PiPedalException.hpp"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace pipedal {
|
namespace pipedal {
|
||||||
|
|
||||||
|
|||||||
+14
-69
@@ -390,8 +390,14 @@ void UninstallP2p()
|
|||||||
restoreP2pDhcpdConfFile();
|
restoreP2pDhcpdConfFile();
|
||||||
restoreP2pDnsmasqConfFile();
|
restoreP2pDnsmasqConfFile();
|
||||||
|
|
||||||
sysExec(SYSTEMCTL_BIN " enable wpa_supplicant");
|
|
||||||
sysExec(SYSTEMCTL_BIN " start wpa_supplicant");
|
sysExec(SYSTEMCTL_BIN " restart dhcpcd");
|
||||||
|
|
||||||
|
WifiDirectConfigSettings wifiDirectConfigSettings;
|
||||||
|
wifiDirectConfigSettings.Load();
|
||||||
|
wifiDirectConfigSettings.enable_ = false;
|
||||||
|
wifiDirectConfigSettings.Save();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,25 +414,7 @@ void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// ******************* pipedal_p2pd ******
|
settings.Save();
|
||||||
{
|
|
||||||
// ${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, PIPEDAL_P2PD_CONF_PATH);
|
|
||||||
|
|
||||||
}
|
|
||||||
// ******************* device_uuid
|
// ******************* device_uuid
|
||||||
|
|
||||||
DeviceIdFile deviceIdFile;
|
DeviceIdFile deviceIdFile;
|
||||||
@@ -436,51 +424,9 @@ void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings)
|
|||||||
|
|
||||||
// ******************** dsnmasq ******
|
// ******************** dsnmasq ******
|
||||||
|
|
||||||
|
std::filesystem::remove(DNSMASQ_P2P_PATH);
|
||||||
std::filesystem::copy_file(DNSMASQ_P2P_SOURCE_PATH, DNSMASQ_P2P_PATH);
|
std::filesystem::copy_file(DNSMASQ_P2P_SOURCE_PATH, DNSMASQ_P2P_PATH);
|
||||||
|
|
||||||
#if JUNK // copy into place instaead.
|
|
||||||
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", P2P_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.EraseLine("except-interface=eth0");
|
|
||||||
dnsMasq.EraseLine("except-interface=wlan0");
|
|
||||||
dnsMasq.EraseLine("except-interface=lo");
|
|
||||||
|
|
||||||
dnsMasq.AppendLine("except-interface=eth0");
|
|
||||||
dnsMasq.AppendLine("except-interface=wlan0");
|
|
||||||
dnsMasq.AppendLine("except-interface=lo");
|
|
||||||
|
|
||||||
dnsMasq.Save(dnsMasqPath);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ****** dhcpd.conf ***/
|
// ****** dhcpd.conf ***/
|
||||||
std::filesystem::path dhcpcdConfig("/etc/dhcpcd.conf");
|
std::filesystem::path dhcpcdConfig("/etc/dhcpcd.conf");
|
||||||
if (std::filesystem::exists(dhcpcdConfig))
|
if (std::filesystem::exists(dhcpcdConfig))
|
||||||
@@ -496,9 +442,9 @@ void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings)
|
|||||||
|
|
||||||
int line = dhcpcd.GetLineThatStartsWith("hostname");
|
int line = dhcpcd.GetLineThatStartsWith("hostname");
|
||||||
std::string hostNameLine;
|
std::string hostNameLine;
|
||||||
if (settings.mdnsName_ != "")
|
if (false)
|
||||||
{
|
{
|
||||||
hostNameLine = "hostname " + settings.mdnsName_;
|
// hostNameLine = "hostname " + settings.mdnsName_;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -559,19 +505,18 @@ void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings)
|
|||||||
sysExec(SYSTEMCTL_BIN " enable dnsmasq");
|
sysExec(SYSTEMCTL_BIN " enable dnsmasq");
|
||||||
|
|
||||||
sysExec(SYSTEMCTL_BIN " restart dhcpcd");
|
sysExec(SYSTEMCTL_BIN " restart dhcpcd");
|
||||||
|
sysExec(SYSTEMCTL_BIN " enable dhcpcd");
|
||||||
|
|
||||||
|
|
||||||
sysExec(SYSTEMCTL_BIN " unmask pipedal_p2pd");
|
sysExec(SYSTEMCTL_BIN " unmask pipedal_p2pd");
|
||||||
cout << "."; cout.flush();
|
|
||||||
if (sysExec(SYSTEMCTL_BIN " restart pipedal_p2pd") != 0)
|
if (sysExec(SYSTEMCTL_BIN " restart pipedal_p2pd") != 0)
|
||||||
{
|
{
|
||||||
throw PiPedalException("Unable to start the pipedal_p2pd.");
|
throw PiPedalException("Unable to start the Wi-Fi Direct access point.");
|
||||||
}
|
}
|
||||||
|
|
||||||
sysExec(SYSTEMCTL_BIN " enable pipedal_p2pd");
|
sysExec(SYSTEMCTL_BIN " enable pipedal_p2pd");
|
||||||
|
|
||||||
}
|
}
|
||||||
cout << "Ready." << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pipedal::OnWifiUninstall()
|
void pipedal::OnWifiUninstall()
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "Lv2Log.hpp"
|
#include "Lv2Log.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
|
|
||||||
@@ -167,12 +168,49 @@ void Storage::SetDataRoot(const std::filesystem::path& path)
|
|||||||
this->dataRoot = ResolveHomePath(path);
|
this->dataRoot = ResolveHomePath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CopyDirectory(const std::filesystem::path &source, const std::filesystem::path &destination)
|
||||||
|
{
|
||||||
|
for (auto &directoryEntry: std::filesystem::directory_iterator(source))
|
||||||
|
{
|
||||||
|
if (directoryEntry.is_regular_file())
|
||||||
|
{
|
||||||
|
std::filesystem::path sourceFile = directoryEntry.path();
|
||||||
|
std::filesystem::path destFile = destination / sourceFile.filename();
|
||||||
|
|
||||||
|
std::filesystem::copy_file(sourceFile,destFile);
|
||||||
|
chmod(destFile.c_str(),S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Storage::MaybeCopyDefaultPresets()
|
||||||
|
{
|
||||||
|
auto presetsDirectory = this->GetPresetsDirectory();
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(presetsDirectory / "index.banks"))
|
||||||
|
{
|
||||||
|
CopyDirectory(this->configRoot / "default_presets" / "presets",
|
||||||
|
presetsDirectory
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pluginDirectory = this->GetPluginPresetsDirectory();
|
||||||
|
if (!std::filesystem::exists(pluginDirectory / "index.json"))
|
||||||
|
{
|
||||||
|
CopyDirectory(this->configRoot / "default_presets" / "plugin_presets",
|
||||||
|
pluginDirectory
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
void Storage::Initialize()
|
void Storage::Initialize()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::filesystem::create_directories(this->GetPresetsDirectory());
|
std::filesystem::create_directories(this->GetPresetsDirectory());
|
||||||
std::filesystem::create_directories(this->GetPluginPresetsDirectory());
|
std::filesystem::create_directories(this->GetPluginPresetsDirectory());
|
||||||
|
|
||||||
|
MaybeCopyDefaultPresets();
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
@@ -189,6 +227,7 @@ void Storage::Initialize()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
LoadWifiConfigSettings();
|
LoadWifiConfigSettings();
|
||||||
|
LoadWifiDirectConfigSettings();
|
||||||
LoadGovernorSettings();
|
LoadGovernorSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,6 +910,21 @@ void Storage::SetWifiConfigSettings(const WifiConfigSettings & wifiConfigSetting
|
|||||||
}
|
}
|
||||||
this->wifiConfigSettings = copyToStore;
|
this->wifiConfigSettings = copyToStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Storage::SetWifiDirectConfigSettings(const WifiDirectConfigSettings & wifiDirectConfigSettings)
|
||||||
|
{
|
||||||
|
WifiDirectConfigSettings copyToSave = wifiDirectConfigSettings;
|
||||||
|
copyToSave.rebootRequired_ = false;
|
||||||
|
if (!copyToSave.enable_)
|
||||||
|
{
|
||||||
|
copyToSave.pinChanged_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WifiDirectConfigSettings copyToStore = wifiDirectConfigSettings;
|
||||||
|
copyToStore.pinChanged_ = false;
|
||||||
|
this->wifiDirectConfigSettings = copyToStore;
|
||||||
|
}
|
||||||
|
|
||||||
void Storage::LoadGovernorSettings()
|
void Storage::LoadGovernorSettings()
|
||||||
{
|
{
|
||||||
std::filesystem::path path = this->dataRoot / GOVERNOR_SETTINGS_FILENAME;
|
std::filesystem::path path = this->dataRoot / GOVERNOR_SETTINGS_FILENAME;
|
||||||
@@ -918,12 +972,27 @@ void Storage::LoadWifiConfigSettings()
|
|||||||
}
|
}
|
||||||
this->wifiConfigSettings.valid_ = true;
|
this->wifiConfigSettings.valid_ = true;
|
||||||
}
|
}
|
||||||
|
void Storage::LoadWifiDirectConfigSettings()
|
||||||
|
{
|
||||||
|
|
||||||
|
WifiDirectConfigSettings settings;
|
||||||
|
settings.enable_ = false;
|
||||||
|
settings.Load();
|
||||||
|
settings.pinChanged_ = false;
|
||||||
|
settings.valid_ = true;
|
||||||
|
this->wifiDirectConfigSettings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WifiConfigSettings Storage::GetWifiConfigSettings()
|
WifiConfigSettings Storage::GetWifiConfigSettings()
|
||||||
{
|
{
|
||||||
return this->wifiConfigSettings;
|
return this->wifiConfigSettings;
|
||||||
}
|
}
|
||||||
|
WifiDirectConfigSettings Storage::GetWifiDirectConfigSettings()
|
||||||
|
{
|
||||||
|
return this->wifiDirectConfigSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Storage::SaveCurrentPreset(const CurrentPreset ¤tPreset)
|
void Storage::SaveCurrentPreset(const CurrentPreset ¤tPreset)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "Banks.hpp"
|
#include "Banks.hpp"
|
||||||
#include "JackConfiguration.hpp"
|
#include "JackConfiguration.hpp"
|
||||||
#include "WifiConfigSettings.hpp"
|
#include "WifiConfigSettings.hpp"
|
||||||
|
#include "WifiDirectConfigSettings.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@ private:
|
|||||||
PluginPresetIndex pluginPresetIndex;
|
PluginPresetIndex pluginPresetIndex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void MaybeCopyDefaultPresets();
|
||||||
static std::string SafeEncodeName(const std::string& name);
|
static std::string SafeEncodeName(const std::string& name);
|
||||||
static std::string SafeDecodeName(const std::string& name);
|
static std::string SafeDecodeName(const std::string& name);
|
||||||
std::filesystem::path GetPresetsDirectory() const;
|
std::filesystem::path GetPresetsDirectory() const;
|
||||||
@@ -74,6 +76,7 @@ private:
|
|||||||
bool isJackChannelSelectionValid = false;
|
bool isJackChannelSelectionValid = false;
|
||||||
JackChannelSelection jackChannelSelection;
|
JackChannelSelection jackChannelSelection;
|
||||||
WifiConfigSettings wifiConfigSettings;
|
WifiConfigSettings wifiConfigSettings;
|
||||||
|
WifiDirectConfigSettings wifiDirectConfigSettings;
|
||||||
std::string governorSettings = "performance";
|
std::string governorSettings = "performance";
|
||||||
public:
|
public:
|
||||||
Storage();
|
Storage();
|
||||||
@@ -89,6 +92,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
void LoadWifiConfigSettings();
|
void LoadWifiConfigSettings();
|
||||||
|
void LoadWifiDirectConfigSettings();
|
||||||
void LoadGovernorSettings();
|
void LoadGovernorSettings();
|
||||||
void LoadBank(int64_t instanceId);
|
void LoadBank(int64_t instanceId);
|
||||||
const PedalBoard& GetCurrentPreset();
|
const PedalBoard& GetCurrentPreset();
|
||||||
@@ -121,6 +125,10 @@ public:
|
|||||||
void SetWifiConfigSettings(const WifiConfigSettings & wifiConfigSettings);
|
void SetWifiConfigSettings(const WifiConfigSettings & wifiConfigSettings);
|
||||||
WifiConfigSettings GetWifiConfigSettings();
|
WifiConfigSettings GetWifiConfigSettings();
|
||||||
|
|
||||||
|
void SetWifiDirectConfigSettings(const WifiDirectConfigSettings & wifiDirectConfigSettings);
|
||||||
|
WifiDirectConfigSettings GetWifiDirectConfigSettings();
|
||||||
|
|
||||||
|
|
||||||
void SetGovernorSettings(const std::string & governor);
|
void SetGovernorSettings(const std::string & governor);
|
||||||
std::string GetGovernorSettings() const;
|
std::string GetGovernorSettings() const;
|
||||||
|
|
||||||
|
|||||||
@@ -17,13 +17,17 @@
|
|||||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
// 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.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#include "pch.h"
|
// #include "pch.h"
|
||||||
#include "WifiDirectConfigSettings.hpp"
|
#include "WifiDirectConfigSettings.hpp"
|
||||||
|
#include "P2pConfigFiles.hpp"
|
||||||
|
|
||||||
#include "WifiConfigSettings.hpp"
|
#include "WifiConfigSettings.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include "ConfigUtil.hpp"
|
#include "ConfigUtil.hpp"
|
||||||
#include "DeviceIdFile.hpp"
|
#include "DeviceIdFile.hpp"
|
||||||
|
#include "WriteTemplateFile.hpp"
|
||||||
|
#include "ss.hpp"
|
||||||
|
|
||||||
|
|
||||||
using namespace pipedal;
|
using namespace pipedal;
|
||||||
@@ -34,11 +38,10 @@ JSON_MAP_BEGIN(WifiDirectConfigSettings)
|
|||||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,rebootRequired)
|
JSON_MAP_REFERENCE(WifiDirectConfigSettings,rebootRequired)
|
||||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,enable)
|
JSON_MAP_REFERENCE(WifiDirectConfigSettings,enable)
|
||||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,hotspotName)
|
JSON_MAP_REFERENCE(WifiDirectConfigSettings,hotspotName)
|
||||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,hasPin)
|
JSON_MAP_REFERENCE(WifiDirectConfigSettings,pinChanged)
|
||||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,pin)
|
JSON_MAP_REFERENCE(WifiDirectConfigSettings,pin)
|
||||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,countryCode)
|
JSON_MAP_REFERENCE(WifiDirectConfigSettings,countryCode)
|
||||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,channel)
|
JSON_MAP_REFERENCE(WifiDirectConfigSettings,channel)
|
||||||
JSON_MAP_REFERENCE(WifiDirectConfigSettings,mdnsName)
|
|
||||||
JSON_MAP_END()
|
JSON_MAP_END()
|
||||||
|
|
||||||
static std::string MakePin()
|
static std::string MakePin()
|
||||||
@@ -79,30 +82,8 @@ void WifiDirectConfigSettings::ParseArguments(const std::vector<std::string> &ar
|
|||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.size() == 0)
|
||||||
{
|
{
|
||||||
if (!ConfigUtil::GetConfigLine("/etc/pipedal/config/pipedal_p2pd.conf","country_code",&this->countryCode_))
|
Load();
|
||||||
{
|
this->enable_ = true;
|
||||||
throw invalid_argument("Default value for country code not found.");
|
|
||||||
}
|
|
||||||
if (!ConfigUtil::GetConfigLine("/etc/pipedal/config/pipedal_p2pd.conf","p2p_pin",&this->pin_))
|
|
||||||
{
|
|
||||||
throw invalid_argument("Default value for pin not found.");
|
|
||||||
}
|
|
||||||
if (!ConfigUtil::GetConfigLine("/etc/pipedal/config/pipedal_p2pd.conf","wifiGroupFrequency",&this->channel_))
|
|
||||||
{
|
|
||||||
throw invalid_argument("Default value for pin not found.");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
DeviceIdFile deviceIdFile;
|
|
||||||
deviceIdFile.Load();
|
|
||||||
if (deviceIdFile.deviceName == "")
|
|
||||||
{
|
|
||||||
throw std::invalid_argument("");
|
|
||||||
}
|
|
||||||
this->hotspotName_ = deviceIdFile.deviceName;
|
|
||||||
} catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
throw std::invalid_argument("Default value for device name not found.");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (arguments.size() < 2 || arguments.size() > 4)
|
if (arguments.size() < 2 || arguments.size() > 4)
|
||||||
{
|
{
|
||||||
@@ -133,3 +114,63 @@ void WifiDirectConfigSettings::ParseArguments(const std::vector<std::string> &ar
|
|||||||
throw invalid_argument("Invalid channel.");
|
throw invalid_argument("Invalid channel.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WifiDirectConfigSettings::Save() const
|
||||||
|
{
|
||||||
|
// ******************* 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"] = this->countryCode_;
|
||||||
|
map["PIN"] = this->pin_;
|
||||||
|
map["DEVICE_NAME"] = ConfigUtil::QuoteString(this->hotspotName_);
|
||||||
|
map["WIFI_CHANNEL"] = SS(this->channel_);
|
||||||
|
map["ENABLED"] = this->enable_ ? "true": "false";
|
||||||
|
map["WIFI_GROUP_FREQUENCY"] = SS(ChannelToWifiFrequency(this->channel_));
|
||||||
|
map["INSTANCE_ID_FILE"] = DEVICE_GUID_FILE;
|
||||||
|
|
||||||
|
|
||||||
|
WriteTemplateFile(map, PIPEDAL_P2PD_CONF_PATH);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void WifiDirectConfigSettings::Load()
|
||||||
|
{
|
||||||
|
if (!ConfigUtil::GetConfigLine("/etc/pipedal/config/pipedal_p2pd.conf","p2p_device_name",&this->hotspotName_))
|
||||||
|
{
|
||||||
|
this->hotspotName_ = "PiPedal";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConfigUtil::GetConfigLine("/etc/pipedal/config/pipedal_p2pd.conf","country_code",&this->countryCode_))
|
||||||
|
{
|
||||||
|
this->countryCode_ = "US";
|
||||||
|
}
|
||||||
|
if (!ConfigUtil::GetConfigLine("/etc/pipedal/config/pipedal_p2pd.conf","p2p_pin",&this->pin_))
|
||||||
|
{
|
||||||
|
this->pin_ = "12345678";
|
||||||
|
}
|
||||||
|
if (!ConfigUtil::GetConfigLine("/etc/pipedal/config/pipedal_p2pd.conf","wifiChannel",&this->channel_))
|
||||||
|
{
|
||||||
|
this->channel_ = "6";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
DeviceIdFile deviceIdFile;
|
||||||
|
deviceIdFile.Load();
|
||||||
|
if (deviceIdFile.deviceName == "")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
this->hotspotName_ = deviceIdFile.deviceName;
|
||||||
|
} catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
this->valid_ = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,11 +35,13 @@ namespace pipedal {
|
|||||||
bool enable_ = false;
|
bool enable_ = false;
|
||||||
std::string countryCode_ = "US"; // iso 3661
|
std::string countryCode_ = "US"; // iso 3661
|
||||||
std::string hotspotName_ = "pipedal";
|
std::string hotspotName_ = "pipedal";
|
||||||
std::string mdnsName_ = "pipedal";
|
bool pinChanged_ = false;
|
||||||
bool hasPin_ = false;
|
|
||||||
std::string pin_;
|
std::string pin_;
|
||||||
std::string channel_ = "g6";
|
std::string channel_ = "6";
|
||||||
|
|
||||||
void ParseArguments(const std::vector<std::string> &arguments);
|
void ParseArguments(const std::vector<std::string> &arguments);
|
||||||
|
void Save() const;
|
||||||
|
void Load();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DECLARE_JSON_MAP(WifiDirectConfigSettings);
|
DECLARE_JSON_MAP(WifiDirectConfigSettings);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "PiPedalException.hpp"
|
#include "PiPedalException.hpp"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,19 @@ template <typename T> class TypeDisplay;
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string_view>
|
|
||||||
|
#include <mutex>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <memory>
|
||||||
|
#ifdef JUNK
|
||||||
|
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
#include <lv2/lv2core.lv2/lv2.h>
|
#include <lv2/lv2core.lv2/lv2.h>
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ p2p_ssid_postfix=${DEVICE_NAME}
|
|||||||
# Should almost always be 2412 (ch1),2437 (ch6), or 2462 (ch11).
|
# Should almost always be 2412 (ch1),2437 (ch6), or 2462 (ch11).
|
||||||
wifiGroupFrequency=${WIFI_GROUP_FREQUENCY}
|
wifiGroupFrequency=${WIFI_GROUP_FREQUENCY}
|
||||||
|
|
||||||
|
# UI use only. wifiGroupFrequency is authoritative
|
||||||
|
wifiChannel=${WIFI_CHANNEL}
|
||||||
|
|
||||||
|
# UI use only. service state is authoritative.
|
||||||
|
enabled=${ENABLED}
|
||||||
# P2P Device info
|
# P2P Device info
|
||||||
p2p_model_name=PiPedal
|
p2p_model_name=PiPedal
|
||||||
p2p_model_number=1
|
p2p_model_number=1
|
||||||
@@ -29,9 +34,6 @@ p2p_go_ht40=0
|
|||||||
p2p_go_vht=0
|
p2p_go_vht=0
|
||||||
p2p_go_he=0
|
p2p_go_he=0
|
||||||
|
|
||||||
# Ipv4 address for the P2P group interface
|
|
||||||
p2p_ip_address=172.24.0.2/16
|
|
||||||
|
|
||||||
# File containing the globally-unique id that identifies the service on this machine
|
# File containing the globally-unique id that identifies the service on this machine
|
||||||
# in this format: 0a6045b0-1753-4104-b3e4-b9713b9cc356
|
# in this format: 0a6045b0-1753-4104-b3e4-b9713b9cc356
|
||||||
service_guid_file=${INSTANCE_ID_FILE}
|
service_guid_file=${INSTANCE_ID_FILE}
|
||||||
|
|||||||
Reference in New Issue
Block a user