Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion src/PepperDash.Essentials.Core/Devices/DeviceJsonApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace PepperDash.Essentials.Core
Expand Down Expand Up @@ -176,7 +177,20 @@ private static object ConvertType(object value, Type conversionType)
{
if (!conversionType.IsEnum)
{
return Convert.ChangeType(value, conversionType, System.Globalization.CultureInfo.InvariantCulture);
if (conversionType == typeof(byte[]) && value is string byteString)
{
var unescaped = UnescapeString(byteString);
return System.Text.Encoding.GetEncoding(28591).GetBytes(unescaped);
}

var converted = Convert.ChangeType(value, conversionType, System.Globalization.CultureInfo.InvariantCulture);

if (conversionType == typeof(string) && converted is string s)
{
return UnescapeString(s);
}

return converted;
}

var stringValue = Convert.ToString(value);
Expand All @@ -189,6 +203,32 @@ private static object ConvertType(object value, Type conversionType)
return Enum.Parse(conversionType, stringValue, true);
}

/// <summary>
/// Processes escape sequences in a string, converting sequences like \r, \n, \t, \xHH
/// to their corresponding non-printable ASCII characters.
/// </summary>
private static string UnescapeString(string input)
Comment thread
ndorin marked this conversation as resolved.
{
if (string.IsNullOrEmpty(input))
return input;

return Regex.Replace(input, @"\\(r|n|t|\\|x[0-9A-Fa-f]{2})", match =>
{
var seq = match.Groups[1].Value;
switch (seq)
{
case "r": return "\r";
case "n": return "\n";
case "t": return "\t";
case "\\": return "\\";
default:
// \xHH hex escape
var hex = seq.Substring(1);
return ((char)Convert.ToInt32(hex, 16)).ToString();
}
});
}

/// <summary>
/// Gets the properties on a device
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,36 @@ protected override void HandleGet(Crestron.SimplSharp.WebScripting.HttpCwsContex
// Start the WS Server
Debug.WebsocketSink.StartServerAndSetPort(port);
Debug.SetWebSocketMinimumDebugLevel(Serilog.Events.LogEventLevel.Verbose);

// Attempt to forward the port to the CS LAN
try
{
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(
EthernetAdapterType.EthernetCSAdapter);
var csIp = CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);

var result = CrestronEthernetHelper.AddPortForwarding(
(ushort)port, (ushort)port, csIp,
CrestronEthernetHelper.ePortMapTransport.TCP);
Comment thread
ndorin marked this conversation as resolved.

if (result != CrestronEthernetHelper.PortForwardingUserPatRetCodes.NoErr)
{
Debug.LogMessage(LogEventLevel.Warning, "Error adding port forwarding for debug websocket: {0}", result);
}
else
{
Debug.LogMessage(LogEventLevel.Information, "Port {0} forwarded to CS LAN for debug websocket", port);
}
}
catch (ArgumentException)
{
Debug.LogMessage(LogEventLevel.Debug, "This processor does not have a CS LAN adapter; skipping port forwarding");
}
catch (Exception ex)
{
Debug.LogMessage(LogEventLevel.Warning, "Error automatically forwarding debug websocket port to CS LAN: {0}", ex.Message);
}
}

var url = Debug.WebsocketSink.Url;
Expand Down Expand Up @@ -90,8 +120,47 @@ protected override void HandleGet(Crestron.SimplSharp.WebScripting.HttpCwsContex
/// <param name="context"></param>
protected override void HandlePost(HttpCwsContext context)
{
var port = Debug.WebsocketSink.Port;

Debug.WebsocketSink.StopServer();

// Remove the port forwarding entry
try
{
var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(
EthernetAdapterType.EthernetCSAdapter);
var csIp = CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId);

if (port <= 0)
{
Debug.LogMessage(LogEventLevel.Debug, "Debug websocket port is not set; skipping port forwarding removal");
}
else
{
var result = CrestronEthernetHelper.RemovePortForwarding(
(ushort)port, (ushort)port, csIp,
CrestronEthernetHelper.ePortMapTransport.TCP);

if (result != CrestronEthernetHelper.PortForwardingUserPatRetCodes.NoErr)
{
Debug.LogMessage(LogEventLevel.Warning, "Error removing port forwarding for debug websocket: {0}", result);
}
else
{
Debug.LogMessage(LogEventLevel.Information, "Port forwarding for port {0} removed", port);
}
}
}
catch (ArgumentException)
{
Debug.LogMessage(LogEventLevel.Debug, "This processor does not have a CS LAN adapter; skipping port forwarding removal");
}
catch (Exception ex)
{
Debug.LogMessage(LogEventLevel.Warning, "Error removing debug websocket port forwarding: {0}", ex.Message);
}

context.Response.StatusCode = 200;
context.Response.StatusDescription = "OK";
context.Response.End();
Expand Down