diff --git a/.github/scripts/ZipBuildOutput.ps1 b/.github/scripts/ZipBuildOutput.ps1
index 6e44736..34856fb 100644
--- a/.github/scripts/ZipBuildOutput.ps1
+++ b/.github/scripts/ZipBuildOutput.ps1
@@ -8,6 +8,7 @@ $destination = "$($Env:GITHUB_HOME)\output"
New-Item -ItemType Directory -Force -Path ($destination)
Get-ChildItem ($destination)
$exclusions = @(git submodule foreach --quiet 'echo $name')
+$exclusions += "Newtonsoft.Json.Compact.dll"
# Trying to get any .json schema files (not currently working)
# Gets any files with the listed extensions.
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.json", "*.nuspec" | ForEach-Object {
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 9e09430..5449af9 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -152,156 +152,3 @@ jobs:
run: nuget push **/*.nupkg -source github
- name: Publish nuget package to nuget.org
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
- # This step always runs and pushes the build to the internal build rep
- Internal_Push_Output:
- needs: Build_Project
- runs-on: windows-latest
- steps:
- # Checkout the repo
- - name: Checkout Builds Repo
- uses: actions/checkout@v2
- with:
- token: ${{ secrets.BUILDS_TOKEN }}
- repository: PepperDash-Engineering/pepperdash-core-builds
- ref: ${{ Env.GITHUB_REF }}
- # Download the version artifact from the build job
- - name: Download Build Version Info
- uses: actions/download-artifact@v1
- with:
- name: Version
- - name: Check Directory
- run: Get-ChildItem "./"
- # Set the version number environment variable from the file we just downloaded
- - name: Set Version Number
- shell: powershell
- run: |
- Get-ChildItem "./Version"
- $version = Get-Content -Path ./Version/version.txt
- Write-Host "Version: $version"
- echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- Remove-Item -Path ./Version/version.txt
- Remove-Item -Path ./Version
- # Checkout/Create the branch
- - name: Create new branch
- run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
- # Download the build output into the repo
- - name: Download Build output
- uses: actions/download-artifact@v1
- with:
- name: Build
- path: ./
- - name: Check directory
- run: Get-ChildItem ./
- # Unzip the build package file
- - name: Unzip Build file
- run: |
- Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
- Remove-Item -Path .\*.zip
- - name: Check directory again
- run: Get-ChildItem ./
- # Copy Contents of output folder to root directory
- - name: Copy Files to root & delete output directory
- run: |
- Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
- Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
- Remove-Item -Path .\output -Recurse
- # Commits the build output to the branch and tags it with the version
- - name: Commit build output and tag the commit
- shell: powershell
- run: |
- git config user.email "actions@pepperdash.com"
- git config user.name "GitHub Actions"
- git add .
- $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
- Write-Host "Commit: $commit"
- git commit -m $commit
- git tag $($Env:VERSION)
- # Push the commit
- - name: Push to Builds Repo
- shell: powershell
- run: |
- $branch = $($Env:GITHUB_REF) -replace "refs/heads/"
- Write-Host "Branch: $branch"
- git push -u origin $($branch) --force
- # Push the tags
- - name: Push tags
- run: git push --tags origin
- - name: Check Directory
- run: Get-ChildItem ./
- # This step only runs if the branch is main or release/ runs and pushes the build to the public build repo
- Public_Push_Output:
- needs: Build_Project
- runs-on: windows-latest
- if: contains(github.ref, 'main') || contains(github.ref, 'release')
- steps:
- # Checkout the repo
- - name: Checkout Builds Repo
- uses: actions/checkout@v2
- with:
- token: ${{ secrets.BUILDS_TOKEN }}
- repository: PepperDash/PepperDashCore-Builds
- ref: ${{ Env.GITHUB_REF }}
- # Download the version artifact from the build job
- - name: Download Build Version Info
- uses: actions/download-artifact@v1
- with:
- name: Version
- - name: Check Directory
- run: Get-ChildItem "./"
- # Set the version number environment variable from the file we just downloaded
- - name: Set Version Number
- shell: powershell
- run: |
- Get-ChildItem "./Version"
- $version = Get-Content -Path ./Version/version.txt
- Write-Host "Version: $version"
- echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- Remove-Item -Path ./Version/version.txt
- Remove-Item -Path ./Version
- # Checkout/Create the branch
- - name: Create new branch
- run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
- # Download the build output into the repo
- - name: Download Build output
- uses: actions/download-artifact@v1
- with:
- name: Build
- path: ./
- - name: Check directory
- run: Get-ChildItem ./
- # Unzip the build package file
- - name: Unzip Build file
- run: |
- Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
- Remove-Item -Path .\*.zip
- - name: Check directory again
- run: Get-ChildItem ./
- # Copy Contents of output folder to root directory
- - name: Copy Files to root & delete output directory
- run: |
- Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
- Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
- Remove-Item -Path .\output -Recurse
- # Commits the build output to the branch and tags it with the version
- - name: Commit build output and tag the commit
- shell: powershell
- run: |
- git config user.email "actions@pepperdash.com"
- git config user.name "GitHub Actions"
- git add .
- $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
- Write-Host "Commit: $commit"
- git commit -m $commit
- git tag $($Env:VERSION)
- # Push the commit
- - name: Push to Builds Repo
- shell: powershell
- run: |
- $branch = $($Env:GITHUB_REF) -replace "refs/heads/"
- Write-Host "Branch: $branch"
- git push -u origin $($branch) --force
- # Push the tags
- - name: Push tags
- run: git push --tags origin
- - name: Check Directory
- run: Get-ChildItem ./
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 3c73887..5acc7a8 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -127,148 +127,3 @@ jobs:
run: nuget push **/*.nupkg -source github
- name: Publish nuget package to nuget.org
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
- Internal_Push_Output:
- needs: Build_Project
- runs-on: windows-latest
- steps:
- # Checkout the repo
- - name: Checkout Builds Repo
- uses: actions/checkout@v2
- with:
- token: ${{ secrets.BUILDS_TOKEN }}
- repository: PepperDash-Engineering/pepperdash-core-builds
- ref: ${{ Env.GITHUB_REF }}
- # Download the version artifact from the build job
- - name: Download Build Version Info
- uses: actions/download-artifact@v1
- with:
- name: Version
- - name: Check Directory
- run: Get-ChildItem "./"
- # Set the version number environment variable from the file we just downloaded
- - name: Set Version Number
- shell: powershell
- run: |
- Get-ChildItem "./Version"
- $version = Get-Content -Path ./Version/version.txt
- Write-Host "Version: $version"
- echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- Remove-Item -Path ./Version/version.txt
- Remove-Item -Path ./Version
- # Checkout/Create the branch
- - name: Create new branch
- run: git checkout main
- # Download the build output into the repo
- - name: Download Build output
- uses: actions/download-artifact@v1
- with:
- name: Build
- path: ./
- - name: Check directory
- run: Get-ChildItem ./
- # Unzip the build package file
- - name: Unzip Build file
- run: |
- Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
- Remove-Item -Path .\*.zip
- - name: Check directory again
- run: Get-ChildItem ./
- # Copy Contents of output folder to root directory
- - name: Copy Files to root & delete output directory
- run: |
- Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
- Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
- Remove-Item -Path .\output -Recurse
- # Commits the build output to the branch and tags it with the version
- - name: Commit build output and tag the commit
- shell: powershell
- run: |
- git config user.email "actions@pepperdash.com"
- git config user.name "GitHub Actions"
- git add .
- $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
- Write-Host "Commit: $commit"
- git commit -m $commit
- git tag $($Env:VERSION)
- # Push the commit
- - name: Push to Builds Repo
- shell: powershell
- run: git push -u origin main --force
- # Push the tags
- - name: Push tags
- run: git push --tags origin
- - name: Check Directory
- run: Get-ChildItem ./
- # This step only runs if the branch is main or release/ runs and pushes the build to the public build repo
- Public_Push_Output:
- needs: Build_Project
- runs-on: windows-latest
- steps:
- # Checkout the repo
- - name: Checkout Builds Repo
- uses: actions/checkout@v2
- with:
- token: ${{ secrets.BUILDS_TOKEN }}
- repository: PepperDash/PepperDashCore-Builds
- ref: ${{ Env.GITHUB_REF }}
- # Download the version artifact from the build job
- - name: Download Build Version Info
- uses: actions/download-artifact@v1
- with:
- name: Version
- - name: Check Directory
- run: Get-ChildItem "./"
- # Set the version number environment variable from the file we just downloaded
- - name: Set Version Number
- shell: powershell
- run: |
- Get-ChildItem "./Version"
- $version = Get-Content -Path ./Version/version.txt
- Write-Host "Version: $version"
- echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- Remove-Item -Path ./Version/version.txt
- Remove-Item -Path ./Version
- # Checkout/Create the branch
- - name: Create new branch
- run: git checkout main
- # Download the build output into the repo
- - name: Download Build output
- uses: actions/download-artifact@v1
- with:
- name: Build
- path: ./
- - name: Check directory
- run: Get-ChildItem ./
- # Unzip the build package file
- - name: Unzip Build file
- run: |
- Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
- Remove-Item -Path .\*.zip
- - name: Check directory again
- run: Get-ChildItem ./
- # Copy Contents of output folder to root directory
- - name: Copy Files to root & delete output directory
- run: |
- Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
- Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
- Remove-Item -Path .\output -Recurse
- # Commits the build output to the branch and tags it with the version
- - name: Commit build output and tag the commit
- shell: powershell
- run: |
- git config user.email "actions@pepperdash.com"
- git config user.name "GitHub Actions"
- git add .
- $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
- Write-Host "Commit: $commit"
- git commit -m $commit
- git tag $($Env:VERSION)
- # Push the commit
- - name: Push to Builds Repo
- shell: powershell
- run: git push -u origin main --force
- # Push the tags
- - name: Push tags
- run: git push --tags origin
- - name: Check Directory
- run: Get-ChildItem ./
diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs
index 6d9a2e5..5c67178 100644
--- a/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs
+++ b/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs
@@ -383,18 +383,24 @@ namespace PepperDash.Core
if (bytes.Length > 0)
{
var bytesHandler = BytesReceived;
- if (bytesHandler != null)
- bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
+ if (bytesHandler != null)
+ {
+ if (StreamDebugging.RxStreamDebuggingIsEnabled)
+ {
+ Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
+ }
+ bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
+ }
+
var textHandler = TextReceived;
if (textHandler != null)
{
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
- textHandler(this, new GenericCommMethodReceiveTextArgs(str));
-
if (StreamDebugging.RxStreamDebuggingIsEnabled)
- Debug.Console(0, this, "Recevied: '{0}'", str);
+ Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetDebugText(str));
- }
+ textHandler(this, new GenericCommMethodReceiveTextArgs(str));
+ }
}
}
@@ -433,14 +439,18 @@ namespace PepperDash.Core
{
try
{
- if (Client != null)
+ if (Client != null && TheStream != null && IsConnected)
{
if (StreamDebugging.TxStreamDebuggingIsEnabled)
- Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, text);
+ Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text));
TheStream.Write(text);
TheStream.Flush();
+ }
+ else
+ {
+ Debug.Console(2, this, "Client is null or disconnected. Cannot Send Text");
}
}
catch (Exception ex)
@@ -462,13 +472,17 @@ namespace PepperDash.Core
{
try
{
- if (Client != null)
+ if (Client != null && TheStream != null && IsConnected)
{
if (StreamDebugging.TxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
TheStream.Write(bytes, 0, bytes.Length);
TheStream.Flush();
+ }
+ else
+ {
+ Debug.Console(2, this, "Client is null or disconnected. Cannot Send Bytes");
}
}
catch
diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericTcpIpClient.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericTcpIpClient.cs
index f151b57..480e4d1 100644
--- a/Pepperdash Core/Pepperdash Core/Comm/GenericTcpIpClient.cs
+++ b/Pepperdash Core/Pepperdash Core/Comm/GenericTcpIpClient.cs
@@ -284,9 +284,17 @@ namespace PepperDash.Core
///
public void Disconnect()
{
+ DisconnectCalledByUser = true;
+
+ // Stop trying reconnects, if we are
+ if (RetryTimer != null)
+ {
+ RetryTimer.Stop();
+ RetryTimer = null;
+ }
+
if (Client != null)
{
- DisconnectCalledByUser = true;
DisconnectClient();
Client = null;
Debug.Console(1, this, "Disconnected");
@@ -329,7 +337,15 @@ namespace PepperDash.Core
Debug.Console(1, this, "Attempting reconnect, status={0}", Client.ClientStatus);
if (!DisconnectCalledByUser)
- RetryTimer = new CTimer(o => { Client.ConnectToServerAsync(ConnectToServerCallback); }, AutoReconnectIntervalMs);
+ RetryTimer = new CTimer(o =>
+ {
+ if (Client == null)
+ {
+ return;
+ }
+
+ Client.ConnectToServerAsync(ConnectToServerCallback);
+ }, AutoReconnectIntervalMs);
}
}
@@ -348,14 +364,20 @@ namespace PepperDash.Core
var bytes = client.IncomingDataBuffer.Take(numBytes).ToArray();
var bytesHandler = BytesReceived;
if (bytesHandler != null)
+ {
+ if (StreamDebugging.RxStreamDebuggingIsEnabled)
+ {
+ Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
+ }
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
+ }
var textHandler = TextReceived;
if (textHandler != null)
{
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
if (StreamDebugging.RxStreamDebuggingIsEnabled)
- Debug.Console(0, this, "Recevied: '{0}'", str);
+ Debug.Console(0, this, "Received {1} characters of text: '{0}'", ComTextHelper.GetDebugText(str), str.Length);
textHandler(this, new GenericCommMethodReceiveTextArgs(str));
@@ -376,7 +398,7 @@ namespace PepperDash.Core
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
// Check debug level before processing byte array
if (StreamDebugging.TxStreamDebuggingIsEnabled)
- Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
+ Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text));
if(Client != null)
Client.SendData(bytes, bytes.Length);
diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericUdpServer.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericUdpServer.cs
index 1ed3d68..36a2657 100644
--- a/Pepperdash Core/Pepperdash Core/Comm/GenericUdpServer.cs
+++ b/Pepperdash Core/Pepperdash Core/Comm/GenericUdpServer.cs
@@ -1,426 +1,393 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-
-using Crestron.SimplSharp;
-using Crestron.SimplSharp.CrestronSockets;
-
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
-
-
-
-namespace PepperDash.Core
-{
- public class GenericUdpServer : Device, ISocketStatusWithStreamDebugging
- {
- private const string SplusKey = "Uninitialized Udp Server";
- public CommunicationStreamDebugging StreamDebugging { get; private set; }
- ///
- ///
- ///
- public event EventHandler BytesReceived;
-
- ///
- ///
- ///
- public event EventHandler TextReceived;
-
- ///
- /// This event will fire when a message is dequeued that includes the source IP and Port info if needed to determine the source of the received data.
- ///
- public event EventHandler DataRecievedExtra;
-
- ///
- /// Queue to temporarily store received messages with the source IP and Port info
- ///
- private CrestronQueue MessageQueue;
-
- ///
- ///
- ///
- public event EventHandler ConnectionChange;
-
- ///
- ///
- ///
- public event EventHandler UpdateConnectionStatus;
-
- ///
- ///
- ///
- public SocketStatus ClientStatus
- {
- get
- {
- return Server.ServerStatus;
- }
- }
-
- ///
- ///
- ///
- public ushort UStatus
- {
- get { return (ushort)Server.ServerStatus; }
- }
-
-
- CCriticalSection DequeueLock;
- ///
- /// Address of server
- ///
- public string Hostname { get; set; }
-
- ///
- /// IP Address of the sender of the last recieved message
- ///
-
-
- ///
- /// Port on server
- ///
- public int Port { get; set; }
-
- ///
- /// Another damn S+ helper because S+ seems to treat large port nums as signed ints
- /// which screws up things
- ///
- public ushort UPort
- {
- get { return Convert.ToUInt16(Port); }
- set { Port = Convert.ToInt32(value); }
- }
-
- ///
- /// Indicates that the UDP Server is enabled
- ///
- public bool IsConnected
- {
- get;
- private set;
- }
-
- public ushort UIsConnected
- {
- get { return IsConnected ? (ushort)1 : (ushort)0; }
- }
-
- ///
- /// Defaults to 2000
- ///
- public int BufferSize { get; set; }
-
- public UDPServer Server { get; private set; }
-
- ///
- /// Constructor for S+. Make sure to set key, address, port, and buffersize using init method
- ///
- public GenericUdpServer()
- : base(SplusKey)
- {
- StreamDebugging = new CommunicationStreamDebugging(SplusKey);
- BufferSize = 5000;
- DequeueLock = new CCriticalSection();
- MessageQueue = new CrestronQueue();
-
- CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
- CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
- }
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public GenericUdpServer(string key, string address, int port, int buffefSize)
- : base(key)
- {
- StreamDebugging = new CommunicationStreamDebugging(key);
- Hostname = address;
- Port = port;
- BufferSize = buffefSize;
-
- DequeueLock = new CCriticalSection();
- MessageQueue = new CrestronQueue();
-
- CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
- CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
- }
-
- ///
- /// Call from S+ to initialize values
- ///
- ///
- ///
- ///
- public void Initialize(string key, string address, ushort port)
- {
- Key = key;
- Hostname = address;
- UPort = port;
- }
-
- ///
- ///
- ///
- ///
- void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
- {
- // Re-enable the server if the link comes back up and the status should be connected
- if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp
- && IsConnected)
- {
- Connect();
- }
- }
-
- ///
- ///
- ///
- ///
- void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
- {
- if (programEventType == eProgramStatusEventType.Stopping)
- {
- Debug.Console(1, this, "Program stopping. Disabling Server");
- Disconnect();
- }
- }
-
- ///
- /// Enables the UDP Server
- ///
- public void Connect()
- {
- if (Server == null)
- {
- Server = new UDPServer();
- }
-
- if (string.IsNullOrEmpty(Hostname))
- {
- Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericUdpServer '{0}': No address set", Key);
- return;
- }
- if (Port < 1 || Port > 65535)
- {
- {
- Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericUdpServer '{0}': Invalid port", Key);
- return;
- }
- }
-
- var status = Server.EnableUDPServer(Hostname, Port);
-
- Debug.Console(2, this, "SocketErrorCode: {0}", status);
- if (status == SocketErrorCodes.SOCKET_OK)
- IsConnected = true;
-
- var handler = UpdateConnectionStatus;
- if (handler != null)
- handler(this, new GenericUdpConnectedEventArgs(UIsConnected));
-
- // Start receiving data
- Server.ReceiveDataAsync(Receive);
- }
-
- ///
- /// Disabled the UDP Server
- ///
- public void Disconnect()
- {
- if(Server != null)
- Server.DisableUDPServer();
-
- IsConnected = false;
-
- var handler = UpdateConnectionStatus;
- if (handler != null)
- handler(this, new GenericUdpConnectedEventArgs(UIsConnected));
- }
-
-
- ///
- /// Recursive method to receive data
- ///
- ///
- ///
- void Receive(UDPServer server, int numBytes)
- {
- Debug.Console(2, this, "Received {0} bytes", numBytes);
-
- if (numBytes > 0)
- {
- var sourceIp = Server.IPAddressLastMessageReceivedFrom;
- var sourcePort = Server.IPPortLastMessageReceivedFrom;
- var bytes = server.IncomingDataBuffer.Take(numBytes).ToArray();
- var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
- MessageQueue.TryToEnqueue(new GenericUdpReceiveTextExtraArgs(str, sourceIp, sourcePort, bytes));
-
- Debug.Console(2, this, "Bytes: {0}", bytes.ToString());
- var bytesHandler = BytesReceived;
- if (bytesHandler != null)
- bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
- else
- Debug.Console(2, this, "bytesHandler is null");
- var textHandler = TextReceived;
- if (textHandler != null)
- {
- if (StreamDebugging.RxStreamDebuggingIsEnabled)
- Debug.Console(0, this, "Recevied: '{0}'", str);
-
- textHandler(this, new GenericCommMethodReceiveTextArgs(str));
- }
- else
- Debug.Console(2, this, "textHandler is null");
- }
- server.ReceiveDataAsync(Receive);
-
- // Attempt to enter the CCritical Secion and if we can, start the dequeue thread
- var gotLock = DequeueLock.TryEnter();
- if (gotLock)
- CrestronInvoke.BeginInvoke((o) => DequeueEvent());
- }
-
- ///
- /// This method gets spooled up in its own thread an protected by a CCriticalSection to prevent multiple threads from running concurrently.
- /// It will dequeue items as they are enqueued automatically.
- ///
- void DequeueEvent()
- {
- try
- {
- while (true)
- {
- // Pull from Queue and fire an event. Block indefinitely until an item can be removed, similar to a Gather.
- var message = MessageQueue.Dequeue();
- var dataRecivedExtra = DataRecievedExtra;
- if (dataRecivedExtra != null)
- {
- dataRecivedExtra(this, message);
- }
- }
- }
- catch (Exception e)
- {
- Debug.Console(0, "GenericUdpServer DequeueEvent error: {0}\r", e);
- }
- // Make sure to leave the CCritical section in case an exception above stops this thread, or we won't be able to restart it.
- if (DequeueLock != null)
- {
- DequeueLock.Leave();
- }
- }
-
- ///
- /// General send method
- ///
- ///
- public void SendText(string text)
- {
- var bytes = Encoding.GetEncoding(28591).GetBytes(text);
-
- if (IsConnected && Server != null)
- {
- if (StreamDebugging.TxStreamDebuggingIsEnabled)
- Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, text);
-
- Server.SendData(bytes, bytes.Length);
- }
- }
-
- ///
- ///
- ///
- ///
- public void SendBytes(byte[] bytes)
- {
- if (StreamDebugging.TxStreamDebuggingIsEnabled)
- Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
-
- if (IsConnected && Server != null)
- Server.SendData(bytes, bytes.Length);
- }
-
- }
-
- ///
- ///
- ///
- public class GenericUdpReceiveTextExtraArgs : EventArgs
- {
- ///
- ///
- ///
- public string Text { get; private set; }
- ///
- ///
- ///
- public string IpAddress { get; private set; }
- ///
- ///
- ///
- public int Port { get; private set; }
- ///
- ///
- ///
- public byte[] Bytes { get; private set; }
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public GenericUdpReceiveTextExtraArgs(string text, string ipAddress, int port, byte[] bytes)
- {
- Text = text;
- IpAddress = ipAddress;
- Port = port;
- Bytes = bytes;
- }
-
- ///
- /// Stupid S+ Constructor
- ///
- public GenericUdpReceiveTextExtraArgs() { }
- }
-
- ///
- ///
- ///
- public class UdpServerPropertiesConfig
- {
- ///
- ///
- ///
- [JsonProperty(Required = Required.Always)]
- public string Address { get; set; }
-
- ///
- ///
- ///
- [JsonProperty(Required = Required.Always)]
- public int Port { get; set; }
-
- ///
- /// Defaults to 32768
- ///
- public int BufferSize { get; set; }
-
- ///
- ///
- ///
- public UdpServerPropertiesConfig()
- {
- BufferSize = 32768;
- }
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using Crestron.SimplSharp;
+using Crestron.SimplSharp.CrestronSockets;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+
+
+
+namespace PepperDash.Core
+{
+ public class GenericUdpServer : Device, ISocketStatusWithStreamDebugging
+ {
+ private const string SplusKey = "Uninitialized Udp Server";
+ public CommunicationStreamDebugging StreamDebugging { get; private set; }
+ ///
+ ///
+ ///
+ public event EventHandler BytesReceived;
+
+ ///
+ ///
+ ///
+ public event EventHandler TextReceived;
+
+ ///
+ /// This event will fire when a message is dequeued that includes the source IP and Port info if needed to determine the source of the received data.
+ ///
+ public event EventHandler DataRecievedExtra;
+
+ ///
+ ///
+ ///
+ public event EventHandler ConnectionChange;
+
+ ///
+ ///
+ ///
+ public event EventHandler UpdateConnectionStatus;
+
+ ///
+ ///
+ ///
+ public SocketStatus ClientStatus
+ {
+ get
+ {
+ return Server.ServerStatus;
+ }
+ }
+
+ ///
+ ///
+ ///
+ public ushort UStatus
+ {
+ get { return (ushort)Server.ServerStatus; }
+ }
+
+ ///
+ /// Address of server
+ ///
+ public string Hostname { get; set; }
+
+ ///
+ /// IP Address of the sender of the last recieved message
+ ///
+
+
+ ///
+ /// Port on server
+ ///
+ public int Port { get; set; }
+
+ ///
+ /// Another damn S+ helper because S+ seems to treat large port nums as signed ints
+ /// which screws up things
+ ///
+ public ushort UPort
+ {
+ get { return Convert.ToUInt16(Port); }
+ set { Port = Convert.ToInt32(value); }
+ }
+
+ ///
+ /// Indicates that the UDP Server is enabled
+ ///
+ public bool IsConnected
+ {
+ get;
+ private set;
+ }
+
+ public ushort UIsConnected
+ {
+ get { return IsConnected ? (ushort)1 : (ushort)0; }
+ }
+
+ ///
+ /// Defaults to 2000
+ ///
+ public int BufferSize { get; set; }
+
+ public UDPServer Server { get; private set; }
+
+ ///
+ /// Constructor for S+. Make sure to set key, address, port, and buffersize using init method
+ ///
+ public GenericUdpServer()
+ : base(SplusKey)
+ {
+ StreamDebugging = new CommunicationStreamDebugging(SplusKey);
+ BufferSize = 5000;
+
+ CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
+ CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public GenericUdpServer(string key, string address, int port, int buffefSize)
+ : base(key)
+ {
+ StreamDebugging = new CommunicationStreamDebugging(key);
+ Hostname = address;
+ Port = port;
+ BufferSize = buffefSize;
+
+ CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
+ CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
+ }
+
+ ///
+ /// Call from S+ to initialize values
+ ///
+ ///
+ ///
+ ///
+ public void Initialize(string key, string address, ushort port)
+ {
+ Key = key;
+ Hostname = address;
+ UPort = port;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
+ {
+ // Re-enable the server if the link comes back up and the status should be connected
+ if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp
+ && IsConnected)
+ {
+ Connect();
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
+ {
+ if (programEventType != eProgramStatusEventType.Stopping)
+ return;
+
+ Debug.Console(1, this, "Program stopping. Disabling Server");
+ Disconnect();
+ }
+
+ ///
+ /// Enables the UDP Server
+ ///
+ public void Connect()
+ {
+ if (Server == null)
+ {
+ Server = new UDPServer();
+ }
+
+ if (string.IsNullOrEmpty(Hostname))
+ {
+ Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericUdpServer '{0}': No address set", Key);
+ return;
+ }
+ if (Port < 1 || Port > 65535)
+ {
+ {
+ Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericUdpServer '{0}': Invalid port", Key);
+ return;
+ }
+ }
+
+ var status = Server.EnableUDPServer(Hostname, Port);
+
+ Debug.Console(2, this, "SocketErrorCode: {0}", status);
+ if (status == SocketErrorCodes.SOCKET_OK)
+ IsConnected = true;
+
+ var handler = UpdateConnectionStatus;
+ if (handler != null)
+ handler(this, new GenericUdpConnectedEventArgs(UIsConnected));
+
+ // Start receiving data
+ Server.ReceiveDataAsync(Receive);
+ }
+
+ ///
+ /// Disabled the UDP Server
+ ///
+ public void Disconnect()
+ {
+ if(Server != null)
+ Server.DisableUDPServer();
+
+ IsConnected = false;
+
+ var handler = UpdateConnectionStatus;
+ if (handler != null)
+ handler(this, new GenericUdpConnectedEventArgs(UIsConnected));
+ }
+
+
+ ///
+ /// Recursive method to receive data
+ ///
+ ///
+ ///
+ void Receive(UDPServer server, int numBytes)
+ {
+ Debug.Console(2, this, "Received {0} bytes", numBytes);
+
+ try
+ {
+ if (numBytes <= 0)
+ return;
+
+ var sourceIp = Server.IPAddressLastMessageReceivedFrom;
+ var sourcePort = Server.IPPortLastMessageReceivedFrom;
+ var bytes = server.IncomingDataBuffer.Take(numBytes).ToArray();
+ var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
+
+ var dataRecivedExtra = DataRecievedExtra;
+ if (dataRecivedExtra != null)
+ dataRecivedExtra(this, new GenericUdpReceiveTextExtraArgs(str, sourceIp, sourcePort, bytes));
+
+ Debug.Console(2, this, "Bytes: {0}", bytes.ToString());
+ var bytesHandler = BytesReceived;
+ if (bytesHandler != null)
+ {
+ if (StreamDebugging.RxStreamDebuggingIsEnabled)
+ {
+ Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
+ }
+ bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
+ }
+ var textHandler = TextReceived;
+ if (textHandler != null)
+ {
+ if (StreamDebugging.RxStreamDebuggingIsEnabled)
+ Debug.Console(0, this, "Received {1} characters of text: '{0}'", ComTextHelper.GetDebugText(str), str.Length);
+ textHandler(this, new GenericCommMethodReceiveTextArgs(str));
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, "GenericUdpServer Receive error: {0}{1}", ex.Message, ex.StackTrace);
+ }
+ finally
+ {
+ server.ReceiveDataAsync(Receive);
+ }
+ }
+
+ ///
+ /// General send method
+ ///
+ ///
+ public void SendText(string text)
+ {
+ var bytes = Encoding.GetEncoding(28591).GetBytes(text);
+
+ if (IsConnected && Server != null)
+ {
+ if (StreamDebugging.TxStreamDebuggingIsEnabled)
+ Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text));
+
+ Server.SendData(bytes, bytes.Length);
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SendBytes(byte[] bytes)
+ {
+ if (StreamDebugging.TxStreamDebuggingIsEnabled)
+ Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
+
+ if (IsConnected && Server != null)
+ Server.SendData(bytes, bytes.Length);
+ }
+
+ }
+
+ ///
+ ///
+ ///
+ public class GenericUdpReceiveTextExtraArgs : EventArgs
+ {
+ ///
+ ///
+ ///
+ public string Text { get; private set; }
+ ///
+ ///
+ ///
+ public string IpAddress { get; private set; }
+ ///
+ ///
+ ///
+ public int Port { get; private set; }
+ ///
+ ///
+ ///
+ public byte[] Bytes { get; private set; }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public GenericUdpReceiveTextExtraArgs(string text, string ipAddress, int port, byte[] bytes)
+ {
+ Text = text;
+ IpAddress = ipAddress;
+ Port = port;
+ Bytes = bytes;
+ }
+
+ ///
+ /// Stupid S+ Constructor
+ ///
+ public GenericUdpReceiveTextExtraArgs() { }
+ }
+
+ ///
+ ///
+ ///
+ public class UdpServerPropertiesConfig
+ {
+ ///
+ ///
+ ///
+ [JsonProperty(Required = Required.Always)]
+ public string Address { get; set; }
+
+ ///
+ ///
+ ///
+ [JsonProperty(Required = Required.Always)]
+ public int Port { get; set; }
+
+ ///
+ /// Defaults to 32768
+ ///
+ public int BufferSize { get; set; }
+
+ ///
+ ///
+ ///
+ public UdpServerPropertiesConfig()
+ {
+ BufferSize = 32768;
+ }
+ }
}
\ No newline at end of file
diff --git a/Pepperdash Core/Pepperdash Core/Comm/QscCoreDoubleTcpIpClient.cs b/Pepperdash Core/Pepperdash Core/Comm/QscCoreDoubleTcpIpClient.cs
new file mode 100644
index 0000000..2f61dc8
--- /dev/null
+++ b/Pepperdash Core/Pepperdash Core/Comm/QscCoreDoubleTcpIpClient.cs
@@ -0,0 +1,312 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+namespace PepperDash.Core
+{
+ public class QscCoreDoubleTcpIpClient : IKeyed
+ {
+ public string Key { get; private set; }
+
+ public event EventHandler BoolChange;
+ public event EventHandler UshortChange;
+ public event EventHandler StringChange;
+
+ public GenericTcpIpClient MasterClient { get; private set; }
+ public GenericTcpIpClient SlaveClient { get; private set; }
+
+ string Username;
+ string Password;
+ string LineEnding;
+
+ CommunicationGather MasterGather;
+ CommunicationGather SlaveGather;
+
+ bool IsPolling;
+ int PollingIntervalSeconds;
+ CTimer PollTimer;
+
+ bool SlaveIsActive;
+
+ ///
+ /// Default constuctor for S+
+ ///
+ public QscCoreDoubleTcpIpClient()
+ {
+ MasterClient = new GenericTcpIpClient("temp-master");
+ MasterClient.AutoReconnect = true;
+ MasterClient.AutoReconnectIntervalMs = 2000;
+ SlaveClient = new GenericTcpIpClient("temp-slave");
+ SlaveClient.AutoReconnect = true;
+ SlaveClient.AutoReconnectIntervalMs = 2000;
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void Connect(string key, string masterAddress, int masterPort,
+ string slaveAddress, int slavePort, string username, string password,
+ int pollingIntervalSeconds, string lineEnding)
+ {
+ Key = key;
+
+ PollingIntervalSeconds = pollingIntervalSeconds;
+ Username = username;
+ Password = password;
+ LineEnding = lineEnding;
+
+ MasterClient.Initialize(key + "-master");
+ SlaveClient.Initialize(key + "-slave");
+
+ MasterClient.Hostname = masterAddress;
+ MasterClient.Port = masterPort;
+
+ if (MasterClient != null)
+ {
+ MasterClient.Disconnect();
+ }
+
+ if (SlaveClient != null)
+ {
+ SlaveClient.Disconnect();
+ }
+
+ if (MasterGather == null)
+ {
+ MasterGather = new CommunicationGather(MasterClient, lineEnding);
+ MasterGather.IncludeDelimiter = true;
+ }
+
+ MasterGather.LineReceived -= MasterGather_LineReceived;
+ MasterGather.LineReceived += new EventHandler(MasterGather_LineReceived);
+
+ MasterClient.ConnectionChange -= MasterClient_SocketStatusChange;
+ MasterClient.ConnectionChange += MasterClient_SocketStatusChange;
+
+ SlaveClient.Hostname = slaveAddress;
+ SlaveClient.Port = slavePort;
+
+ if (SlaveGather == null)
+ {
+ SlaveGather = new CommunicationGather(SlaveClient, lineEnding);
+ SlaveGather.IncludeDelimiter = true;
+ }
+
+ SlaveGather.LineReceived -= MasterGather_LineReceived;
+ SlaveGather.LineReceived += new EventHandler(SlaveGather_LineReceived);
+
+ SlaveClient.ConnectionChange -= SlaveClient_SocketStatusChange;
+ SlaveClient.ConnectionChange += SlaveClient_SocketStatusChange;
+
+ MasterClient.Connect();
+ SlaveClient.Connect();
+ }
+
+ ///
+ ///
+ ///
+ public void Disconnect()
+ {
+ if (MasterClient != null)
+ {
+ MasterGather.LineReceived -= MasterGather_LineReceived;
+ MasterClient.Disconnect();
+ }
+ if (SlaveClient != null)
+ {
+ SlaveGather.LineReceived -= SlaveGather_LineReceived;
+ SlaveClient.Disconnect();
+ }
+ if (PollTimer != null)
+ {
+ IsPolling = false;
+
+ PollTimer.Stop();
+ PollTimer = null;
+ }
+ }
+
+ ///
+ /// Does not include line feed
+ ///
+ public void SendText(string s)
+ {
+ if (SlaveIsActive)
+ {
+ if (SlaveClient != null)
+ {
+ Debug.Console(2, this, "Sending to Slave: {0}", s);
+ SlaveClient.SendText(s);
+ }
+ }
+ else
+ {
+ if (MasterClient != null)
+ {
+ Debug.Console(2, this, "Sending to Master: {0}", s);
+ MasterClient.SendText(s);
+ }
+ }
+ }
+
+ void MasterClient_SocketStatusChange(object sender, GenericSocketStatusChageEventArgs args)
+ {
+ OnUshortChange((ushort)args.Client.ClientStatus, MasterClientStatusId);
+
+ if (args.Client.IsConnected)
+ {
+ MasterGather.LineReceived += MasterGather_LineReceived;
+
+ StartPolling();
+ }
+ else
+ MasterGather.LineReceived -= MasterGather_LineReceived;
+ }
+
+ void SlaveClient_SocketStatusChange(object sender, GenericSocketStatusChageEventArgs args)
+ {
+ OnUshortChange((ushort)args.Client.ClientStatus, SlaveClientStatusId);
+
+ if (args.Client.IsConnected)
+ {
+ SlaveGather.LineReceived += SlaveGather_LineReceived;
+
+ StartPolling();
+ }
+ else
+ SlaveGather.LineReceived -= SlaveGather_LineReceived;
+
+ }
+
+
+ void MasterGather_LineReceived(object sender, GenericCommMethodReceiveTextArgs e)
+ {
+ if (e.Text.Contains("login_required"))
+ {
+ MasterClient.SendText(string.Format("login {0} {1} \x0d\x0a", Username, Password));
+ }
+ else if (e.Text.Contains("login_success"))
+ {
+ // START THE POLLING, YO!
+ }
+ else if (e.Text.StartsWith("sr"))
+ {
+ // example response "sr "MyDesign" "NIEC2bxnVZ6a" 1 1"
+
+ var split = e.Text.Trim().Split(' ');
+ if (split[split.Length - 1] == "1")
+ {
+ SlaveIsActive = false;
+ OnBoolChange(false, SlaveIsActiveId);
+ OnBoolChange(true, MasterIsActiveId);
+ }
+ }
+ if (!SlaveIsActive)
+ OnStringChange(e.Text, LineReceivedId);
+ }
+
+ void SlaveGather_LineReceived(object sender, GenericCommMethodReceiveTextArgs e)
+ {
+ if (e.Text.Contains("login_required"))
+ {
+ SlaveClient.SendText(string.Format("login {0} {1} \x0d\x0a", Username, Password));
+ }
+ else if (e.Text.Contains("login_success"))
+ {
+ // START THE POLLING, YO!
+ }
+ else if (e.Text.StartsWith("sr"))
+ {
+ var split = e.Text.Trim().Split(' ');
+ if (split[split.Length - 1] == "1")
+ {
+ SlaveIsActive = true;
+ OnBoolChange(true, SlaveIsActiveId);
+ OnBoolChange(false, MasterIsActiveId);
+ }
+ }
+ if (SlaveIsActive)
+ OnStringChange(e.Text, LineReceivedId);
+ }
+
+ void StartPolling()
+ {
+ if (!IsPolling)
+ {
+ IsPolling = true;
+
+ Poll();
+ if (PollTimer != null)
+ PollTimer.Stop();
+
+ PollTimer = new CTimer(o => Poll(), null, PollingIntervalSeconds * 1000, PollingIntervalSeconds * 1000);
+ }
+ }
+
+ void Poll()
+ {
+ if (MasterClient != null && MasterClient.IsConnected)
+ {
+ Debug.Console(2, this, "Polling Master.");
+ MasterClient.SendText("sg\x0d\x0a");
+
+ }
+ if (SlaveClient != null && SlaveClient.IsConnected)
+ {
+ Debug.Console(2, this, "Polling Slave.");
+ SlaveClient.SendText("sg\x0d\x0a");
+ }
+ }
+
+
+
+ // login NAME PIN ---> login_success, login_failed
+
+ // status get
+ // sg --> sr DESIGN_NAME DESIGN_ID IS_PRIMARY IS_ACTIVE
+
+ // CRLF
+
+ void OnBoolChange(bool state, ushort type)
+ {
+ var handler = BoolChange;
+ if (handler != null)
+ handler(this, new BoolChangeEventArgs(state, type));
+ }
+
+ void OnUshortChange(ushort state, ushort type)
+ {
+ var handler = UshortChange;
+ if (handler != null)
+ handler(this, new UshrtChangeEventArgs(state, type));
+ }
+
+ void OnStringChange(string value, ushort type)
+ {
+ var handler = StringChange;
+ if (handler != null)
+ handler(this, new StringChangeEventArgs(value, type));
+ }
+
+
+ public const ushort MasterIsActiveId = 3;
+ public const ushort SlaveIsActiveId = 4;
+ public const ushort MainModuleInitiailzeId = 5;
+
+ public const ushort MasterClientStatusId = 101;
+ public const ushort SlaveClientStatusId = 102;
+
+ public const ushort LineReceivedId = 201;
+ }
+}
\ No newline at end of file
diff --git a/Pepperdash Core/Pepperdash Core/CommunicationExtras.cs b/Pepperdash Core/Pepperdash Core/CommunicationExtras.cs
index c5892a4..9dc4b48 100644
--- a/Pepperdash Core/Pepperdash Core/CommunicationExtras.cs
+++ b/Pepperdash Core/Pepperdash Core/CommunicationExtras.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets;
-
+using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -138,5 +138,10 @@ namespace PepperDash.Core
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
return String.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
}
+
+ public static string GetDebugText(string text)
+ {
+ return Regex.Replace(text, @"[^\u0020-\u007E]", a => GetEscapedText(a.Value));
+ }
}
}
\ No newline at end of file
diff --git a/Pepperdash Core/Pepperdash Core/Device.cs b/Pepperdash Core/Pepperdash Core/Device.cs
index 62dc6b1..bfbe359 100644
--- a/Pepperdash Core/Pepperdash Core/Device.cs
+++ b/Pepperdash Core/Pepperdash Core/Device.cs
@@ -119,7 +119,14 @@ namespace PepperDash.Core
///
public virtual bool Deactivate() { return true; }
- ///
+ ///
+ /// Call this method to start communications with a device. Overriding classes do not need to call base.Initialize()
+ ///
+ public virtual void Initialize()
+ {
+ }
+
+ ///
/// Helper method to check object for bool value false and fire an Action method
///
/// Should be of type bool, others will be ignored
diff --git a/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj b/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj
index f746202..aa8d2c2 100644
--- a/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj
+++ b/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj
@@ -83,6 +83,7 @@
+
diff --git a/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigAnalogToken.cs b/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigAnalogToken.cs
index 41427fe..6236f3e 100644
--- a/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigAnalogToken.cs
+++ b/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigAnalogToken.cs
@@ -29,7 +29,7 @@ namespace PepperDash.Core.Intersystem.Tokens
public override byte[] GetBytes()
{
return new[] {
- (byte)(0xC0 | ((Value & 0xC000) >> 10) | (Index >> 7)),
+ (byte)(0xC0 | ((Value & 0xC000) >> 10) | (Index - 1 >> 7)),
(byte)((Index - 1) & 0x7F),
(byte)((Value & 0x3F80) >> 7),
(byte)(Value & 0x7F)
diff --git a/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigDigitalToken.cs b/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigDigitalToken.cs
index f721387..7840e90 100644
--- a/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigDigitalToken.cs
+++ b/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigDigitalToken.cs
@@ -29,7 +29,7 @@ namespace PepperDash.Core.Intersystem.Tokens
public override byte[] GetBytes()
{
return new[] {
- (byte)(0x80 | (Value ? 0 : 0x20) | (Index >> 7)),
+ (byte)(0x80 | (Value ? 0 : 0x20) | ((Index - 1) >> 7)),
(byte)((Index - 1) & 0x7F)
};
}
diff --git a/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigSerialToken.cs b/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigSerialToken.cs
index cc61b1f..deb721a 100644
--- a/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigSerialToken.cs
+++ b/Pepperdash Core/Pepperdash Core/XSigUtility/Tokens/XSigSerialToken.cs
@@ -32,7 +32,7 @@ namespace PepperDash.Core.Intersystem.Tokens
var serialBytes = String.IsNullOrEmpty(Value) ? new byte[0] : Encoding.GetEncoding(28591).GetBytes(Value);
var xsig = new byte[serialBytes.Length + 3];
- xsig[0] = (byte)(0xC8 | (Index >> 7));
+ xsig[0] = (byte)(0xC8 | (Index - 1 >> 7));
xsig[1] = (byte)((Index - 1) & 0x7F);
xsig[xsig.Length - 1] = 0xFF;