Merge branch 'hotfix/ssh-logging' of https://github.com/PepperDash/PepperDashCore into hotfix/ssh-logging

This commit is contained in:
Andrew Welker
2022-02-09 09:29:51 -07:00
13 changed files with 772 additions and 741 deletions

View File

@@ -8,6 +8,7 @@ $destination = "$($Env:GITHUB_HOME)\output"
New-Item -ItemType Directory -Force -Path ($destination) New-Item -ItemType Directory -Force -Path ($destination)
Get-ChildItem ($destination) Get-ChildItem ($destination)
$exclusions = @(git submodule foreach --quiet 'echo $name') $exclusions = @(git submodule foreach --quiet 'echo $name')
$exclusions += "Newtonsoft.Json.Compact.dll"
# Trying to get any .json schema files (not currently working) # Trying to get any .json schema files (not currently working)
# Gets any files with the listed extensions. # Gets any files with the listed extensions.
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.json", "*.nuspec" | ForEach-Object { Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.json", "*.nuspec" | ForEach-Object {

View File

@@ -152,156 +152,3 @@ jobs:
run: nuget push **/*.nupkg -source github run: nuget push **/*.nupkg -source github
- name: Publish nuget package to nuget.org - name: Publish nuget package to nuget.org
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json 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 ./

View File

@@ -127,148 +127,3 @@ jobs:
run: nuget push **/*.nupkg -source github run: nuget push **/*.nupkg -source github
- name: Publish nuget package to nuget.org - name: Publish nuget package to nuget.org
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json 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 ./

View File

@@ -383,18 +383,24 @@ namespace PepperDash.Core
if (bytes.Length > 0) if (bytes.Length > 0)
{ {
var bytesHandler = BytesReceived; var bytesHandler = BytesReceived;
if (bytesHandler != null) if (bytesHandler != null)
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes)); {
if (StreamDebugging.RxStreamDebuggingIsEnabled)
{
Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
}
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
}
var textHandler = TextReceived; var textHandler = TextReceived;
if (textHandler != null) if (textHandler != null)
{ {
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length); var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
textHandler(this, new GenericCommMethodReceiveTextArgs(str));
if (StreamDebugging.RxStreamDebuggingIsEnabled) 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 try
{ {
if (Client != null) if (Client != null && TheStream != null && IsConnected)
{ {
if (StreamDebugging.TxStreamDebuggingIsEnabled) 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.Write(text);
TheStream.Flush(); TheStream.Flush();
}
else
{
Debug.Console(2, this, "Client is null or disconnected. Cannot Send Text");
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -462,13 +472,17 @@ namespace PepperDash.Core
{ {
try try
{ {
if (Client != null) if (Client != null && TheStream != null && IsConnected)
{ {
if (StreamDebugging.TxStreamDebuggingIsEnabled) if (StreamDebugging.TxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes)); Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
TheStream.Write(bytes, 0, bytes.Length); TheStream.Write(bytes, 0, bytes.Length);
TheStream.Flush(); TheStream.Flush();
}
else
{
Debug.Console(2, this, "Client is null or disconnected. Cannot Send Bytes");
} }
} }
catch catch

View File

@@ -284,9 +284,17 @@ namespace PepperDash.Core
/// </summary> /// </summary>
public void Disconnect() public void Disconnect()
{ {
DisconnectCalledByUser = true;
// Stop trying reconnects, if we are
if (RetryTimer != null)
{
RetryTimer.Stop();
RetryTimer = null;
}
if (Client != null) if (Client != null)
{ {
DisconnectCalledByUser = true;
DisconnectClient(); DisconnectClient();
Client = null; Client = null;
Debug.Console(1, this, "Disconnected"); Debug.Console(1, this, "Disconnected");
@@ -329,7 +337,15 @@ namespace PepperDash.Core
Debug.Console(1, this, "Attempting reconnect, status={0}", Client.ClientStatus); Debug.Console(1, this, "Attempting reconnect, status={0}", Client.ClientStatus);
if (!DisconnectCalledByUser) 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 bytes = client.IncomingDataBuffer.Take(numBytes).ToArray();
var bytesHandler = BytesReceived; var bytesHandler = BytesReceived;
if (bytesHandler != null) if (bytesHandler != null)
{
if (StreamDebugging.RxStreamDebuggingIsEnabled)
{
Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
}
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes)); bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
}
var textHandler = TextReceived; var textHandler = TextReceived;
if (textHandler != null) if (textHandler != null)
{ {
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length); var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
if (StreamDebugging.RxStreamDebuggingIsEnabled) 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)); textHandler(this, new GenericCommMethodReceiveTextArgs(str));
@@ -376,7 +398,7 @@ namespace PepperDash.Core
var bytes = Encoding.GetEncoding(28591).GetBytes(text); var bytes = Encoding.GetEncoding(28591).GetBytes(text);
// Check debug level before processing byte array // Check debug level before processing byte array
if (StreamDebugging.TxStreamDebuggingIsEnabled) 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) if(Client != null)
Client.SendData(bytes, bytes.Length); Client.SendData(bytes, bytes.Length);

View File

@@ -1,426 +1,393 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets; using Crestron.SimplSharp.CrestronSockets;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace PepperDash.Core namespace PepperDash.Core
{ {
public class GenericUdpServer : Device, ISocketStatusWithStreamDebugging public class GenericUdpServer : Device, ISocketStatusWithStreamDebugging
{ {
private const string SplusKey = "Uninitialized Udp Server"; private const string SplusKey = "Uninitialized Udp Server";
public CommunicationStreamDebugging StreamDebugging { get; private set; } public CommunicationStreamDebugging StreamDebugging { get; private set; }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived; public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived; public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
/// <summary> /// <summary>
/// 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. /// 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.
/// </summary> /// </summary>
public event EventHandler<GenericUdpReceiveTextExtraArgs> DataRecievedExtra; public event EventHandler<GenericUdpReceiveTextExtraArgs> DataRecievedExtra;
/// <summary> /// <summary>
/// Queue to temporarily store received messages with the source IP and Port info ///
/// </summary> /// </summary>
private CrestronQueue<GenericUdpReceiveTextExtraArgs> MessageQueue; public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public event EventHandler<GenericSocketStatusChageEventArgs> ConnectionChange; public event EventHandler<GenericUdpConnectedEventArgs> UpdateConnectionStatus;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public event EventHandler<GenericUdpConnectedEventArgs> UpdateConnectionStatus; public SocketStatus ClientStatus
{
/// <summary> get
/// {
/// </summary> return Server.ServerStatus;
public SocketStatus ClientStatus }
{ }
get
{ /// <summary>
return Server.ServerStatus; ///
} /// </summary>
} public ushort UStatus
{
/// <summary> get { return (ushort)Server.ServerStatus; }
/// }
/// </summary>
public ushort UStatus /// <summary>
{ /// Address of server
get { return (ushort)Server.ServerStatus; } /// </summary>
} public string Hostname { get; set; }
/// <summary>
CCriticalSection DequeueLock; /// IP Address of the sender of the last recieved message
/// <summary> /// </summary>
/// Address of server
/// </summary>
public string Hostname { get; set; } /// <summary>
/// Port on server
/// <summary> /// </summary>
/// IP Address of the sender of the last recieved message public int Port { get; set; }
/// </summary>
/// <summary>
/// Another damn S+ helper because S+ seems to treat large port nums as signed ints
/// <summary> /// which screws up things
/// Port on server /// </summary>
/// </summary> public ushort UPort
public int Port { get; set; } {
get { return Convert.ToUInt16(Port); }
/// <summary> set { Port = Convert.ToInt32(value); }
/// Another damn S+ helper because S+ seems to treat large port nums as signed ints }
/// which screws up things
/// </summary> /// <summary>
public ushort UPort /// Indicates that the UDP Server is enabled
{ /// </summary>
get { return Convert.ToUInt16(Port); } public bool IsConnected
set { Port = Convert.ToInt32(value); } {
} get;
private set;
/// <summary> }
/// Indicates that the UDP Server is enabled
/// </summary> public ushort UIsConnected
public bool IsConnected {
{ get { return IsConnected ? (ushort)1 : (ushort)0; }
get; }
private set;
} /// <summary>
/// Defaults to 2000
public ushort UIsConnected /// </summary>
{ public int BufferSize { get; set; }
get { return IsConnected ? (ushort)1 : (ushort)0; }
} public UDPServer Server { get; private set; }
/// <summary> /// <summary>
/// Defaults to 2000 /// Constructor for S+. Make sure to set key, address, port, and buffersize using init method
/// </summary> /// </summary>
public int BufferSize { get; set; } public GenericUdpServer()
: base(SplusKey)
public UDPServer Server { get; private set; } {
StreamDebugging = new CommunicationStreamDebugging(SplusKey);
/// <summary> BufferSize = 5000;
/// Constructor for S+. Make sure to set key, address, port, and buffersize using init method
/// </summary> CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
public GenericUdpServer() CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
: base(SplusKey) }
{
StreamDebugging = new CommunicationStreamDebugging(SplusKey); /// <summary>
BufferSize = 5000; ///
DequeueLock = new CCriticalSection(); /// </summary>
MessageQueue = new CrestronQueue<GenericUdpReceiveTextExtraArgs>(); /// <param name="key"></param>
/// <param name="address"></param>
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); /// <param name="port"></param>
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler); /// <param name="buffefSize"></param>
} public GenericUdpServer(string key, string address, int port, int buffefSize)
: base(key)
/// <summary> {
/// StreamDebugging = new CommunicationStreamDebugging(key);
/// </summary> Hostname = address;
/// <param name="key"></param> Port = port;
/// <param name="address"></param> BufferSize = buffefSize;
/// <param name="port"></param>
/// <param name="buffefSize"></param> CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
public GenericUdpServer(string key, string address, int port, int buffefSize) CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
: base(key) }
{
StreamDebugging = new CommunicationStreamDebugging(key); /// <summary>
Hostname = address; /// Call from S+ to initialize values
Port = port; /// </summary>
BufferSize = buffefSize; /// <param name="key"></param>
/// <param name="address"></param>
DequeueLock = new CCriticalSection(); /// <param name="port"></param>
MessageQueue = new CrestronQueue<GenericUdpReceiveTextExtraArgs>(); public void Initialize(string key, string address, ushort port)
{
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); Key = key;
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler); Hostname = address;
} UPort = port;
}
/// <summary>
/// Call from S+ to initialize values /// <summary>
/// </summary> ///
/// <param name="key"></param> /// </summary>
/// <param name="address"></param> /// <param name="ethernetEventArgs"></param>
/// <param name="port"></param> void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
public void Initialize(string key, string address, ushort port) {
{ // Re-enable the server if the link comes back up and the status should be connected
Key = key; if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp
Hostname = address; && IsConnected)
UPort = port; {
} Connect();
}
/// <summary> }
///
/// </summary> /// <summary>
/// <param name="ethernetEventArgs"></param> ///
void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs) /// </summary>
{ /// <param name="programEventType"></param>
// Re-enable the server if the link comes back up and the status should be connected void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp {
&& IsConnected) if (programEventType != eProgramStatusEventType.Stopping)
{ return;
Connect();
} Debug.Console(1, this, "Program stopping. Disabling Server");
} Disconnect();
}
/// <summary>
/// /// <summary>
/// </summary> /// Enables the UDP Server
/// <param name="programEventType"></param> /// </summary>
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) public void Connect()
{ {
if (programEventType == eProgramStatusEventType.Stopping) if (Server == null)
{ {
Debug.Console(1, this, "Program stopping. Disabling Server"); Server = new UDPServer();
Disconnect(); }
}
} if (string.IsNullOrEmpty(Hostname))
{
/// <summary> Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericUdpServer '{0}': No address set", Key);
/// Enables the UDP Server return;
/// </summary> }
public void Connect() if (Port < 1 || Port > 65535)
{ {
if (Server == null) {
{ Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericUdpServer '{0}': Invalid port", Key);
Server = new UDPServer(); return;
} }
}
if (string.IsNullOrEmpty(Hostname))
{ var status = Server.EnableUDPServer(Hostname, Port);
Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericUdpServer '{0}': No address set", Key);
return; Debug.Console(2, this, "SocketErrorCode: {0}", status);
} if (status == SocketErrorCodes.SOCKET_OK)
if (Port < 1 || Port > 65535) IsConnected = true;
{
{ var handler = UpdateConnectionStatus;
Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericUdpServer '{0}': Invalid port", Key); if (handler != null)
return; handler(this, new GenericUdpConnectedEventArgs(UIsConnected));
}
} // Start receiving data
Server.ReceiveDataAsync(Receive);
var status = Server.EnableUDPServer(Hostname, Port); }
Debug.Console(2, this, "SocketErrorCode: {0}", status); /// <summary>
if (status == SocketErrorCodes.SOCKET_OK) /// Disabled the UDP Server
IsConnected = true; /// </summary>
public void Disconnect()
var handler = UpdateConnectionStatus; {
if (handler != null) if(Server != null)
handler(this, new GenericUdpConnectedEventArgs(UIsConnected)); Server.DisableUDPServer();
// Start receiving data IsConnected = false;
Server.ReceiveDataAsync(Receive);
} var handler = UpdateConnectionStatus;
if (handler != null)
/// <summary> handler(this, new GenericUdpConnectedEventArgs(UIsConnected));
/// Disabled the UDP Server }
/// </summary>
public void Disconnect()
{ /// <summary>
if(Server != null) /// Recursive method to receive data
Server.DisableUDPServer(); /// </summary>
/// <param name="server"></param>
IsConnected = false; /// <param name="numBytes"></param>
void Receive(UDPServer server, int numBytes)
var handler = UpdateConnectionStatus; {
if (handler != null) Debug.Console(2, this, "Received {0} bytes", numBytes);
handler(this, new GenericUdpConnectedEventArgs(UIsConnected));
} try
{
if (numBytes <= 0)
/// <summary> return;
/// Recursive method to receive data
/// </summary> var sourceIp = Server.IPAddressLastMessageReceivedFrom;
/// <param name="server"></param> var sourcePort = Server.IPPortLastMessageReceivedFrom;
/// <param name="numBytes"></param> var bytes = server.IncomingDataBuffer.Take(numBytes).ToArray();
void Receive(UDPServer server, int numBytes) var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
{
Debug.Console(2, this, "Received {0} bytes", numBytes); var dataRecivedExtra = DataRecievedExtra;
if (dataRecivedExtra != null)
if (numBytes > 0) dataRecivedExtra(this, new GenericUdpReceiveTextExtraArgs(str, sourceIp, sourcePort, bytes));
{
var sourceIp = Server.IPAddressLastMessageReceivedFrom; Debug.Console(2, this, "Bytes: {0}", bytes.ToString());
var sourcePort = Server.IPPortLastMessageReceivedFrom; var bytesHandler = BytesReceived;
var bytes = server.IncomingDataBuffer.Take(numBytes).ToArray(); if (bytesHandler != null)
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length); {
MessageQueue.TryToEnqueue(new GenericUdpReceiveTextExtraArgs(str, sourceIp, sourcePort, bytes)); if (StreamDebugging.RxStreamDebuggingIsEnabled)
{
Debug.Console(2, this, "Bytes: {0}", bytes.ToString()); Debug.Console(0, this, "Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
var bytesHandler = BytesReceived; }
if (bytesHandler != null) bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes)); }
else var textHandler = TextReceived;
Debug.Console(2, this, "bytesHandler is null"); if (textHandler != null)
var textHandler = TextReceived; {
if (textHandler != null) if (StreamDebugging.RxStreamDebuggingIsEnabled)
{ Debug.Console(0, this, "Received {1} characters of text: '{0}'", ComTextHelper.GetDebugText(str), str.Length);
if (StreamDebugging.RxStreamDebuggingIsEnabled) textHandler(this, new GenericCommMethodReceiveTextArgs(str));
Debug.Console(0, this, "Recevied: '{0}'", str); }
}
textHandler(this, new GenericCommMethodReceiveTextArgs(str)); catch (Exception ex)
} {
else Debug.Console(0, "GenericUdpServer Receive error: {0}{1}", ex.Message, ex.StackTrace);
Debug.Console(2, this, "textHandler is null"); }
} finally
server.ReceiveDataAsync(Receive); {
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()); /// <summary>
} /// General send method
/// </summary>
/// <summary> /// <param name="text"></param>
/// This method gets spooled up in its own thread an protected by a CCriticalSection to prevent multiple threads from running concurrently. public void SendText(string text)
/// It will dequeue items as they are enqueued automatically. {
/// </summary> var bytes = Encoding.GetEncoding(28591).GetBytes(text);
void DequeueEvent()
{ if (IsConnected && Server != null)
try {
{ if (StreamDebugging.TxStreamDebuggingIsEnabled)
while (true) Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text));
{
// Pull from Queue and fire an event. Block indefinitely until an item can be removed, similar to a Gather. Server.SendData(bytes, bytes.Length);
var message = MessageQueue.Dequeue(); }
var dataRecivedExtra = DataRecievedExtra; }
if (dataRecivedExtra != null)
{ /// <summary>
dataRecivedExtra(this, message); ///
} /// </summary>
} /// <param name="bytes"></param>
} public void SendBytes(byte[] bytes)
catch (Exception e) {
{ if (StreamDebugging.TxStreamDebuggingIsEnabled)
Debug.Console(0, "GenericUdpServer DequeueEvent error: {0}\r", e); Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
}
// 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 (IsConnected && Server != null)
if (DequeueLock != null) Server.SendData(bytes, bytes.Length);
{ }
DequeueLock.Leave();
} }
}
/// <summary>
/// <summary> ///
/// General send method /// </summary>
/// </summary> public class GenericUdpReceiveTextExtraArgs : EventArgs
/// <param name="text"></param> {
public void SendText(string text) /// <summary>
{ ///
var bytes = Encoding.GetEncoding(28591).GetBytes(text); /// </summary>
public string Text { get; private set; }
if (IsConnected && Server != null) /// <summary>
{ ///
if (StreamDebugging.TxStreamDebuggingIsEnabled) /// </summary>
Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, text); public string IpAddress { get; private set; }
/// <summary>
Server.SendData(bytes, bytes.Length); ///
} /// </summary>
} public int Port { get; private set; }
/// <summary>
/// <summary> ///
/// /// </summary>
/// </summary> public byte[] Bytes { get; private set; }
/// <param name="bytes"></param>
public void SendBytes(byte[] bytes) /// <summary>
{ ///
if (StreamDebugging.TxStreamDebuggingIsEnabled) /// </summary>
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes)); /// <param name="text"></param>
/// <param name="ipAddress"></param>
if (IsConnected && Server != null) /// <param name="port"></param>
Server.SendData(bytes, bytes.Length); /// <param name="bytes"></param>
} public GenericUdpReceiveTextExtraArgs(string text, string ipAddress, int port, byte[] bytes)
{
} Text = text;
IpAddress = ipAddress;
/// <summary> Port = port;
/// Bytes = bytes;
/// </summary> }
public class GenericUdpReceiveTextExtraArgs : EventArgs
{ /// <summary>
/// <summary> /// Stupid S+ Constructor
/// /// </summary>
/// </summary> public GenericUdpReceiveTextExtraArgs() { }
public string Text { get; private set; } }
/// <summary>
/// /// <summary>
/// </summary> ///
public string IpAddress { get; private set; } /// </summary>
/// <summary> public class UdpServerPropertiesConfig
/// {
/// </summary> /// <summary>
public int Port { get; private set; } ///
/// <summary> /// </summary>
/// [JsonProperty(Required = Required.Always)]
/// </summary> public string Address { get; set; }
public byte[] Bytes { get; private set; }
/// <summary>
/// <summary> ///
/// /// </summary>
/// </summary> [JsonProperty(Required = Required.Always)]
/// <param name="text"></param> public int Port { get; set; }
/// <param name="ipAddress"></param>
/// <param name="port"></param> /// <summary>
/// <param name="bytes"></param> /// Defaults to 32768
public GenericUdpReceiveTextExtraArgs(string text, string ipAddress, int port, byte[] bytes) /// </summary>
{ public int BufferSize { get; set; }
Text = text;
IpAddress = ipAddress; /// <summary>
Port = port; ///
Bytes = bytes; /// </summary>
} public UdpServerPropertiesConfig()
{
/// <summary> BufferSize = 32768;
/// Stupid S+ Constructor }
/// </summary> }
public GenericUdpReceiveTextExtraArgs() { }
}
/// <summary>
///
/// </summary>
public class UdpServerPropertiesConfig
{
/// <summary>
///
/// </summary>
[JsonProperty(Required = Required.Always)]
public string Address { get; set; }
/// <summary>
///
/// </summary>
[JsonProperty(Required = Required.Always)]
public int Port { get; set; }
/// <summary>
/// Defaults to 32768
/// </summary>
public int BufferSize { get; set; }
/// <summary>
///
/// </summary>
public UdpServerPropertiesConfig()
{
BufferSize = 32768;
}
}
} }

