mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-31 21:34:58 +00:00
chore: move all files to file-scoped namespace
This commit is contained in:
@@ -1,19 +1,18 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
public class AuthorizationResponse
|
||||
{
|
||||
public class AuthorizationResponse
|
||||
{
|
||||
[JsonProperty("authorized")]
|
||||
public bool Authorized { get; set; }
|
||||
[JsonProperty("authorized")]
|
||||
public bool Authorized { get; set; }
|
||||
|
||||
[JsonProperty("reason", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Reason { get; set; } = null;
|
||||
}
|
||||
|
||||
public class AuthorizationRequest
|
||||
{
|
||||
[JsonProperty("grantCode")]
|
||||
public string GrantCode { get; set; }
|
||||
}
|
||||
[JsonProperty("reason", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Reason { get; set; } = null;
|
||||
}
|
||||
|
||||
public class AuthorizationRequest
|
||||
{
|
||||
[JsonProperty("grantCode")]
|
||||
public string GrantCode { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a room whose configuration is derived from runtime data,
|
||||
/// perhaps from another program, and that the data may not be fully
|
||||
/// available at startup.
|
||||
/// </summary>
|
||||
public interface IDelayedConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a room whose configuration is derived from runtime data,
|
||||
/// perhaps from another program, and that the data may not be fully
|
||||
/// available at startup.
|
||||
/// </summary>
|
||||
public interface IDelayedConfiguration
|
||||
{
|
||||
|
||||
|
||||
event EventHandler<EventArgs> ConfigurationIsReady;
|
||||
}
|
||||
event EventHandler<EventArgs> ConfigurationIsReady;
|
||||
}
|
||||
@@ -2,18 +2,17 @@
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
public class MobileControlAction : IMobileControlAction
|
||||
{
|
||||
public class MobileControlAction : IMobileControlAction
|
||||
public IMobileControlMessenger Messenger { get; private set; }
|
||||
|
||||
public Action<string, string, JToken> Action { get; private set; }
|
||||
|
||||
public MobileControlAction(IMobileControlMessenger messenger, Action<string, string, JToken> handler)
|
||||
{
|
||||
public IMobileControlMessenger Messenger { get; private set; }
|
||||
|
||||
public Action<string, string, JToken> Action { get; private set; }
|
||||
|
||||
public MobileControlAction(IMobileControlMessenger messenger, Action<string, string, JToken> handler)
|
||||
{
|
||||
Messenger = messenger;
|
||||
Action = handler;
|
||||
}
|
||||
Messenger = messenger;
|
||||
Action = handler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,143 +2,142 @@
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MobileControlConfig
|
||||
{
|
||||
[JsonProperty("serverUrl")]
|
||||
public string ServerUrl { get; set; }
|
||||
|
||||
[JsonProperty("clientAppUrl")]
|
||||
public string ClientAppUrl { get; set; }
|
||||
|
||||
[JsonProperty("directServer")]
|
||||
public MobileControlDirectServerPropertiesConfig DirectServer { get; set; }
|
||||
|
||||
[JsonProperty("applicationConfig")]
|
||||
public MobileControlApplicationConfig ApplicationConfig { get; set; } = null;
|
||||
|
||||
[JsonProperty("enableApiServer")]
|
||||
public bool EnableApiServer { get; set; } = true;
|
||||
}
|
||||
|
||||
public class MobileControlDirectServerPropertiesConfig
|
||||
{
|
||||
[JsonProperty("enableDirectServer")]
|
||||
public bool EnableDirectServer { get; set; }
|
||||
|
||||
[JsonProperty("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
[JsonProperty("logging")]
|
||||
public MobileControlLoggingConfig Logging { get; set; }
|
||||
|
||||
[JsonProperty("automaticallyForwardPortToCSLAN")]
|
||||
public bool? AutomaticallyForwardPortToCSLAN { get; set; }
|
||||
|
||||
public MobileControlDirectServerPropertiesConfig()
|
||||
{
|
||||
Logging = new MobileControlLoggingConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileControlLoggingConfig
|
||||
{
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
public bool EnableRemoteLogging { get; set; }
|
||||
|
||||
[JsonProperty("host")]
|
||||
public string Host { get; set; }
|
||||
|
||||
[JsonProperty("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class MobileControlRoomBridgePropertiesConfig
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MobileControlSimplRoomBridgePropertiesConfig
|
||||
{
|
||||
[JsonProperty("eiscId")]
|
||||
public string EiscId { get; set; }
|
||||
}
|
||||
|
||||
public class MobileControlApplicationConfig
|
||||
{
|
||||
[JsonProperty("apiPath")]
|
||||
public string ApiPath { get; set; }
|
||||
|
||||
[JsonProperty("gatewayAppPath")]
|
||||
public string GatewayAppPath { get; set; }
|
||||
|
||||
[JsonProperty("enableDev")]
|
||||
public bool? EnableDev { get; set; }
|
||||
|
||||
[JsonProperty("logoPath")]
|
||||
/// <summary>
|
||||
///
|
||||
/// Client logo to be used in header and/or splash screen
|
||||
/// </summary>
|
||||
public class MobileControlConfig
|
||||
{
|
||||
[JsonProperty("serverUrl")]
|
||||
public string ServerUrl { get; set; }
|
||||
public string LogoPath { get; set; }
|
||||
|
||||
[JsonProperty("clientAppUrl")]
|
||||
public string ClientAppUrl { get; set; }
|
||||
[JsonProperty("iconSet")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MCIconSet? IconSet { get; set; }
|
||||
|
||||
[JsonProperty("directServer")]
|
||||
public MobileControlDirectServerPropertiesConfig DirectServer { get; set; }
|
||||
[JsonProperty("loginMode")]
|
||||
public string LoginMode { get; set; }
|
||||
|
||||
[JsonProperty("applicationConfig")]
|
||||
public MobileControlApplicationConfig ApplicationConfig { get; set; } = null;
|
||||
[JsonProperty("modes")]
|
||||
public Dictionary<string, McMode> Modes { get; set; }
|
||||
|
||||
[JsonProperty("enableApiServer")]
|
||||
public bool EnableApiServer { get; set; } = true;
|
||||
}
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
public bool Logging { get; set; }
|
||||
|
||||
public class MobileControlDirectServerPropertiesConfig
|
||||
{
|
||||
[JsonProperty("enableDirectServer")]
|
||||
public bool EnableDirectServer { get; set; }
|
||||
[JsonProperty("partnerMetadata", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<MobileControlPartnerMetadata> PartnerMetadata { get; set; }
|
||||
}
|
||||
|
||||
[JsonProperty("port")]
|
||||
public int Port { get; set; }
|
||||
public class MobileControlPartnerMetadata
|
||||
{
|
||||
[JsonProperty("role")]
|
||||
public string Role { get; set; }
|
||||
|
||||
[JsonProperty("logging")]
|
||||
public MobileControlLoggingConfig Logging { get; set; }
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty("automaticallyForwardPortToCSLAN")]
|
||||
public bool? AutomaticallyForwardPortToCSLAN { get; set; }
|
||||
[JsonProperty("logoPath")]
|
||||
public string LogoPath { get; set; }
|
||||
}
|
||||
|
||||
public MobileControlDirectServerPropertiesConfig()
|
||||
{
|
||||
Logging = new MobileControlLoggingConfig();
|
||||
}
|
||||
}
|
||||
public class McMode
|
||||
{
|
||||
[JsonProperty("listPageText")]
|
||||
public string ListPageText { get; set; }
|
||||
[JsonProperty("loginHelpText")]
|
||||
public string LoginHelpText { get; set; }
|
||||
|
||||
public class MobileControlLoggingConfig
|
||||
{
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
public bool EnableRemoteLogging { get; set; }
|
||||
[JsonProperty("passcodePageText")]
|
||||
public string PasscodePageText { get; set; }
|
||||
}
|
||||
|
||||
[JsonProperty("host")]
|
||||
public string Host { get; set; }
|
||||
|
||||
[JsonProperty("port")]
|
||||
public int Port { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class MobileControlRoomBridgePropertiesConfig
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MobileControlSimplRoomBridgePropertiesConfig
|
||||
{
|
||||
[JsonProperty("eiscId")]
|
||||
public string EiscId { get; set; }
|
||||
}
|
||||
|
||||
public class MobileControlApplicationConfig
|
||||
{
|
||||
[JsonProperty("apiPath")]
|
||||
public string ApiPath { get; set; }
|
||||
|
||||
[JsonProperty("gatewayAppPath")]
|
||||
public string GatewayAppPath { get; set; }
|
||||
|
||||
[JsonProperty("enableDev")]
|
||||
public bool? EnableDev { get; set; }
|
||||
|
||||
[JsonProperty("logoPath")]
|
||||
/// <summary>
|
||||
/// Client logo to be used in header and/or splash screen
|
||||
/// </summary>
|
||||
public string LogoPath { get; set; }
|
||||
|
||||
[JsonProperty("iconSet")]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public MCIconSet? IconSet { get; set; }
|
||||
|
||||
[JsonProperty("loginMode")]
|
||||
public string LoginMode { get; set; }
|
||||
|
||||
[JsonProperty("modes")]
|
||||
public Dictionary<string, McMode> Modes { get; set; }
|
||||
|
||||
[JsonProperty("enableRemoteLogging")]
|
||||
public bool Logging { get; set; }
|
||||
|
||||
[JsonProperty("partnerMetadata", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<MobileControlPartnerMetadata> PartnerMetadata { get; set; }
|
||||
}
|
||||
|
||||
public class MobileControlPartnerMetadata
|
||||
{
|
||||
[JsonProperty("role")]
|
||||
public string Role { get; set; }
|
||||
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty("logoPath")]
|
||||
public string LogoPath { get; set; }
|
||||
}
|
||||
|
||||
public class McMode
|
||||
{
|
||||
[JsonProperty("listPageText")]
|
||||
public string ListPageText { get; set; }
|
||||
[JsonProperty("loginHelpText")]
|
||||
public string LoginHelpText { get; set; }
|
||||
|
||||
[JsonProperty("passcodePageText")]
|
||||
public string PasscodePageText { get; set; }
|
||||
}
|
||||
|
||||
public enum MCIconSet
|
||||
{
|
||||
GOOGLE,
|
||||
HABANERO,
|
||||
NEO
|
||||
}
|
||||
public enum MCIconSet
|
||||
{
|
||||
GOOGLE,
|
||||
HABANERO,
|
||||
NEO
|
||||
}
|
||||
@@ -8,27 +8,26 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class MobileControlDeviceFactory : EssentialsDeviceFactory<MobileControlSystemController>
|
||||
{
|
||||
public MobileControlDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "appserver", "mobilecontrol", "webserver" };
|
||||
}
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
public class MobileControlDeviceFactory : EssentialsDeviceFactory<MobileControlSystemController>
|
||||
{
|
||||
public MobileControlDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "appserver", "mobilecontrol", "webserver" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var props = dc.Properties.ToObject<MobileControlConfig>();
|
||||
return new MobileControlSystemController(dc.Key, dc.Name, props);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(e, "Error building Mobile Control System Controller");
|
||||
return null;
|
||||
}
|
||||
var props = dc.Properties.ToObject<MobileControlConfig>();
|
||||
return new MobileControlSystemController(dc.Key, dc.Name, props);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogMessage(e, "Error building Mobile Control System Controller");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,52 +3,51 @@ using PepperDash.Essentials.Core.Config;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
/// <summary>
|
||||
/// Used to overlay additional config data from mobile control on
|
||||
/// </summary>
|
||||
public class MobileControlEssentialsConfig : EssentialsConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to overlay additional config data from mobile control on
|
||||
/// </summary>
|
||||
public class MobileControlEssentialsConfig : EssentialsConfig
|
||||
[JsonProperty("runtimeInfo")]
|
||||
public MobileControlRuntimeInfo RuntimeInfo { get; set; }
|
||||
|
||||
public MobileControlEssentialsConfig(EssentialsConfig config)
|
||||
: base()
|
||||
{
|
||||
[JsonProperty("runtimeInfo")]
|
||||
public MobileControlRuntimeInfo RuntimeInfo { get; set; }
|
||||
// TODO: Consider using Reflection to iterate properties
|
||||
this.Devices = config.Devices;
|
||||
this.Info = config.Info;
|
||||
this.JoinMaps = config.JoinMaps;
|
||||
this.Rooms = config.Rooms;
|
||||
this.SourceLists = config.SourceLists;
|
||||
this.DestinationLists = config.DestinationLists;
|
||||
this.SystemUrl = config.SystemUrl;
|
||||
this.TemplateUrl = config.TemplateUrl;
|
||||
this.TieLines = config.TieLines;
|
||||
|
||||
public MobileControlEssentialsConfig(EssentialsConfig config)
|
||||
: base()
|
||||
{
|
||||
// TODO: Consider using Reflection to iterate properties
|
||||
this.Devices = config.Devices;
|
||||
this.Info = config.Info;
|
||||
this.JoinMaps = config.JoinMaps;
|
||||
this.Rooms = config.Rooms;
|
||||
this.SourceLists = config.SourceLists;
|
||||
this.DestinationLists = config.DestinationLists;
|
||||
this.SystemUrl = config.SystemUrl;
|
||||
this.TemplateUrl = config.TemplateUrl;
|
||||
this.TieLines = config.TieLines;
|
||||
if (this.Info == null)
|
||||
this.Info = new InfoConfig();
|
||||
|
||||
if (this.Info == null)
|
||||
this.Info = new InfoConfig();
|
||||
|
||||
RuntimeInfo = new MobileControlRuntimeInfo();
|
||||
}
|
||||
RuntimeInfo = new MobileControlRuntimeInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to add any additional runtime information from mobile control to be send to the API
|
||||
/// </summary>
|
||||
public class MobileControlRuntimeInfo
|
||||
{
|
||||
[JsonProperty("pluginVersion")]
|
||||
public string PluginVersion { get; set; }
|
||||
/// <summary>
|
||||
/// Used to add any additional runtime information from mobile control to be send to the API
|
||||
/// </summary>
|
||||
public class MobileControlRuntimeInfo
|
||||
{
|
||||
[JsonProperty("pluginVersion")]
|
||||
public string PluginVersion { get; set; }
|
||||
|
||||
[JsonProperty("essentialsVersion")]
|
||||
public string EssentialsVersion { get; set; }
|
||||
[JsonProperty("essentialsVersion")]
|
||||
public string EssentialsVersion { get; set; }
|
||||
|
||||
[JsonProperty("pepperDashCoreVersion")]
|
||||
public string PepperDashCoreVersion { get; set; }
|
||||
[JsonProperty("pepperDashCoreVersion")]
|
||||
public string PepperDashCoreVersion { get; set; }
|
||||
|
||||
[JsonProperty("essentialsPlugins")]
|
||||
public List<LoadedAssembly> EssentialsPlugins { get; set; }
|
||||
}
|
||||
[JsonProperty("essentialsPlugins")]
|
||||
public List<LoadedAssembly> EssentialsPlugins { get; set; }
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,127 +5,126 @@ using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using System;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.RoomBridges
|
||||
namespace PepperDash.Essentials.RoomBridges;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class MobileControlBridgeBase : MessengerBase, IMobileControlRoomMessenger
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class MobileControlBridgeBase : MessengerBase, IMobileControlRoomMessenger
|
||||
public event EventHandler<EventArgs> UserCodeChanged;
|
||||
|
||||
public event EventHandler<EventArgs> UserPromptedForCode;
|
||||
|
||||
public event EventHandler<EventArgs> ClientJoined;
|
||||
|
||||
public event EventHandler<EventArgs> AppUrlChanged;
|
||||
|
||||
public IMobileControl Parent { get; private set; }
|
||||
|
||||
public string AppUrl { get; private set; }
|
||||
public string UserCode { get; private set; }
|
||||
|
||||
public string QrCodeUrl { get; protected set; }
|
||||
|
||||
public string QrCodeChecksum { get; protected set; }
|
||||
|
||||
public string McServerUrl { get; private set; }
|
||||
|
||||
public abstract string RoomName { get; }
|
||||
|
||||
public abstract string RoomKey { get; }
|
||||
|
||||
protected MobileControlBridgeBase(string key, string messagePath)
|
||||
: base(key, messagePath)
|
||||
{
|
||||
public event EventHandler<EventArgs> UserCodeChanged;
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> UserPromptedForCode;
|
||||
protected MobileControlBridgeBase(string key, string messagePath, IKeyName device)
|
||||
: base(key, messagePath, device)
|
||||
{
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> ClientJoined;
|
||||
/// <summary>
|
||||
/// Set the parent. Does nothing else. Override to add functionality such
|
||||
/// as adding actions to parent
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
public virtual void AddParent(IMobileControl parent)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
public event EventHandler<EventArgs> AppUrlChanged;
|
||||
McServerUrl = Parent.ClientAppUrl;
|
||||
}
|
||||
|
||||
public IMobileControl Parent { get; private set; }
|
||||
|
||||
public string AppUrl { get; private set; }
|
||||
public string UserCode { get; private set; }
|
||||
|
||||
public string QrCodeUrl { get; protected set; }
|
||||
|
||||
public string QrCodeChecksum { get; protected set; }
|
||||
|
||||
public string McServerUrl { get; private set; }
|
||||
|
||||
public abstract string RoomName { get; }
|
||||
|
||||
public abstract string RoomKey { get; }
|
||||
|
||||
protected MobileControlBridgeBase(string key, string messagePath)
|
||||
: base(key, messagePath)
|
||||
/// <summary>
|
||||
/// Sets the UserCode on the bridge object. Called from controller. A changed code will
|
||||
/// fire method UserCodeChange. Override that to handle changes
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
public void SetUserCode(string code)
|
||||
{
|
||||
var changed = UserCode != code;
|
||||
UserCode = code;
|
||||
if (changed)
|
||||
{
|
||||
}
|
||||
|
||||
protected MobileControlBridgeBase(string key, string messagePath, IKeyName device)
|
||||
: base(key, messagePath, device)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the parent. Does nothing else. Override to add functionality such
|
||||
/// as adding actions to parent
|
||||
/// </summary>
|
||||
/// <param name="parent"></param>
|
||||
public virtual void AddParent(IMobileControl parent)
|
||||
{
|
||||
Parent = parent;
|
||||
|
||||
McServerUrl = Parent.ClientAppUrl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the UserCode on the bridge object. Called from controller. A changed code will
|
||||
/// fire method UserCodeChange. Override that to handle changes
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
public void SetUserCode(string code)
|
||||
{
|
||||
var changed = UserCode != code;
|
||||
UserCode = code;
|
||||
if (changed)
|
||||
{
|
||||
UserCodeChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the UserCode on the bridge object. Called from controller. A changed code will
|
||||
/// fire method UserCodeChange. Override that to handle changes
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="qrChecksum">Checksum of the QR code. Used for Cisco codec branding command</param>
|
||||
public void SetUserCode(string code, string qrChecksum)
|
||||
{
|
||||
QrCodeChecksum = qrChecksum;
|
||||
|
||||
SetUserCode(code);
|
||||
}
|
||||
|
||||
public virtual void UpdateAppUrl(string url)
|
||||
{
|
||||
AppUrl = url;
|
||||
|
||||
var handler = AppUrlChanged;
|
||||
|
||||
if (handler == null) return;
|
||||
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empty method in base class. Override this to add functionality
|
||||
/// when code changes
|
||||
/// </summary>
|
||||
protected virtual void UserCodeChange()
|
||||
{
|
||||
this.LogDebug("Server user code changed: {userCode}", UserCode);
|
||||
|
||||
var qrUrl = string.Format($"{Parent.Host}/api/rooms/{Parent.SystemUuid}/{RoomKey}/qr?x={new Random().Next()}");
|
||||
QrCodeUrl = qrUrl;
|
||||
|
||||
this.LogDebug("Server user code changed: {userCode} - {qrCodeUrl}", UserCode, qrUrl);
|
||||
|
||||
OnUserCodeChanged();
|
||||
}
|
||||
|
||||
protected void OnUserCodeChanged()
|
||||
{
|
||||
UserCodeChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
protected void OnUserPromptedForCode()
|
||||
{
|
||||
UserPromptedForCode?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
protected void OnClientJoined()
|
||||
{
|
||||
ClientJoined?.Invoke(this, new EventArgs());
|
||||
UserCodeChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the UserCode on the bridge object. Called from controller. A changed code will
|
||||
/// fire method UserCodeChange. Override that to handle changes
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="qrChecksum">Checksum of the QR code. Used for Cisco codec branding command</param>
|
||||
public void SetUserCode(string code, string qrChecksum)
|
||||
{
|
||||
QrCodeChecksum = qrChecksum;
|
||||
|
||||
SetUserCode(code);
|
||||
}
|
||||
|
||||
public virtual void UpdateAppUrl(string url)
|
||||
{
|
||||
AppUrl = url;
|
||||
|
||||
var handler = AppUrlChanged;
|
||||
|
||||
if (handler == null) return;
|
||||
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empty method in base class. Override this to add functionality
|
||||
/// when code changes
|
||||
/// </summary>
|
||||
protected virtual void UserCodeChange()
|
||||
{
|
||||
this.LogDebug("Server user code changed: {userCode}", UserCode);
|
||||
|
||||
var qrUrl = string.Format($"{Parent.Host}/api/rooms/{Parent.SystemUuid}/{RoomKey}/qr?x={new Random().Next()}");
|
||||
QrCodeUrl = qrUrl;
|
||||
|
||||
this.LogDebug("Server user code changed: {userCode} - {qrCodeUrl}", UserCode, qrUrl);
|
||||
|
||||
OnUserCodeChanged();
|
||||
}
|
||||
|
||||
protected void OnUserCodeChanged()
|
||||
{
|
||||
UserCodeChanged?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
protected void OnUserPromptedForCode()
|
||||
{
|
||||
UserPromptedForCode?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
protected void OnClientJoined()
|
||||
{
|
||||
ClientJoined?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,75 +3,74 @@ using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.Services
|
||||
namespace PepperDash.Essentials.Services;
|
||||
|
||||
|
||||
public class MobileControlApiService
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public class MobileControlApiService
|
||||
public MobileControlApiService(string apiUrl)
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
|
||||
public MobileControlApiService(string apiUrl)
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
AllowAutoRedirect = false,
|
||||
ServerCertificateCustomValidationCallback = (req, cert, certChain, errors) => true
|
||||
};
|
||||
|
||||
_client = new HttpClient(handler);
|
||||
}
|
||||
|
||||
public async Task<AuthorizationResponse> SendAuthorizationRequest(string apiUrl, string grantCode, string systemUuid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, $"{apiUrl}/system/{systemUuid}/authorize?grantCode={grantCode}");
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Sending authorization request to {host}", null, request.RequestUri);
|
||||
|
||||
var response = await _client.SendAsync(request);
|
||||
|
||||
var authResponse = new AuthorizationResponse
|
||||
{
|
||||
AllowAutoRedirect = false,
|
||||
ServerCertificateCustomValidationCallback = (req, cert, certChain, errors) => true
|
||||
Authorized = response.StatusCode == System.Net.HttpStatusCode.OK
|
||||
};
|
||||
|
||||
_client = new HttpClient(handler);
|
||||
}
|
||||
|
||||
public async Task<AuthorizationResponse> SendAuthorizationRequest(string apiUrl, string grantCode, string systemUuid)
|
||||
{
|
||||
try
|
||||
if (authResponse.Authorized)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, $"{apiUrl}/system/{systemUuid}/authorize?grantCode={grantCode}");
|
||||
return authResponse;
|
||||
}
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, "Sending authorization request to {host}", null, request.RequestUri);
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.Moved)
|
||||
{
|
||||
var location = response.Headers.Location;
|
||||
|
||||
var response = await _client.SendAsync(request);
|
||||
|
||||
var authResponse = new AuthorizationResponse
|
||||
{
|
||||
Authorized = response.StatusCode == System.Net.HttpStatusCode.OK
|
||||
};
|
||||
|
||||
if (authResponse.Authorized)
|
||||
{
|
||||
return authResponse;
|
||||
}
|
||||
|
||||
if (response.StatusCode == System.Net.HttpStatusCode.Moved)
|
||||
{
|
||||
var location = response.Headers.Location;
|
||||
|
||||
authResponse.Reason = $"ERROR: Mobile Control API has moved. Please adjust configuration to \"{location}\"";
|
||||
|
||||
return authResponse;
|
||||
}
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
switch (responseString)
|
||||
{
|
||||
case "codeNotFound":
|
||||
authResponse.Reason = $"Authorization failed. Code not found for system UUID {systemUuid}";
|
||||
break;
|
||||
case "uuidNotFound":
|
||||
authResponse.Reason = $"Authorization failed. System UUID {systemUuid} not found. Check Essentials configuration.";
|
||||
break;
|
||||
default:
|
||||
authResponse.Reason = $"Authorization failed. Response {response.StatusCode}: {responseString}";
|
||||
break;
|
||||
}
|
||||
authResponse.Reason = $"ERROR: Mobile Control API has moved. Please adjust configuration to \"{location}\"";
|
||||
|
||||
return authResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
|
||||
switch (responseString)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error authorizing with Mobile Control");
|
||||
return new AuthorizationResponse { Authorized = false, Reason = ex.Message };
|
||||
case "codeNotFound":
|
||||
authResponse.Reason = $"Authorization failed. Code not found for system UUID {systemUuid}";
|
||||
break;
|
||||
case "uuidNotFound":
|
||||
authResponse.Reason = $"Authorization failed. System UUID {systemUuid} not found. Check Essentials configuration.";
|
||||
break;
|
||||
default:
|
||||
authResponse.Reason = $"Authorization failed. Response {response.StatusCode}: {responseString}";
|
||||
break;
|
||||
}
|
||||
|
||||
return authResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Error authorizing with Mobile Control");
|
||||
return new AuthorizationResponse { Authorized = false, Reason = ex.Message };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
{
|
||||
public interface ITheme : IKeyed
|
||||
{
|
||||
string Theme { get; }
|
||||
namespace PepperDash.Essentials.Touchpanel;
|
||||
|
||||
void UpdateTheme(string theme);
|
||||
}
|
||||
public interface ITheme : IKeyed
|
||||
{
|
||||
string Theme { get; }
|
||||
|
||||
void UpdateTheme(string theme);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
namespace PepperDash.Essentials.Touchpanel;
|
||||
|
||||
public interface ITswAppControl : IKeyed
|
||||
{
|
||||
public interface ITswAppControl : IKeyed
|
||||
{
|
||||
BoolFeedback AppOpenFeedback { get; }
|
||||
BoolFeedback AppOpenFeedback { get; }
|
||||
|
||||
void HideOpenApp();
|
||||
void HideOpenApp();
|
||||
|
||||
void CloseOpenApp();
|
||||
void CloseOpenApp();
|
||||
|
||||
void OpenApp();
|
||||
}
|
||||
|
||||
public interface ITswZoomControl : IKeyed
|
||||
{
|
||||
BoolFeedback ZoomIncomingCallFeedback { get; }
|
||||
|
||||
BoolFeedback ZoomInCallFeedback { get; }
|
||||
|
||||
void EndZoomCall();
|
||||
}
|
||||
void OpenApp();
|
||||
}
|
||||
|
||||
public interface ITswZoomControl : IKeyed
|
||||
{
|
||||
BoolFeedback ZoomIncomingCallFeedback { get; }
|
||||
|
||||
BoolFeedback ZoomInCallFeedback { get; }
|
||||
|
||||
void EndZoomCall();
|
||||
}
|
||||
|
||||
@@ -4,56 +4,55 @@ using PepperDash.Core;
|
||||
using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
namespace PepperDash.Essentials.Touchpanel;
|
||||
|
||||
public class ITswAppControlMessenger : MessengerBase
|
||||
{
|
||||
public class ITswAppControlMessenger : MessengerBase
|
||||
private readonly ITswAppControl _appControl;
|
||||
|
||||
public ITswAppControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
private readonly ITswAppControl _appControl;
|
||||
|
||||
public ITswAppControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
_appControl = device as ITswAppControl;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
if (_appControl == null)
|
||||
{
|
||||
this.LogInformation("{deviceKey} does not implement ITswAppControl", _device.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
AddAction($"/fullStatus", (id, context) => SendFullStatus());
|
||||
|
||||
AddAction($"/openApp", (id, context) => _appControl.OpenApp());
|
||||
|
||||
AddAction($"/closeApp", (id, context) => _appControl.CloseOpenApp());
|
||||
|
||||
AddAction($"/hideApp", (id, context) => _appControl.HideOpenApp());
|
||||
|
||||
_appControl.AppOpenFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
appOpen = a.BoolValue
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var message = new TswAppStateMessage
|
||||
{
|
||||
AppOpen = _appControl.AppOpenFeedback.BoolValue,
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
_appControl = device as ITswAppControl;
|
||||
}
|
||||
|
||||
public class TswAppStateMessage : DeviceStateMessageBase
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
[JsonProperty("appOpen", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? AppOpen { get; set; }
|
||||
if (_appControl == null)
|
||||
{
|
||||
this.LogInformation("{deviceKey} does not implement ITswAppControl", _device.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
AddAction($"/fullStatus", (id, context) => SendFullStatus());
|
||||
|
||||
AddAction($"/openApp", (id, context) => _appControl.OpenApp());
|
||||
|
||||
AddAction($"/closeApp", (id, context) => _appControl.CloseOpenApp());
|
||||
|
||||
AddAction($"/hideApp", (id, context) => _appControl.HideOpenApp());
|
||||
|
||||
_appControl.AppOpenFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
appOpen = a.BoolValue
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var message = new TswAppStateMessage
|
||||
{
|
||||
AppOpen = _appControl.AppOpenFeedback.BoolValue,
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public class TswAppStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("appOpen", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? AppOpen { get; set; }
|
||||
}
|
||||
|
||||
@@ -5,69 +5,68 @@ using PepperDash.Core.Logging;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
namespace PepperDash.Essentials.Touchpanel;
|
||||
|
||||
public class ITswZoomControlMessenger : MessengerBase
|
||||
{
|
||||
public class ITswZoomControlMessenger : MessengerBase
|
||||
private readonly ITswZoomControl _zoomControl;
|
||||
|
||||
public ITswZoomControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
private readonly ITswZoomControl _zoomControl;
|
||||
|
||||
public ITswZoomControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
|
||||
{
|
||||
_zoomControl = device as ITswZoomControl;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
if (_zoomControl == null)
|
||||
{
|
||||
this.LogInformation("{deviceKey} does not implement ITswZoomControl", _device.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
AddAction($"/fullStatus", (id, context) => SendFullStatus());
|
||||
|
||||
|
||||
AddAction($"/endCall", (id, context) => _zoomControl.EndZoomCall());
|
||||
|
||||
_zoomControl.ZoomIncomingCallFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
incomingCall = a.BoolValue,
|
||||
inCall = _zoomControl.ZoomInCallFeedback.BoolValue
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
_zoomControl.ZoomInCallFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(
|
||||
new
|
||||
{
|
||||
inCall = a.BoolValue,
|
||||
incomingCall = _zoomControl.ZoomIncomingCallFeedback.BoolValue
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var message = new TswZoomStateMessage
|
||||
{
|
||||
InCall = _zoomControl?.ZoomInCallFeedback.BoolValue,
|
||||
IncomingCall = _zoomControl?.ZoomIncomingCallFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
_zoomControl = device as ITswZoomControl;
|
||||
}
|
||||
|
||||
public class TswZoomStateMessage : DeviceStateMessageBase
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
[JsonProperty("inCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? InCall { get; set; }
|
||||
if (_zoomControl == null)
|
||||
{
|
||||
this.LogInformation("{deviceKey} does not implement ITswZoomControl", _device.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
[JsonProperty("incomingCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IncomingCall { get; set; }
|
||||
AddAction($"/fullStatus", (id, context) => SendFullStatus());
|
||||
|
||||
|
||||
AddAction($"/endCall", (id, context) => _zoomControl.EndZoomCall());
|
||||
|
||||
_zoomControl.ZoomIncomingCallFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(new
|
||||
{
|
||||
incomingCall = a.BoolValue,
|
||||
inCall = _zoomControl.ZoomInCallFeedback.BoolValue
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
_zoomControl.ZoomInCallFeedback.OutputChange += (s, a) =>
|
||||
{
|
||||
PostStatusMessage(JToken.FromObject(
|
||||
new
|
||||
{
|
||||
inCall = a.BoolValue,
|
||||
incomingCall = _zoomControl.ZoomIncomingCallFeedback.BoolValue
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
private void SendFullStatus()
|
||||
{
|
||||
var message = new TswZoomStateMessage
|
||||
{
|
||||
InCall = _zoomControl?.ZoomInCallFeedback.BoolValue,
|
||||
IncomingCall = _zoomControl?.ZoomIncomingCallFeedback.BoolValue
|
||||
};
|
||||
|
||||
PostStatusMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
public class TswZoomStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("inCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? InCall { get; set; }
|
||||
|
||||
[JsonProperty("incomingCall", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? IncomingCall { get; set; }
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,19 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
namespace PepperDash.Essentials.Touchpanel;
|
||||
|
||||
public class MobileControlTouchpanelProperties : CrestronTouchpanelPropertiesConfig
|
||||
{
|
||||
public class MobileControlTouchpanelProperties : CrestronTouchpanelPropertiesConfig
|
||||
{
|
||||
[JsonProperty("useDirectServer")]
|
||||
public bool UseDirectServer { get; set; } = false;
|
||||
[JsonProperty("useDirectServer")]
|
||||
public bool UseDirectServer { get; set; } = false;
|
||||
|
||||
[JsonProperty("zoomRoomController")]
|
||||
public bool ZoomRoomController { get; set; } = false;
|
||||
[JsonProperty("zoomRoomController")]
|
||||
public bool ZoomRoomController { get; set; } = false;
|
||||
|
||||
[JsonProperty("buttonToolbarTimeoutInS")]
|
||||
public ushort ButtonToolbarTimoutInS { get; set; } = 0;
|
||||
[JsonProperty("buttonToolbarTimeoutInS")]
|
||||
public ushort ButtonToolbarTimoutInS { get; set; } = 0;
|
||||
|
||||
[JsonProperty("theme")]
|
||||
public string Theme { get; set; } = "light";
|
||||
}
|
||||
[JsonProperty("theme")]
|
||||
public string Theme { get; set; } = "light";
|
||||
}
|
||||
@@ -4,39 +4,38 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.AppServer;
|
||||
using PepperDash.Essentials.AppServer.Messengers;
|
||||
|
||||
namespace PepperDash.Essentials.Touchpanel
|
||||
namespace PepperDash.Essentials.Touchpanel;
|
||||
|
||||
public class ThemeMessenger : MessengerBase
|
||||
{
|
||||
public class ThemeMessenger : MessengerBase
|
||||
private readonly ITheme _tpDevice;
|
||||
|
||||
public ThemeMessenger(string key, string path, ITheme device) : base(key, path, device as Device)
|
||||
{
|
||||
private readonly ITheme _tpDevice;
|
||||
|
||||
public ThemeMessenger(string key, string path, ITheme device) : base(key, path, device as Device)
|
||||
{
|
||||
_tpDevice = device;
|
||||
}
|
||||
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
AddAction("/fullStatus", (id, content) =>
|
||||
{
|
||||
PostStatusMessage(new ThemeUpdateMessage { Theme = _tpDevice.Theme });
|
||||
});
|
||||
|
||||
AddAction("/saveTheme", (id, content) =>
|
||||
{
|
||||
var theme = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Setting theme to {theme}", this, theme.Value);
|
||||
_tpDevice.UpdateTheme(theme.Value);
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new { theme = theme.Value }));
|
||||
});
|
||||
}
|
||||
_tpDevice = device;
|
||||
}
|
||||
|
||||
public class ThemeUpdateMessage : DeviceStateMessageBase
|
||||
protected override void RegisterActions()
|
||||
{
|
||||
[JsonProperty("theme")]
|
||||
public string Theme { get; set; }
|
||||
AddAction("/fullStatus", (id, content) =>
|
||||
{
|
||||
PostStatusMessage(new ThemeUpdateMessage { Theme = _tpDevice.Theme });
|
||||
});
|
||||
|
||||
AddAction("/saveTheme", (id, content) =>
|
||||
{
|
||||
var theme = content.ToObject<MobileControlSimpleContent<string>>();
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Setting theme to {theme}", this, theme.Value);
|
||||
_tpDevice.UpdateTheme(theme.Value);
|
||||
|
||||
PostStatusMessage(JToken.FromObject(new { theme = theme.Value }));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class ThemeUpdateMessage : DeviceStateMessageBase
|
||||
{
|
||||
[JsonProperty("theme")]
|
||||
public string Theme { get; set; }
|
||||
}
|
||||
|
||||
@@ -10,121 +10,119 @@ using System;
|
||||
using System.Threading;
|
||||
using WebSocketSharp;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
public class TransmitMessage : IQueueMessage
|
||||
{
|
||||
public class TransmitMessage : IQueueMessage
|
||||
private readonly WebSocket _ws;
|
||||
private readonly object msgToSend;
|
||||
|
||||
public TransmitMessage(object msg, WebSocket ws)
|
||||
{
|
||||
private readonly WebSocket _ws;
|
||||
private readonly object msgToSend;
|
||||
|
||||
public TransmitMessage(object msg, WebSocket ws)
|
||||
{
|
||||
_ws = ws;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
public TransmitMessage(DeviceStateMessageBase msg, WebSocket ws)
|
||||
{
|
||||
_ws = ws;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
#region Implementation of IQueueMessage
|
||||
|
||||
public void Dispatch()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_ws == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Cannot send message. Websocket client is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_ws.IsAlive)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Cannot send message. Websocket client is not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var message = JsonConvert.SerializeObject(msgToSend, Formatting.None,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = { new IsoDateTimeConverter() } });
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Message TX: {0}", null, message);
|
||||
|
||||
_ws.Send(message);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Caught an exception in the Transmit Processor");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
_ws = ws;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class MessageToClients : IQueueMessage
|
||||
public TransmitMessage(DeviceStateMessageBase msg, WebSocket ws)
|
||||
{
|
||||
private readonly MobileControlWebsocketServer _server;
|
||||
private readonly object msgToSend;
|
||||
_ws = ws;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
public MessageToClients(object msg, MobileControlWebsocketServer server)
|
||||
#region Implementation of IQueueMessage
|
||||
|
||||
public void Dispatch()
|
||||
{
|
||||
try
|
||||
{
|
||||
_server = server;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
public MessageToClients(DeviceStateMessageBase msg, MobileControlWebsocketServer server)
|
||||
{
|
||||
_server = server;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
#region Implementation of IQueueMessage
|
||||
|
||||
public void Dispatch()
|
||||
{
|
||||
try
|
||||
if (_ws == null)
|
||||
{
|
||||
if (_server == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Cannot send message. Server is null");
|
||||
return;
|
||||
}
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Cannot send message. Websocket client is null");
|
||||
return;
|
||||
}
|
||||
|
||||
var message = JsonConvert.SerializeObject(msgToSend, Formatting.None,
|
||||
if (!_ws.IsAlive)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Cannot send message. Websocket client is not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var message = JsonConvert.SerializeObject(msgToSend, Formatting.None,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = { new IsoDateTimeConverter() } });
|
||||
|
||||
var clientSpecificMessage = msgToSend as MobileControlMessage;
|
||||
if (clientSpecificMessage.ClientId != null)
|
||||
{
|
||||
var clientId = clientSpecificMessage.ClientId;
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "Message TX: {0}", null, message);
|
||||
|
||||
_server.LogVerbose("Message TX To client {clientId} Message: {message}", clientId, message);
|
||||
_ws.Send(message);
|
||||
|
||||
_server.SendMessageToClient(clientId, message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_server.SendMessageToAllClients(message);
|
||||
|
||||
_server.LogVerbose("Message TX To all clients: {message}", message);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
//Swallowing this exception, as it occurs on shutdown and there's no need to print out a scary stack trace
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Caught an exception in the Transmit Processor");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Caught an exception in the Transmit Processor");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class MessageToClients : IQueueMessage
|
||||
{
|
||||
private readonly MobileControlWebsocketServer _server;
|
||||
private readonly object msgToSend;
|
||||
|
||||
public MessageToClients(object msg, MobileControlWebsocketServer server)
|
||||
{
|
||||
_server = server;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
public MessageToClients(DeviceStateMessageBase msg, MobileControlWebsocketServer server)
|
||||
{
|
||||
_server = server;
|
||||
msgToSend = msg;
|
||||
}
|
||||
|
||||
#region Implementation of IQueueMessage
|
||||
|
||||
public void Dispatch()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_server == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Cannot send message. Server is null");
|
||||
return;
|
||||
}
|
||||
|
||||
var message = JsonConvert.SerializeObject(msgToSend, Formatting.None,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = { new IsoDateTimeConverter() } });
|
||||
|
||||
var clientSpecificMessage = msgToSend as MobileControlMessage;
|
||||
if (clientSpecificMessage.ClientId != null)
|
||||
{
|
||||
var clientId = clientSpecificMessage.ClientId;
|
||||
|
||||
_server.LogVerbose("Message TX To client {clientId} Message: {message}", clientId, message);
|
||||
|
||||
_server.SendMessageToClient(clientId, message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_server.SendMessageToAllClients(message);
|
||||
|
||||
_server.LogVerbose("Message TX To all clients: {message}", message);
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
{
|
||||
//Swallowing this exception, as it occurs on shutdown and there's no need to print out a scary stack trace
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Caught an exception in the Transmit Processor");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class UserCodeChangedContent
|
||||
{
|
||||
[JsonProperty("userCode")]
|
||||
public string UserCode { get; set; }
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
[JsonProperty("qrChecksum", NullValueHandling = NullValueHandling.Include)]
|
||||
public string QrChecksum { get; set; }
|
||||
}
|
||||
public class UserCodeChangedContent
|
||||
{
|
||||
[JsonProperty("userCode")]
|
||||
public string UserCode { get; set; }
|
||||
|
||||
[JsonProperty("qrChecksum", NullValueHandling = NullValueHandling.Include)]
|
||||
public string QrChecksum { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,76 +1,75 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
namespace PepperDash.Essentials;
|
||||
|
||||
public class Volumes
|
||||
{
|
||||
public class Volumes
|
||||
[JsonProperty("master", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Volume Master { get; set; }
|
||||
|
||||
[JsonProperty("auxFaders", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Dictionary<string, Volume> AuxFaders { get; set; }
|
||||
|
||||
[JsonProperty("numberOfAuxFaders", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? NumberOfAuxFaders { get; set; }
|
||||
|
||||
public Volumes()
|
||||
{
|
||||
[JsonProperty("master", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Volume Master { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("auxFaders", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public Dictionary<string, Volume> AuxFaders { get; set; }
|
||||
public class Volume
|
||||
{
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key { get; set; }
|
||||
|
||||
[JsonProperty("numberOfAuxFaders", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? NumberOfAuxFaders { get; set; }
|
||||
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? Level { get; set; }
|
||||
|
||||
public Volumes()
|
||||
{
|
||||
}
|
||||
[JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? Muted { get; set; }
|
||||
|
||||
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Label { get; set; }
|
||||
|
||||
[JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasMute { get; set; }
|
||||
|
||||
[JsonProperty("hasPrivacyMute", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasPrivacyMute { get; set; }
|
||||
|
||||
[JsonProperty("privacyMuted", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? PrivacyMuted { get; set; }
|
||||
|
||||
|
||||
[JsonProperty("muteIcon", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string MuteIcon { get; set; }
|
||||
|
||||
public Volume(string key, int level, bool muted, string label, bool hasMute, string muteIcon)
|
||||
: this(key)
|
||||
{
|
||||
Level = level;
|
||||
Muted = muted;
|
||||
Label = label;
|
||||
HasMute = hasMute;
|
||||
MuteIcon = muteIcon;
|
||||
}
|
||||
|
||||
public class Volume
|
||||
public Volume(string key, int level)
|
||||
: this(key)
|
||||
{
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key { get; set; }
|
||||
Level = level;
|
||||
}
|
||||
|
||||
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? Level { get; set; }
|
||||
public Volume(string key, bool muted)
|
||||
: this(key)
|
||||
{
|
||||
Muted = muted;
|
||||
}
|
||||
|
||||
[JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? Muted { get; set; }
|
||||
|
||||
[JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Label { get; set; }
|
||||
|
||||
[JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasMute { get; set; }
|
||||
|
||||
[JsonProperty("hasPrivacyMute", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? HasPrivacyMute { get; set; }
|
||||
|
||||
[JsonProperty("privacyMuted", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? PrivacyMuted { get; set; }
|
||||
|
||||
|
||||
[JsonProperty("muteIcon", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string MuteIcon { get; set; }
|
||||
|
||||
public Volume(string key, int level, bool muted, string label, bool hasMute, string muteIcon)
|
||||
: this(key)
|
||||
{
|
||||
Level = level;
|
||||
Muted = muted;
|
||||
Label = label;
|
||||
HasMute = hasMute;
|
||||
MuteIcon = muteIcon;
|
||||
}
|
||||
|
||||
public Volume(string key, int level)
|
||||
: this(key)
|
||||
{
|
||||
Level = level;
|
||||
}
|
||||
|
||||
public Volume(string key, bool muted)
|
||||
: this(key)
|
||||
{
|
||||
Muted = muted;
|
||||
}
|
||||
|
||||
public Volume(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
public Volume(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
@@ -4,48 +4,47 @@ using PepperDash.Core.Web.RequestHandlers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.WebApiHandlers
|
||||
namespace PepperDash.Essentials.WebApiHandlers;
|
||||
|
||||
public class ActionPathsHandler : WebApiBaseRequestHandler
|
||||
{
|
||||
public class ActionPathsHandler : WebApiBaseRequestHandler
|
||||
private readonly MobileControlSystemController mcController;
|
||||
public ActionPathsHandler(MobileControlSystemController controller) : base(true)
|
||||
{
|
||||
private readonly MobileControlSystemController mcController;
|
||||
public ActionPathsHandler(MobileControlSystemController controller) : base(true)
|
||||
{
|
||||
mcController = controller;
|
||||
}
|
||||
|
||||
protected override void HandleGet(HttpCwsContext context)
|
||||
{
|
||||
var response = JsonConvert.SerializeObject(new ActionPathsResponse(mcController));
|
||||
|
||||
context.Response.StatusCode = 200;
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.Headers.Add("Content-Type", "application/json");
|
||||
context.Response.Write(response, false);
|
||||
context.Response.End();
|
||||
}
|
||||
mcController = controller;
|
||||
}
|
||||
|
||||
public class ActionPathsResponse
|
||||
protected override void HandleGet(HttpCwsContext context)
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly MobileControlSystemController mcController;
|
||||
var response = JsonConvert.SerializeObject(new ActionPathsResponse(mcController));
|
||||
|
||||
[JsonProperty("actionPaths")]
|
||||
public List<ActionPath> ActionPaths => mcController.GetActionDictionaryPaths().Select((path) => new ActionPath { MessengerKey = path.Item1, Path = path.Item2 }).ToList();
|
||||
|
||||
public ActionPathsResponse(MobileControlSystemController mcController)
|
||||
{
|
||||
this.mcController = mcController;
|
||||
}
|
||||
}
|
||||
|
||||
public class ActionPath
|
||||
{
|
||||
[JsonProperty("messengerKey")]
|
||||
public string MessengerKey { get; set; }
|
||||
|
||||
[JsonProperty("path")]
|
||||
public string Path { get; set; }
|
||||
context.Response.StatusCode = 200;
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.Headers.Add("Content-Type", "application/json");
|
||||
context.Response.Write(response, false);
|
||||
context.Response.End();
|
||||
}
|
||||
}
|
||||
|
||||
public class ActionPathsResponse
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly MobileControlSystemController mcController;
|
||||
|
||||
[JsonProperty("actionPaths")]
|
||||
public List<ActionPath> ActionPaths => mcController.GetActionDictionaryPaths().Select((path) => new ActionPath { MessengerKey = path.Item1, Path = path.Item2 }).ToList();
|
||||
|
||||
public ActionPathsResponse(MobileControlSystemController mcController)
|
||||
{
|
||||
this.mcController = mcController;
|
||||
}
|
||||
}
|
||||
|
||||
public class ActionPath
|
||||
{
|
||||
[JsonProperty("messengerKey")]
|
||||
public string MessengerKey { get; set; }
|
||||
|
||||
[JsonProperty("path")]
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
@@ -6,54 +6,53 @@ using PepperDash.Essentials.Core.Web;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PepperDash.Essentials.WebApiHandlers
|
||||
namespace PepperDash.Essentials.WebApiHandlers;
|
||||
|
||||
public class MobileAuthRequestHandler : WebApiBaseRequestAsyncHandler
|
||||
{
|
||||
public class MobileAuthRequestHandler : WebApiBaseRequestAsyncHandler
|
||||
private readonly MobileControlSystemController mcController;
|
||||
|
||||
public MobileAuthRequestHandler(MobileControlSystemController controller) : base(true)
|
||||
{
|
||||
private readonly MobileControlSystemController mcController;
|
||||
mcController = controller;
|
||||
}
|
||||
|
||||
public MobileAuthRequestHandler(MobileControlSystemController controller) : base(true)
|
||||
protected override async Task HandlePost(HttpCwsContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
mcController = controller;
|
||||
}
|
||||
var requestBody = EssentialsWebApiHelpers.GetRequestBody(context.Request);
|
||||
|
||||
protected override async Task HandlePost(HttpCwsContext context)
|
||||
{
|
||||
try
|
||||
var grantCode = JsonConvert.DeserializeObject<AuthorizationRequest>(requestBody);
|
||||
|
||||
if (string.IsNullOrEmpty(grantCode?.GrantCode))
|
||||
{
|
||||
var requestBody = EssentialsWebApiHelpers.GetRequestBody(context.Request);
|
||||
|
||||
var grantCode = JsonConvert.DeserializeObject<AuthorizationRequest>(requestBody);
|
||||
|
||||
if (string.IsNullOrEmpty(grantCode?.GrantCode))
|
||||
{
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Error, "Missing grant code");
|
||||
context.Response.StatusCode = 400;
|
||||
context.Response.StatusDescription = "Missing grant code";
|
||||
context.Response.End();
|
||||
return;
|
||||
}
|
||||
|
||||
var response = await mcController.ApiService.SendAuthorizationRequest(mcController.Host, grantCode.GrantCode, mcController.SystemUuid);
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, $"response received");
|
||||
if (response.Authorized)
|
||||
{
|
||||
mcController.RegisterSystemToServer();
|
||||
}
|
||||
|
||||
|
||||
context.Response.StatusCode = 200;
|
||||
var responseBody = JsonConvert.SerializeObject(response, Formatting.None);
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.Headers.Add("Content-Type", "application/json");
|
||||
context.Response.Write(responseBody, false);
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Error, "Missing grant code");
|
||||
context.Response.StatusCode = 400;
|
||||
context.Response.StatusDescription = "Missing grant code";
|
||||
context.Response.End();
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
var response = await mcController.ApiService.SendAuthorizationRequest(mcController.Host, grantCode.GrantCode, mcController.SystemUuid);
|
||||
|
||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, $"response received");
|
||||
if (response.Authorized)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception recieved authorizing system");
|
||||
mcController.RegisterSystemToServer();
|
||||
}
|
||||
|
||||
|
||||
context.Response.StatusCode = 200;
|
||||
var responseBody = JsonConvert.SerializeObject(response, Formatting.None);
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.Headers.Add("Content-Type", "application/json");
|
||||
context.Response.Write(responseBody, false);
|
||||
context.Response.End();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "Exception recieved authorizing system");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,152 +8,151 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.WebApiHandlers
|
||||
namespace PepperDash.Essentials.WebApiHandlers;
|
||||
|
||||
public class MobileInfoHandler : WebApiBaseRequestHandler
|
||||
{
|
||||
public class MobileInfoHandler : WebApiBaseRequestHandler
|
||||
private readonly MobileControlSystemController mcController;
|
||||
public MobileInfoHandler(MobileControlSystemController controller) : base(true)
|
||||
{
|
||||
private readonly MobileControlSystemController mcController;
|
||||
public MobileInfoHandler(MobileControlSystemController controller) : base(true)
|
||||
{
|
||||
mcController = controller;
|
||||
}
|
||||
|
||||
protected override void HandleGet(HttpCwsContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = new InformationResponse(mcController);
|
||||
|
||||
context.Response.StatusCode = 200;
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.Write(JsonConvert.SerializeObject(response), false);
|
||||
context.Response.End();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogMessage(ex, "exception showing mobile info");
|
||||
|
||||
context.Response.StatusCode = 500;
|
||||
context.Response.End();
|
||||
}
|
||||
}
|
||||
mcController = controller;
|
||||
}
|
||||
|
||||
public class InformationResponse
|
||||
protected override void HandleGet(HttpCwsContext context)
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly MobileControlSystemController mcController;
|
||||
|
||||
[JsonProperty("edgeServer", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public MobileControlEdgeServer EdgeServer => mcController.Config.EnableApiServer ? new MobileControlEdgeServer(mcController) : null;
|
||||
|
||||
|
||||
[JsonProperty("directServer", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public MobileControlDirectServer DirectServer => mcController.Config.DirectServer.EnableDirectServer ? new MobileControlDirectServer(mcController.DirectServer) : null;
|
||||
|
||||
|
||||
public InformationResponse(MobileControlSystemController controller)
|
||||
try
|
||||
{
|
||||
mcController = controller;
|
||||
var response = new InformationResponse(mcController);
|
||||
|
||||
context.Response.StatusCode = 200;
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.Write(JsonConvert.SerializeObject(response), false);
|
||||
context.Response.End();
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileControlEdgeServer
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly MobileControlSystemController mcController;
|
||||
|
||||
[JsonProperty("serverAddress")]
|
||||
public string ServerAddress => mcController.Config == null ? "No Config" : mcController.Host;
|
||||
|
||||
[JsonProperty("systemName")]
|
||||
public string SystemName => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].RoomName : "No Config";
|
||||
|
||||
[JsonProperty("systemUrl")]
|
||||
public string SystemUrl => ConfigReader.ConfigObject.SystemUrl;
|
||||
|
||||
[JsonProperty("userCode")]
|
||||
public string UserCode => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].UserCode : "Not available";
|
||||
|
||||
[JsonProperty("connected")]
|
||||
public bool Connected => mcController.Connected;
|
||||
|
||||
[JsonProperty("secondsSinceLastAck")]
|
||||
public int SecondsSinceLastAck => (DateTime.Now - mcController.LastAckMessage).Seconds;
|
||||
|
||||
public MobileControlEdgeServer(MobileControlSystemController controller)
|
||||
catch (Exception ex)
|
||||
{
|
||||
mcController = controller;
|
||||
}
|
||||
}
|
||||
Debug.LogMessage(ex, "exception showing mobile info");
|
||||
|
||||
public class MobileControlDirectServer
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly MobileControlWebsocketServer directServer;
|
||||
|
||||
[JsonProperty("userAppUrl")]
|
||||
public string UserAppUrl => $"{directServer.UserAppUrlPrefix}/[insert_client_token]";
|
||||
|
||||
[JsonProperty("serverPort")]
|
||||
public int ServerPort => directServer.Port;
|
||||
|
||||
[JsonProperty("tokensDefined")]
|
||||
public int TokensDefined => directServer.UiClients.Count;
|
||||
|
||||
[JsonProperty("clientsConnected")]
|
||||
public int ClientsConnected => directServer.ConnectedUiClientsCount;
|
||||
|
||||
[JsonProperty("clients")]
|
||||
public List<MobileControlDirectClient> Clients => directServer.UiClients.Select((c, i) => { return new MobileControlDirectClient(c, i, directServer.UserAppUrlPrefix); }).ToList();
|
||||
|
||||
public MobileControlDirectServer(MobileControlWebsocketServer server)
|
||||
{
|
||||
directServer = server;
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileControlDirectClient
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly UiClientContext context;
|
||||
|
||||
[JsonIgnore]
|
||||
private readonly string Key;
|
||||
|
||||
[JsonIgnore]
|
||||
private readonly int clientNumber;
|
||||
|
||||
[JsonIgnore]
|
||||
private readonly string urlPrefix;
|
||||
|
||||
[JsonProperty("clientNumber")]
|
||||
public string ClientNumber => $"{clientNumber}";
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey => context.Token.RoomKey;
|
||||
|
||||
[JsonProperty("touchpanelKey")]
|
||||
public string TouchpanelKey => context.Token.TouchpanelKey;
|
||||
|
||||
[JsonProperty("url")]
|
||||
public string Url => $"{urlPrefix}{Key}";
|
||||
|
||||
[JsonProperty("token")]
|
||||
public string Token => Key;
|
||||
|
||||
[JsonProperty("connected")]
|
||||
public bool Connected => context.Client != null && context.Client.Context.WebSocket.IsAlive;
|
||||
|
||||
[JsonProperty("duration")]
|
||||
public double Duration => context.Client == null ? 0 : context.Client.ConnectedDuration.TotalSeconds;
|
||||
|
||||
public MobileControlDirectClient(KeyValuePair<string, UiClientContext> clientContext, int index, string urlPrefix)
|
||||
{
|
||||
context = clientContext.Value;
|
||||
Key = clientContext.Key;
|
||||
clientNumber = index;
|
||||
this.urlPrefix = urlPrefix;
|
||||
context.Response.StatusCode = 500;
|
||||
context.Response.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class InformationResponse
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly MobileControlSystemController mcController;
|
||||
|
||||
[JsonProperty("edgeServer", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public MobileControlEdgeServer EdgeServer => mcController.Config.EnableApiServer ? new MobileControlEdgeServer(mcController) : null;
|
||||
|
||||
|
||||
[JsonProperty("directServer", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public MobileControlDirectServer DirectServer => mcController.Config.DirectServer.EnableDirectServer ? new MobileControlDirectServer(mcController.DirectServer) : null;
|
||||
|
||||
|
||||
public InformationResponse(MobileControlSystemController controller)
|
||||
{
|
||||
mcController = controller;
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileControlEdgeServer
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly MobileControlSystemController mcController;
|
||||
|
||||
[JsonProperty("serverAddress")]
|
||||
public string ServerAddress => mcController.Config == null ? "No Config" : mcController.Host;
|
||||
|
||||
[JsonProperty("systemName")]
|
||||
public string SystemName => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].RoomName : "No Config";
|
||||
|
||||
[JsonProperty("systemUrl")]
|
||||
public string SystemUrl => ConfigReader.ConfigObject.SystemUrl;
|
||||
|
||||
[JsonProperty("userCode")]
|
||||
public string UserCode => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].UserCode : "Not available";
|
||||
|
||||
[JsonProperty("connected")]
|
||||
public bool Connected => mcController.Connected;
|
||||
|
||||
[JsonProperty("secondsSinceLastAck")]
|
||||
public int SecondsSinceLastAck => (DateTime.Now - mcController.LastAckMessage).Seconds;
|
||||
|
||||
public MobileControlEdgeServer(MobileControlSystemController controller)
|
||||
{
|
||||
mcController = controller;
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileControlDirectServer
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly MobileControlWebsocketServer directServer;
|
||||
|
||||
[JsonProperty("userAppUrl")]
|
||||
public string UserAppUrl => $"{directServer.UserAppUrlPrefix}/[insert_client_token]";
|
||||
|
||||
[JsonProperty("serverPort")]
|
||||
public int ServerPort => directServer.Port;
|
||||
|
||||
[JsonProperty("tokensDefined")]
|
||||
public int TokensDefined => directServer.UiClients.Count;
|
||||
|
||||
[JsonProperty("clientsConnected")]
|
||||
public int ClientsConnected => directServer.ConnectedUiClientsCount;
|
||||
|
||||
[JsonProperty("clients")]
|
||||
public List<MobileControlDirectClient> Clients => directServer.UiClients.Select((c, i) => { return new MobileControlDirectClient(c, i, directServer.UserAppUrlPrefix); }).ToList();
|
||||
|
||||
public MobileControlDirectServer(MobileControlWebsocketServer server)
|
||||
{
|
||||
directServer = server;
|
||||
}
|
||||
}
|
||||
|
||||
public class MobileControlDirectClient
|
||||
{
|
||||
[JsonIgnore]
|
||||
private readonly UiClientContext context;
|
||||
|
||||
[JsonIgnore]
|
||||
private readonly string Key;
|
||||
|
||||
[JsonIgnore]
|
||||
private readonly int clientNumber;
|
||||
|
||||
[JsonIgnore]
|
||||
private readonly string urlPrefix;
|
||||
|
||||
[JsonProperty("clientNumber")]
|
||||
public string ClientNumber => $"{clientNumber}";
|
||||
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey => context.Token.RoomKey;
|
||||
|
||||
[JsonProperty("touchpanelKey")]
|
||||
public string TouchpanelKey => context.Token.TouchpanelKey;
|
||||
|
||||
[JsonProperty("url")]
|
||||
public string Url => $"{urlPrefix}{Key}";
|
||||
|
||||
[JsonProperty("token")]
|
||||
public string Token => Key;
|
||||
|
||||
[JsonProperty("connected")]
|
||||
public bool Connected => context.Client != null && context.Client.Context.WebSocket.IsAlive;
|
||||
|
||||
[JsonProperty("duration")]
|
||||
public double Duration => context.Client == null ? 0 : context.Client.ConnectedDuration.TotalSeconds;
|
||||
|
||||
public MobileControlDirectClient(KeyValuePair<string, UiClientContext> clientContext, int index, string urlPrefix)
|
||||
{
|
||||
context = clientContext.Value;
|
||||
Key = clientContext.Key;
|
||||
clientNumber = index;
|
||||
this.urlPrefix = urlPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,161 +6,160 @@ using PepperDash.Essentials.Core.Web;
|
||||
using PepperDash.Essentials.WebSocketServer;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials.WebApiHandlers
|
||||
namespace PepperDash.Essentials.WebApiHandlers;
|
||||
|
||||
public class UiClientHandler : WebApiBaseRequestHandler
|
||||
{
|
||||
public class UiClientHandler : WebApiBaseRequestHandler
|
||||
private readonly MobileControlWebsocketServer server;
|
||||
public UiClientHandler(MobileControlWebsocketServer directServer) : base(true)
|
||||
{
|
||||
private readonly MobileControlWebsocketServer server;
|
||||
public UiClientHandler(MobileControlWebsocketServer directServer) : base(true)
|
||||
server = directServer;
|
||||
}
|
||||
|
||||
protected override void HandlePost(HttpCwsContext context)
|
||||
{
|
||||
var req = context.Request;
|
||||
var res = context.Response;
|
||||
var body = EssentialsWebApiHelpers.GetRequestBody(req);
|
||||
|
||||
var request = JsonConvert.DeserializeObject<ClientRequest>(body);
|
||||
|
||||
var response = new ClientResponse();
|
||||
|
||||
if (string.IsNullOrEmpty(request?.RoomKey))
|
||||
{
|
||||
server = directServer;
|
||||
response.Error = "roomKey is required";
|
||||
|
||||
res.StatusCode = 400;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
return;
|
||||
}
|
||||
|
||||
protected override void HandlePost(HttpCwsContext context)
|
||||
if (string.IsNullOrEmpty(request.GrantCode))
|
||||
{
|
||||
var req = context.Request;
|
||||
var res = context.Response;
|
||||
var body = EssentialsWebApiHelpers.GetRequestBody(req);
|
||||
response.Error = "grantCode is required";
|
||||
|
||||
var request = JsonConvert.DeserializeObject<ClientRequest>(body);
|
||||
res.StatusCode = 400;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
return;
|
||||
}
|
||||
|
||||
var response = new ClientResponse();
|
||||
var (token, path) = server.ValidateGrantCode(request.GrantCode, request.RoomKey);
|
||||
|
||||
if (string.IsNullOrEmpty(request?.RoomKey))
|
||||
response.Token = token;
|
||||
response.Path = path;
|
||||
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
}
|
||||
|
||||
protected override void HandleDelete(HttpCwsContext context)
|
||||
{
|
||||
var req = context.Request;
|
||||
var res = context.Response;
|
||||
var body = EssentialsWebApiHelpers.GetRequestBody(req);
|
||||
|
||||
var request = JsonConvert.DeserializeObject<ClientRequest>(body);
|
||||
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(request?.Token))
|
||||
{
|
||||
var response = new ClientResponse
|
||||
{
|
||||
response.Error = "roomKey is required";
|
||||
Error = "token is required"
|
||||
};
|
||||
|
||||
res.StatusCode = 400;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
return;
|
||||
}
|
||||
res.StatusCode = 400;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
|
||||
if (string.IsNullOrEmpty(request.GrantCode))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!server.UiClients.TryGetValue(request.Token, out UiClientContext clientContext))
|
||||
{
|
||||
var response = new ClientResponse
|
||||
{
|
||||
response.Error = "grantCode is required";
|
||||
|
||||
res.StatusCode = 400;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
return;
|
||||
}
|
||||
|
||||
var (token, path) = server.ValidateGrantCode(request.GrantCode, request.RoomKey);
|
||||
|
||||
response.Token = token;
|
||||
response.Path = path;
|
||||
Error = $"Unable to find client with token: {request.Token}"
|
||||
};
|
||||
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
protected override void HandleDelete(HttpCwsContext context)
|
||||
if (clientContext.Client != null && clientContext.Client.Context.WebSocket.IsAlive)
|
||||
{
|
||||
var req = context.Request;
|
||||
var res = context.Response;
|
||||
var body = EssentialsWebApiHelpers.GetRequestBody(req);
|
||||
|
||||
var request = JsonConvert.DeserializeObject<ClientRequest>(body);
|
||||
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(request?.Token))
|
||||
{
|
||||
var response = new ClientResponse
|
||||
{
|
||||
Error = "token is required"
|
||||
};
|
||||
|
||||
res.StatusCode = 400;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!server.UiClients.TryGetValue(request.Token, out UiClientContext clientContext))
|
||||
{
|
||||
var response = new ClientResponse
|
||||
{
|
||||
Error = $"Unable to find client with token: {request.Token}"
|
||||
};
|
||||
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (clientContext.Client != null && clientContext.Client.Context.WebSocket.IsAlive)
|
||||
{
|
||||
clientContext.Client.Context.WebSocket.Close(WebSocketSharp.CloseStatusCode.Normal, "Token removed from server");
|
||||
}
|
||||
|
||||
var path = server.WsPath + request.Token;
|
||||
|
||||
if (!server.Server.RemoveWebSocketService(path))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Unable to remove client with token {token}", request.Token);
|
||||
|
||||
var response = new ClientResponse
|
||||
{
|
||||
Error = $"Unable to remove client with token {request.Token}"
|
||||
};
|
||||
|
||||
res.StatusCode = 500;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
server.UiClients.Remove(request.Token);
|
||||
|
||||
server.UpdateSecret();
|
||||
|
||||
res.StatusCode = 200;
|
||||
res.End();
|
||||
clientContext.Client.Context.WebSocket.Close(WebSocketSharp.CloseStatusCode.Normal, "Token removed from server");
|
||||
}
|
||||
}
|
||||
|
||||
public class ClientRequest
|
||||
{
|
||||
[JsonProperty("roomKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string RoomKey { get; set; }
|
||||
var path = server.WsPath + request.Token;
|
||||
|
||||
[JsonProperty("grantCode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string GrantCode { get; set; }
|
||||
if (!server.Server.RemoveWebSocketService(path))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Warning, "Unable to remove client with token {token}", request.Token);
|
||||
|
||||
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
var response = new ClientResponse
|
||||
{
|
||||
Error = $"Unable to remove client with token {request.Token}"
|
||||
};
|
||||
|
||||
public class ClientResponse
|
||||
{
|
||||
[JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Error { get; set; }
|
||||
res.StatusCode = 500;
|
||||
res.ContentType = "application/json";
|
||||
res.Headers.Add("Content-Type", "application/json");
|
||||
res.Write(JsonConvert.SerializeObject(response), false);
|
||||
res.End();
|
||||
|
||||
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Token { get; set; }
|
||||
return;
|
||||
}
|
||||
|
||||
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Path { get; set; }
|
||||
server.UiClients.Remove(request.Token);
|
||||
|
||||
server.UpdateSecret();
|
||||
|
||||
res.StatusCode = 200;
|
||||
res.End();
|
||||
}
|
||||
}
|
||||
|
||||
public class ClientRequest
|
||||
{
|
||||
[JsonProperty("roomKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("grantCode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string GrantCode { get; set; }
|
||||
|
||||
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
public class ClientResponse
|
||||
{
|
||||
[JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Error { get; set; }
|
||||
|
||||
[JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Token { get; set; }
|
||||
|
||||
[JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,135 +11,134 @@ using WebSocketSharp.Server;
|
||||
using ErrorEventArgs = WebSocketSharp.ErrorEventArgs;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the behaviour to associate with a UiClient for WebSocket communication
|
||||
/// </summary>
|
||||
public class UiClient : WebSocketBehavior
|
||||
namespace PepperDash.Essentials.WebSocketServer;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the behaviour to associate with a UiClient for WebSocket communication
|
||||
/// </summary>
|
||||
public class UiClient : WebSocketBehavior
|
||||
{
|
||||
public MobileControlSystemController Controller { get; set; }
|
||||
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
private string _clientId;
|
||||
|
||||
private DateTime _connectionTime;
|
||||
|
||||
public TimeSpan ConnectedDuration
|
||||
{
|
||||
public MobileControlSystemController Controller { get; set; }
|
||||
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
private string _clientId;
|
||||
|
||||
private DateTime _connectionTime;
|
||||
|
||||
public TimeSpan ConnectedDuration
|
||||
get
|
||||
{
|
||||
get
|
||||
if (Context.WebSocket.IsAlive)
|
||||
{
|
||||
if (Context.WebSocket.IsAlive)
|
||||
{
|
||||
return DateTime.Now - _connectionTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TimeSpan(0);
|
||||
}
|
||||
return DateTime.Now - _connectionTime;
|
||||
}
|
||||
}
|
||||
|
||||
public UiClient()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnOpen()
|
||||
{
|
||||
base.OnOpen();
|
||||
|
||||
var url = Context.WebSocket.Url;
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "New WebSocket Connection from: {0}", null, url);
|
||||
|
||||
var match = Regex.Match(url.AbsoluteUri, "(?:ws|wss):\\/\\/.*(?:\\/mc\\/api\\/ui\\/join\\/)(.*)");
|
||||
|
||||
if (!match.Success)
|
||||
else
|
||||
{
|
||||
_connectionTime = DateTime.Now;
|
||||
return;
|
||||
return new TimeSpan(0);
|
||||
}
|
||||
|
||||
var clientId = match.Groups[1].Value;
|
||||
_clientId = clientId;
|
||||
|
||||
if (Controller == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "WebSocket UiClient Controller is null");
|
||||
_connectionTime = DateTime.Now;
|
||||
}
|
||||
|
||||
var clientJoinedMessage = new MobileControlMessage
|
||||
{
|
||||
Type = "/system/clientJoined",
|
||||
Content = JToken.FromObject(new
|
||||
{
|
||||
clientId,
|
||||
roomKey = RoomKey,
|
||||
})
|
||||
};
|
||||
|
||||
Controller.HandleClientMessage(JsonConvert.SerializeObject(clientJoinedMessage));
|
||||
|
||||
var bridge = Controller.GetRoomBridge(RoomKey);
|
||||
|
||||
if (bridge == null) return;
|
||||
|
||||
SendUserCodeToClient(bridge, clientId);
|
||||
|
||||
bridge.UserCodeChanged -= Bridge_UserCodeChanged;
|
||||
bridge.UserCodeChanged += Bridge_UserCodeChanged;
|
||||
|
||||
// TODO: Future: Check token to see if there's already an open session using that token and reject/close the session
|
||||
}
|
||||
|
||||
private void Bridge_UserCodeChanged(object sender, EventArgs e)
|
||||
{
|
||||
SendUserCodeToClient((MobileControlEssentialsRoomBridge)sender, _clientId);
|
||||
}
|
||||
|
||||
private void SendUserCodeToClient(MobileControlBridgeBase bridge, string clientId)
|
||||
{
|
||||
var content = new
|
||||
{
|
||||
userCode = bridge.UserCode,
|
||||
qrUrl = bridge.QrCodeUrl,
|
||||
};
|
||||
|
||||
var message = new MobileControlMessage
|
||||
{
|
||||
Type = "/system/userCodeChanged",
|
||||
ClientId = clientId,
|
||||
Content = JToken.FromObject(content)
|
||||
};
|
||||
|
||||
Controller.SendMessageObjectToDirectClient(message);
|
||||
}
|
||||
|
||||
protected override void OnMessage(MessageEventArgs e)
|
||||
{
|
||||
base.OnMessage(e);
|
||||
|
||||
if (e.IsText && e.Data.Length > 0 && Controller != null)
|
||||
{
|
||||
// Forward the message to the controller to be put on the receive queue
|
||||
Controller.HandleClientMessage(e.Data);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClose(CloseEventArgs e)
|
||||
{
|
||||
base.OnClose(e);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "WebSocket UiClient Closing: {0} reason: {1}", null, e.Code, e.Reason);
|
||||
}
|
||||
|
||||
protected override void OnError(ErrorEventArgs e)
|
||||
{
|
||||
base.OnError(e);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "WebSocket UiClient Error: {exception} message: {message}", e.Exception, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public UiClient()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnOpen()
|
||||
{
|
||||
base.OnOpen();
|
||||
|
||||
var url = Context.WebSocket.Url;
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "New WebSocket Connection from: {0}", null, url);
|
||||
|
||||
var match = Regex.Match(url.AbsoluteUri, "(?:ws|wss):\\/\\/.*(?:\\/mc\\/api\\/ui\\/join\\/)(.*)");
|
||||
|
||||
if (!match.Success)
|
||||
{
|
||||
_connectionTime = DateTime.Now;
|
||||
return;
|
||||
}
|
||||
|
||||
var clientId = match.Groups[1].Value;
|
||||
_clientId = clientId;
|
||||
|
||||
if (Controller == null)
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "WebSocket UiClient Controller is null");
|
||||
_connectionTime = DateTime.Now;
|
||||
}
|
||||
|
||||
var clientJoinedMessage = new MobileControlMessage
|
||||
{
|
||||
Type = "/system/clientJoined",
|
||||
Content = JToken.FromObject(new
|
||||
{
|
||||
clientId,
|
||||
roomKey = RoomKey,
|
||||
})
|
||||
};
|
||||
|
||||
Controller.HandleClientMessage(JsonConvert.SerializeObject(clientJoinedMessage));
|
||||
|
||||
var bridge = Controller.GetRoomBridge(RoomKey);
|
||||
|
||||
if (bridge == null) return;
|
||||
|
||||
SendUserCodeToClient(bridge, clientId);
|
||||
|
||||
bridge.UserCodeChanged -= Bridge_UserCodeChanged;
|
||||
bridge.UserCodeChanged += Bridge_UserCodeChanged;
|
||||
|
||||
// TODO: Future: Check token to see if there's already an open session using that token and reject/close the session
|
||||
}
|
||||
|
||||
private void Bridge_UserCodeChanged(object sender, EventArgs e)
|
||||
{
|
||||
SendUserCodeToClient((MobileControlEssentialsRoomBridge)sender, _clientId);
|
||||
}
|
||||
|
||||
private void SendUserCodeToClient(MobileControlBridgeBase bridge, string clientId)
|
||||
{
|
||||
var content = new
|
||||
{
|
||||
userCode = bridge.UserCode,
|
||||
qrUrl = bridge.QrCodeUrl,
|
||||
};
|
||||
|
||||
var message = new MobileControlMessage
|
||||
{
|
||||
Type = "/system/userCodeChanged",
|
||||
ClientId = clientId,
|
||||
Content = JToken.FromObject(content)
|
||||
};
|
||||
|
||||
Controller.SendMessageObjectToDirectClient(message);
|
||||
}
|
||||
|
||||
protected override void OnMessage(MessageEventArgs e)
|
||||
{
|
||||
base.OnMessage(e);
|
||||
|
||||
if (e.IsText && e.Data.Length > 0 && Controller != null)
|
||||
{
|
||||
// Forward the message to the controller to be put on the receive queue
|
||||
Controller.HandleClientMessage(e.Data);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClose(CloseEventArgs e)
|
||||
{
|
||||
base.OnClose(e);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "WebSocket UiClient Closing: {0} reason: {1}", null, e.Code, e.Reason);
|
||||
}
|
||||
|
||||
protected override void OnError(ErrorEventArgs e)
|
||||
{
|
||||
base.OnError(e);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Verbose, "WebSocket UiClient Error: {exception} message: {message}", e.Exception, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,34 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.WebSocketServer
|
||||
namespace PepperDash.Essentials.WebSocketServer;
|
||||
|
||||
internal class WebSocketServerSecretProvider : CrestronLocalSecretsProvider
|
||||
{
|
||||
internal class WebSocketServerSecretProvider : CrestronLocalSecretsProvider
|
||||
public WebSocketServerSecretProvider(string key)
|
||||
: base(key)
|
||||
{
|
||||
public WebSocketServerSecretProvider(string key)
|
||||
: base(key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
|
||||
public class WebSocketServerSecret : ISecret
|
||||
{
|
||||
public ISecretProvider Provider { get; private set; }
|
||||
|
||||
public string Key { get; private set; }
|
||||
|
||||
public object Value { get; private set; }
|
||||
|
||||
public WebSocketServerSecret(string key, object value, ISecretProvider provider)
|
||||
{
|
||||
Key = key;
|
||||
Value = JsonConvert.SerializeObject(value);
|
||||
Provider = provider;
|
||||
}
|
||||
|
||||
public ServerTokenSecrets DeserializeSecret()
|
||||
{
|
||||
return JsonConvert.DeserializeObject<ServerTokenSecrets>(Value.ToString());
|
||||
}
|
||||
|
||||
public class WebSocketServerSecret : ISecret
|
||||
{
|
||||
public ISecretProvider Provider { get; private set; }
|
||||
|
||||
public string Key { get; private set; }
|
||||
|
||||
public object Value { get; private set; }
|
||||
|
||||
public WebSocketServerSecret(string key, object value, ISecretProvider provider)
|
||||
{
|
||||
Key = key;
|
||||
Value = JsonConvert.SerializeObject(value);
|
||||
Provider = provider;
|
||||
}
|
||||
|
||||
public ServerTokenSecrets DeserializeSecret()
|
||||
{
|
||||
return JsonConvert.DeserializeObject<ServerTokenSecrets>(Value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user