diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/Interfaces/ICodecCallControls.cs b/src/PepperDash.Essentials.Devices.Common/Codec/Interfaces/ICodecCallControls.cs
new file mode 100644
index 00000000..6110bb1a
--- /dev/null
+++ b/src/PepperDash.Essentials.Devices.Common/Codec/Interfaces/ICodecCallControls.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+
+namespace PepperDash.Essentials.Devices.Common.Codec;
+
+///
+/// Defines call control functionality for a codec, extending the base dialer interface
+/// with active call list access and meeting dialing.
+///
+public interface ICodecCallControls : IHasDialer
+{
+ ///
+ /// Gets the list of currently active, dialing, or incoming calls
+ ///
+ List ActiveCalls { get; }
+
+ ///
+ /// Dials the specified meeting
+ ///
+ /// The meeting to dial
+ void Dial(Meeting meeting);
+}
diff --git a/src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs b/src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs
index f378e621..95371404 100644
--- a/src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs
+++ b/src/PepperDash.Essentials.Devices.Common/Codec/iHasDialer.cs
@@ -53,5 +53,7 @@ public interface IHasDialer
/// Gets a value indicating whether the device is currently in a call
///
bool IsInCall { get; }
+
+
}
diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs
index 8b1be9e9..a2dd9e55 100644
--- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs
+++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/iVideoCodecInfo.cs
@@ -5,7 +5,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
///
/// Implements a common set of data about a codec
///
- public interface iVideoCodecInfo
+ public interface IVideoCodecInfo
{
///
/// Gets the codec information
diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs
index 8ed740d3..59f6097b 100644
--- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs
+++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/VideoCodecBase.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Core.Intersystem;
using PepperDash.Core.Intersystem.Tokens;
@@ -29,7 +28,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec;
/// Also contains the logic to link commonly implemented interfaces to the API bridge.
///
public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
- IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode
+ IUsageTracking, ICodecCallControls, IHasContentSharing, ICodecAudio, IVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode, IHasReady
{
private const int XSigEncoding = 28591;
@@ -338,7 +337,7 @@ public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutpu
///
/// Fired when the Codec is ready to be used
///
- public event EventHandler IsReadyChange;
+ public event EventHandler IsReadyEvent;
///
/// Dials the specified meeting
@@ -405,7 +404,7 @@ public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutpu
try
{
IsReady = true;
- IsReadyChange?.Invoke(this, new EventArgs());
+ IsReadyEvent?.Invoke(this, new IsReadyEventArgs(IsReady));
}
catch (Exception e)
{
@@ -498,7 +497,7 @@ public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutpu
LinkVideoCodecInfoToApi(trilist, joinMap);
// Register for this event to link any functions that require the codec to be ready first
- codec.IsReadyChange += (o, a) =>
+ codec.IsReadyEvent += (o, a) =>
{
if (codec is IHasCodecCameras)
{
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCallControlsMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCallControlsMessenger.cs
new file mode 100644
index 00000000..c28cbede
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCallControlsMessenger.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common.Codec;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class ICallControlsMessenger : MessengerBase
+ {
+ private readonly ICodecCallControls _callControls;
+
+ /// Initializes a new instance of the class.
+ public ICallControlsMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _callControls = device as ICodecCallControls ?? throw new ArgumentNullException(nameof(device));
+ _callControls.CallStatusChange += CallControls_CallStatusChange;
+ }
+
+ ///
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/callControlsStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/dialMeeting", (id, content) =>
+ _callControls.Dial(content.ToObject()));
+
+ AddAction("/endCallById", (id, content) =>
+ {
+ var s = content.ToObject>();
+ var call = GetCallWithId(s.Value);
+ if (call != null)
+ _callControls.EndCall(call);
+ });
+
+ AddAction("/rejectById", (id, content) =>
+ {
+ var s = content.ToObject>();
+ var call = GetCallWithId(s.Value);
+ if (call != null)
+ _callControls.RejectCall(call);
+ });
+
+ AddAction("/acceptById", (id, content) =>
+ {
+ var s = content.ToObject>();
+ var call = GetCallWithId(s.Value);
+ if (call != null)
+ _callControls.AcceptCall(call);
+ });
+ }
+
+ private void CallControls_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ {
+ try
+ {
+ PostStatusMessage(BuildState());
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting call controls status");
+ }
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ Task.Run(() => PostStatusMessage(BuildState(), id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending call controls full status");
+ }
+ }
+
+ private ICallControlsStateMessage BuildState()
+ {
+ return new ICallControlsStateMessage
+ {
+ Calls = _callControls.ActiveCalls,
+ };
+ }
+
+ private CodecActiveCallItem GetCallWithId(string id)
+ {
+ return _callControls.ActiveCalls?.FirstOrDefault(c => c.Id == id);
+ }
+ }
+
+ ///
+ /// State message for
+ ///
+ public class ICallControlsStateMessage : DeviceStateMessageBase
+ {
+ ///
+ /// Gets or sets the list of active calls. Null if unknown or not applicable.
+ ///
+ [JsonProperty("calls", NullValueHandling = NullValueHandling.Ignore)]
+ public List Calls { get; set; }
+
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCallHistoryMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCallHistoryMessenger.cs
index 10e2f8d6..388f6a3c 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCallHistoryMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCallHistoryMessenger.cs
@@ -65,7 +65,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
PostStatusMessage(new IHasCallHistoryStateMessage
{
- RecentCalls = recents
+ RecentCalls = recents,
});
}
}
@@ -76,9 +76,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
}
+ ///
+ /// State message for
+ ///
+ ///
public class IHasCallHistoryStateMessage : DeviceStateMessageBase
{
+ ///
+ /// Gets or sets the list of recent calls. Null if unknown or not applicable.
+ ///
[JsonProperty("recentCalls", NullValueHandling = NullValueHandling.Ignore)]
public List RecentCalls { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the device has call history functionality. Null if unknown or not applicable.
+ ///
+ [JsonProperty("hasRecents", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? HasRecents { get; set; } = true; // Since this messenger should only be used for devices with call history, default to true unless specified otherwise.
}
}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlsMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlsMessenger.cs
index e20eabdc..cb83a26e 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlsMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlsMessenger.cs
@@ -81,7 +81,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
foreach (var cam in CameraController.Cameras)
{
- cameraList.Add(new KeyName{
+ cameraList.Add(new KeyName
+ {
Key = cam.Key,
Name = cam.Name
});
@@ -96,10 +97,27 @@ namespace PepperDash.Essentials.AppServer.Messengers
};
}
+ string mode = "";
+
+ if (CameraController is IHasCameraAutoMode speakerTrackCodec)
+ {
+ mode = speakerTrackCodec.CameraAutoModeIsOnFeedback.BoolValue
+ ? eCameraControlMode.Auto.ToString().ToLower()
+ : eCameraControlMode.Manual.ToString().ToLower();
+ }
+
+ if (CameraController is IHasCameraOff cameraOffCodec)
+ {
+ if (cameraOffCodec.CameraIsOffFeedback.BoolValue)
+ mode = eCameraControlMode.Off.ToString().ToLower();
+ }
+
var state = new IHasCamerasWithControlsStateMessage
{
CameraList = cameraList,
- SelectedCamera = selectedCamera
+ SelectedCamera = selectedCamera,
+ CameraMode = mode,
+ HasCameraAutoMode = CameraController is IHasCameraAutoMode,
};
PostStatusMessage(state, clientId);
@@ -122,6 +140,18 @@ namespace PepperDash.Essentials.AppServer.Messengers
///
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
public IKeyName SelectedCamera { get; set; }
+
+ ///
+ /// Indicates whether the device has any cameras. Null if unknown or not applicable.
+ ///
+ [JsonProperty("hasCameras", NullValueHandling = NullValueHandling.Ignore)]
+ public bool HasCameras { get; set; } = true; // Since this messenger should only be used for devices with cameras, default to true unless specified otherwise.
+
+ [JsonProperty("hasCameraAutoMode", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? HasCameraAutoMode { get; set; }
+
+ [JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
+ public string CameraMode { get; set; }
}
class KeyName : IKeyName
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecCamerasMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecCamerasMessenger.cs
index c3f8d3fd..9ea151bc 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecCamerasMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecCamerasMessenger.cs
@@ -249,6 +249,35 @@ namespace PepperDash.Essentials.AppServer.Messengers
return presetsCodec.NearEndPresets;
}
+ private Camera GetSelectedCamera(IHasCodecCameras camerasCodec)
+ {
+ var camera = new Camera();
+
+ if (camerasCodec.SelectedCameraFeedback != null)
+ camera.Key = camerasCodec.SelectedCameraFeedback.StringValue;
+ if (camerasCodec.SelectedCamera != null)
+ {
+ camera.Name = camerasCodec.SelectedCamera.Name;
+
+ if(camerasCodec.SelectedCamera is IHasCameraPtzControl cameraControls)
+ {
+ camera.Capabilities = new CameraCapabilities()
+ {
+ CanPan = cameraControls is IHasCameraPanControl,
+ CanTilt = cameraControls is IHasCameraTiltControl,
+ CanZoom = cameraControls is IHasCameraZoomControl,
+ CanFocus = cameraControls is IHasCameraFocusControl,
+ };
+ };
+ }
+
+ if (camerasCodec.ControllingFarEndCameraFeedback != null)
+ camera.IsFarEnd = camerasCodec.ControllingFarEndCameraFeedback.BoolValue;
+
+
+ return camera;
+ }
+
private void PostCameraMode()
{
try
@@ -294,6 +323,31 @@ namespace PepperDash.Essentials.AppServer.Messengers
this.LogError(ex, "Error posting camera presets");
}
}
+
+ private void SendFullStatus()
+ {
+ try
+ {
+ PostStatusMessage(new IHasCodecCamerasStateMessage
+ {
+ CameraMode = GetCameraMode(),
+ Cameras = new CameraStatus
+ {
+ CameraManualIsSupported = true,
+ CameraAutoIsSupported = _codec.SupportsCameraAutoMode,
+ CameraOffIsSupported = _codec.SupportsCameraOff,
+ CameraMode = GetCameraMode(),
+ Cameras = _cameraCodec.Cameras,
+ SelectedCamera = GetSelectedCamera(_cameraCodec)
+ },
+ Presets = GetCurrentPresets()
+ });
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending full camera status");
+ }
+ }
}
public class IHasCodecCamerasStateMessage : DeviceStateMessageBase
@@ -306,5 +360,96 @@ namespace PepperDash.Essentials.AppServer.Messengers
[JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
public List Presets { get; set; }
+
+ [JsonProperty("cameraSupportsAutoMode", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CameraSupportsAutoMode { get; set; }
+
+ [JsonProperty("cameraSupportsOffMode", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CameraSupportsOffMode { get; set; }
+ }
+
+ ///
+ /// Represents a CameraStatus
+ ///
+ public class CameraStatus
+ {
+ [JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CameraManualIsSupported { get; set; }
+
+ [JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CameraAutoIsSupported { get; set; }
+
+ [JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CameraOffIsSupported { get; set; }
+
+
+ ///
+ /// Gets or sets the CameraMode
+ ///
+ [JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
+ public string CameraMode { get; set; }
+
+
+ ///
+ /// Gets or sets the Cameras
+ ///
+ [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
+ public List Cameras { get; set; }
+
+
+ ///
+ /// Gets or sets the SelectedCamera
+ ///
+ [JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
+ public Camera SelectedCamera { get; set; }
+ }
+
+ ///
+ /// Represents a Camera
+ ///
+ public class Camera
+ {
+
+ ///
+ /// Gets or sets the Key
+ ///
+ [JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
+ public string Key { get; set; }
+
+
+ ///
+ /// Gets or sets the Name
+ ///
+ [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
+ public string Name { get; set; }
+
+ [JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? IsFarEnd { get; set; }
+
+
+ ///
+ /// Gets or sets the Capabilities
+ ///
+ [JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
+ public CameraCapabilities Capabilities { get; set; }
+ }
+
+ ///
+ /// Represents a CameraCapabilities
+ ///
+ public class CameraCapabilities
+ {
+ [JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CanPan { get; set; }
+
+ [JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CanTilt { get; set; }
+
+ [JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CanZoom { get; set; }
+
+ [JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? CanFocus { get; set; }
+
}
}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecRoomPresetsMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecRoomPresetsMessenger.cs
new file mode 100644
index 00000000..4bcbe254
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecRoomPresetsMessenger.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common.Cameras;
+using PepperDash.Essentials.Devices.Common.VideoCodec;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IHasCodecRoomPresetsMessenger : MessengerBase
+ {
+ private readonly IHasCodecRoomPresets _presets;
+ private readonly EssentialsDevice _device;
+
+ public IHasCodecRoomPresetsMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _device = device ?? throw new ArgumentNullException(nameof(device));
+ _presets = device as IHasCodecRoomPresets ?? throw new ArgumentNullException(nameof(device));
+ _presets.CodecRoomPresetsListHasChanged += Presets_ListHasChanged;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+ }
+
+ private void Presets_ListHasChanged(object sender, EventArgs e)
+ {
+ try
+ {
+ PostStatusMessage(new IHasCodecRoomPresetsStateMessage
+ {
+ Presets = GetCurrentPresets()
+ });
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting codec room presets");
+ }
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IHasCodecRoomPresetsStateMessage
+ {
+ Presets = GetCurrentPresets()
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending room presets full status");
+ }
+ }
+
+ private List GetCurrentPresets()
+ {
+ if (_device is IHasFarEndCameraControl farEndControl &&
+ farEndControl.ControllingFarEndCameraFeedback.BoolValue)
+ return _presets.FarEndRoomPresets;
+
+ return _presets.NearEndPresets;
+ }
+ }
+
+ public class IHasCodecRoomPresetsStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
+ public List Presets { get; set; }
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecSelfViewMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecSelfViewMessenger.cs
index dd31e547..85e103f7 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecSelfViewMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCodecSelfViewMessenger.cs
@@ -53,7 +53,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
PostStatusMessage(new IHasCodecSelfViewStateMessage
{
- CameraSelfViewIsOn = _selfView.SelfviewIsOnFeedback.BoolValue
+ CameraSelfViewIsOn = _selfView.SelfviewIsOnFeedback.BoolValue,
+ ShowSelfViewByDefault = _selfView.ShowSelfViewByDefault
});
}
catch (Exception ex)
@@ -63,9 +64,23 @@ namespace PepperDash.Essentials.AppServer.Messengers
}
}
+ ///
+ /// State message for
+ ///
public class IHasCodecSelfViewStateMessage : DeviceStateMessageBase
{
+ ///
+ /// Gets or sets a value indicating whether the codec's self view is currently on. Null if unknown or not applicable.
+ ///
+ ///
[JsonProperty("cameraSelfView", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraSelfViewIsOn { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the codec is set to show self view by default. Null if unknown or not applicable.
+ ///
+ ///
+ [JsonProperty("showSelfViewByDefault", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? ShowSelfViewByDefault { get; set; }
}
}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasContentSharingMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasContentSharingMessenger.cs
new file mode 100644
index 00000000..159c9a02
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasContentSharingMessenger.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common.Codec;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IHasContentSharingMessenger : MessengerBase
+ {
+ private readonly IHasContentSharing _sharing;
+
+ public IHasContentSharingMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _sharing = device as IHasContentSharing ?? throw new ArgumentNullException(nameof(device));
+ _sharing.SharingContentIsOnFeedback.OutputChange += SharingContentIsOnFeedback_OutputChange;
+ _sharing.SharingSourceFeedback.OutputChange += SharingSourceFeedback_OutputChange;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+ AddAction("/sharingStart", (id, content) => _sharing.StartSharing());
+ AddAction("/sharingStop", (id, content) => _sharing.StopSharing());
+ }
+
+ private void SharingContentIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ try
+ {
+ PostStatusMessage(new IHasContentSharingStateMessage
+ {
+ SharingContentIsOn = e.BoolValue
+ });
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting sharing content is on");
+ }
+ }
+
+ private void SharingSourceFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ try
+ {
+ PostStatusMessage(new IHasContentSharingStateMessage
+ {
+ SharingSource = e.StringValue
+ });
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting sharing source");
+ }
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IHasContentSharingStateMessage
+ {
+ SharingContentIsOn = _sharing.SharingContentIsOnFeedback.BoolValue,
+ SharingSource = _sharing.SharingSourceFeedback.StringValue
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending content sharing full status");
+ }
+ }
+ }
+
+ public class IHasContentSharingStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("sharingContentIsOn", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? SharingContentIsOn { get; set; }
+
+ [JsonProperty("sharingSource", NullValueHandling = NullValueHandling.Ignore)]
+ public string SharingSource { get; set; }
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasDialerMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasDialerMessenger.cs
new file mode 100644
index 00000000..143f953e
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasDialerMessenger.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common.Codec;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IHasDialerMessenger : MessengerBase
+ {
+ private readonly IHasDialer _dialer;
+
+ ///
+ public IHasDialerMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _dialer = device as IHasDialer ?? throw new ArgumentNullException(nameof(device));
+ _dialer.CallStatusChange += Dialer_CallStatusChange;
+ }
+
+ ///
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/dialStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/dial", (id, content) =>
+ {
+ var value = content.ToObject>();
+ _dialer.Dial(value.Value);
+ });
+
+
+ AddAction("/endAllCalls", (id, content) => _dialer.EndAllCalls());
+
+ AddAction("/dtmf", (id, content) =>
+ {
+ var s = content.ToObject>();
+ _dialer.SendDtmf(s.Value);
+ });
+ }
+
+ private void Dialer_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ {
+ try
+ {
+ var state = new IHasDialerStateMessage
+ {
+ IsInCall = _dialer.IsInCall
+ };
+
+ PostStatusMessage(state);
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting dialer call status");
+ }
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IHasDialerStateMessage
+ {
+ IsInCall = _dialer.IsInCall,
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending dialer full status");
+ }
+ }
+ }
+
+ ///
+ /// Message class representing the state of a device implementing
+ ///
+ public class IHasDialerStateMessage : DeviceStateMessageBase
+ {
+ ///
+ /// Indicates whether the device is currently in a call
+ ///
+ [JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? IsInCall { get; set; }
+
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasDirectoryMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasDirectoryMessenger.cs
index 8859a9fc..a19a4ae8 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasDirectoryMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasDirectoryMessenger.cs
@@ -129,7 +129,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
InitialPhonebookSyncComplete = _directory.PhonebookSyncState.InitialSyncComplete,
HasDirectory = true,
HasDirectorySearch = true,
- });
+ });
}
}
@@ -147,5 +147,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
[JsonProperty("hasDirectorySearch", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasDirectorySearch { get; set; }
+ ///
+ /// Gets or sets the DirectorySelectedFolderName
+ ///
+ [JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
+ public string DirectorySelectedFolderName { get; set; }
+
}
}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasFarEndContentStatusMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasFarEndContentStatusMessenger.cs
index 0e307a6f..c736bf82 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasFarEndContentStatusMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasFarEndContentStatusMessenger.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core.Logging;
@@ -12,7 +13,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
///
public class IHasFarEndContentStatusMessenger : MessengerBase
{
- private readonly IHasFarEndContentStatus _device;
+ private readonly IHasFarEndContentStatus device;
///
/// Initializes a new instance of the class.
@@ -20,7 +21,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
public IHasFarEndContentStatusMessenger(string key, string messagePath, EssentialsDevice device)
: base(key, messagePath, device)
{
- _device = device as IHasFarEndContentStatus ?? throw new ArgumentException("device must implement IHasFarEndContentStatus", nameof(device));
+ this.device = device as IHasFarEndContentStatus ?? throw new ArgumentException("device must implement IHasFarEndContentStatus", nameof(device));
}
///
@@ -28,7 +29,11 @@ namespace PepperDash.Essentials.AppServer.Messengers
{
base.RegisterActions();
- _device.ReceivingContent.OutputChange += (sender, args) => PostReceivingContent(args.BoolValue);
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/farEndContentStatus", (id, content) => SendFullStatus(id));
+
+ device.ReceivingContent.OutputChange += (sender, args) => PostReceivingContent(args.BoolValue);
}
private void PostReceivingContent(bool receivingContent)
@@ -45,10 +50,33 @@ namespace PepperDash.Essentials.AppServer.Messengers
this.LogError(ex, "Error posting receiving content");
}
}
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IHasFarEndContentStatusStateMessage
+ {
+ ReceivingContent = device.ReceivingContent.BoolValue
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting full status");
+ }
+ }
}
+ ///
+ /// Message class representing the state of a device implementing
+ ///
public class IHasFarEndContentStatusStateMessage : DeviceStateMessageBase
{
+ ///
+ /// Indicates whether the device is currently receiving content from the far end
+ ///
[JsonProperty("receivingContent", NullValueHandling = NullValueHandling.Ignore)]
public bool? ReceivingContent { get; set; }
}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasMeetingInfoMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasMeetingInfoMessenger.cs
new file mode 100644
index 00000000..7aeb6765
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasMeetingInfoMessenger.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IHasMeetingInfoMessenger : MessengerBase
+ {
+ private readonly IHasMeetingInfo _meetingInfo;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IHasMeetingInfoMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _meetingInfo = device as IHasMeetingInfo ?? throw new ArgumentNullException(nameof(device));
+ _meetingInfo.MeetingInfoChanged += MeetingInfo_Changed;
+ }
+
+ ///
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/meetingInfoStatus", (id, content) => SendFullStatus(id));
+ }
+
+ private void MeetingInfo_Changed(object sender, MeetingInfoEventArgs e)
+ {
+ try
+ {
+ PostStatusMessage(new IHasMeetingInfoStateMessage
+ {
+ MeetingInfo = _meetingInfo.MeetingInfo
+ });
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting meeting info");
+ }
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IHasMeetingInfoStateMessage
+ {
+ MeetingInfo = _meetingInfo.MeetingInfo
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending meeting info full status");
+ }
+ }
+ }
+
+ ///
+ /// Message class for devices implementing
+ ///
+ public class IHasMeetingInfoStateMessage : DeviceStateMessageBase
+ {
+ ///
+ /// Gets or sets the MeetingInfo
+ ///
+ [JsonProperty("meetingInfo", NullValueHandling = NullValueHandling.Ignore)]
+ public MeetingInfo MeetingInfo { get; set; }
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasReadyMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasReadyMessenger.cs
new file mode 100644
index 00000000..3b704087
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasReadyMessenger.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IHasReadyMessenger : MessengerBase
+ {
+ private readonly IHasReady _hasReady;
+
+ public IHasReadyMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _hasReady = device as IHasReady ?? throw new ArgumentNullException(nameof(device));
+ _hasReady.IsReadyEvent += HasReady_IsReadyEvent;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/isReady", (id, content) => SendFullStatus(id));
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+ }
+
+ private void HasReady_IsReadyEvent(object sender, IsReadyEventArgs e)
+ {
+ try
+ {
+ PostStatusMessage(new IHasReadyStateMessage
+ {
+ IsReady = e.IsReady
+ });
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting ready state");
+ }
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IHasReadyStateMessage
+ {
+ IsReady = _hasReady.IsReady
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending ready full status");
+ }
+ }
+ }
+
+ public class IHasReadyStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("isReady", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? IsReady { get; set; }
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasStandbyModeMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasStandbyModeMessenger.cs
new file mode 100644
index 00000000..da493d4d
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasStandbyModeMessenger.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common.VideoCodec;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IHasStandbyModeMessenger : MessengerBase
+ {
+ private readonly IHasStandbyMode _standby;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public IHasStandbyModeMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _standby = device as IHasStandbyMode ?? throw new ArgumentNullException(nameof(device));
+ _standby.StandbyIsOnFeedback.OutputChange += StandbyIsOnFeedback_OutputChange;
+ }
+
+ ///
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+ AddAction("/standbyStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/standbyOn", (id, content) => _standby.StandbyActivate());
+ AddAction("/standbyOff", (id, content) => _standby.StandbyDeactivate());
+ }
+
+ private void StandbyIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ try
+ {
+ PostStatusMessage(new IHasStandbyModeStateMessage
+ {
+ StandbyIsOn = e.BoolValue
+ });
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting standby state");
+ }
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IHasStandbyModeStateMessage
+ {
+ StandbyIsOn = _standby.StandbyIsOnFeedback.BoolValue
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending standby full status");
+ }
+ }
+ }
+
+ ///
+ /// State message for
+ ///
+ public class IHasStandbyModeStateMessage : DeviceStateMessageBase
+ {
+ ///
+ /// Indicates whether the device is in standby mode. Null if unknown or not applicable.
+ ///
+ [JsonProperty("standbyIsOn", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? StandbyIsOn { get; set; }
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasStartMeetingMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasStartMeetingMessenger.cs
new file mode 100644
index 00000000..bc8559c0
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasStartMeetingMessenger.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IHasStartMeetingMessenger : MessengerBase
+ {
+ private readonly IHasStartMeeting _startMeeting;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The key for the messenger.
+ /// The message path for the messenger.
+ /// The device implementing .
+ /// Thrown if the device does not implement .
+ public IHasStartMeetingMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _startMeeting = device as IHasStartMeeting ?? throw new ArgumentNullException(nameof(device));
+ }
+
+ ///
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/startMeetingStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/startMeeting", (id, content) =>
+ {
+ var msg = content.ToObject>();
+ _startMeeting.StartMeeting(msg?.Value ?? _startMeeting.DefaultMeetingDurationMin);
+ });
+
+ AddAction("/leaveMeeting", (id, content) => _startMeeting.LeaveMeeting());
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IHasStartMeetingStateMessage
+ {
+ DefaultMeetingDurationMin = _startMeeting.DefaultMeetingDurationMin
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending start meeting full status");
+ }
+ }
+ }
+
+ ///
+ /// State message for devices implementing
+ ///
+ public class IHasStartMeetingStateMessage : DeviceStateMessageBase
+ {
+ ///
+ /// Indicates whether the device supports ad-hoc meetings (meetings started from the device rather than an external calendar invite)
+ ///
+ ///
+ [JsonProperty("supportsAdHocMeeting", NullValueHandling = NullValueHandling.Ignore)]
+ public bool SupportsAdHocMeeting { get; set; } = true;
+
+ ///
+ /// The default meeting duration in minutes for meetings started from the device. Null if unknown or not applicable.
+ ///
+ [JsonProperty("defaultMeetingDurationMin", NullValueHandling = NullValueHandling.Ignore)]
+ public uint DefaultMeetingDurationMin { get; set; }
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IPrivacyMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IPrivacyMessenger.cs
new file mode 100644
index 00000000..7657606e
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IPrivacyMessenger.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IPrivacyMessenger : MessengerBase
+ {
+ private readonly IPrivacy _privacy;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The key for the messenger.
+ /// The message path for the messenger.
+ /// The device implementing .
+ public IPrivacyMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _privacy = device as IPrivacy ?? throw new ArgumentNullException(nameof(device));
+ _privacy.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
+ }
+
+ ///
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+ AddAction("/privacyStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/privacyModeOn", (id, content) => _privacy.PrivacyModeOn());
+ AddAction("/privacyModeOff", (id, content) => _privacy.PrivacyModeOff());
+ AddAction("/privacyModeToggle", (id, content) => _privacy.PrivacyModeToggle());
+ }
+
+ private void PrivacyModeIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ try
+ {
+ PostStatusMessage(new IPrivacyStateMessage
+ {
+ PrivacyModeIsOn = e.BoolValue
+ });
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error posting privacy mode state");
+ }
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new IPrivacyStateMessage
+ {
+ PrivacyModeIsOn = _privacy.PrivacyModeIsOnFeedback.BoolValue
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending privacy full status");
+ }
+ }
+ }
+
+ ///
+ /// State message for
+ ///
+ public class IPrivacyStateMessage : DeviceStateMessageBase
+ {
+ ///
+ /// Gets or sets a value indicating whether privacy mode is on. Null if unknown or not
+ /// applicable.
+ ///
+ [JsonProperty("privacyModeIsOn", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? PrivacyModeIsOn { get; set; }
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IVideoCodecInfoMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IVideoCodecInfoMessenger.cs
new file mode 100644
index 00000000..8a8d51fa
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IVideoCodecInfoMessenger.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Core.Logging;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common.Codec;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Provides a messaging bridge for devices implementing
+ ///
+ public class IVideoCodecInfoMessenger : MessengerBase
+ {
+ private readonly IVideoCodecInfo _codecInfo;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IVideoCodecInfoMessenger(string key, string messagePath, EssentialsDevice device)
+ : base(key, messagePath, device)
+ {
+ _codecInfo = device as IVideoCodecInfo ?? throw new ArgumentNullException(nameof(device));
+ }
+
+ ///
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus(id));
+
+ AddAction("/codecInfoStatus", (id, content) => SendFullStatus(id));
+ }
+
+ private void SendFullStatus(string id = null)
+ {
+ try
+ {
+ var state = new iVideoCodecInfoStateMessage
+ {
+ Info = _codecInfo.CodecInfo
+ };
+
+ Task.Run(() => PostStatusMessage(state, id));
+ }
+ catch (Exception ex)
+ {
+ this.LogError(ex, "Error sending codec info full status");
+ }
+ }
+ }
+
+ ///
+ /// State message for
+ ///
+ public class iVideoCodecInfoStateMessage : DeviceStateMessageBase
+ {
+ ///
+ /// Gets or sets the codec information. Null if unknown or not applicable.
+ ///
+ [JsonProperty("info", NullValueHandling = NullValueHandling.Ignore)]
+ public VideoCodecInfo Info { get; set; }
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/VideoCodecBaseMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/VideoCodecBaseMessenger.cs
deleted file mode 100644
index 58e5da2f..00000000
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/VideoCodecBaseMessenger.cs
+++ /dev/null
@@ -1,550 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Crestron.SimplSharp;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using PepperDash.Core;
-using PepperDash.Core.Logging;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-using PepperDash.Essentials.Devices.Common.Cameras;
-using PepperDash.Essentials.Devices.Common.Codec;
-using PepperDash.Essentials.Devices.Common.VideoCodec;
-using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
-
-namespace PepperDash.Essentials.AppServer.Messengers
-{
- ///
- /// Provides a messaging bridge for a VideoCodecBase device
- ///
- public class VideoCodecBaseMessenger : MessengerBase
- {
- ///
- ///
- ///
- protected VideoCodecBase Codec { get; private set; }
-
- ///
- ///
- ///
- ///
- ///
- ///
- public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messagePath)
- : base(key, messagePath, codec)
- {
- Codec = codec ?? throw new ArgumentNullException("codec");
- codec.CallStatusChange += Codec_CallStatusChange;
- codec.IsReadyChange += Codec_IsReadyChange;
- }
-
- ///
- ///
- ///
- ///
- ///
- private void Codec_IsReadyChange(object sender, EventArgs e)
- {
- try
- {
- var state = new VideoCodecBaseStateMessage
- {
- IsReady = true
- };
-
- PostStatusMessage(state);
-
- SendFullStatus();
- }
- catch (Exception ex)
- {
- this.LogError(ex, "Error sending codec ready status");
- }
- }
-
- ///
- /// Called from base's RegisterWithAppServer method
- ///
- protected override void RegisterActions()
- {
- try
- {
- base.RegisterActions();
-
- AddAction("/isReady", (id, content) => SendIsReady());
-
- AddAction("/fullStatus", (id, content) => SendFullStatus(id));
- AddAction("/codecStatus", (id, content) => SendFullStatus(id));
-
- AddAction("/dial", (id, content) =>
- {
- var value = content.ToObject>();
-
- Codec.Dial(value.Value);
- });
-
- AddAction("/dialMeeting", (id, content) => Codec.Dial(content.ToObject()));
-
- AddAction("/endCallById", (id, content) =>
- {
- var s = content.ToObject>();
- var call = GetCallWithId(s.Value);
- if (call != null)
- Codec.EndCall(call);
- });
-
- AddAction("/endAllCalls", (id, content) => Codec.EndAllCalls());
-
- AddAction("/dtmf", (id, content) =>
- {
- var s = content.ToObject>();
- Codec.SendDtmf(s.Value);
- });
-
- AddAction("/rejectById", (id, content) =>
- {
- var s = content.ToObject>();
-
- var call = GetCallWithId(s.Value);
- if (call != null)
- Codec.RejectCall(call);
- });
-
- AddAction("/acceptById", (id, content) =>
- {
- var s = content.ToObject>();
-
- var call = GetCallWithId(s.Value);
- if (call != null)
- Codec.AcceptCall(call);
- });
-
- Codec.SharingContentIsOnFeedback.OutputChange += SharingContentIsOnFeedback_OutputChange;
- Codec.SharingSourceFeedback.OutputChange += SharingSourceFeedback_OutputChange;
-
- this.LogVerbose("Adding Privacy & Standby Actions");
-
- AddAction("/privacyModeOn", (id, content) => Codec.PrivacyModeOn());
- AddAction("/privacyModeOff", (id, content) => Codec.PrivacyModeOff());
- AddAction("/privacyModeToggle", (id, content) => Codec.PrivacyModeToggle());
- AddAction("/sharingStart", (id, content) => Codec.StartSharing());
- AddAction("/sharingStop", (id, content) => Codec.StopSharing());
- AddAction("/standbyOn", (id, content) => Codec.StandbyActivate());
- AddAction("/standbyOff", (id, content) => Codec.StandbyDeactivate());
- }
- catch (Exception e)
- {
- this.LogException(e, "Exception adding paths");
- }
- }
-
- private void SharingSourceFeedback_OutputChange(object sender, FeedbackEventArgs e)
- {
- try
- {
- var state = new VideoCodecBaseStateMessage
- {
- SharingSource = e.StringValue
- };
-
- PostStatusMessage(state);
- }
- catch (Exception ex)
- {
- this.LogError(ex, "Error posting sharing source");
- }
- }
-
- private void SharingContentIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
- {
- try
- {
- var state = new VideoCodecBaseStateMessage
- {
- SharingContentIsOn = e.BoolValue
- };
-
- PostStatusMessage(state);
- }
- catch (Exception ex)
- {
- this.LogError(ex, "Error posting sharing content");
- }
- }
-
- ///
- /// Handler for codec changes
- ///
- private void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
- {
- SendFullStatus();
- }
-
- ///
- ///
- ///
- private void SendIsReady()
- {
- try
- {
- var status = new VideoCodecBaseStateMessage();
-
- var codecType = Codec.GetType();
-
- status.IsReady = Codec.IsReady;
- status.IsZoomRoom = codecType.GetInterface("IHasZoomRoomLayouts") != null;
-
- PostStatusMessage(status);
- }
- catch (Exception ex)
- {
- this.LogError(ex, "Error sending codec ready status");
- }
- }
-
- ///
- /// Helper method to build call status for vtc
- ///
- ///
- protected VideoCodecBaseStateMessage GetStatus()
- {
- try
- {
- var status = new VideoCodecBaseStateMessage();
-
- if (Codec is IHasCodecCameras camerasCodec)
- {
- status.Cameras = new CameraStatus
- {
- CameraManualIsSupported = true,
- CameraAutoIsSupported = Codec.SupportsCameraAutoMode,
- CameraOffIsSupported = Codec.SupportsCameraOff,
- CameraMode = GetCameraMode(),
- Cameras = camerasCodec.Cameras,
- SelectedCamera = GetSelectedCamera(camerasCodec)
- };
- }
-
- var codecType = Codec.GetType();
-
- status.CameraSelfViewIsOn = Codec is IHasCodecSelfView && (Codec as IHasCodecSelfView).SelfviewIsOnFeedback.BoolValue;
- status.IsInCall = Codec.IsInCall;
- status.PrivacyModeIsOn = Codec.PrivacyModeIsOnFeedback.BoolValue;
- status.SharingContentIsOn = Codec.SharingContentIsOnFeedback.BoolValue;
- status.SharingSource = Codec.SharingSourceFeedback.StringValue;
- status.StandbyIsOn = Codec.StandbyIsOnFeedback.BoolValue;
- status.Calls = Codec.ActiveCalls;
- status.Info = Codec.CodecInfo;
- status.ShowSelfViewByDefault = Codec.ShowSelfViewByDefault;
- status.SupportsAdHocMeeting = Codec is IHasStartMeeting;
- status.HasRecents = Codec is IHasCallHistory;
- status.HasCameras = Codec is IHasCamerasWithControls;
- status.Presets = GetCurrentPresets();
- status.IsZoomRoom = codecType.GetInterface("IHasZoomRoomLayouts") != null;
- status.ReceivingContent = Codec is IHasFarEndContentStatus && (Codec as IHasFarEndContentStatus).ReceivingContent.BoolValue;
-
- if (Codec is IHasMeetingInfo meetingInfoCodec)
- {
- status.MeetingInfo = meetingInfoCodec.MeetingInfo;
- }
-
- return status;
- }
- catch (Exception ex)
- {
- this.LogError(ex, "Error getting codec status");
- return null;
- }
- }
-
- ///
- /// Sends the full status of the codec, including active calls, camera status, and directory info if applicable
- ///
- ///
- protected virtual void SendFullStatus(string id = null)
- {
- if (!Codec.IsReady)
- {
- return;
- }
-
- Task.Run(() => PostStatusMessage(GetStatus(), id));
- }
-
- ///
- /// Helper to grab a call with string ID
- ///
- private CodecActiveCallItem GetCallWithId(string id)
- {
- return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
- }
-
- private string GetCameraMode()
- {
- string m = "";
-
- if (Codec is IHasCameraAutoMode speakerTrackCodec)
- {
- m = speakerTrackCodec.CameraAutoModeIsOnFeedback.BoolValue
- ? eCameraControlMode.Auto.ToString().ToLower()
- : eCameraControlMode.Manual.ToString().ToLower();
- }
-
- if (Codec is IHasCameraOff cameraOffCodec)
- {
- if (cameraOffCodec.CameraIsOffFeedback.BoolValue)
- m = eCameraControlMode.Off.ToString().ToLower();
- }
-
- return m;
- }
-
- private Camera GetSelectedCamera(IHasCodecCameras camerasCodec)
- {
- var camera = new Camera();
-
- if (camerasCodec.SelectedCameraFeedback != null)
- camera.Key = camerasCodec.SelectedCameraFeedback.StringValue;
- if (camerasCodec.SelectedCamera != null)
- {
- camera.Name = camerasCodec.SelectedCamera.Name;
-
- if(camerasCodec.SelectedCamera is IHasCameraPtzControl cameraControls)
- {
- camera.Capabilities = new CameraCapabilities()
- {
- CanPan = cameraControls is IHasCameraPanControl,
- CanTilt = cameraControls is IHasCameraTiltControl,
- CanZoom = cameraControls is IHasCameraZoomControl,
- CanFocus = cameraControls is IHasCameraFocusControl,
- };
- };
- }
-
- if (camerasCodec.ControllingFarEndCameraFeedback != null)
- camera.IsFarEnd = camerasCodec.ControllingFarEndCameraFeedback.BoolValue;
-
-
- return camera;
- }
-
- private List GetCurrentPresets()
- {
- var presetsCodec = Codec as IHasCodecRoomPresets;
-
- List currentPresets = null;
-
- if (presetsCodec != null && Codec is IHasFarEndCameraControl &&
- (Codec as IHasFarEndCameraControl).ControllingFarEndCameraFeedback.BoolValue)
- currentPresets = presetsCodec.FarEndRoomPresets;
- else if (presetsCodec != null) currentPresets = presetsCodec.NearEndPresets;
-
- return currentPresets;
- }
- }
-
- ///
- /// Represents a VideoCodecBaseStateMessage
- ///
- public class VideoCodecBaseStateMessage : DeviceStateMessageBase
- {
-
- [JsonProperty("calls", NullValueHandling = NullValueHandling.Ignore)]
- public List Calls { get; set; }
-
- [JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
- public string CameraMode { get; set; }
-
- [JsonProperty("cameraSelfView", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CameraSelfViewIsOn { get; set; }
-
- [JsonProperty("cameras", NullValueHandling = NullValueHandling.Ignore)]
- ///
- /// Gets or sets the Cameras
- ///
- public CameraStatus Cameras { get; set; }
-
- [JsonProperty("cameraSupportsAutoMode", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CameraSupportsAutoMode { get; set; }
-
- [JsonProperty("cameraSupportsOffMode", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CameraSupportsOffMode { get; set; }
-
-
- ///
- /// Gets or sets the CurrentDialString
- ///
- [JsonProperty("currentDialString", NullValueHandling = NullValueHandling.Ignore)]
- public string CurrentDialString { get; set; }
-
-
-
- ///
- /// Gets or sets the DirectorySelectedFolderName
- ///
- [JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
- public string DirectorySelectedFolderName { get; set; }
-
- [JsonProperty("hasCameras", NullValueHandling = NullValueHandling.Ignore)]
- public bool? HasCameras { get; set; }
-
-
-
- [JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)]
- public bool? HasPresets { get; set; }
-
- [JsonProperty("hasRecents", NullValueHandling = NullValueHandling.Ignore)]
- public bool? HasRecents { get; set; }
-
- [JsonProperty("initialPhonebookSyncComplete", NullValueHandling = NullValueHandling.Ignore)]
- public bool? InitialPhonebookSyncComplete { get; set; }
-
-
- ///
- /// Gets or sets the Info
- ///
- [JsonProperty("info", NullValueHandling = NullValueHandling.Ignore)]
- public VideoCodecInfo Info { get; set; }
-
- [JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)]
- public bool? IsInCall { get; set; }
-
- [JsonProperty("isReady", NullValueHandling = NullValueHandling.Ignore)]
- public bool? IsReady { get; set; }
-
- [JsonProperty("isZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
- public bool? IsZoomRoom { get; set; }
-
-
- ///
- /// Gets or sets the MeetingInfo
- ///
- [JsonProperty("meetingInfo", NullValueHandling = NullValueHandling.Ignore)]
- public MeetingInfo MeetingInfo { get; set; }
-
-
- ///
- /// Gets or sets the Presets
- ///
- [JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
- public List Presets { get; set; }
-
- [JsonProperty("privacyModeIsOn", NullValueHandling = NullValueHandling.Ignore)]
- public bool? PrivacyModeIsOn { get; set; }
-
- [JsonProperty("receivingContent", NullValueHandling = NullValueHandling.Ignore)]
- public bool? ReceivingContent { get; set; }
-
- [JsonProperty("recentCalls", NullValueHandling = NullValueHandling.Ignore)]
- public List RecentCalls { get; set; }
-
- [JsonProperty("sharingContentIsOn", NullValueHandling = NullValueHandling.Ignore)]
- public bool? SharingContentIsOn { get; set; }
-
-
- ///
- /// Gets or sets the SharingSource
- ///
- [JsonProperty("sharingSource", NullValueHandling = NullValueHandling.Ignore)]
- public string SharingSource { get; set; }
-
- [JsonProperty("showCamerasWhenNotInCall", NullValueHandling = NullValueHandling.Ignore)]
- public bool? ShowCamerasWhenNotInCall { get; set; }
-
- [JsonProperty("showSelfViewByDefault", NullValueHandling = NullValueHandling.Ignore)]
- public bool? ShowSelfViewByDefault { get; set; }
-
- [JsonProperty("standbyIsOn", NullValueHandling = NullValueHandling.Ignore)]
- public bool? StandbyIsOn { get; set; }
-
- [JsonProperty("supportsAdHocMeeting", NullValueHandling = NullValueHandling.Ignore)]
- public bool? SupportsAdHocMeeting { get; set; }
- }
-
- ///
- /// Represents a CameraStatus
- ///
- public class CameraStatus
- {
- [JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CameraManualIsSupported { get; set; }
-
- [JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CameraAutoIsSupported { get; set; }
-
- [JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CameraOffIsSupported { get; set; }
-
-
- ///
- /// Gets or sets the CameraMode
- ///
- [JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
- public string CameraMode { get; set; }
-
-
- ///
- /// Gets or sets the Cameras
- ///
- [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
- public List Cameras { get; set; }
-
-
- ///
- /// Gets or sets the SelectedCamera
- ///
- [JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
- public Camera SelectedCamera { get; set; }
- }
-
- ///
- /// Represents a Camera
- ///
- public class Camera
- {
-
- ///
- /// Gets or sets the Key
- ///
- [JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
- public string Key { get; set; }
-
-
- ///
- /// Gets or sets the Name
- ///
- [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
- public string Name { get; set; }
-
- [JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)]
- public bool? IsFarEnd { get; set; }
-
-
- ///
- /// Gets or sets the Capabilities
- ///
- [JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
- public CameraCapabilities Capabilities { get; set; }
- }
-
- ///
- /// Represents a CameraCapabilities
- ///
- public class CameraCapabilities
- {
- [JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CanPan { get; set; }
-
- [JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CanTilt { get; set; }
-
- [JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CanZoom { get; set; }
-
- [JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
- public bool? CanFocus { get; set; }
-
- }
-}
\ No newline at end of file
diff --git a/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs b/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs
index 96bc8ee5..ae757962 100644
--- a/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs
+++ b/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs
@@ -14,6 +14,7 @@ using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.Displays;
using PepperDash.Essentials.Devices.Common.SoftCodec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
+using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
using PepperDash.Essentials.Room.MobileControl;
namespace PepperDash.Essentials
@@ -161,9 +162,39 @@ namespace PepperDash.Essentials
// ── Codecs ───────────────────────────────────────────────────────────────
new MessengerFactoryEntry(
- typeof(VideoCodecBase),
- (d, mp, ck) => new VideoCodecBaseMessenger(
- $"{d.Key}-videoCodec-{ck}", (VideoCodecBase)d, mp)
+ typeof(IHasReady),
+ (d, mp, ck) => new IHasReadyMessenger(
+ $"{d.Key}-ready-{ck}", mp, d)
+ ),
+ new MessengerFactoryEntry(
+ typeof(IHasDialer),
+ (d, mp, ck) => new IHasDialerMessenger(
+ $"{d.Key}-dialer-{ck}", mp, d)
+ ),
+ new MessengerFactoryEntry(
+ typeof(ICodecCallControls),
+ (d, mp, ck) => new ICallControlsMessenger(
+ $"{d.Key}-callControls-{ck}", mp, d)
+ ),
+ new MessengerFactoryEntry(
+ typeof(IHasContentSharing),
+ (d, mp, ck) => new IHasContentSharingMessenger(
+ $"{d.Key}-contentSharing-{ck}", mp, d)
+ ),
+ new MessengerFactoryEntry(
+ typeof(IHasStandbyMode),
+ (d, mp, ck) => new IHasStandbyModeMessenger(
+ $"{d.Key}-standby-{ck}", mp, d)
+ ),
+ new MessengerFactoryEntry(
+ typeof(IPrivacy),
+ (d, mp, ck) => new IPrivacyMessenger(
+ $"{d.Key}-privacy-{ck}", mp, d)
+ ),
+ new MessengerFactoryEntry(
+ typeof(IVideoCodecInfo),
+ (d, mp, ck) => new IVideoCodecInfoMessenger(
+ $"{d.Key}-codecInfo-{ck}", mp, d)
),
new MessengerFactoryEntry(
typeof(IHasDirectory),
@@ -186,6 +217,11 @@ namespace PepperDash.Essentials
$"{d.Key}-codecCameras-{ck}", mp, (VideoCodecBase)d),
predicate: d => d is VideoCodecBase && d is IHasCodecCameras
),
+ new MessengerFactoryEntry(
+ typeof(IHasCodecRoomPresets),
+ (d, mp, ck) => new IHasCodecRoomPresetsMessenger(
+ $"{d.Key}-codecRoomPresets-{ck}", mp, d)
+ ),
new MessengerFactoryEntry(
typeof(IHasCodecSelfView),
(d, mp, ck) => new IHasCodecSelfViewMessenger(
@@ -201,6 +237,16 @@ namespace PepperDash.Essentials
(d, mp, ck) => new IHasFarEndContentStatusMessenger(
$"{d.Key}-farEndContent-{ck}", mp, d)
),
+ new MessengerFactoryEntry(
+ typeof(IHasMeetingInfo),
+ (d, mp, ck) => new IHasMeetingInfoMessenger(
+ $"{d.Key}-meetingInfo-{ck}", mp, d)
+ ),
+ new MessengerFactoryEntry(
+ typeof(IHasStartMeeting),
+ (d, mp, ck) => new IHasStartMeetingMessenger(
+ $"{d.Key}-startMeeting-{ck}", mp, d)
+ ),
new MessengerFactoryEntry(
typeof(IDialerCallStatus),
(d, mp, ck) => new IDialerCallStatusMessenger(