View File

@@ -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<BoolChangeEventArgs> BoolChange;
public event EventHandler<UshrtChangeEventArgs> UshortChange;
public event EventHandler<StringChangeEventArgs> 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;
/// <summary>
/// Default constuctor for S+
/// </summary>
public QscCoreDoubleTcpIpClient()
{
MasterClient = new GenericTcpIpClient("temp-master");
MasterClient.AutoReconnect = true;
MasterClient.AutoReconnectIntervalMs = 2000;
SlaveClient = new GenericTcpIpClient("temp-slave");
SlaveClient.AutoReconnect = true;
SlaveClient.AutoReconnectIntervalMs = 2000;
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="masterAddress"></param>
/// <param name="masterPort"></param>
/// <param name="slaveAddress"></param>
/// <param name="slavePort"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="pollingIntervalSeconds"></param>
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<GenericCommMethodReceiveTextArgs>(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<GenericCommMethodReceiveTextArgs>(SlaveGather_LineReceived);
SlaveClient.ConnectionChange -= SlaveClient_SocketStatusChange;
SlaveClient.ConnectionChange += SlaveClient_SocketStatusChange;
MasterClient.Connect();
SlaveClient.Connect();
}
/// <summary>
///
/// </summary>
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;
}
}
/// <summary>
/// Does not include line feed
/// </summary>
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;
}
}

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets; using Crestron.SimplSharp.CrestronSockets;
using System.Text.RegularExpressions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@@ -138,5 +138,10 @@ namespace PepperDash.Core
var bytes = Encoding.GetEncoding(28591).GetBytes(text); var bytes = Encoding.GetEncoding(28591).GetBytes(text);
return String.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray()); 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));
}
} }
} }

