Vendored
+1
-1
@@ -76,7 +76,7 @@
|
||||
"request": "launch",
|
||||
// Resolved by CMake Tools:
|
||||
"program": "${command:cmake.launchTargetPath}",
|
||||
"args": [ "/etc/pipedal/config", "/etc/pipedal/react", "-port", "0.0.0.0:8080" ],
|
||||
"args": [ "/etc/pipedal/config", "/etc/pipedal/react", "-port", "0.0.0.0:8080", "-log-level","debug" ],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
project(pipedal
|
||||
VERSION 1.3.56
|
||||
VERSION 1.3.57
|
||||
DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi"
|
||||
HOMEPAGE_URL "https://rerdavies.github.io/pipedal"
|
||||
)
|
||||
set (DISPLAY_VERSION "PiPedal v1.3.56-Release")
|
||||
set (DISPLAY_VERSION "PiPedal v1.3.57-Release")
|
||||
set (PACKAGE_ARCHITECTURE "arm64")
|
||||
set (CMAKE_INSTALL_PREFIX "/usr/")
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
<a href="https://rerdavies.github.io/pipedal/LicensePiPedal.html"><img src="https://img.shields.io/badge/MIT-MIT?label=license&color=%23808080"/></a>
|
||||
<a href="https://github.com/rerdavies/pipedal/actions"><img src="https://img.shields.io/github/actions/workflow/status/rerdavies/pipedal/cmake.yml?branch=main"/></a>
|
||||
|
||||
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.3.56</a>
|
||||
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.3.57</a>
|
||||
Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal).
|
||||
Documentation: [https://rerdavies.github.io/pipedal/Documentation.html](https://rerdavies.github.io/pipedal/Documentation.html).
|
||||
|
||||
|
||||
|
||||
#### NEW version 1.3.56 Release, providing [snapshots](https://rerdavies.github.io/pipedal/Snaphots.html), and a new Performance View. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||
#### NEW version 1.3.57 Release, providing [snapshots](https://rerdavies.github.io/pipedal/Snaphots.html), and a new Performance View. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ You can optionally restrict the addresses on which PiPedal will respond by provi
|
||||
|
||||
To configure PiPedal to only accept connections on the Wi-Fi host access point:
|
||||
|
||||
sudo pipedalconfig --install --port 172.23.0.2:80
|
||||
sudo pipedalconfig --install --port 192.168.60.1:80
|
||||
|
||||
--------
|
||||
[<< Command-Line Configuration of PiPedal](CommandLine.md) | [Up](Documentation.md) | [Using LV2 Audio Plugins >>](UsingLv2Plugins.md)
|
||||
+3
-3
@@ -13,17 +13,17 @@ page_icon: img/Install4.jpg
|
||||
|
||||
Download the most recent Debian (.deb) package for your platform:
|
||||
|
||||
- [Raspberry Pi OS bookworm (64-bit) v1.3.56](https://github.com/rerdavies/pipedal/releases/download/)
|
||||
- [Raspberry Pi OS bookworm (64-bit) v1.3.57](https://github.com/rerdavies/pipedal/releases/download/)
|
||||
- [Ubuntu/Raspberry Pi OS bullseyeye (64-bit) v1.2.31](https://github.com/rerdavies/pipedal/releases/download/v1.1.31/pipedal_1.1.31_arm64.deb)
|
||||
|
||||
Version 1.3.56 has not yet been tested on Ubuntu or Raspberry Pi OS bullseye. On these platforms, we recommend that you use version 1.1.31.
|
||||
Version 1.3.57 has not yet been tested on Ubuntu or Raspberry Pi OS bullseye. On these platforms, we recommend that you use version 1.1.31.
|
||||
|
||||
Install the package by running
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
cd ~/Downloads
|
||||
sudo apt-get install pipedal_1.3.56_arm64.deb
|
||||
sudo apt-get install pipedal_1.3.57_arm64.deb
|
||||
```
|
||||
Adjust accordingly if you have downloaded v1.1.31.
|
||||
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# Release Notes
|
||||
|
||||
## PiPedal 1.3.57 Release
|
||||
|
||||
Features:
|
||||
- dB readings displayed as text under the main VUs.
|
||||
- Snapshot button title text now gets larger on large screens.
|
||||
- Selection indicators on Snapshot buttons are more visible.
|
||||
|
||||
|
||||
Bug fixes:
|
||||
- Setting Dark Mode to follow system settings now tracks properly on the Android PiPedal Remote app.
|
||||
- No longer crashes when using an audio adapter with mono input.
|
||||
- Reload after a being suspended in the Android Client in order to ensure that controls and VUs continue to update. Not ideal, but when Android suspends a web app, web socket messages get silently discarded, so there's not much choice about it.
|
||||
- GxTuner display now updates.
|
||||
- Correct Escape and Enter key handling in search control of the Load Plugin dialog.
|
||||
- Android remote: can connect when both Data connection and hotspot connection are active.
|
||||
- Stack dumps get written to systemd log on segment violations (should make it easier to diagnose crashes in the field).
|
||||
|
||||
Known issues:
|
||||
- To get the Android client to correctly follow system Dark Mode settings, you must update the Android app. You can work around the problem by explicitly selecting Light or Dark mode instead.
|
||||
- To get the Android client to connect when both the hot-spot and data connections are active, you must update the Android app. In the meantime, you can work around the problem by going to Android Network Settings, and clicking to disconnect and then reconnect the hot-spot connection (which will disable the data connection).
|
||||
|
||||
The updated Android app has been submitted, and should show up on Google Play sometime tomorrow morning.
|
||||
|
||||
|
||||
## PiPedal 1.3.56 Release
|
||||
|
||||
More snapshot problems.
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
Download the most recent Debian (.deb) package for your platform:
|
||||
|
||||
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.3.56/pipedal_1.3.56_arm64.deb">Raspberry Pi OS Bookworm (64-bit) v1.3.56</a>
|
||||
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.3.57/pipedal_1.3.57_arm64.deb">Raspberry Pi OS Bookworm (64-bit) v1.3.57</a>
|
||||
|
||||
|
||||
Install the package by running
|
||||
@@ -12,7 +12,7 @@ Install the package by running
|
||||
```
|
||||
sudo apt update
|
||||
cd ~/Downloads
|
||||
sudo apt-get install ./pipedal_1.3.56_arm64.deb
|
||||
sudo apt-get install ./pipedal_1.3.57_arm64.deb
|
||||
```
|
||||
|
||||
Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation.
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
<img src="GithubBanner.png" width="100%"/>
|
||||
<a href="Installing.html"><i>v1.3.56</i></a>
|
||||
<a href="Installing.html"><i>v1.3.57</i></a>
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ To download PiPedal, click [here](download.md).
|
||||
To view PiPedal documentation, click [here](Documentation.md).
|
||||
|
||||
|
||||
#### NEW version 1.3.56 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||
#### NEW version 1.3.57 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
|
||||
|
||||
|
||||
|
||||
|
||||
+29
-8
@@ -6,7 +6,8 @@
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="PiPedal Guitar Pedals" />
|
||||
<meta name="color-scheme" content="dark light"/> <!-- uses media queries in web views. -->
|
||||
<meta name="description" content="PiPedal Guitar Pedals" />
|
||||
<!--
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
|
||||
-->
|
||||
@@ -42,19 +43,39 @@
|
||||
<script>
|
||||
const androidHosted = !!(window.AndroidHost);
|
||||
|
||||
var colorScheme = localStorage.getItem("colorScheme");
|
||||
if (androidHosted)
|
||||
{
|
||||
var hostColorScheme = window.AndroidHost.getThemePreference();
|
||||
switch (hostColorScheme)
|
||||
{
|
||||
case 0:
|
||||
colorScheme = "Light";
|
||||
break;
|
||||
case 1:
|
||||
colorScheme = "Dark";
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
// use the host's interpretation of the current system night mode.
|
||||
colorScheme = window.AndroidHost.isDarkTheme() ? "Dark": "Light";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!colorScheme)
|
||||
{
|
||||
colorScheme = "Dark";
|
||||
}
|
||||
var darkMode = false;
|
||||
var useSystem = false;
|
||||
|
||||
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
switch (localStorage.getItem("colorScheme")) {
|
||||
switch (colorScheme) {
|
||||
case null:
|
||||
default:
|
||||
if (androidHosted) {
|
||||
useSystem = true;
|
||||
} else {
|
||||
darkMode = false;
|
||||
}
|
||||
darkMode = false;
|
||||
break;
|
||||
|
||||
case "Light":
|
||||
@@ -68,7 +89,7 @@
|
||||
break;
|
||||
}
|
||||
if (useSystem) {
|
||||
darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
darkMode = prefersDark;
|
||||
}
|
||||
|
||||
if (!darkMode) {
|
||||
|
||||
@@ -31,6 +31,7 @@ export interface AndroidHostInterface {
|
||||
launchExternalUrl(url:string): boolean;
|
||||
setThemePreference(theme: number): void;
|
||||
getThemePreference(): number;
|
||||
isDarkTheme?: ()=> boolean;
|
||||
};
|
||||
|
||||
export class FakeAndroidHost implements AndroidHostInterface
|
||||
@@ -43,6 +44,9 @@ export class FakeAndroidHost implements AndroidHostInterface
|
||||
}
|
||||
chooseNewDevice(): void {
|
||||
|
||||
}
|
||||
isDarkTheme(): boolean {
|
||||
return true;
|
||||
}
|
||||
setDisconnected(isDisconnected: boolean): void {
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ const appStyles = (theme: Theme) => createStyles({
|
||||
bottom: "0px",
|
||||
opacity: 0.8,
|
||||
background:
|
||||
isDarkMode() ? "#222" : "#DDD",
|
||||
isDarkMode() ? "#222" : "#EEE",
|
||||
},
|
||||
loadingContent: {
|
||||
display: "block",
|
||||
|
||||
+28
-4
@@ -17,7 +17,7 @@
|
||||
// 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 { AndroidHostInterface } from "./AndroidHost";
|
||||
import { AndroidHostInterface, getAndroidHost } from "./AndroidHost";
|
||||
|
||||
export enum ColorTheme {
|
||||
Light,
|
||||
@@ -25,7 +25,16 @@ export enum ColorTheme {
|
||||
System
|
||||
};
|
||||
|
||||
|
||||
export function getEffectiveColorScheme(): ColorTheme {
|
||||
let androidHost = (window as any).AndroidHost as AndroidHostInterface;
|
||||
if (androidHost) {
|
||||
if (androidHost.isDarkTheme)
|
||||
return androidHost.isDarkTheme() ? ColorTheme.Dark: ColorTheme.Light;
|
||||
return ColorTheme.Dark;
|
||||
}
|
||||
return getColorScheme();
|
||||
|
||||
}
|
||||
|
||||
export function getColorScheme(): ColorTheme {
|
||||
let androidHost = (window as any).AndroidHost as AndroidHostInterface;
|
||||
@@ -85,13 +94,28 @@ export function setColorScheme(value: ColorTheme): void {
|
||||
localStorage.setItem("colorScheme", storageValue);
|
||||
}
|
||||
|
||||
var gIsDarkTheme: boolean| undefined = undefined;
|
||||
|
||||
export function isDarkMode(): boolean {
|
||||
if (gIsDarkTheme !== undefined)
|
||||
{
|
||||
return gIsDarkTheme;
|
||||
}
|
||||
var colorTheme = getColorScheme();
|
||||
if (colorTheme === ColorTheme.System) {
|
||||
let androidHost = getAndroidHost();
|
||||
if (androidHost)
|
||||
{
|
||||
if (androidHost.isDarkTheme)
|
||||
{
|
||||
return gIsDarkTheme = androidHost.isDarkTheme();
|
||||
}
|
||||
return gIsDarkTheme = true;
|
||||
}
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
return true;
|
||||
return gIsDarkTheme = true;
|
||||
}
|
||||
}
|
||||
return colorTheme === ColorTheme.Dark;
|
||||
return gIsDarkTheme = (colorTheme === ColorTheme.Dark);
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,8 @@ const GxTunerControl =
|
||||
{
|
||||
midiNote = value;
|
||||
} else {
|
||||
if (value < 65)
|
||||
hz = value;
|
||||
if (hz < 65)
|
||||
{
|
||||
hz = -1;
|
||||
midiNote = -1;
|
||||
|
||||
@@ -607,6 +607,11 @@ export const LoadPluginDialog =
|
||||
this.hSearchTimeout = undefined;
|
||||
}
|
||||
|
||||
handleApplyFilter()
|
||||
{
|
||||
this.handleSearchStringReady();
|
||||
}
|
||||
|
||||
cancelSearchTimeout()
|
||||
{
|
||||
if (this.hSearchTimeout) {
|
||||
@@ -734,6 +739,9 @@ export const LoadPluginDialog =
|
||||
onTextChanged={(text) => {
|
||||
this.handleSearchStringChanged(text);
|
||||
}}
|
||||
onApplyFilter={() => {
|
||||
this.handleApplyFilter();
|
||||
}}
|
||||
onClearFilterClick={() => {
|
||||
if (this.state.search_string !== "") {
|
||||
this.requestScrollTo();
|
||||
|
||||
+40
-19
@@ -457,13 +457,39 @@ export class PiPedalModel //implements PiPedalModel
|
||||
this.onSocketConnectionLost = this.onSocketConnectionLost.bind(this);
|
||||
}
|
||||
|
||||
|
||||
private expectDisconnectTimer?: NodeJS.Timeout = undefined;
|
||||
|
||||
cancelExpectDisconnectTimer()
|
||||
{
|
||||
if (this.expectDisconnectTimer) {
|
||||
clearTimeout(this.expectDisconnectTimer);
|
||||
}
|
||||
}
|
||||
startExpectDisconnectTimer()
|
||||
{
|
||||
this.cancelExpectDisconnectTimer();
|
||||
// poll for access to a running pipedal server
|
||||
this.expectDisconnectTimer = setTimeout(
|
||||
async () => {
|
||||
this.reconnectReason = ReconnectReason.Disconnected;
|
||||
},
|
||||
5 * 1000);
|
||||
|
||||
}
|
||||
|
||||
expectDisconnect(reason: ReconnectReason) {
|
||||
this.cancelExpectDisconnectTimer();
|
||||
this.reconnectReason = reason;
|
||||
if (this.reconnectReason !== ReconnectReason.Disconnected)
|
||||
{
|
||||
this.startExpectDisconnectTimer();
|
||||
}
|
||||
}
|
||||
|
||||
onSocketReconnecting(retry: number, maxRetries: number): boolean {
|
||||
this.cancelExpectDisconnectTimer();
|
||||
if (this.isClosed) return false;
|
||||
if (this.visibilityState.get() === VisibilityState.Hidden) return false;
|
||||
//if (retry !== 0) {
|
||||
switch (this.reconnectReason) {
|
||||
case ReconnectReason.Disconnected:
|
||||
@@ -515,7 +541,6 @@ export class PiPedalModel //implements PiPedalModel
|
||||
|
||||
}
|
||||
onSocketMessage(header: PiPedalMessageHeader, body?: any) {
|
||||
if (this.visibilityState.get() === VisibilityState.Hidden) return;
|
||||
|
||||
let message = header.message;
|
||||
if (message === "onControlChanged") {
|
||||
@@ -1187,7 +1212,6 @@ export class PiPedalModel //implements PiPedalModel
|
||||
if (this.backgroundStateTimeout) {
|
||||
clearTimeout(this.backgroundStateTimeout);
|
||||
this.backgroundStateTimeout = undefined;
|
||||
return;
|
||||
}
|
||||
if (this.state.get() === State.Background) {
|
||||
console.log("Exiting background state.");
|
||||
@@ -1200,17 +1224,19 @@ export class PiPedalModel //implements PiPedalModel
|
||||
// on Android, delay entering background state by 180 seconds,
|
||||
// since background management is more complicated. e.g. screen flips, and system upload dialogs.
|
||||
|
||||
if (this.isAndroidHosted()) {
|
||||
if (this.backgroundStateTimeout) {
|
||||
clearTimeout(this.backgroundStateTimeout);
|
||||
}
|
||||
this.backgroundStateTimeout = setTimeout(() => {
|
||||
this.backgroundStateTimeout = undefined;
|
||||
this.enterBackgroundState_();
|
||||
}, 180000);
|
||||
} else {
|
||||
this.enterBackgroundState_();
|
||||
}
|
||||
// if (this.isAndroidHosted()) {
|
||||
// yyyx;
|
||||
// if (this.backgroundStateTimeout) {
|
||||
// clearTimeout(this.backgroundStateTimeout);
|
||||
// }
|
||||
// this.backgroundStateTimeout = setTimeout(() => {
|
||||
// this.backgroundStateTimeout = undefined;
|
||||
// this.enterBackgroundState_();
|
||||
// }, 180000);
|
||||
// } else {
|
||||
// this.enterBackgroundState_();
|
||||
// }
|
||||
this.enterBackgroundState_();
|
||||
}
|
||||
enterBackgroundState_() {
|
||||
if (this.state.get() !== State.Background) {
|
||||
@@ -1227,11 +1253,9 @@ export class PiPedalModel //implements PiPedalModel
|
||||
|
||||
switch (document.visibilityState) {
|
||||
case "visible":
|
||||
this.visibilityState.set(VisibilityState.Visible);
|
||||
this.exitBackgroundState();
|
||||
break;
|
||||
case "hidden":
|
||||
this.visibilityState.set(VisibilityState.Hidden);
|
||||
this.enterBackgroundState();
|
||||
break;
|
||||
}
|
||||
@@ -2424,9 +2448,6 @@ export class PiPedalModel //implements PiPedalModel
|
||||
|
||||
}
|
||||
private handleNotifyPatchProperty(clientHandle: number, instanceId: number, propertyUri: string, jsonObject: any) {
|
||||
// yyy this whole path is obsolete. We now get property change notifications
|
||||
// always, since the entire pedalboard must track excactly.
|
||||
// Review carefully.
|
||||
let pedalboard = this.pedalboard.get();
|
||||
let pedalboardItem = pedalboard.getItem(instanceId);
|
||||
if (pedalboardItem) {
|
||||
|
||||
@@ -94,7 +94,7 @@ const styles = (theme: Theme) => createStyles({
|
||||
},
|
||||
vuMeterL: {
|
||||
position: "fixed",
|
||||
paddingLeft: 12,
|
||||
paddingLeft: 6,
|
||||
paddingRight: 4,
|
||||
paddingBottom: 24,
|
||||
left: 0,
|
||||
@@ -634,10 +634,10 @@ const PluginControlView =
|
||||
return (
|
||||
<div className={classes.frame}>
|
||||
<div className={classes.vuMeterL}>
|
||||
<VuMeter display="input" instanceId={pedalboardItem.instanceId} />
|
||||
<VuMeter displayText={true} display="input" instanceId={pedalboardItem.instanceId} />
|
||||
</div>
|
||||
<div className={vuMeterRClass}>
|
||||
<VuMeter display="output" instanceId={pedalboardItem.instanceId} />
|
||||
<VuMeter displayText={true} display="output" instanceId={pedalboardItem.instanceId} />
|
||||
</div>
|
||||
<div className={gridClass} >
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// 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 React, { KeyboardEvent } from 'react';
|
||||
import { Theme } from '@mui/material/styles';
|
||||
import { WithStyles } from '@mui/styles';
|
||||
import withStyles from '@mui/styles/withStyles';
|
||||
@@ -39,6 +39,7 @@ interface SearchControlProps extends WithStyles<typeof styles> {
|
||||
onTextChanged: (searchString: string) => void;
|
||||
onClick: () => void;
|
||||
onClearFilterClick: () => void;
|
||||
onApplyFilter: () => void;
|
||||
inputRef?: React.RefObject<HTMLInputElement>;
|
||||
showSearchIcon?: boolean
|
||||
|
||||
@@ -66,6 +67,17 @@ const SearchControl = withStyles(styles, { withTheme: true })(
|
||||
}
|
||||
return this.defaultInputRef;
|
||||
}
|
||||
onKeyDown(ev: KeyboardEvent)
|
||||
{
|
||||
ev.stopPropagation(); // don't let the ENTER key propagate propagate the enclosing dialog Enter key handler.
|
||||
if (ev.key === "Enter")
|
||||
{
|
||||
this.props.onApplyFilter();
|
||||
} else if (ev.key === "Escape")
|
||||
{
|
||||
this.props.onClearFilterClick();
|
||||
}
|
||||
}
|
||||
componentDidUpdate(oldProps: SearchControlProps) {
|
||||
if (oldProps.collapsed ?? false !== this.props.collapsed ?? false) {
|
||||
let inputRef = this.getInputRef();
|
||||
@@ -96,7 +108,9 @@ const SearchControl = withStyles(styles, { withTheme: true })(
|
||||
)
|
||||
|
||||
}
|
||||
<Input spellCheck={false} style={{
|
||||
<Input spellCheck={false}
|
||||
onKeyDown={(ev)=>{this.onKeyDown(ev);}}
|
||||
style={{
|
||||
flex: "1 1", visibility: (this.props.collapsed ?? false) ? "collapse" : "visible", marginRight: 12, height: 32,
|
||||
}}
|
||||
inputRef={this.getInputRef()}
|
||||
|
||||
@@ -86,7 +86,7 @@ export default class SnapshotDialog extends ResizeResponsiveComponent<SnapshotDi
|
||||
}
|
||||
|
||||
getFullScreen() {
|
||||
return window.innerHeight < 450;
|
||||
return window.innerHeight < 450 || window.innerWidth < 450;
|
||||
}
|
||||
onWindowSizeChanged(width: number, height: number): void {
|
||||
this.setState(
|
||||
|
||||
@@ -211,7 +211,7 @@ export default class UpdateDialog extends ResizeResponsiveComponent<UpdateDialog
|
||||
<Typography noWrap variant="body2" color="textSecondary" >
|
||||
Update version:
|
||||
</Typography>
|
||||
<Typography noWrap variant="body2" color="textSecondary" >
|
||||
<Typography noWrap variant="body2" color="textSecondary" style={{ marginLeft: 16 }} >
|
||||
{updateRelease.upgradeVersionDisplayName}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
+84
-5
@@ -20,8 +20,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Theme } from '@mui/material/styles';
|
||||
import { WithStyles } from '@mui/styles';
|
||||
import createStyles from '@mui/styles/createStyles';
|
||||
import withStyles from '@mui/styles/withStyles';
|
||||
import {createStyles,withStyles} from '@mui/styles';
|
||||
import { PiPedalModel, State,PiPedalModelFactory, VuUpdateInfo, VuSubscriptionHandle } from './PiPedalModel';
|
||||
|
||||
|
||||
@@ -55,13 +54,15 @@ class TelltaleState {
|
||||
telltaleDb: number = MIN_DB;
|
||||
lastTelltaleTime: number = 0;
|
||||
telltaleHoldTime: number = 0;
|
||||
telltaleHoldValue: number = MIN_DB;
|
||||
|
||||
reset() : void {
|
||||
this.telltaleHoldTime = 0;
|
||||
this.lastTelltaleTime = 0;
|
||||
this.telltaleDb = MIN_DB;
|
||||
this.telltaleHoldValue = MIN_DB;
|
||||
}
|
||||
getValue(currentDb: number): number {
|
||||
getTelltaleHoldValue(currentDb: number): number {
|
||||
let t = new Date().getTime();
|
||||
|
||||
let holdValue: number;
|
||||
@@ -78,6 +79,7 @@ class TelltaleState {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.telltaleHoldValue = holdValue;
|
||||
|
||||
if (currentDb > holdValue) {
|
||||
this.telltaleDb = currentDb;
|
||||
@@ -93,7 +95,7 @@ class TelltaleState {
|
||||
const LEFT_X = BORDER_THICKNESS;
|
||||
const RIGHT_X = BORDER_THICKNESS + + CHANNEL_WIDTH + BORDER_THICKNESS;
|
||||
|
||||
const styles = ({ palette }: Theme) => createStyles({
|
||||
const styles = (theme: Theme) => createStyles({
|
||||
frame: {
|
||||
position: "relative",
|
||||
width: CHANNEL_WIDTH + 2*BORDER_THICKNESS,
|
||||
@@ -114,6 +116,23 @@ const styles = ({ palette }: Theme) => createStyles({
|
||||
background: "black",
|
||||
overflow: "hidden",
|
||||
},
|
||||
monoTextFrame: {
|
||||
display: "flex",flexFlow: "column nowrap", alignItems: "center", textAlign: "center"
|
||||
},
|
||||
stereoTextFrame: {
|
||||
display: "flex",flexFlow: "column nowrap", alignItems: "center", textAlign: "center"
|
||||
},
|
||||
vuTextFrame: {
|
||||
color: theme.palette.text.secondary,
|
||||
display: "table-cell",
|
||||
position: "relative",
|
||||
marginTop: 4,
|
||||
textAlign: "center",
|
||||
width: 20, height: 16,
|
||||
fontSize: "11px",
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
},
|
||||
redFrameL: {
|
||||
position: "absolute",
|
||||
top: "100%",
|
||||
@@ -189,6 +208,7 @@ interface VuMeterProps extends WithStyles<typeof styles> {
|
||||
instanceId: number;
|
||||
display: "input" | "output";
|
||||
theme: Theme;
|
||||
displayText?: boolean;
|
||||
}
|
||||
|
||||
interface VuMeterState {
|
||||
@@ -213,6 +233,7 @@ export const VuMeter =
|
||||
class extends Component<VuMeterProps, VuMeterState>
|
||||
{
|
||||
divRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||
textRef: React.RefObject<HTMLDivElement> = React.createRef();
|
||||
model: PiPedalModel;
|
||||
|
||||
yZero: number;
|
||||
@@ -240,6 +261,35 @@ export const VuMeter =
|
||||
vuInfo?: VuUpdateInfo;
|
||||
requesttedStereoState: boolean = false;
|
||||
|
||||
updateText(telltaleDb: number)
|
||||
{
|
||||
if (this.textRef.current) {
|
||||
let displayValue: string;
|
||||
if (telltaleDb <= MIN_DB)
|
||||
{
|
||||
displayValue = "-";
|
||||
} else {
|
||||
let iDb = Math.round(telltaleDb);
|
||||
if (iDb > 0)
|
||||
{
|
||||
displayValue = "+" + Math.round(telltaleDb).toString() + "\u00A0"
|
||||
} else if (iDb < 0) {
|
||||
displayValue = Math.round(telltaleDb).toString() + "\u00A0";
|
||||
} else {
|
||||
if (telltaleDb === 0) {
|
||||
displayValue = "0";
|
||||
} else if (telltaleDb > 0)
|
||||
{
|
||||
displayValue = "+0\u00A0";
|
||||
} else {
|
||||
displayValue = "-0\u00A0";
|
||||
}
|
||||
}
|
||||
}
|
||||
this.textRef.current.innerText = displayValue;
|
||||
}
|
||||
}
|
||||
|
||||
onVuChanged(vuInfo: VuUpdateInfo): void {
|
||||
let value: number;
|
||||
let valueR: number;
|
||||
@@ -291,6 +341,15 @@ export const VuMeter =
|
||||
};
|
||||
this.updateChannel(vuData, this.telltaleStateR);
|
||||
}
|
||||
if (this.props.displayText)
|
||||
{
|
||||
if (this.state.isStereo)
|
||||
{
|
||||
this.updateText(Math.max(this.telltaleStateL.telltaleHoldValue,this.telltaleStateR.telltaleHoldValue));
|
||||
} else {
|
||||
this.updateText(this.telltaleStateL.telltaleHoldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resetTelltales() {
|
||||
@@ -319,7 +378,7 @@ export const VuMeter =
|
||||
vuData.redDiv.style.top = y + "px";
|
||||
}
|
||||
}
|
||||
let dbTelltale = telltaleState.getValue(db);
|
||||
let dbTelltale = telltaleState.getTelltaleHoldValue(db);
|
||||
let yTelltale = dbToY(dbTelltale);
|
||||
|
||||
if (yTelltale < this.yZero) {
|
||||
@@ -381,8 +440,28 @@ export const VuMeter =
|
||||
|
||||
|
||||
render() {
|
||||
let displayText = this.props.displayText??false;
|
||||
let classes = this.props.classes;
|
||||
if (displayText)
|
||||
{
|
||||
return (
|
||||
<div className={this.state.isStereo? classes.stereoTextFrame: classes.monoTextFrame}>
|
||||
{
|
||||
this.renderVus()
|
||||
}
|
||||
<div ref={this.textRef} className={classes.vuTextFrame}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return this.renderVus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
renderVus() {
|
||||
|
||||
let classes = this.props.classes;
|
||||
if (!this.state.isStereo) {
|
||||
return (<div className={classes.frame} ref={this.divRef}
|
||||
>
|
||||
|
||||
+17
-6
@@ -5,6 +5,10 @@ set (CMAKE_INSTALL_PREFIX "/usr/")
|
||||
|
||||
set (USE_PCH 1)
|
||||
|
||||
set (ENABLE_BACKTRACE 1)
|
||||
|
||||
set (USE_SANITIZE true)
|
||||
|
||||
set(CXX_STANDARD 20)
|
||||
|
||||
include(FindPkgConfig)
|
||||
@@ -96,9 +100,6 @@ endif()
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
set (USE_SANITIZE true)
|
||||
|
||||
|
||||
if (!ENABLE_VST3)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-psabi -DARCHITECTURE=${CPACK_SYSTEM_NAME}")
|
||||
else()
|
||||
@@ -119,10 +120,17 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
endif()
|
||||
elseif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
|
||||
message(STATUS "RelWithgDebInfo build")
|
||||
#set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "" )
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG" )
|
||||
else()
|
||||
message(STATUS "Release build")
|
||||
#set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "" )
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG" )
|
||||
endif()
|
||||
|
||||
if (ENABLE_BACKTRACE)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -rdynamic")
|
||||
if (${DEBIAN_ARCHITECTURE} MATCHES arm64)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -funwind-tables")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -292,6 +300,9 @@ add_executable(pipedald
|
||||
)
|
||||
target_include_directories(pipedald PRIVATE ${PIPEDAL_INCLUDES})
|
||||
|
||||
target_compile_definitions(pipedald PRIVATE "ENABLE_BACKTRACE=${ENABLE_BACKTRACE}")
|
||||
|
||||
|
||||
target_link_libraries(pipedald PRIVATE PiPedalCommon
|
||||
|
||||
${PIPEDAL_LIBS}
|
||||
@@ -627,7 +638,7 @@ add_executable(pipedalconfig
|
||||
|
||||
)
|
||||
|
||||
target_link_libraries(pipedalconfig PRIVATE PiPedalCommon pthread atomic uuid stdc++fs
|
||||
target_link_libraries(pipedalconfig PRIVATE PiPedalCommon pthread atomic uuid stdc++fs
|
||||
)
|
||||
|
||||
add_executable(pipedal_latency_test
|
||||
|
||||
+35
-2
@@ -44,6 +44,9 @@
|
||||
#include <grp.h>
|
||||
#include "ofstream_synced.hpp"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define P2PD_DISABLED
|
||||
|
||||
#if JACK_HOST
|
||||
@@ -88,6 +91,29 @@ namespace fs = std::filesystem;
|
||||
#define REMOVE_OLD_SERVICE 0 // Grandfathering: whether to remove the old shutdown service (now pipedaladmind)
|
||||
#define OLD_SHUTDOWN_SERVICE "pipedalshutdownd"
|
||||
|
||||
|
||||
|
||||
void changeUserShell(const char* username, const char* newShell) {
|
||||
struct passwd* pw;
|
||||
struct passwd p;
|
||||
char buf[1024];
|
||||
|
||||
pw = getpwnam(username);
|
||||
if (pw == nullptr) {
|
||||
throw std::runtime_error("User not found");
|
||||
}
|
||||
if (strcmp(pw->pw_shell,newShell) == 0) {
|
||||
return;
|
||||
}
|
||||
std::string args = SS("/usr/sbin/usermod -s " << newShell << " " << username);
|
||||
|
||||
if (silentSysExec(args.c_str()) != EXIT_SUCCESS)
|
||||
{
|
||||
cout << "Failed to set shell for " << username << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fs::path GetServiceFileName(const std::string &serviceName)
|
||||
{
|
||||
return fs::path(SERVICE_PATH) / (serviceName + ".service");
|
||||
@@ -926,7 +952,7 @@ void Install(const fs::path &programPrefix, const std::string endpointAddress)
|
||||
try
|
||||
{
|
||||
// apply policy changes we dropped into the polkit configuration files (allows pipedal_d to use NetworkManager dbus apis).
|
||||
silentSysExec(SYSTEMCTL_BIN " restart polkit");
|
||||
silentSysExec(SYSTEMCTL_BIN " restart polkit.service");
|
||||
|
||||
DeployVarConfig();
|
||||
|
||||
@@ -994,7 +1020,7 @@ void Install(const fs::path &programPrefix, const std::string endpointAddress)
|
||||
|
||||
if (!userExists(SERVICE_ACCOUNT_NAME))
|
||||
{
|
||||
if (sysExec(USERADD_BIN " " SERVICE_ACCOUNT_NAME " -g " SERVICE_GROUP_NAME " -m --home /var/pipedal/home -N -r") != EXIT_SUCCESS)
|
||||
if (sysExec(USERADD_BIN " " SERVICE_ACCOUNT_NAME " -g " SERVICE_GROUP_NAME " -s /usr/sbin/nologin -m --home /var/pipedal/home -N -r") != EXIT_SUCCESS)
|
||||
{
|
||||
// throw std::runtime_error("Failed to create service account.");
|
||||
}
|
||||
@@ -1007,6 +1033,13 @@ void Install(const fs::path &programPrefix, const std::string endpointAddress)
|
||||
// add to netdev group
|
||||
sysExec(USERMOD_BIN " -a -G " NETDEV_GROUP_NAME " " SERVICE_ACCOUNT_NAME);
|
||||
|
||||
try {
|
||||
changeUserShell(SERVICE_ACCOUNT_NAME, "/usr/sbin/nologon");
|
||||
} catch (const std::exception&e)
|
||||
{
|
||||
cout << "Error: Can't set user shell for pipedal_d. " << e.what() << std::endl;
|
||||
|
||||
}
|
||||
// create and configure /var directory.
|
||||
|
||||
fs::path varDirectory("/var/pipedal");
|
||||
|
||||
+17
-13
@@ -467,7 +467,7 @@ void HotspotManagerImpl::onReload()
|
||||
case State::HotspotConnected:
|
||||
default:
|
||||
// force a reload.
|
||||
StopHotspot();
|
||||
StopHotspot();
|
||||
SetState(State::Monitoring);
|
||||
MaybeStartHotspot();
|
||||
return;
|
||||
@@ -861,28 +861,32 @@ void HotspotManagerImpl::StartHotspot()
|
||||
|
||||
settings["ipv4"]["method"] = "shared";
|
||||
settings["ipv6"]["method"] = "shared";
|
||||
settings["ipv6"]["addr-gen-mode"] = 1; // "stable-privacy";
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Create connection
|
||||
settings["ipv4"]["method"] = sdbus::Variant(std::string("shared"));
|
||||
//settings["ipv6"]["method"] = sdbus::Variant(std::string("ignore"));
|
||||
// Create connection
|
||||
settings["ipv4"]["method"] = sdbus::Variant(std::string("shared"));
|
||||
// settings["ipv6"]["method"] = sdbus::Variant(std::string("ignore"));
|
||||
|
||||
settings["ipv4"]["address-data"] = sdbus::Variant(std::vector<std::map<std::string, sdbus::Variant>>{{{"address", sdbus::Variant("192.168.60.1")},
|
||||
{"prefix", sdbus::Variant(uint32_t(24))}}});
|
||||
// settings["ipv4"]["gateway'"] = sdbus::Variant(std::string("192.168.60.1"));
|
||||
settings["ipv4"]["dhcp-send-hostname"] = sdbus::Variant(true);
|
||||
settings["ipv4"]["dhcp-hostname"] = sdbus::Variant("raspberrypi");
|
||||
// settings["ipv4"]["dhcp-options"] = sdbus::Variant(std::vector<std::string>{
|
||||
// "option:classless-static-route,192.168.60.0/24,0.0.0.0,0.0.0.0/0,192.168.60.1"});
|
||||
// "option:classless-static-route,192.168.60.0/23,0.0.0.0,0.0.0.0/0,192.168.60.1"});
|
||||
|
||||
// settings["ipv4"]["dhcp-options"] = sdbus::Variant(std::vector<std::string>{
|
||||
// "option:classless-static-route,192.168.60.0/23,192.168.60.1"});
|
||||
|
||||
settings["ipv4"]["route-data"] = sdbus::Variant(std::vector<std::map<std::string, sdbus::Variant>>{{
|
||||
{"dest", sdbus::Variant("192.168.4.0")},
|
||||
{"prefix", sdbus::Variant(uint32_t(24))},
|
||||
{"metric", sdbus::Variant((uint32_t)99)}
|
||||
}});
|
||||
////////////////////////////////////////////////////////////
|
||||
// settings["ipv6"]["addr-gen-mode"] = "stable-privacy";
|
||||
|
||||
settings["ipv6"]["address-data"] = sdbus::Variant(std::vector<std::map<std::string, sdbus::Variant>>{
|
||||
{{"address", sdbus::Variant("fdd2:e477:7b37:5b09::1")},
|
||||
{"prefix", sdbus::Variant(uint32_t(64))}}});
|
||||
|
||||
settings["ipv6"]["gateway"] = sdbus::Variant("fdd2:e477:7b37:5b09::1");
|
||||
std::map<std::string, sdbus::Variant> options;
|
||||
options["persist"] = "disk";
|
||||
|
||||
|
||||
+10
-10
@@ -544,9 +544,9 @@ p2p configuration:
|
||||
dnsmaqsq.d/30-pipedal-p2p.conf:
|
||||
|
||||
interface=p2p-wlan0-0
|
||||
dhcp-range=p2p-wlan0,173.24.0.3,172.23.0.127,1h
|
||||
dhcp-range=p2p-wlan0,173.24.0.3,192.168.60.127,1h
|
||||
domain=local
|
||||
address=/pipedal.local/172.23.0.2
|
||||
address=/pipedal.local/192.168.60.2
|
||||
|
||||
except-interface=eth0
|
||||
except-interface=wlan0
|
||||
@@ -556,8 +556,8 @@ except-interface=lo
|
||||
dhcpcd.conf:
|
||||
======
|
||||
interface p2p-wlan0-0
|
||||
static ip_address=172.24.0.1/16
|
||||
domain_name_servers=172.24.0.1
|
||||
static ip_address=192.168.60.1/16
|
||||
domain_name_servers=192.168.60.1
|
||||
|
||||
Watch resolv.conf to make sure we don't lose DNS servers.
|
||||
************************************************************************************/
|
||||
@@ -672,8 +672,8 @@ static void ConfigDhcpcdForP2p()
|
||||
// dhcpcd.conf:
|
||||
// ======
|
||||
// interface p2p-wlan0-0
|
||||
// static ip_address=172.24.0.1/24
|
||||
// domain_name_server=172.24.0.1
|
||||
// static ip_address=192.168.60.1/24
|
||||
// domain_name_server=192.168.60.1
|
||||
|
||||
int line = dhcpcd.GetLineThatStartsWith("hostname");
|
||||
std::string hostNameLine;
|
||||
@@ -691,8 +691,8 @@ static void ConfigDhcpcdForP2p()
|
||||
{
|
||||
line = dhcpcd.GetLineCount();
|
||||
// interface p2p-wlan0-0
|
||||
// static ip_address=172.24.0.1/16 (trying int on .1.)
|
||||
// domain_name_server=172.24.0.1
|
||||
// static ip_address=192.168.60.1/16 (trying int on .1.)
|
||||
// domain_name_server=192.168.60.1
|
||||
|
||||
dhcpcd.InsertLine(line++, "interface p2p-wlan0-0");
|
||||
dhcpcd.InsertLine(line++, " static ip_address=" P2P_INTERFACE_ADDR);
|
||||
@@ -705,8 +705,8 @@ static void ConfigDhcpcdForP2p()
|
||||
line = dhcpcd.GetLineCount();
|
||||
}
|
||||
// interface p2p-wlan0-0
|
||||
// static ip_address=172.24.0.1/16 (trying int on .1.)
|
||||
// domain_name_server=172.24.0.1
|
||||
// static ip_address=192.168.60.1/16 (trying int on .1.)
|
||||
// domain_name_server=192.168.60.1
|
||||
|
||||
dhcpcd.InsertLine(line++, SS("allowinterfaces p2p-" << GetWifiConfigWlanAddress() << "-*").c_str());
|
||||
dhcpcd.InsertLine(line++, "static ip_address=" P2P_INTERFACE_ADDR);
|
||||
|
||||
+56
-2
@@ -27,7 +27,7 @@
|
||||
#include "ServiceConfiguration.hpp"
|
||||
#include "AvahiService.hpp"
|
||||
#include "WebServerConfig.hpp"
|
||||
|
||||
#include <execinfo.h>
|
||||
#include "PiPedalSocket.hpp"
|
||||
#include "PluginHost.hpp"
|
||||
#include <boost/system/error_code.hpp>
|
||||
@@ -87,11 +87,50 @@ static void AsanCheck()
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#if ENABLE_BACKTRACE
|
||||
void segvHandler(int sig) {
|
||||
void *array[10];
|
||||
|
||||
// Get void*'s for all entries on the stack
|
||||
size_t size;
|
||||
size = backtrace(array, 10);
|
||||
|
||||
// Print out all the frames to stderr
|
||||
const char *message = "Error: SEGV signal received.\n";
|
||||
write(STDERR_FILENO,message,strlen(message));
|
||||
|
||||
backtrace_symbols_fd(array+2, size-2, STDERR_FILENO);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
static void EnableBacktrace()
|
||||
{
|
||||
signal(SIGSEGV, segvHandler);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool TryGetLogLevel(const std::string&strLogLevel,LogLevel*result)
|
||||
{
|
||||
if (strLogLevel == "debug") {*result= LogLevel::Debug; return true;}
|
||||
if (strLogLevel == "info") {*result= LogLevel::Info; return true;}
|
||||
if (strLogLevel == "warning") {*result= LogLevel::Warning; return true;}
|
||||
if (strLogLevel == "error") { *result= LogLevel::Error; return true;}
|
||||
*result = LogLevel::Info;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
#ifndef WIN32
|
||||
umask(002); // newly created files in /var/pipedal get 775-ish permissions, which improves debugging/live-service interaction.
|
||||
umask(002); // newly created files in /var/pipedal get 7cd75-ish permissions, which improves debugging/live-service interaction.
|
||||
#endif
|
||||
|
||||
#if ENABLE_BACKTRACE
|
||||
EnableBacktrace();
|
||||
#endif
|
||||
|
||||
// Check command line arguments.
|
||||
@@ -99,12 +138,14 @@ int main(int argc, char *argv[])
|
||||
bool error = false;
|
||||
bool systemd = false;
|
||||
bool testExtraDevice = false;
|
||||
std::string logLevel;
|
||||
std::string portOption;
|
||||
|
||||
CommandLineParser parser;
|
||||
parser.AddOption("-h", &help);
|
||||
parser.AddOption("--help", &help);
|
||||
parser.AddOption("-systemd", &systemd);
|
||||
parser.AddOption("-log-level",&logLevel);
|
||||
parser.AddOption("-port", &portOption);
|
||||
parser.AddOption("-test-extra-device", &testExtraDevice); // advertise two different devices (for testing multi-device connect)
|
||||
|
||||
@@ -139,6 +180,7 @@ int main(int argc, char *argv[])
|
||||
<< "Options:\n"
|
||||
<< " -systemd: Log to systemd journals instead of to the console.\n"
|
||||
<< " -port: Port to listen on e.g. 80, or 0.0.0.0:80\n"
|
||||
<< " -log-level: (debug|info|warning|error)"
|
||||
<< "Example:\n"
|
||||
<< " pipedald /etc/pipedal/config /etc/pipedal/react -port 80 \n"
|
||||
"\n"
|
||||
@@ -180,6 +222,18 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
Lv2Log::log_level(configuration.GetLogLevel());
|
||||
if (logLevel.length() != 0)
|
||||
{
|
||||
LogLevel lv2LogLevel;
|
||||
if (TryGetLogLevel(logLevel,&lv2LogLevel))
|
||||
{
|
||||
Lv2Log::log_level(lv2LogLevel);
|
||||
|
||||
} else {
|
||||
Lv2Log::error(SS("Invalid log level: " << logLevel));
|
||||
return EXIT_SUCCESS; // indicate to systemd that we don't want a restart.
|
||||
}
|
||||
}
|
||||
|
||||
if (portOption.length() != 0)
|
||||
{
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
interface=p2p-${WLAN}-*
|
||||
#disable dns, dhcp only.a"
|
||||
port=0
|
||||
dhcp-range=172.23.0.20,172.23.0.127,15m
|
||||
dhcp-range=192.168.60.20,192.168.60.127,15m
|
||||
domain=local
|
||||
address=/pipedal-p2p.local/172.23.0.2
|
||||
address=/pipedal-p2p.local/192.168.60.2
|
||||
|
||||
except-interface=eth0
|
||||
except-interface=${WLAN}
|
||||
|
||||
@@ -3,9 +3,9 @@ server=8.8.4.4
|
||||
|
||||
|
||||
interface=p2p-wlan0-0
|
||||
dhcp-range=172.23.0.3,172.23.0.127,15m
|
||||
dhcp-range=192.168.60.3,192.168.60.127,15m
|
||||
domain=local
|
||||
address=/pipedal.local/172.23.0.2
|
||||
address=/pipedal.local/192.168.60.2
|
||||
|
||||
except-interface=eth0
|
||||
except-interface=wlan0
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# PiPedal dnsmasq settings for p2p
|
||||
#disable dns, dhcp only."
|
||||
port=0
|
||||
dhcp-range=172.23.0.3,172.23.0.127,15m
|
||||
dhcp-range=192.168.60.3,192.168.60.127,15m
|
||||
domain=local
|
||||
address=/pipedal-p2p.local/172.23.0.2
|
||||
address=/pipedal-p2p.local/192.168.60.2
|
||||
|
||||
# defensive. Not actually required.
|
||||
except-interface=eth0
|
||||
|
||||
Reference in New Issue
Block a user