diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/Base Classes/VideoCodecBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/Base Classes/VideoCodecBase.cs
index 1c31ab20..016379b3 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/Base Classes/VideoCodecBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/Base Classes/VideoCodecBase.cs
@@ -2,81 +2,38 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Crestron.SimplSharp.CrestronIO;
+using Crestron.SimplSharp.Ssh;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharp;
using PepperDash.Core;
+using PepperDash.Core.Intersystem;
+using PepperDash.Core.Intersystem.Tokens;
+using PepperDash.Core.WebApi.Presets;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash.Essentials.Core.Bridges.JoinMaps;
using PepperDash.Essentials.Core.Config;
-using PepperDash.Essentials.Core.Routing;
+using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Devices.Codec;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Routing;
using PepperDash.Essentials.Devices.Common.Codec;
+using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
+using PepperDash.Essentials.Devices.Core.VideoCodec;
+using Feedback = PepperDash.Essentials.Core.Feedback;
-namespace PepperDash.Essentials.Core.Devices.VideoCodec
+namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
- IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo
+ IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
{
- ///
- /// Fires when the status of any active, dialing, or incoming call changes or is new
- ///
- public event EventHandler CallStatusChange;
-
- public event EventHandler IsReadyChange;
-
- public IBasicCommunication Communication { get; protected set; }
-
- #region IUsageTracking Members
-
- ///
- /// This object can be added by outside users of this class to provide usage tracking
- /// for various services
- ///
- public UsageTracking UsageTracker { get; set; }
-
- #endregion
-
- ///
- /// An internal pseudo-source that is routable and connected to the osd input
- ///
- public DummyRoutingInputsDevice OsdSource { get; protected set; }
-
- public RoutingPortCollection InputPorts { get; private set; }
-
- public RoutingPortCollection OutputPorts { get; private set; }
-
- ///
- /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected
- ///
- public bool IsInCall
- {
- get
- {
- bool value;
-
- if (ActiveCalls != null)
- value = ActiveCalls.Any(c => c.IsActiveCall);
- else
- value = false;
- return value;
- }
- }
-
- public BoolFeedback StandbyIsOnFeedback { get; private set; }
-
- abstract protected Func PrivacyModeIsOnFeedbackFunc { get; }
- abstract protected Func VolumeLevelFeedbackFunc { get; }
- abstract protected Func MuteFeedbackFunc { get; }
- abstract protected Func StandbyIsOnFeedbackFunc { get; }
-
- public List ActiveCalls { get; set; }
-
- public VideoCodecInfo CodecInfo { get; protected set; }
-
- public bool ShowSelfViewByDefault { get; protected set; }
-
-
- public bool IsReady { get; protected set; }
-
- public VideoCodecBase(DeviceConfig config)
+ private const int XSigEncoding = 28591;
+ private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
+ protected VideoCodecBase(DeviceConfig config)
: base(config)
{
+
StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc);
PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc);
VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc);
@@ -86,85 +43,47 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
InputPorts = new RoutingPortCollection();
OutputPorts = new RoutingPortCollection();
-
+
ActiveCalls = new List();
}
- #region IHasDialer Members
+ public IBasicCommunication Communication { get; protected set; }
- public abstract void Dial(string number);
- public abstract void Dial(Meeting meeting);
- public virtual void Dial(IInvitableContact contact)
- {
+ ///
+ /// An internal pseudo-source that is routable and connected to the osd input
+ ///
+ public DummyRoutingInputsDevice OsdSource { get; protected set; }
- }
- public abstract void EndCall(CodecActiveCallItem call);
- public abstract void EndAllCalls();
- public abstract void AcceptCall(CodecActiveCallItem call);
- public abstract void RejectCall(CodecActiveCallItem call);
- public abstract void SendDtmf(string s);
+ public BoolFeedback StandbyIsOnFeedback { get; private set; }
- #endregion
+ protected abstract Func PrivacyModeIsOnFeedbackFunc { get; }
+ protected abstract Func VolumeLevelFeedbackFunc { get; }
+ protected abstract Func MuteFeedbackFunc { get; }
+ protected abstract Func StandbyIsOnFeedbackFunc { get; }
+
+ public List ActiveCalls { get; set; }
+
+ public bool ShowSelfViewByDefault { get; protected set; }
+
+ protected bool SupportsCameraOff;
+ protected bool SupportsCameraAutoMode;
+
+ public bool IsReady { get; protected set; }
public virtual List Feedbacks
{
get
{
return new List
- {
+ {
PrivacyModeIsOnFeedback,
SharingSourceFeedback
- };
+ };
}
}
- public abstract void ExecuteSwitch(object selector);
-
- ///
- /// Helper method to fire CallStatusChange event with old and new status
- ///
- protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call)
- {
- call.Status = newStatus;
-
- OnCallStatusChange(call);
-
- }
-
- ///
- ///
- ///
- ///
- ///
- ///
- protected void OnCallStatusChange(CodecActiveCallItem item)
- {
- var handler = CallStatusChange;
- if (handler != null)
- handler(this, new CodecCallStatusItemChangeEventArgs(item));
-
- if (AutoShareContentWhileInCall)
- StartSharing();
-
- if (UsageTracker != null)
- {
- if (IsInCall && !UsageTracker.UsageTrackingStarted)
- UsageTracker.StartDeviceUsage();
- else if (UsageTracker.UsageTrackingStarted && !IsInCall)
- UsageTracker.EndDeviceUsage();
- }
- }
-
- ///
- /// Sets IsReady property and fires the event. Used for dependent classes to sync up their data.
- ///
- protected void SetIsReady()
- {
- IsReady = true;
- var h = IsReadyChange;
- if(h != null)
- h(this, new EventArgs());
- }
+ protected abstract Func SharingSourceFeedbackFunc { get; }
+ protected abstract Func SharingContentIsOnFeedbackFunc { get; }
#region ICodecAudio Members
@@ -193,7 +112,7 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
#endregion
- #region IHasSharing Members
+ #region IHasContentSharing Members
public abstract void StartSharing();
public abstract void StopSharing();
@@ -203,12 +122,134 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
public StringFeedback SharingSourceFeedback { get; private set; }
public BoolFeedback SharingContentIsOnFeedback { get; private set; }
- abstract protected Func SharingSourceFeedbackFunc { get; }
- abstract protected Func SharingContentIsOnFeedbackFunc { get; }
+ #endregion
+ #region IHasDialer Members
+
+ ///
+ /// Fires when the status of any active, dialing, or incoming call changes or is new
+ ///
+ public event EventHandler CallStatusChange;
+
+ ///
+ /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected
+ ///
+ public bool IsInCall
+ {
+ get
+ {
+ var value = ActiveCalls != null && ActiveCalls.Any(c => c.IsActiveCall);
+ return value;
+ }
+ }
+
+ public abstract void Dial(string number);
+ public abstract void EndCall(CodecActiveCallItem call);
+ public abstract void EndAllCalls();
+ public abstract void AcceptCall(CodecActiveCallItem call);
+ public abstract void RejectCall(CodecActiveCallItem call);
+ public abstract void SendDtmf(string s);
#endregion
+ #region IRoutingInputsOutputs Members
+
+ public RoutingPortCollection InputPorts { get; private set; }
+
+ public RoutingPortCollection OutputPorts { get; private set; }
+
+ #endregion
+
+ #region IUsageTracking Members
+
+ ///
+ /// This object can be added by outside users of this class to provide usage tracking
+ /// for various services
+ ///
+ public UsageTracking UsageTracker { get; set; }
+
+ #endregion
+
+ #region iVideoCodecInfo Members
+
+ public VideoCodecInfo CodecInfo { get; protected set; }
+
+ #endregion
+
+ public event EventHandler IsReadyChange;
+ public abstract void Dial(Meeting meeting);
+
+ public virtual void Dial(IInvitableContact contact)
+ {
+ }
+
+ public abstract void ExecuteSwitch(object selector);
+
+ ///
+ /// Helper method to fire CallStatusChange event with old and new status
+ ///
+ protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call)
+ {
+ call.Status = newStatus;
+
+ OnCallStatusChange(call);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected virtual void OnCallStatusChange(CodecActiveCallItem item)
+ {
+ var handler = CallStatusChange;
+ if (handler != null)
+ {
+ handler(this, new CodecCallStatusItemChangeEventArgs(item));
+ }
+
+ if (AutoShareContentWhileInCall)
+ {
+ StartSharing();
+ }
+
+ if (UsageTracker != null)
+ {
+ if (IsInCall && !UsageTracker.UsageTrackingStarted)
+ {
+ UsageTracker.StartDeviceUsage();
+ }
+ else if (UsageTracker.UsageTrackingStarted && !IsInCall)
+ {
+ UsageTracker.EndDeviceUsage();
+ }
+ }
+ }
+
+ ///
+ /// Sets IsReady property and fires the event. Used for dependent classes to sync up their data.
+ ///
+ protected void SetIsReady()
+ {
+ CrestronInvoke.BeginInvoke( (o) =>
+ {
+ try
+ {
+ IsReady = true;
+ var h = IsReadyChange;
+ if (h != null)
+ {
+ h(this, new EventArgs());
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Console(2, this, "Error in SetIsReady() : {0}", e);
+ }
+ });
+ }
+
// **** DEBUGGING THINGS ****
///
///
@@ -217,7 +258,9 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
{
var sb = new StringBuilder();
foreach (var c in ActiveCalls)
+ {
sb.AppendFormat("{0} {1} -- {2} {3}\n", c.Id, c.Number, c.Name, c.Status);
+ }
Debug.Console(1, this, "\n{0}\n", sb.ToString());
}
@@ -225,6 +268,888 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
public abstract void StandbyDeactivate();
+ #region Implementation of IBridgeAdvanced
+
+ public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
+
+ protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
+ EiscApiAdvanced bridge)
+ {
+ var joinMap = new VideoCodecControllerJoinMap(joinStart);
+
+ var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
+
+ if (customJoins != null)
+ {
+ joinMap.SetCustomJoinData(customJoins);
+ }
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+
+ Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
+
+
+
+ LinkVideoCodecDtmfToApi(trilist, joinMap);
+
+ LinkVideoCodecCallControlsToApi(trilist, joinMap);
+
+ LinkVideoCodecContentSharingToApi(trilist, joinMap);
+
+ LinkVideoCodecPrivacyToApi(trilist, joinMap);
+
+ LinkVideoCodecVolumeToApi(trilist, joinMap);
+
+ if (codec is ICommunicationMonitor)
+ {
+ LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap);
+ }
+
+ if (codec is IHasCodecCameras)
+ {
+ LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap);
+ }
+
+ if (codec is IHasCodecSelfView)
+ {
+ LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap);
+ }
+
+ if (codec is IHasCameraAutoMode)
+ {
+ trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode);
+ LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap);
+ }
+
+ if (codec is IHasCameraOff)
+ {
+ trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff);
+ LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap);
+ }
+
+ if (codec is IHasCodecLayouts)
+ {
+ LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap);
+ }
+
+ if (codec is IHasSelfviewPosition)
+ {
+ LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap);
+ }
+
+ if (codec is IHasDirectory)
+ {
+ LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap);
+ }
+
+ if (codec is IHasScheduleAwareness)
+ {
+ LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap);
+ }
+
+ if (codec is IHasParticipants)
+ {
+ LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap);
+ }
+
+ if (codec is IHasFarEndContentStatus)
+ {
+ (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]);
+ }
+
+ if (codec is IHasPhoneDialing)
+ {
+ LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap);
+ }
+
+ trilist.OnlineStatusChange += (device, args) =>
+ {
+ if (!args.DeviceOnLine) return;
+
+ if (codec is IHasDirectory)
+ {
+ (codec as IHasDirectory).SetCurrentDirectoryToRoot();
+ }
+
+ if (codec is IHasScheduleAwareness)
+ {
+ (codec as IHasScheduleAwareness).GetSchedule();
+ }
+
+ if (codec is IHasParticipants)
+ {
+ UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants);
+ }
+
+ if (codec is IHasCameraAutoMode)
+ {
+ trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true);
+
+ (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
+ }
+
+ if (codec is IHasCodecSelfView)
+ {
+ (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate();
+ }
+
+ if (codec is IHasCameraAutoMode)
+ {
+ (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
+ }
+
+ if (codec is IHasCameraOff)
+ {
+ (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate();
+ }
+
+ if (codec is IHasPhoneDialing)
+ {
+ (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate();
+ }
+
+ SharingContentIsOnFeedback.FireUpdate();
+
+ trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
+
+ trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
+ };
+ }
+
+ private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber,
+ () => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue));
+
+ trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall);
+ }
+
+ private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle);
+
+ codec.SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.SelfviewPositionFb.JoinNumber]);
+ }
+
+ private void LinkVideoCodecCameraOffToApi(IHasCameraOff codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.CameraModeOff.JoinNumber, codec.CameraOff);
+
+ codec.CameraIsOffFeedback.OutputChange += (o, a) =>
+ {
+ if (a.BoolValue)
+ {
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+
+ var autoCodec = codec as IHasCameraAutoMode;
+
+ if (autoCodec == null) return;
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
+ };
+
+ if (codec.CameraIsOffFeedback.BoolValue)
+ {
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+
+ var autoModeCodec = codec as IHasCameraAutoMode;
+
+ if (autoModeCodec == null) return;
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
+ }
+
+ private void LinkVideoCodecVolumeToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
+ MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.VolumeMuteOn.JoinNumber, MuteOn);
+ trilist.SetSigFalseAction(joinMap.VolumeMuteOff.JoinNumber, MuteOff);
+ trilist.SetSigFalseAction(joinMap.VolumeMuteToggle.JoinNumber, MuteToggle);
+
+ VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
+
+ trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, VolumeUp);
+ trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, VolumeDown);
+
+ trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, SetVolume);
+
+ }
+
+ private void LinkVideoCodecPrivacyToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ PrivacyModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.MicMuteOn.JoinNumber]);
+ PrivacyModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.MicMuteOff.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.MicMuteOn.JoinNumber, PrivacyModeOn);
+ trilist.SetSigFalseAction(joinMap.MicMuteOff.JoinNumber, PrivacyModeOff);
+ trilist.SetSigFalseAction(joinMap.MicMuteToggle.JoinNumber, PrivacyModeToggle);
+ }
+
+ private void LinkVideoCodecCommMonitorToApi(ICommunicationMonitor codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
+ }
+
+ private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.Participants.ParticipantsListHasChanged += (sender, args) =>
+ {
+ string participantsXSig;
+
+ if (codec.Participants.CurrentParticipants.Count == 0)
+ {
+ participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
+ trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
+ trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
+ return;
+ }
+
+ participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
+
+ trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
+
+ trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort) codec.Participants.CurrentParticipants.Count);
+ };
+ }
+
+ private string UpdateParticipantsXSig(List currentParticipants)
+ {
+ const int maxParticipants = 50;
+ const int maxDigitals = 5;
+ const int maxStrings = 1;
+ const int offset = maxDigitals + maxStrings;
+ var digitalIndex = maxStrings * maxParticipants; //15
+ var stringIndex = 0;
+ var meetingIndex = 0;
+
+ var tokenArray = new XSigToken[maxParticipants * offset];
+
+ foreach (var participant in currentParticipants)
+ {
+ if (meetingIndex >= maxParticipants * offset) break;
+
+ //digitals
+ tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb);
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb);
+ tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
+ tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
+ tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
+
+ //serials
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
+
+ digitalIndex += maxDigitals;
+ meetingIndex += offset;
+ stringIndex += maxStrings;
+ }
+
+ while (meetingIndex < maxParticipants*offset)
+ {
+ tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
+ tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
+ tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
+ tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
+
+ //serials
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
+
+ digitalIndex += maxDigitals;
+ meetingIndex += offset;
+ stringIndex += maxStrings;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]);
+ SharingContentIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.SourceShareEnd.JoinNumber]);
+
+ SharingSourceFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentSource.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.SourceShareStart.JoinNumber, StartSharing);
+ trilist.SetSigFalseAction(joinMap.SourceShareEnd.JoinNumber, StopSharing);
+
+ trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
+ }
+
+ private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.UpdateMeetings.JoinNumber, codec.GetSchedule);
+
+ trilist.SetUShortSigAction(joinMap.MinutesBeforeMeetingStart.JoinNumber, (i) =>
+ {
+ codec.CodecSchedule.MeetingWarningMinutes = i;
+ });
+
+ codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap);
+
+ codec.CodecSchedule.MeetingEventChange +=
+ (sender, args) =>
+ {
+ if (args.ChangeType == eMeetingEventChangeType.MeetingStartWarning)
+ {
+ UpdateMeetingsList(codec, trilist, joinMap);
+ }
+ };
+ }
+
+ private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ var currentTime = DateTime.Now;
+ var currentMeetings =
+ codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
+
+ var meetingsData = UpdateMeetingsListXSig(currentMeetings);
+
+ trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
+
+ trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
+ {
+ if(codec.CodecSchedule.Meetings[0] != null)
+ Dial(codec.CodecSchedule.Meetings[0]);
+ });
+ trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
+ {
+ if (codec.CodecSchedule.Meetings[1] != null)
+ Dial(codec.CodecSchedule.Meetings[1]);
+ });
+ trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
+ {
+ if (codec.CodecSchedule.Meetings[2] != null)
+ Dial(codec.CodecSchedule.Meetings[2]);
+ });
+
+ trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)currentMeetings.Count);
+ }
+
+ private string UpdateMeetingsListXSig(List meetings)
+ {
+ const int maxMeetings = 3;
+ const int maxDigitals = 2;
+ const int maxStrings = 7;
+ const int offset = maxDigitals + maxStrings;
+ var digitalIndex = maxStrings*maxMeetings; //15
+ var stringIndex = 0;
+ var meetingIndex = 0;
+
+ var tokenArray = new XSigToken[maxMeetings*offset];
+ /*
+ * Digitals
+ * IsJoinable - 1
+ * IsDialable - 2
+ *
+ * Serials
+ * Organizer - 1
+ * Title - 2
+ * Start Date - 3
+ * Start Time - 4
+ * End Date - 5
+ * End Time - 6
+ */
+
+
+ foreach(var meeting in meetings)
+ {
+ var currentTime = DateTime.Now;
+
+ if(meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue;
+
+ if (meetingIndex >= maxMeetings*offset)
+ {
+ Debug.Console(2, this, "Max Meetings reached");
+ break;}
+
+ //digitals
+ tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable);
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0");
+
+ //serials
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer);
+ tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title);
+ tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString());
+ tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString());
+ tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString());
+ tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString());
+ tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id);
+
+
+ digitalIndex += maxDigitals;
+ meetingIndex += offset;
+ stringIndex += maxStrings;
+ }
+
+ while (meetingIndex < maxMeetings*offset)
+ {
+ Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}",
+ meetingIndex, maxMeetings*offset);
+
+ //digitals
+ tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
+
+ //serials
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
+ tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty);
+ tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty);
+ tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty);
+ tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty);
+ tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty);
+ tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty);
+
+ digitalIndex += maxDigitals;
+ meetingIndex += offset;
+ stringIndex += maxStrings;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private void LinkVideoCodecDirectoryToApi(IHasDirectory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.CurrentDirectoryResultIsNotDirectoryRoot.LinkComplementInputSig(
+ trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot);
+
+ trilist.SetStringSigAction(joinMap.DirectorySearchString.JoinNumber, codec.SearchDirectory);
+
+ trilist.SetUShortSigAction(joinMap.DirectorySelectRow.JoinNumber, (i) => SelectDirectoryEntry(codec, i));
+
+ trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot);
+
+ trilist.SetSigFalseAction(joinMap.DirectoryFolderBack.JoinNumber, codec.GetDirectoryParentFolderContents);
+
+ codec.DirectoryResultReturned += (sender, args) =>
+ {
+ trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort) args.Directory.CurrentDirectoryResults.Count);
+
+ var clearBytes = XSigHelpers.ClearOutputs();
+
+ trilist.SetString(joinMap.DirectoryEntries.JoinNumber,
+ Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length));
+ var directoryXSig = UpdateDirectoryXSig(args.Directory, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue);
+
+ trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig);
+ };
+ }
+
+ private void SelectDirectoryEntry(IHasDirectory codec, ushort i)
+ {
+ var entry = codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1];
+
+ if (entry is DirectoryFolder)
+ {
+ codec.GetDirectoryFolderContents(entry.FolderId);
+ return;
+ }
+
+ var dialableEntry = entry as IInvitableContact;
+
+ if (dialableEntry != null)
+ {
+ Dial(dialableEntry);
+ return;
+ }
+
+ var entryToDial = entry as DirectoryContact;
+
+ if (entryToDial == null) return;
+
+ Dial(entryToDial.ContactMethods[0].Number);
+ }
+
+ private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot)
+ {
+ var contactIndex = 1;
+ var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count];
+
+ foreach(var entry in directory.CurrentDirectoryResults)
+ {
+ var arrayIndex = contactIndex - 1;
+
+ if (entry is DirectoryFolder && entry.ParentFolderId == "root")
+ {
+ tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, String.Format("[+] {0}", entry.Name));
+
+ contactIndex++;
+
+ continue;
+ }
+
+ if(isRoot && String.IsNullOrEmpty(entry.FolderId)) continue;
+
+ tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, entry.Name);
+
+ contactIndex++;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.ManualDial.JoinNumber,
+ () => Dial(trilist.StringOutput[joinMap.CurrentDialString.JoinNumber].StringValue));
+
+ //End All calls for now
+ trilist.SetSigFalseAction(joinMap.EndCall.JoinNumber, EndAllCalls);
+
+ trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
+
+ CallStatusChange += (sender, args) =>
+ {
+ trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
+
+ Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction);
+ Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming);
+ trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status != eCodecCallStatus.Disconnected);
+
+ if (args.CallItem.Direction == eCodecCallDirection.Incoming)
+ {
+ trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem));
+ trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem));
+ }
+
+ trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
+ };
+ }
+
+ private string UpdateCallStatusXSig()
+ {
+ const int maxCalls = 8;
+ const int maxStrings = 5;
+ const int offset = 6;
+ var stringIndex = 0;
+ var digitalIndex = maxStrings * maxCalls;
+ var arrayIndex = 0;
+
+ var tokenArray = new XSigToken[maxCalls*offset]; //set array size for number of calls * pieces of info
+
+ foreach (var call in ActiveCalls)
+ {
+ if (arrayIndex >= maxCalls * offset)
+ break;
+ //digitals
+ tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall);
+
+ //serials
+ tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty);
+ tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty);
+ tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString());
+ tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, call.Type.ToString());
+ tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, call.Status.ToString());
+
+ arrayIndex += offset;
+ stringIndex += maxStrings;
+ digitalIndex++;
+ }
+ while (digitalIndex < maxCalls)
+ {
+ //digitals
+ tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, false);
+
+ //serials
+ tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty);
+ tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty);
+ tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty);
+ tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, String.Empty);
+ tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, String.Empty);
+
+ arrayIndex += offset;
+ stringIndex += maxStrings;
+ digitalIndex++;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private void LinkVideoCodecDtmfToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmf("0"));
+ trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmf("1"));
+ trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmf("2"));
+ trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmf("3"));
+ trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmf("4"));
+ trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmf("5"));
+ trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmf("6"));
+ trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmf("7"));
+ trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmf("8"));
+ trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmf("9"));
+ trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmf("*"));
+ trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmf("#"));
+ }
+
+ private void LinkVideoCodecCameraLayoutsToApi(IHasCodecLayouts codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.CameraLayout.JoinNumber, codec.LocalLayoutToggle);
+
+ codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CameraLayoutStringFb.JoinNumber]);
+ }
+
+ private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn);
+ trilist.SetSigFalseAction(joinMap.CameraModeManual.JoinNumber, codec.CameraAutoModeOff);
+
+ codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) =>
+ {
+ var offCodec = codec as IHasCameraOff;
+
+ if (offCodec != null)
+ {
+ if (offCodec.CameraIsOffFeedback.BoolValue)
+ {
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+ };
+
+ var offModeCodec = codec as IHasCameraOff;
+
+ if (offModeCodec != null)
+ {
+ if (offModeCodec.CameraIsOffFeedback.BoolValue)
+ {
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+ return;
+ }
+
+ trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
+ trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
+ }
+
+ private void LinkVideoCodecSelfviewToApi(IHasCodecSelfView codec, BasicTriList trilist,
+ VideoCodecControllerJoinMap joinMap)
+ {
+ trilist.SetSigFalseAction(joinMap.CameraSelfView.JoinNumber, codec.SelfViewModeToggle);
+
+ codec.SelfviewIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CameraSelfView.JoinNumber]);
+ }
+
+ private void LinkVideoCodecCameraToApi(IHasCodecCameras codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ //Camera PTZ
+ trilist.SetBoolSigAction(joinMap.CameraTiltUp.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.TiltUp();
+ else camera.TiltStop();
+ });
+
+ trilist.SetBoolSigAction(joinMap.CameraTiltDown.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.TiltDown();
+ else camera.TiltStop();
+ });
+ trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.PanLeft();
+ else camera.PanStop();
+ });
+ trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.PanRight();
+ else camera.PanStop();
+ });
+
+ trilist.SetBoolSigAction(joinMap.CameraZoomIn.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.ZoomIn();
+ else camera.ZoomStop();
+ });
+
+ trilist.SetBoolSigAction(joinMap.CameraZoomOut.JoinNumber, (b) =>
+ {
+ if (codec.SelectedCamera == null) return;
+ var camera = codec.SelectedCamera as IHasCameraPtzControl;
+
+ if (camera == null) return;
+
+ if (b) camera.ZoomOut();
+ else camera.ZoomStop();
+ });
+
+ //Camera Select
+ trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) =>
+ {
+ if (codec.SelectedCamera == null) return;
+
+ codec.SelectCamera(codec.Cameras[i].Key);
+ });
+
+ codec.CameraSelected += (sender, args) =>
+ {
+ var i = (ushort) codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key);
+
+ if (codec is IHasCodecRoomPresets)
+ {
+ return;
+ }
+
+ if (!(args.SelectedCamera is IHasCameraPresets))
+ {
+ return;
+ }
+
+ var cam = args.SelectedCamera as IHasCameraPresets;
+ SetCameraPresetNames(cam.Presets);
+
+ (args.SelectedCamera as IHasCameraPresets).PresetsListHasChanged += (o, eventArgs) => SetCameraPresetNames(cam.Presets);
+
+ trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber,
+ (a) =>
+ {
+ cam.PresetSelect(a);
+ trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, a);
+ });
+
+ trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber,
+ () =>
+ {
+ cam.PresetStore(trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue,
+ String.Empty);
+ trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
+ });
+ };
+
+ if (!(codec is IHasCodecRoomPresets)) return;
+
+ var presetCodec = codec as IHasCodecRoomPresets;
+
+ presetCodec.CodecRoomPresetsListHasChanged +=
+ (sender, args) => SetCameraPresetNames(presetCodec.NearEndPresets);
+
+ //Camera Presets
+ trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, (i) =>
+ {
+ presetCodec.CodecRoomPresetSelect(i);
+
+ trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i);
+ });
+
+ trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber,
+ () =>
+ {
+ presetCodec.CodecRoomPresetStore(
+ trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty);
+ trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
+ });
+ }
+
+ private string SetCameraPresetNames(IEnumerable presets)
+ {
+ return SetCameraPresetNames(presets.Select(p => p.Description).ToList());
+ }
+
+ private string SetCameraPresetNames(IEnumerable presets)
+ {
+ return SetCameraPresetNames(presets.Select(p => p.Description).ToList());
+ }
+
+ private string SetCameraPresetNames(ICollection presets)
+ {
+ var i = 1; //start index for xsig;
+
+ var tokenArray = new XSigToken[presets.Count];
+
+ foreach (var preset in presets)
+ {
+ var cameraPreset = new XSigSerialToken(i, preset);
+ tokenArray[i - 1] = cameraPreset;
+ i++;
+ }
+
+ return GetXSigString(tokenArray);
+ }
+
+ private string GetXSigString(XSigToken[] tokenArray)
+ {
+ string returnString;
+ using (var s = new MemoryStream())
+ {
+ using (var tw = new XSigTokenStreamWriter(s, true))
+ {
+ tw.WriteXSigData(tokenArray);
+ }
+
+ var xSig = s.ToArray();
+
+ returnString = Encoding.GetEncoding(XSigEncoding).GetString(xSig, 0, xSig.Length);
+ }
+
+ return returnString;
+ }
+
+ #endregion
}
@@ -233,11 +1158,14 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
///
public class CodecPhonebookSyncState : IKeyed
{
- bool _InitialSyncComplete;
+ private bool _InitialSyncComplete;
- public event EventHandler InitialSyncCompleted;
+ public CodecPhonebookSyncState(string key)
+ {
+ Key = key;
- public string Key { get; private set; }
+ CodecDisconnected();
+ }
public bool InitialSyncComplete
{
@@ -248,7 +1176,9 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
{
var handler = InitialSyncCompleted;
if (handler != null)
+ {
handler(this, new EventArgs());
+ }
}
_InitialSyncComplete = value;
}
@@ -264,12 +1194,13 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
public int NumberOfContacts { get; private set; }
- public CodecPhonebookSyncState(string key)
- {
- Key = key;
+ #region IKeyed Members
- CodecDisconnected();
- }
+ public string Key { get; private set; }
+
+ #endregion
+
+ public event EventHandler InitialSyncCompleted;
public void InitialPhonebookFoldersReceived()
{
@@ -310,7 +1241,7 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
NumberOfContactsWasReceived = false;
}
- void CheckSyncStatus()
+ private void CheckSyncStatus()
{
if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved)
{
@@ -318,7 +1249,9 @@ namespace PepperDash.Essentials.Core.Devices.VideoCodec
Debug.Console(1, this, "Initial Phonebook Sync Complete!");
}
else
+ {
InitialSyncComplete = false;
+ }
}
}
}
\ No newline at end of file