View File

@@ -119,7 +119,14 @@ namespace PepperDash.Core
/// <returns></returns> /// <returns></returns>
public virtual bool Deactivate() { return true; } public virtual bool Deactivate() { return true; }
/// <summary> /// <summary>
/// Call this method to start communications with a device. Overriding classes do not need to call base.Initialize()
/// </summary>
public virtual void Initialize()
{
}
/// <summary>
/// Helper method to check object for bool value false and fire an Action method /// Helper method to check object for bool value false and fire an Action method
/// </summary> /// </summary>
/// <param name="o">Should be of type bool, others will be ignored</param> /// <param name="o">Should be of type bool, others will be ignored</param>

View File

@@ -83,6 +83,7 @@
<Compile Include="Comm\EventArgs.cs" /> <Compile Include="Comm\EventArgs.cs" />
<Compile Include="Comm\GenericSshClient.cs" /> <Compile Include="Comm\GenericSshClient.cs" />
<Compile Include="Comm\GenericUdpServer.cs" /> <Compile Include="Comm\GenericUdpServer.cs" />
<Compile Include="Comm\QscCoreDoubleTcpIpClient.cs" />
<Compile Include="Comm\TcpClientConfigObject.cs" /> <Compile Include="Comm\TcpClientConfigObject.cs" />
<Compile Include="Comm\TcpServerConfigObject.cs" /> <Compile Include="Comm\TcpServerConfigObject.cs" />
<Compile Include="Config\PortalConfigReader.cs" /> <Compile Include="Config\PortalConfigReader.cs" />

View File

@@ -29,7 +29,7 @@ namespace PepperDash.Core.Intersystem.Tokens
public override byte[] GetBytes() public override byte[] GetBytes()
{ {
return new[] { return new[] {
(byte)(0xC0 | ((Value & 0xC000) >> 10) | (Index >> 7)), (byte)(0xC0 | ((Value & 0xC000) >> 10) | (Index - 1 >> 7)),
(byte)((Index - 1) & 0x7F), (byte)((Index - 1) & 0x7F),
(byte)((Value & 0x3F80) >> 7), (byte)((Value & 0x3F80) >> 7),
(byte)(Value & 0x7F) (byte)(Value & 0x7F)

View File

@@ -29,7 +29,7 @@ namespace PepperDash.Core.Intersystem.Tokens
public override byte[] GetBytes() public override byte[] GetBytes()
{ {
return new[] { return new[] {
(byte)(0x80 | (Value ? 0 : 0x20) | (Index >> 7)), (byte)(0x80 | (Value ? 0 : 0x20) | ((Index - 1) >> 7)),
(byte)((Index - 1) & 0x7F) (byte)((Index - 1) & 0x7F)
}; };
} }

View File

@@ -32,7 +32,7 @@ namespace PepperDash.Core.Intersystem.Tokens
var serialBytes = String.IsNullOrEmpty(Value) ? new byte[0] : Encoding.GetEncoding(28591).GetBytes(Value); var serialBytes = String.IsNullOrEmpty(Value) ? new byte[0] : Encoding.GetEncoding(28591).GetBytes(Value);
var xsig = new byte[serialBytes.Length + 3]; 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[1] = (byte)((Index - 1) & 0x7F);
xsig[xsig.Length - 1] = 0xFF; xsig[xsig.Length - 1] = 0xFF;