mirror of
https://github.com/PepperDash/PepperDashCore.git
synced 2026-01-11 19:44:44 +00:00
Initial. Moving certain classes out of Essentials Base
This commit is contained in:
20
Pepperdash Core/Pepperdash Core.sln
Normal file
20
Pepperdash Core/Pepperdash Core.sln
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash_Core", "Pepperdash Core\PepperDash_Core.csproj", "{87E29B4C-569B-4368-A4ED-984AC1440C96}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{87E29B4C-569B-4368-A4ED-984AC1440C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{87E29B4C-569B-4368-A4ED-984AC1440C96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{87E29B4C-569B-4368-A4ED-984AC1440C96}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{87E29B4C-569B-4368-A4ED-984AC1440C96}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
67
Pepperdash Core/Pepperdash Core/CommunicationExtras.cs
Normal file
67
Pepperdash Core/Pepperdash Core/CommunicationExtras.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a device that uses basic connection
|
||||
/// </summary>
|
||||
public interface IBasicCommunication : IKeyed
|
||||
{
|
||||
event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||
event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||
bool IsConnected { get; }
|
||||
bool Connected { get; }
|
||||
void SendText(string text);
|
||||
void SendBytes(byte[] bytes);
|
||||
void Connect();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class GenericCommMethodReceiveBytesArgs : EventArgs
|
||||
{
|
||||
public byte[] Bytes { get; private set; }
|
||||
public GenericCommMethodReceiveBytesArgs(byte[] bytes)
|
||||
{
|
||||
Bytes = bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class GenericCommMethodReceiveTextArgs : EventArgs
|
||||
{
|
||||
public string Text { get; private set; }
|
||||
public GenericCommMethodReceiveTextArgs(string text)
|
||||
{
|
||||
Text = text;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ComTextHelper
|
||||
{
|
||||
public static string GetEscapedText(byte[] bytes)
|
||||
{
|
||||
return String.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
|
||||
}
|
||||
|
||||
public static string GetEscapedText(string text)
|
||||
{
|
||||
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
|
||||
return String.Concat(bytes.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Pepperdash Core/Pepperdash Core/CoreInterfaces.cs
Normal file
13
Pepperdash Core/Pepperdash Core/CoreInterfaces.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Core
|
||||
{
|
||||
public interface IKeyed
|
||||
{
|
||||
string Key { get; }
|
||||
}
|
||||
}
|
||||
141
Pepperdash Core/Pepperdash Core/Debug.cs
Normal file
141
Pepperdash Core/Pepperdash Core/Debug.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronDataStore;
|
||||
|
||||
|
||||
namespace PepperDash.Core
|
||||
{
|
||||
public class Debug
|
||||
{
|
||||
public static uint Level { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// This should called from the ControlSystem Initiailize method.
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
// Add command to console
|
||||
CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
|
||||
"appdebug:P [0-2]: Sets the application's console debug message level",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
uint level = 0;
|
||||
var err = CrestronDataStoreStatic.GetGlobalUintValue("DebugLevel", out level);
|
||||
if (err == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
SetDebugLevel(level);
|
||||
else if (err == CrestronDataStore.CDS_ERROR.CDS_RECORD_NOT_FOUND)
|
||||
CrestronDataStoreStatic.SetGlobalUintValue("DebugLevel", 0);
|
||||
else
|
||||
CrestronConsole.PrintLine("Error restoring console debug level setting: {0}", err);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for console command
|
||||
/// </summary>
|
||||
/// <param name="levelString"></param>
|
||||
public static void SetDebugFromConsole(string levelString)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(levelString.Trim()))
|
||||
{
|
||||
CrestronConsole.PrintLine("AppDebug level = {0}", Level);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDebugLevel(Convert.ToUInt32(levelString));
|
||||
}
|
||||
catch
|
||||
{
|
||||
CrestronConsole.PrintLine("Usage: appdebug:P [0-2]");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the debug level
|
||||
/// </summary>
|
||||
/// <param name="level"> Valid values 0 (no debug), 1 (critical), 2 (all messages)</param>
|
||||
public static void SetDebugLevel(uint level)
|
||||
{
|
||||
if (level <= 2)
|
||||
{
|
||||
Level = 2;
|
||||
CrestronConsole.PrintLine("[Application {0}], Debug level set to {1}",
|
||||
InitialParametersClass.ApplicationNumber, level);
|
||||
var err = CrestronDataStoreStatic.SetGlobalUintValue("DebugLevel", level);
|
||||
if(err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
CrestronConsole.PrintLine("Error saving console debug level setting: {0}", err);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints message to console if current debug level is equal to or higher than the level of this message.
|
||||
/// Uses CrestronConsole.PrintLine.
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="format">Console format string</param>
|
||||
/// <param name="items">Object parameters</param>
|
||||
public static void Console(uint level, string format, params object[] items)
|
||||
{
|
||||
if (Level >= level)
|
||||
CrestronConsole.PrintLine("App {0}:{1}", InitialParametersClass.ApplicationNumber,
|
||||
string.Format(format, items));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a device Key to the beginning of a message
|
||||
/// </summary>
|
||||
public static void Console(uint level, IKeyed dev, string format, params object[] items)
|
||||
{
|
||||
if (Level >= level)
|
||||
Console(level, "[{0}] {1}", dev.Key, string.Format(format, items));
|
||||
}
|
||||
|
||||
public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel,
|
||||
string format, params object[] items)
|
||||
{
|
||||
if (Level >= level)
|
||||
{
|
||||
var str = string.Format("[{0}] {1}", dev.Key, string.Format(format, items));
|
||||
Console(level, str);
|
||||
LogError(errorLogLevel, str);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Console(uint level, ErrorLogLevel errorLogLevel,
|
||||
string format, params object[] items)
|
||||
{
|
||||
if (Level >= level)
|
||||
{
|
||||
var str = string.Format(format, items);
|
||||
Console(level, str);
|
||||
LogError(errorLogLevel, str);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LogError(ErrorLogLevel errorLogLevel, string str)
|
||||
{
|
||||
string msg = string.Format("App {0}:{1}", InitialParametersClass.ApplicationNumber, str);
|
||||
switch (errorLogLevel)
|
||||
{
|
||||
case ErrorLogLevel.Error:
|
||||
ErrorLog.Error(msg);
|
||||
break;
|
||||
case ErrorLogLevel.Warning:
|
||||
ErrorLog.Warn(msg);
|
||||
break;
|
||||
case ErrorLogLevel.Notice:
|
||||
ErrorLog.Notice(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ErrorLogLevel
|
||||
{
|
||||
Error, Warning, Notice, None
|
||||
}
|
||||
}
|
||||
}
|
||||
92
Pepperdash Core/Pepperdash Core/Device.cs
Normal file
92
Pepperdash Core/Pepperdash Core/Device.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Core
|
||||
{
|
||||
//*********************************************************************************************************
|
||||
/// <summary>
|
||||
/// The core event and status-bearing class that most if not all device and connectors can derive from.
|
||||
/// </summary>
|
||||
public class Device : IKeyed
|
||||
{
|
||||
public string Key { get; protected set; }
|
||||
public string Name { get; protected set; }
|
||||
public bool Enabled { get; protected set; }
|
||||
List<Action> _PreActivationActions;
|
||||
List<Action> _PostActivationActions;
|
||||
|
||||
public static Device DefaultDevice { get { return _DefaultDevice; } }
|
||||
static Device _DefaultDevice = new Device("Default", "Default");
|
||||
|
||||
/// <summary>
|
||||
/// Base constructor for all Devices.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public Device(string key)
|
||||
{
|
||||
Key = key;
|
||||
if (key.Contains('.')) Debug.Console(0, this, "WARNING: Device name's should not include '.'");
|
||||
Name = "";
|
||||
}
|
||||
|
||||
public Device(string key, string name) : this(key)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public void AddPreActivationAction(Action act)
|
||||
{
|
||||
if (_PreActivationActions == null)
|
||||
_PreActivationActions = new List<Action>();
|
||||
_PreActivationActions.Add(act);
|
||||
}
|
||||
|
||||
public void AddPostActivationAction(Action act)
|
||||
{
|
||||
if (_PostActivationActions == null)
|
||||
_PostActivationActions = new List<Action>();
|
||||
_PostActivationActions.Add(act);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets this device ready to be used in the system. Runs any added pre-activation items, and
|
||||
/// all post-activation at end. Classes needing additional logic to
|
||||
/// run should override CustomActivate()
|
||||
/// </summary>
|
||||
public bool Activate()
|
||||
{
|
||||
if (_PreActivationActions != null)
|
||||
_PreActivationActions.ForEach(a => a.Invoke());
|
||||
var result = CustomActivate();
|
||||
if(result && _PostActivationActions != null)
|
||||
_PostActivationActions.ForEach(a => a.Invoke());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called in between Pre and PostActivationActions when Activate() is called.
|
||||
/// Override to provide addtitional setup when calling activation. Overriding classes
|
||||
/// do not need to call base.CustomActivate()
|
||||
/// </summary>
|
||||
/// <returns>true if device activated successfully.</returns>
|
||||
public virtual bool CustomActivate() { return true; }
|
||||
|
||||
/// <summary>
|
||||
/// Call to deactivate device - unlink events, etc. Overriding classes do not
|
||||
/// need to call base.Deactivate()
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool Deactivate() { return true; }
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to check object for bool value false and fire an Action method
|
||||
/// </summary>
|
||||
/// <param name="o">Should be of type bool, others will be ignored</param>
|
||||
/// <param name="a">Action to be run when o is false</param>
|
||||
public void OnFalse(object o, Action a)
|
||||
{
|
||||
if (o is bool && !(bool)o) a();
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Pepperdash Core/Pepperdash Core/EthernetHelper.cs
Normal file
118
Pepperdash Core/Pepperdash Core/EthernetHelper.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Core
|
||||
{
|
||||
public class EthernetHelper
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static EthernetHelper LanHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_LanHelper == null) _LanHelper = new EthernetHelper(0);
|
||||
return LanHelper;
|
||||
}
|
||||
}
|
||||
static EthernetHelper _LanHelper;
|
||||
|
||||
// ADD OTHER HELPERS HERE
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int PortNumber { get; private set; }
|
||||
|
||||
private EthernetHelper(int portNumber)
|
||||
{
|
||||
PortNumber = portNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonProperty("linkActive")]
|
||||
public bool LinkActive
|
||||
{
|
||||
get
|
||||
{
|
||||
var status = CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_LINK_STATUS, 0);
|
||||
Debug.Console(0, "LinkActive = {0}", status);
|
||||
return status == "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonProperty("dchpActive")]
|
||||
public bool DhcpActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, 0) == "ON";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonProperty("hostname")]
|
||||
public string Hostname
|
||||
{
|
||||
get
|
||||
{
|
||||
return CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonProperty("ipAddress")]
|
||||
public string IPAddress
|
||||
{
|
||||
get
|
||||
{
|
||||
return CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonProperty("subnetMask")]
|
||||
public string SubnetMask
|
||||
{
|
||||
get
|
||||
{
|
||||
return CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[JsonProperty("defaultGateway")]
|
||||
public string DefaultGateway
|
||||
{
|
||||
get
|
||||
{
|
||||
return CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
209
Pepperdash Core/Pepperdash Core/Feedbacks HAS SSP LINKS.cs
Normal file
209
Pepperdash Core/Pepperdash Core/Feedbacks HAS SSP LINKS.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using Crestron.SimplSharp;
|
||||
|
||||
//namespace PepperDash.Core
|
||||
//{
|
||||
// public abstract class Feedback
|
||||
// {
|
||||
// public event EventHandler<EventArgs> OutputChange;
|
||||
|
||||
// public virtual bool BoolValue { get { return false; } }
|
||||
// public virtual int IntValue { get { return 0; } }
|
||||
// public virtual string StringValue { get { return ""; } }
|
||||
|
||||
// public Cue Cue { get; private set; }
|
||||
|
||||
// public abstract eCueType Type { get; }
|
||||
|
||||
// protected Feedback()
|
||||
// {
|
||||
// }
|
||||
|
||||
// protected Feedback(Cue cue)
|
||||
// {
|
||||
// Cue = cue;
|
||||
// }
|
||||
|
||||
// public abstract void FireUpdate();
|
||||
|
||||
// protected void OnOutputChange()
|
||||
// {
|
||||
// if (OutputChange != null) OutputChange(this, EventArgs.Empty);
|
||||
// }
|
||||
// }
|
||||
|
||||
// public class BoolFeedbackLocalStorage
|
||||
// {
|
||||
// public bool BoolValue
|
||||
// {
|
||||
// get { return Output.BoolValue; }
|
||||
// set
|
||||
// {
|
||||
|
||||
// }
|
||||
// }
|
||||
// public BoolFeedback Output { get; private set; }
|
||||
|
||||
// public BoolFeedbackLocalStorage(BoolFeedback bo)
|
||||
// {
|
||||
// Output = bo;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// public class BoolFeedback : Feedback
|
||||
// {
|
||||
// public override bool BoolValue { get { return ValueFunc.Invoke(); } }
|
||||
|
||||
// public override eCueType Type { get { return eCueType.Bool; } }
|
||||
|
||||
// public Func<bool> ValueFunc { get; private set; }
|
||||
// List<BoolInputSig> LinkedInputSigs = new List<BoolInputSig>();
|
||||
// List<BoolInputSig> LinkedComplementInputSigs = new List<BoolInputSig>();
|
||||
|
||||
// public BoolFeedback(Func<bool> valueFunc)
|
||||
// : this(Cue.DefaultBoolCue, valueFunc)
|
||||
// {
|
||||
// }
|
||||
|
||||
// public BoolFeedback(Cue cue, Func<bool> valueFunc)
|
||||
// : base(cue)
|
||||
// {
|
||||
// if (cue == null) throw new ArgumentNullException("cue");
|
||||
// ValueFunc = valueFunc;
|
||||
// }
|
||||
|
||||
// public override void FireUpdate()
|
||||
// {
|
||||
// LinkedInputSigs.ForEach(s => UpdateSig(s));
|
||||
// LinkedComplementInputSigs.ForEach(s => UpdateComplementSig(s));
|
||||
// OnOutputChange();
|
||||
// }
|
||||
|
||||
// public void LinkInputSig(BoolInputSig sig)
|
||||
// {
|
||||
// LinkedInputSigs.Add(sig);
|
||||
// UpdateSig(sig);
|
||||
// }
|
||||
|
||||
// public void UnlinkInputSig(BoolInputSig sig)
|
||||
// {
|
||||
// LinkedInputSigs.Remove(sig);
|
||||
// }
|
||||
|
||||
// public void LinkComplementInputSig(BoolInputSig sig)
|
||||
// {
|
||||
// LinkedComplementInputSigs.Add(sig);
|
||||
// UpdateComplementSig(sig);
|
||||
// }
|
||||
|
||||
// public void UnlinkComplementInputSig(BoolInputSig sig)
|
||||
// {
|
||||
// LinkedComplementInputSigs.Remove(sig);
|
||||
// }
|
||||
|
||||
// void UpdateSig(BoolInputSig sig)
|
||||
// {
|
||||
// sig.BoolValue = ValueFunc.Invoke();
|
||||
// }
|
||||
|
||||
// void UpdateComplementSig(BoolInputSig sig)
|
||||
// {
|
||||
// sig.BoolValue = !ValueFunc.Invoke();
|
||||
// }
|
||||
// }
|
||||
|
||||
// //******************************************************************************
|
||||
// public class IntFeedback : Feedback
|
||||
// {
|
||||
// public override int IntValue { get { return ValueFunc.Invoke(); } }
|
||||
// public ushort UShortValue { get { return (ushort)ValueFunc.Invoke(); } }
|
||||
// public override eCueType Type { get { return eCueType.Int; } }
|
||||
|
||||
// Func<int> ValueFunc;
|
||||
// List<UShortInputSig> LinkedInputSigs = new List<UShortInputSig>();
|
||||
|
||||
// public IntFeedback(Func<int> valueFunc)
|
||||
// : this(Cue.DefaultIntCue, valueFunc)
|
||||
// {
|
||||
// }
|
||||
|
||||
// public IntFeedback(Cue cue, Func<int> valueFunc)
|
||||
// : base(cue)
|
||||
// {
|
||||
// if (cue == null) throw new ArgumentNullException("cue");
|
||||
// ValueFunc = valueFunc;
|
||||
// }
|
||||
|
||||
// public override void FireUpdate()
|
||||
// {
|
||||
// LinkedInputSigs.ForEach(s => UpdateSig(s));
|
||||
// OnOutputChange();
|
||||
// }
|
||||
|
||||
// public void LinkInputSig(UShortInputSig sig)
|
||||
// {
|
||||
// LinkedInputSigs.Add(sig);
|
||||
// UpdateSig(sig);
|
||||
// }
|
||||
|
||||
// public void UnlinkInputSig(UShortInputSig sig)
|
||||
// {
|
||||
// LinkedInputSigs.Remove(sig);
|
||||
// }
|
||||
|
||||
// void UpdateSig(UShortInputSig sig)
|
||||
// {
|
||||
// sig.UShortValue = this.UShortValue;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// //******************************************************************************
|
||||
// public class StringFeedback : Feedback
|
||||
// {
|
||||
// public override string StringValue { get { return ValueFunc.Invoke(); } }
|
||||
// public override eCueType Type { get { return eCueType.String; } }
|
||||
|
||||
// public Func<string> ValueFunc { get; private set; }
|
||||
// List<StringInputSig> LinkedInputSigs = new List<StringInputSig>();
|
||||
|
||||
// public StringFeedback(Func<string> valueFunc)
|
||||
// : this(Cue.DefaultStringCue, valueFunc)
|
||||
// {
|
||||
// }
|
||||
|
||||
// public StringFeedback(Cue cue, Func<string> valueFunc)
|
||||
// : base(cue)
|
||||
// {
|
||||
// if (cue == null) throw new ArgumentNullException("cue");
|
||||
// ValueFunc = valueFunc;
|
||||
|
||||
// }
|
||||
|
||||
// public override void FireUpdate()
|
||||
// {
|
||||
// LinkedInputSigs.ForEach(s => UpdateSig(s));
|
||||
// OnOutputChange();
|
||||
// }
|
||||
|
||||
// public void LinkInputSig(StringInputSig sig)
|
||||
// {
|
||||
// LinkedInputSigs.Add(sig);
|
||||
// UpdateSig(sig);
|
||||
// }
|
||||
|
||||
// public void UnlinkInputSig(StringInputSig sig)
|
||||
// {
|
||||
// LinkedInputSigs.Remove(sig);
|
||||
// }
|
||||
|
||||
// void UpdateSig(StringInputSig sig)
|
||||
// {
|
||||
// sig.StringValue = ValueFunc.Invoke();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
189
Pepperdash Core/Pepperdash Core/GenericTcpIpClient.cs
Normal file
189
Pepperdash Core/Pepperdash Core/GenericTcpIpClient.cs
Normal file
@@ -0,0 +1,189 @@
|
||||
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 GenericTcpIpClient : Device, IBasicCommunication
|
||||
{
|
||||
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||
|
||||
public bool IsConnected { get { return Client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } }
|
||||
public string Status { get { return Client.ClientStatus.ToString(); } }
|
||||
public string ConnectionFailure { get { return Client.ClientStatus.ToString(); } }
|
||||
|
||||
public bool Connected
|
||||
{
|
||||
get { return Client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; }
|
||||
}
|
||||
|
||||
TCPClient Client;
|
||||
CTimer RetryTimer;
|
||||
|
||||
public GenericTcpIpClient(string key, string address, int port, int bufferSize)
|
||||
: base(key)
|
||||
{
|
||||
Client = new TCPClient(address, port, bufferSize);
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
Client.SocketStatusChange += new TCPClientSocketStatusChangeEventHandler(Client_SocketStatusChange);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Deactivate()
|
||||
{
|
||||
Client.SocketStatusChange -= this.Client_SocketStatusChange;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Connect()
|
||||
{
|
||||
Client.ConnectToServerAsync(null);
|
||||
}
|
||||
|
||||
public void Disconnnect()
|
||||
{
|
||||
Client.DisconnectFromServer();
|
||||
}
|
||||
|
||||
void ConnectToServerCallback(TCPClient c)
|
||||
{
|
||||
if (c.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
|
||||
WaitAndTryReconnect();
|
||||
}
|
||||
|
||||
void WaitAndTryReconnect()
|
||||
{
|
||||
Client.DisconnectFromServer();
|
||||
Debug.Console(2, "Attempting reconnect, status={0}", Client.ClientStatus);
|
||||
RetryTimer = new CTimer(o => { Client.ConnectToServerAsync(ConnectToServerCallback); }, 1000);
|
||||
}
|
||||
|
||||
void Receive(TCPClient client, int numBytes)
|
||||
{
|
||||
if (numBytes > 0)
|
||||
{
|
||||
var bytes = client.IncomingDataBuffer.Take(numBytes).ToArray();
|
||||
//if (Debug.Level == 2)
|
||||
// Debug.Console(2, this, "Received: {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
||||
var bytesHandler = BytesReceived;
|
||||
if (bytesHandler != null)
|
||||
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));
|
||||
}
|
||||
}
|
||||
Client.ReceiveDataAsync(Receive);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// General send method
|
||||
/// </summary>
|
||||
public void SendText(string text)
|
||||
{
|
||||
var bytes = Encoding.GetEncoding(28591).GetBytes(text);
|
||||
// Check debug level before processing byte array
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
||||
Client.SendData(bytes, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is useful from console and...?
|
||||
/// </summary>
|
||||
public void SendEscapedText(string text)
|
||||
{
|
||||
//if (Client.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED)
|
||||
// Connect();
|
||||
var unescapedText = Regex.Replace(text, @"\\x([0-9a-fA-F][0-9a-fA-F])", s =>
|
||||
{
|
||||
var hex = s.Groups[1].Value;
|
||||
return ((char)Convert.ToByte(hex, 16)).ToString();
|
||||
});
|
||||
SendText(unescapedText);
|
||||
|
||||
//var bytes = Encoding.GetEncoding(28591).GetBytes(unescapedText);
|
||||
//Debug.Console(2, this, "Sending {0} bytes: '{1}'", bytes.Length, text);
|
||||
//Client.SendData(bytes, bytes.Length);
|
||||
}
|
||||
|
||||
public void SendBytes(byte[] bytes)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
||||
Client.SendData(bytes, bytes.Length);
|
||||
}
|
||||
|
||||
|
||||
void Client_SocketStatusChange(TCPClient client, SocketStatus clientSocketStatus)
|
||||
{
|
||||
if (client.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED &&
|
||||
client.ClientStatus != SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY)
|
||||
WaitAndTryReconnect();
|
||||
|
||||
|
||||
Debug.Console(2, this, "Socket status change {0}", clientSocketStatus);
|
||||
switch (clientSocketStatus)
|
||||
{
|
||||
case SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_BROKEN_REMOTELY:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_CONNECTED:
|
||||
Client.ReceiveDataAsync(Receive);
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_CONNECT_FAILED:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_DNS_FAILED:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_DNS_LOOKUP:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_DNS_RESOLVED:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_LINK_LOST:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_NO_CONNECT:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_SOCKET_NOT_EXIST:
|
||||
break;
|
||||
case SocketStatus.SOCKET_STATUS_WAITING:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TcpIpConfig
|
||||
{
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
public string Address { get; set; }
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defaults to 32768
|
||||
/// </summary>
|
||||
public int BufferSize { get; set; }
|
||||
|
||||
public TcpIpConfig()
|
||||
{
|
||||
BufferSize = 32768;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
53
Pepperdash Core/Pepperdash Core/IHasFeedbacks.cs
Normal file
53
Pepperdash Core/Pepperdash Core/IHasFeedbacks.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
|
||||
//namespace PepperDash.Core
|
||||
//{
|
||||
// public interface IHasFeedback : IKeyed
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// This method shall return a list of all Output objects on a device,
|
||||
// /// including all "aggregate" devices.
|
||||
// /// </summary>
|
||||
// List<Feedback> Feedbacks { get; }
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// public static class IHasFeedbackExtensions
|
||||
// {
|
||||
// public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
|
||||
// {
|
||||
// var outputs = source.Feedbacks.OrderBy(x => x.Type);
|
||||
// if (outputs != null)
|
||||
// {
|
||||
// Debug.Console(0, source, "\n\nAvailable outputs:");
|
||||
// foreach (var o in outputs)
|
||||
// {
|
||||
// string val = "";
|
||||
// if (getCurrentStates)
|
||||
// {
|
||||
// switch (o.Type)
|
||||
// {
|
||||
// case eCueType.Bool:
|
||||
// val = " = " + o.BoolValue;
|
||||
// break;
|
||||
// case eCueType.Int:
|
||||
// val = " = " + o.IntValue;
|
||||
// break;
|
||||
// case eCueType.String:
|
||||
// val = " = " + o.StringValue;
|
||||
// break;
|
||||
// //case eOutputType.Other:
|
||||
// // break;
|
||||
// }
|
||||
// }
|
||||
// Debug.Console(0, "{0,-8} {1,5} {2}{3}", o.Type, o.Cue.Number,
|
||||
// (string.IsNullOrEmpty(o.Cue.Name) ? "-none-" : o.Cue.Name), val);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// Debug.Console(0, source, "No available outputs:");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
96
Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj
Normal file
96
Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj
Normal file
@@ -0,0 +1,96 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{87E29B4C-569B-4368-A4ED-984AC1440C96}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>PepperDash_Core</RootNamespace>
|
||||
<AssemblyName>PepperDash_Core</AssemblyName>
|
||||
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92500};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PlatformFamilyName>WindowsCE</PlatformFamilyName>
|
||||
<PlatformID>E2BECB1F-8C8C-41ba-B736-9BE7D946A398</PlatformID>
|
||||
<OSVersion>5.0</OSVersion>
|
||||
<DeployDirSuffix>SmartDeviceProject1</DeployDirSuffix>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<NativePlatformName>Windows CE</NativePlatformName>
|
||||
<FormFactorID>
|
||||
</FormFactorID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<AllowedReferenceRelatedFileExtensions>.allowedReferenceRelatedFileExtensions</AllowedReferenceRelatedFileExtensions>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<NoConfig>true</NoConfig>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<AllowedReferenceRelatedFileExtensions>.allowedReferenceRelatedFileExtensions</AllowedReferenceRelatedFileExtensions>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<NoConfig>true</NoConfig>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="Newtonsoft.Json.Compact, Version=3.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\Newtonsoft.Json.Compact.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CommunicationExtras.cs" />
|
||||
<Compile Include="CoreInterfaces.cs" />
|
||||
<Compile Include="Debug.cs" />
|
||||
<Compile Include="Device.cs" />
|
||||
<Compile Include="EthernetHelper.cs" />
|
||||
<Compile Include="Feedbacks HAS SSP LINKS.cs" />
|
||||
<Compile Include="GenericTcpIpClient.cs" />
|
||||
<Compile Include="IHasFeedbacks.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<None Include="Properties\ControlSystem.cfg" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{0B4745B0-194B-4BB6-8E21-E9057CA92500}">
|
||||
<ProgramIdTag>PepperDash_Core</ProgramIdTag>
|
||||
<SystemName>PepperDash_Core</SystemName>
|
||||
<Programmer />
|
||||
<ArchiveFilename>C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\Pepperdash_Core.clz</ArchiveFilename>
|
||||
<MinFirmwareVersion>1.007.0017</MinFirmwareVersion>
|
||||
<CompiledOn>6/15/2016 10:01:37 AM</CompiledOn>
|
||||
<AdditionalInfo />
|
||||
<EmbedSourceArchive>False</EmbedSourceArchive>
|
||||
<CopyTo />
|
||||
<OriginalReferenceSources />
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>rem S# preparation will execute after these operations</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyTitle("Pepperdash_Core")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Pepperdash_Core")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyVersion("1.0.0.*")]
|
||||
|
||||
BIN
Pepperdash Core/Pepperdash Core/bin/PepperDash_Core.clz
Normal file
BIN
Pepperdash Core/Pepperdash Core/bin/PepperDash_Core.clz
Normal file
Binary file not shown.
16
Pepperdash Core/Pepperdash Core/bin/PepperDash_Core.config
Normal file
16
Pepperdash Core/Pepperdash Core/bin/PepperDash_Core.config
Normal file
@@ -0,0 +1,16 @@
|
||||
<ProgramInfo>
|
||||
<RequiredInfo>
|
||||
<FriendlyName>PepperDash_Core</FriendlyName>
|
||||
<SystemName>PepperDash_Core</SystemName>
|
||||
<EntryPoint>PepperDash_Core</EntryPoint>
|
||||
<MinFirmwareVersion>1.007.0017</MinFirmwareVersion>
|
||||
<ProgramTool>SIMPL# Plugin</ProgramTool>
|
||||
<DesignToolId>5</DesignToolId>
|
||||
<ProgramToolId>5</ProgramToolId>
|
||||
<ArchiveName />
|
||||
</RequiredInfo>
|
||||
<OptionalInfo>
|
||||
<CompiledOn>6/15/2016 10:01:37 AM</CompiledOn>
|
||||
<CompilerRev>1.0.0.16248</CompilerRev>
|
||||
</OptionalInfo>
|
||||
</ProgramInfo>
|
||||
BIN
Pepperdash Core/Pepperdash Core/bin/SimplSharpData.dat
Normal file
BIN
Pepperdash Core/Pepperdash Core/bin/SimplSharpData.dat
Normal file
Binary file not shown.
14
Pepperdash Core/Pepperdash Core/bin/manifest.info
Normal file
14
Pepperdash Core/Pepperdash Core/bin/manifest.info
Normal file
@@ -0,0 +1,14 @@
|
||||
MainAssembly=PepperDash_Core.dll:92b05d53de3375de2f6efeacaf9dd897
|
||||
MainAssemblyMinFirmwareVersion=1.007.0017
|
||||
ü
|
||||
DependencySource=Newtonsoft.Json.Compact.dll:ea996aa2ec65aa1878e7c9d09e37a896
|
||||
DependencyPath=PepperDash_Core.clz:Newtonsoft.Json.Compact.dll
|
||||
DependencyMainAssembly=Newtonsoft.Json.Compact.dll:ea996aa2ec65aa1878e7c9d09e37a896
|
||||
ü
|
||||
DependencySource=SimplSharpCustomAttributesInterface.dll:9c4b4d4c519b655af90016edca2d66b9
|
||||
DependencyPath=PepperDash_Core.clz:SimplSharpCustomAttributesInterface.dll
|
||||
DependencyMainAssembly=SimplSharpCustomAttributesInterface.dll:9c4b4d4c519b655af90016edca2d66b9
|
||||
ü
|
||||
DependencySource=SimplSharpHelperInterface.dll:aed72eb0e19559a3f56708be76445dcd
|
||||
DependencyPath=PepperDash_Core.clz:SimplSharpHelperInterface.dll
|
||||
DependencyMainAssembly=SimplSharpHelperInterface.dll:aed72eb0e19559a3f56708be76445dcd
|
||||
BIN
Pepperdash Core/Pepperdash Core/bin/manifest.ser
Normal file
BIN
Pepperdash Core/Pepperdash Core/bin/manifest.ser
Normal file
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\obj\Debug\ResolveAssemblyReference.cache
|
||||
C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\SimplSharpCustomAttributesInterface.dll
|
||||
C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\SimplSharpHelperInterface.dll
|
||||
C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\Newtonsoft.Json.Compact.dll
|
||||
C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.dll
|
||||
C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\bin\PepperDash_Core.pdb
|
||||
C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\obj\Debug\PepperDash_Core.dll
|
||||
C:\Users\hvolm\Desktop\working\pepperdash-simplsharp-core\Pepperdash Core\Pepperdash Core\obj\Debug\PepperDash_Core.pdb
|
||||
Reference in New Issue
Block a user