diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..c969d2a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,34 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: "[BUG]-"
+labels: bug
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**Stacktrace**
+
+Include a stack trace of the exception if possible.
+```
+Paste stack trace here
+```
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..0a854e7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,21 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: "[FEATURE]-"
+labels: enhancement
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+If this is a request for support for a new device or type, be as specific as possible and include any pertinent manufacturer and model information.
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..c4cf0f9
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,20 @@
+name: Build Non-Release Branch
+
+
+on:
+ push:
+ branches:
+ - feature/*
+ - bugfix/*
+ - hotfix/*
+
+
+jobs:
+ build:
+ name: Build
+ runs-on: self-hosted
+ steps:
+ - run: Invoke-WebRequest -URI "http://localhost:8080/job/PepperDash%20Core%20Branch%20Builds/build?token=$($Env:projectToken)" -Headers @{Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("ndorin:$($Env:token)")))"} -Method POST -UseBasicParsing
+ env:
+ token: ${{ secrets.TOKEN }}
+ projectToken: ${{ secrets.PROJECTTOKEN}}
diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericSecureTcpIpServer.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericSecureTcpIpServer.cs
index 6703551..74ce8cb 100644
--- a/Pepperdash Core/Pepperdash Core/Comm/GenericSecureTcpIpServer.cs
+++ b/Pepperdash Core/Pepperdash Core/Comm/GenericSecureTcpIpServer.cs
@@ -418,11 +418,21 @@ namespace PepperDash.Core
SecureServer.PortNumber = Port;
}
ServerStopped = false;
- SecureServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
- OnServerStateChange(SecureServer.State);
- Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Secure Server Status: {0}, Socket Status: {1}", SecureServer.State, SecureServer.ServerSocketStatus);
- ServerCCSection.Leave();
-
+
+ // Start the listner
+ SocketErrorCodes status = SecureServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
+ if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error starting WaitForConnectionAsync {0}", status);
+ }
+ else
+ {
+ ServerStopped = false;
+ }
+ OnServerStateChange(SecureServer.State);
+ Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Secure Server Status: {0}, Socket Status: {1}", SecureServer.State, SecureServer.ServerSocketStatus);
+ ServerCCSection.Leave();
+
}
catch (Exception ex)
{
@@ -758,29 +768,27 @@ namespace PepperDash.Core
}
else
{
- Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Client attempt faulty.");
- if (!ServerStopped)
- {
- server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
- return;
- }
+ Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Client attempt faulty.");
}
}
catch (Exception ex)
{
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Connect Callback. Error: {0}", ex);
}
- //Debug.Console(1, this, Debug.ErrorLogLevel, "((((((Server State bitfield={0}; maxclient={1}; ServerStopped={2}))))))",
- // server.State,
- // MaxClients,
- // ServerStopped);
- if ((server.State & ServerState.SERVER_LISTENING) != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped)
- {
- Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Waiting for next connection");
- server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
- }
- }
+ // Rearm the listner
+ SocketErrorCodes status = server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
+ if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Socket status connect callback status {0}", status);
+ if (status == SocketErrorCodes.SOCKET_CONNECTION_IN_PROGRESS)
+ {
+ // There is an issue where on a failed negotiation we need to stop and start the server. This should still leave connected clients intact.
+ server.Stop();
+ Listen();
+ }
+ }
+ }
#endregion
diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs
index 46892c7..ef57ae0 100644
--- a/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs
+++ b/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs
@@ -62,6 +62,8 @@ namespace PepperDash.Core
get { return ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
}
+ private bool IsConnecting = false;
+
///
/// S+ helper for IsConnected
///
@@ -184,6 +186,13 @@ namespace PepperDash.Core
///
public void Connect()
{
+ if (IsConnecting)
+ {
+ Debug.Console(0, this, "Connection attempt in progress. Exiting Connect()");
+ return;
+ }
+
+ IsConnecting = true;
ConnectEnabled = true;
Debug.Console(1, this, "attempting connect");
@@ -236,6 +245,7 @@ namespace PepperDash.Core
//TheStream.ErrorOccurred += TheStream_ErrorOccurred;
Debug.Console(1, this, "Connected");
ClientStatus = SocketStatus.SOCKET_STATUS_CONNECTED;
+ IsConnecting = false;
return; // Success will not pass here
}
catch (SshConnectionException e)
@@ -291,6 +301,7 @@ namespace PepperDash.Core
if (Client != null)
{
+ IsConnecting = false;
Client.Disconnect();
Client = null;
ClientStatus = status;
@@ -303,6 +314,7 @@ namespace PepperDash.Core
///
void HandleConnectionFailure()
{
+
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
Debug.Console(2, this, "Client nulled due to connection failure. AutoReconnect: {0}, ConnectEnabled: {1}", AutoReconnect, ConnectEnabled);
diff --git a/Pepperdash Core/Pepperdash Core/Logging/Debug.cs b/Pepperdash Core/Pepperdash Core/Logging/Debug.cs
index 14c6b37..cf4d8df 100644
--- a/Pepperdash Core/Pepperdash Core/Logging/Debug.cs
+++ b/Pepperdash Core/Pepperdash Core/Logging/Debug.cs
@@ -91,7 +91,8 @@ namespace PepperDash.Core
Level = context.Level;
DoNotLoadOnNextBoot = context.DoNotLoadOnNextBoot;
- CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber));
+ if(DoNotLoadOnNextBoot)
+ CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber));
try
{
diff --git a/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj b/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj
index 1d98c97..92ce8c8 100644
--- a/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj
+++ b/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj
@@ -49,19 +49,19 @@
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll
False
- ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll
+ ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll