diff --git a/Essentials Devices Common/Essentials Devices Common/Codec/CodecActiveCallItem.cs b/Essentials Devices Common/Essentials Devices Common/Codec/CodecActiveCallItem.cs index 8cded7f6..17b39bc9 100644 --- a/Essentials Devices Common/Essentials Devices Common/Codec/CodecActiveCallItem.cs +++ b/Essentials Devices Common/Essentials Devices Common/Codec/CodecActiveCallItem.cs @@ -1,38 +1,40 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.Codec - -{ - public class CodecActiveCallItem - { - public string Name { get; set; } - - public string Number { get; set; } - - public eCodecCallType Type { get; set; } - - public eCodecCallStatus Status { get; set; } - - public string Id { get; set; } - - public object CallMetaData { get; set; } - - /// - /// Returns true when this call is any status other than - /// Unknown, Disconnected, Disconnecting - /// - public bool IsActiveCall - { - get - { - return !(Status == eCodecCallStatus.Disconnected - || Status == eCodecCallStatus.Disconnecting - || Status == eCodecCallStatus.Unknown); - } - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.Codec + +{ + public class CodecActiveCallItem + { + public string Name { get; set; } + + public string Number { get; set; } + + public eCodecCallType Type { get; set; } + + public eCodecCallStatus Status { get; set; } + + public eCodecCallDirection Direction { get; set; } + + public string Id { get; set; } + + //public object CallMetaData { get; set; } + + /// + /// Returns true when this call is any status other than + /// Unknown, Disconnected, Disconnecting + /// + public bool IsActiveCall + { + get + { + return !(Status == eCodecCallStatus.Disconnected + || Status == eCodecCallStatus.Disconnecting + || Status == eCodecCallStatus.Unknown); + } + } + } } \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/Codec/eCodecCallStatus.cs b/Essentials Devices Common/Essentials Devices Common/Codec/eCodecCallStatus.cs index a6aa2bf7..b05a3a9d 100644 --- a/Essentials Devices Common/Essentials Devices Common/Codec/eCodecCallStatus.cs +++ b/Essentials Devices Common/Essentials Devices Common/Codec/eCodecCallStatus.cs @@ -1,25 +1,94 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.Codec -{ - public enum eCodecCallStatus - { - Unknown = 0, - Connected, - Connecting, - Dialing, - Disconnected, - Disconnecting, - EarlyMedia, - Idle, - Incoming, - OnHold, - Ringing, - Preserved, - RemotePreserved, - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + public enum eCodecCallStatus + { + Unknown = 0, + Connected, + Connecting, + Dialing, + Disconnected, + Disconnecting, + EarlyMedia, + Idle, + Incoming, + OnHold, + Ringing, + Preserved, + RemotePreserved, + } + + + public class CodecCallStatus + { + + /// + /// Takes the Cisco call type and converts to the matching enum + /// + /// + /// + public static eCodecCallStatus ConvertToStatusEnum(string s) + { + switch (s) + { + case "Connected": + { + return eCodecCallStatus.Connected; + } + case "Connecting": + { + return eCodecCallStatus.Connecting; + } + case "Dialling": + { + return eCodecCallStatus.Dialing; + } + case "Disconnected": + { + return eCodecCallStatus.Disconnected; + } + case "Disconnecting": + { + return eCodecCallStatus.Disconnecting; + } + case "EarlyMedia": + { + return eCodecCallStatus.EarlyMedia; + } + case "Idle": + { + return eCodecCallStatus.Idle; + } + case "Incoming": + { + return eCodecCallStatus.Incoming; + } + case "OnHold": + { + return eCodecCallStatus.OnHold; + } + case "Ringing": + { + return eCodecCallStatus.Ringing; + } + case "Preserved": + { + return eCodecCallStatus.Preserved; + } + case "RemotePreserved": + { + return eCodecCallStatus.RemotePreserved; + } + default: + return eCodecCallStatus.Unknown; + } + + } + + } } \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/Codec/eCodecCallType.cs b/Essentials Devices Common/Essentials Devices Common/Codec/eCodecCallType.cs index 6c7ab627..ab94eefa 100644 --- a/Essentials Devices Common/Essentials Devices Common/Codec/eCodecCallType.cs +++ b/Essentials Devices Common/Essentials Devices Common/Codec/eCodecCallType.cs @@ -1,22 +1,22 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Common.Codec - -{ - public enum eCodecCallType +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.Codec + +{ + public enum eCodecCallType { Unknown = 0, Audio, Video, AudioCanEscalate, ForwardAllCall - } - - public class CodecCallType + } + + public class CodecCallType { /// @@ -48,7 +48,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec return eCodecCallType.Unknown; } - } - - } + } + + } } \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/Codec/iHasCallFavorites.cs b/Essentials Devices Common/Essentials Devices Common/Codec/iHasCallFavorites.cs new file mode 100644 index 00000000..5eb2d99f --- /dev/null +++ b/Essentials Devices Common/Essentials Devices Common/Codec/iHasCallFavorites.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + public interface iHasCallFavorites + { + CodecCallFavorites CallFavorites { get; } + } + + /// + /// Represents favorites entries for a codec device + /// + public class CodecCallFavorites + { + public List Favorites { get; set; } + + public CodecCallFavorites() + { + Favorites = new List(); + } + } +} \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/Codec/iHasCallHistory.cs b/Essentials Devices Common/Essentials Devices Common/Codec/iHasCallHistory.cs index 63140918..c8b645a9 100644 --- a/Essentials Devices Common/Essentials Devices Common/Codec/iHasCallHistory.cs +++ b/Essentials Devices Common/Essentials Devices Common/Codec/iHasCallHistory.cs @@ -4,15 +4,15 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using PepperDash.Core; + namespace PepperDash.Essentials.Devices.Common.Codec { public interface IHasCallHistory { - event EventHandler RecentCallsListHasChanged; + CodecCallHistory CallHistory { get; } - List RecentCalls { get; } - - void RemoveEntry(CallHistory.CallHistoryEntry entry); + void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry); } public enum eCodecOccurrenctType @@ -23,8 +23,54 @@ namespace PepperDash.Essentials.Devices.Common.Codec NoAnswer } - public class CallHistory + /// + /// Represents the recent call history for a codec device + /// + public class CodecCallHistory { + event EventHandler RecentCallsListHasChanged; + + public List RecentCalls { get; private set; } + + /// + /// Item that gets added to the list when there are no recent calls in history + /// + CallHistoryEntry ListEmptyEntry; + + public CodecCallHistory() + { + ListEmptyEntry = new CallHistoryEntry() { Name = "No Recent Calls" }; + + RecentCalls = new List(); + + RecentCalls.Add(ListEmptyEntry); + } + + void OnRecentCallsListChange() + { + var handler = RecentCallsListHasChanged; + if (handler != null) + { + handler(this, new EventArgs()); + + if (Debug.Level == 1) + { + + Debug.Console(1, "RecentCalls:\n"); + + foreach (CodecCallHistory.CallHistoryEntry entry in RecentCalls) + { + Debug.Console(1, "\nName: {0}\nNumber: {1}\nStartTime: {2}\nType: {3}\n", entry.Name, entry.Number, entry.StartTime.ToString(), entry.OccurenceType); + } + } + } + } + + public void RemoveEntry(CallHistoryEntry entry) + { + RecentCalls.Remove(entry); + OnRecentCallsListChange(); + } /// /// Generic call history entry, not device specific @@ -41,7 +87,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// /// /// - public static List ConvertCiscoCallHistoryToGeneric(List entries) + public void ConvertCiscoCallHistoryToGeneric(List entries) { var genericEntries = new List(); @@ -57,15 +103,19 @@ namespace PepperDash.Essentials.Devices.Common.Codec }); } - return genericEntries; + // Check if list is empty and if so, add an item to display No Recent Calls + if(genericEntries.Count == 0) + genericEntries.Add(ListEmptyEntry); + RecentCalls = genericEntries; + OnRecentCallsListChange(); } /// /// Takes the Cisco occurence type and converts it to the matching enum /// /// - /// Requirements for a device that has dialing capabilities - /// - public interface IHasDialer - { - // Add requirements for Dialer functionality - - void Dial(string number); - void EndCall(CodecActiveCallItem activeCall); - void EndAllCalls(); - void AcceptCall(CodecActiveCallItem item); - void RejectCall(CodecActiveCallItem item); - void SendDtmf(string digit); - - BoolFeedback IncomingCallFeedback { get; } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Requirements for a device that has dialing capabilities + /// + public interface IHasDialer + { + // Add requirements for Dialer functionality + + void Dial(string number); + void EndCall(CodecActiveCallItem activeCall); + void EndAllCalls(); + void AcceptCall(CodecActiveCallItem item); + void RejectCall(CodecActiveCallItem item); + void SendDtmf(string digit); + + BoolFeedback IncomingCallFeedback { get; } } @@ -35,5 +35,5 @@ namespace PepperDash.Essentials.Devices.Common.Codec { // Upcoming Meeting warning event - } + } } \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index fca8c23d..e8ff9e0e 100644 --- a/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -107,6 +107,7 @@ + @@ -134,6 +135,7 @@ + diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs index 8adc21d0..5214c41f 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs @@ -1,188 +1,201 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharp.Net.Https; -using Crestron.SimplSharp.CrestronXml; -using Crestron.SimplSharp.CrestronXml.Serialization; -using Newtonsoft.Json; -using Cisco_One_Button_To_Push; -using Cisco_SX80_Corporate_Phone_Book; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Routing; -using PepperDash.Essentials.Devices.Common.Codec; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco -{ - enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; - - public class CiscoCodec : VideoCodecBase, IHasCallHistory +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.Net.Https; +using Crestron.SimplSharp.CrestronXml; +using Crestron.SimplSharp.CrestronXml.Serialization; +using Newtonsoft.Json; +using Cisco_One_Button_To_Push; +using Cisco_SX80_Corporate_Phone_Book; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Routing; +using PepperDash.Essentials.Devices.Common.Codec; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco +{ + enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; + + public class CiscoCodec : VideoCodecBase, IHasCallHistory, iHasCallFavorites { - public event EventHandler RecentCallsListHasChanged; - - public IBasicCommunication Communication { get; private set; } - public CommunicationGather PortGather { get; private set; } - public CommunicationGather JsonGather { get; private set; } - - public StatusMonitorBase CommunicationMonitor { get; private set; } - - public BoolFeedback StandbyIsOnFeedback { get; private set; } - - public BoolFeedback RoomIsOccupiedFeedback { get; private set; } - - public IntFeedback PeopleCountFeedback { get; private set; } - - public BoolFeedback SpeakerTrackIsOnFeedback { get; private set; } - - private CiscoOneButtonToPush CodecObtp; - - private Corporate_Phone_Book PhoneBook; - - private CiscoCodecConfiguration.RootObject CodecConfiguration; - + public IBasicCommunication Communication { get; private set; } + public CommunicationGather PortGather { get; private set; } + public CommunicationGather JsonGather { get; private set; } + + public StatusMonitorBase CommunicationMonitor { get; private set; } + + public BoolFeedback StandbyIsOnFeedback { get; private set; } + + public BoolFeedback RoomIsOccupiedFeedback { get; private set; } + + public IntFeedback PeopleCountFeedback { get; private set; } + + public BoolFeedback SpeakerTrackIsOnFeedback { get; private set; } + + //private CiscoOneButtonToPush CodecObtp; + + //private Corporate_Phone_Book PhoneBook; + + private CiscoCodecConfiguration.RootObject CodecConfiguration; + private CiscoCodecStatus.RootObject CodecStatus; - private CiscoCallHistory.RootObject CodecCallHistory; + public CodecCallHistory CallHistory { get; private set; } + + public CodecCallFavorites CallFavorites { get; private set; } + + /// + /// Gets and returns the scaled volume of the codec + /// + protected override Func VolumeLevelFeedbackFunc + { + get + { + return () => CrestronEnvironment.ScaleWithLimits(CodecStatus.Status.Audio.Volume.IntValue, 100, 0, 65535, 0); + } + } + + protected override Func PrivacyModeIsOnFeedbackFunc + { + get + { + return () => CodecStatus.Status.Audio.Microphones.Mute.BoolValue; + } + } + + protected Func StandbyStateFeedbackFunc + { + get + { + return () => CodecStatus.Status.Standby.State.BoolValue; + } + } - public List RecentCalls { get; private set; } - - //private CiscoCodecEvents.RootObject CodecEvent; - - /// - /// Gets and returns the scaled volume of the codec - /// - protected override Func VolumeLevelFeedbackFunc - { - get - { - return () => CrestronEnvironment.ScaleWithLimits(CodecStatus.Status.Audio.Volume.IntValue, 100, 0, 65535, 0); - } - } - - protected override Func PrivacyModeIsOnFeedbackFunc - { - get - { - return () => CodecStatus.Status.Audio.Microphones.Mute.BoolValue; - } - } - - protected Func StandbyStateFeedbackFunc - { - get - { - return () => CodecStatus.Status.Standby.State.BoolValue; - } - } - /// /// Gets the value of the currently shared source, or returns null - /// - protected override Func SharingSourceFeedbackFunc - { -#warning figure out how to return the key of the shared source somehow - get + /// + protected override Func SharingSourceFeedbackFunc + { +#warning figure out how to return the key of the shared source somehow + get { - return () => "todo"; - } - } - - protected override Func MuteFeedbackFunc - { - get - { - return () => CodecStatus.Status.Audio.VolumeMute.BoolValue; - } - } - - protected Func RoomIsOccupiedFeedbackFunc - { - get - { - return () => CodecStatus.Status.RoomAnalytics.PeoplePresence.BoolValue; - } - } - - protected Func PeopleCountFeedbackFunc - { - get - { - return () => CodecStatus.Status.RoomAnalytics.PeopleCount.Current.IntValue; - } - } - - protected Func SpeakerTrackIsOnFeedbackFunc - { - get - { - return () => CodecStatus.Status.Cameras.SpeakerTrack.Status.BoolValue; - } + return () => "todo"; + } } - protected override Func ActiveCallCountFeedbackFunc + protected override Func MuteFeedbackFunc { - get { return () => ActiveCalls.Count; } + get + { + return () => CodecStatus.Status.Audio.VolumeMute.BoolValue; + } } - - //private HttpsClient Client; - - //private HttpApiServer Server; - - //private int ServerPort; - - //private string CodecUrl; - - //private string HttpSessionId; - - //private string FeedbackRegistrationExpression; - - private string CliFeedbackRegistrationExpression; - - private CodecSyncState SyncState; - - private StringBuilder JsonMessage; - - private bool JsonFeedbackMessageIsIncoming; - - string Delimiter = "\r\n"; - - int PresentationSource; - - public bool CommDebuggingIsOn; - - // Constructor for IBasicCommunication - public CiscoCodec(string key, string name, IBasicCommunication comm, int serverPort) - : base(key, name) - { + + protected Func RoomIsOccupiedFeedbackFunc + { + get + { + return () => CodecStatus.Status.RoomAnalytics.PeoplePresence.BoolValue; + } + } + + protected Func PeopleCountFeedbackFunc + { + get + { + return () => CodecStatus.Status.RoomAnalytics.PeopleCount.Current.IntValue; + } + } + + protected Func SpeakerTrackIsOnFeedbackFunc + { + get + { + return () => CodecStatus.Status.Cameras.SpeakerTrack.Status.BoolValue; + } + } + + //protected override Func ActiveCallCountFeedbackFunc + //{ + // get { return () => ActiveCalls.Count; } + //} + + //private HttpsClient Client; + + //private HttpApiServer Server; + + //private int ServerPort; + + //private string CodecUrl; + + //private string HttpSessionId; + + //private string FeedbackRegistrationExpression; + + private string CliFeedbackRegistrationExpression; + + private CodecSyncState SyncState; + + private StringBuilder JsonMessage; + + private bool JsonFeedbackMessageIsIncoming; + + public bool CommDebuggingIsOn; + + string Delimiter = "\r\n"; + + int PresentationSource; + + string PhoneBookMode; + + // Constructor for IBasicCommunication + public CiscoCodec(string key, string name, IBasicCommunication comm, CiscoCodecPropertiesConfig props ) + : base(key, name) + { StandbyIsOnFeedback = new BoolFeedback(StandbyStateFeedbackFunc); - RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); - PeopleCountFeedback = new IntFeedback(PeopleCountFeedbackFunc); - SpeakerTrackIsOnFeedback = new BoolFeedback(SpeakerTrackIsOnFeedbackFunc); - - - Communication = comm; - + RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); + PeopleCountFeedback = new IntFeedback(PeopleCountFeedbackFunc); + SpeakerTrackIsOnFeedback = new BoolFeedback(SpeakerTrackIsOnFeedbackFunc); + + Communication = comm; + + if (props.CommunicationMonitorProperties != null) + { + CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties); + } + else + { + CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 2000, 120000, 300000, "xStatus SystemUnit Software Version\r"); + } + + DeviceManager.AddDevice(CommunicationMonitor); + + PhoneBookMode = props.PhonebookMode; + SyncState = new CodecSyncState(key + "--sync"); - SyncState.InitialSyncCompleted += new EventHandler(SyncState_InitialSyncCompleted); - - PortGather = new CommunicationGather(Communication, Delimiter); - PortGather.IncludeDelimiter = true; - PortGather.LineReceived += this.Port_LineReceived; - - CodecObtp = new CiscoOneButtonToPush(); - - PhoneBook = new Corporate_Phone_Book(); - - CodecConfiguration = new CiscoCodecConfiguration.RootObject(); - + SyncState.InitialSyncCompleted += new EventHandler(SyncState_InitialSyncCompleted); + + PortGather = new CommunicationGather(Communication, Delimiter); + PortGather.IncludeDelimiter = true; + PortGather.LineReceived += this.Port_LineReceived; + + //CodecObtp = new CiscoOneButtonToPush(); + + //PhoneBook = new Corporate_Phone_Book(); + + CodecConfiguration = new CiscoCodecConfiguration.RootObject(); CodecStatus = new CiscoCodecStatus.RootObject(); - CodecCallHistory = new CiscoCallHistory.RootObject(); + CallHistory = new CodecCallHistory(); + + CallFavorites = new CodecCallFavorites(); + CallFavorites.Favorites = props.Favorites; + //Set Feedback Actions CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate; CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate; CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate; @@ -190,12 +203,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate; CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate; CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = SpeakerTrackIsOnFeedback.FireUpdate; - - //ServerPort = serverPort; - - //Client = new HttpsClient(); - - //Server = new HttpApiServer(); } /// @@ -205,154 +212,114 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// void SyncState_InitialSyncCompleted(object sender, EventArgs e) { - SendText("xCommand CallHistory Recents Limit: 20 Order: OccurrenceTime"); + GetCallHistory(); // Get bookings for the day //SendText("xCommand Bookings List Days: 1 DayOffset: 0"); // Get Phonebook (determine local/corporate from config, and set results limit) //SendText("xCommand Phonebook Search PhonebookType: {0} ContactType: Folder Limit: {0}", PhonebookType, PhonebookResultsLimit); - } - - /// - /// Starts the HTTP feedback server and syncronizes state of codec - /// - /// - public override bool CustomActivate() - { - CrestronConsole.AddNewConsoleCommand(SendText, "send" + Key, "", ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCiscoCommDebug", "0 for Off, 1 for on", ConsoleAccessLevelEnum.AccessOperator); - - - - Communication.Connect(); - var socket = Communication as ISocketStatus; - if (socket != null) - { - socket.ConnectionChange += new EventHandler(socket_ConnectionChange); - } - - InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this)); - InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource2), this)); - - //Debug.Console(1, this, "Starting Cisco API Server"); - - //Server.Start(ServerPort); - - //Server.ApiRequest += new EventHandler(Server_ApiRequest); - - //CodecUrl = string.Format("http://{0}", (Communication as GenericSshClient).Hostname); - - CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 2000, 120000, 300000, "xStatus SystemUnit Software Version\r"); - DeviceManager.AddDevice(CommunicationMonitor); - - //Client = new HttpsClient(); - - //Client.Verbose = true; - //Client.KeepAlive = true; - - - // Temp feedback registration - - //FeedbackRegistrationExpression = - // "1" + - // string.Format("http://{0}:{1}/cisco/api", CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0), ServerPort) + - // "JSON" + - // "/Configuration" + - // "/Event/CallDisconnect" + - // "/Status/Call" + - // "" + - // "" + - // ""; - - string prefix = "xFeedback register "; - CliFeedbackRegistrationExpression = - prefix + "/Configuration" + Delimiter + - prefix + "/Status/Audio" + Delimiter + - prefix + "/Status/Call" + Delimiter + - prefix + "/Status/Conference/Presentation" + Delimiter + - prefix + "/Status/Cameras/SpeakerTrack" + Delimiter + - prefix + "/Status/RoomAnalytics" + Delimiter + - prefix + "/Status/Standby" + Delimiter + - prefix + "/Status/Video/Selfview" + Delimiter + - prefix + "/Bookings" + Delimiter + - prefix + "/Event/CallDisconnect" + Delimiter; - - //StartHttpsSession(); - - //CodecObtp.Initialize(); - - //CodecObtp.GetMeetings(); - - //PhoneBook.DownloadPhoneBook(Corporate_Phone_Book.ePhoneBookLocation.Corporate); - - return base.CustomActivate(); - } - - public void SetCommDebug(string s) - { - if (s == "1") - { - CommDebuggingIsOn = true; - Debug.Console(0, this, "Comm Debug Enabled."); - } - else - { - CommDebuggingIsOn = false; - Debug.Console(0, this, "Comm Debug Disabled."); - } - } - - void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) - { - // Reset sync status on disconnect - if (!e.Client.IsConnected) - SyncState.CodecDisconnected(); - } - - /// - /// Gathers responses from the codec (including the delimiter. Responses are checked to see if they contain JSON data and if so, the data is collected until a complete JSON - /// message is received before forwarding the message to be deserialized. - /// - /// - /// - void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) - { - if (CommDebuggingIsOn) - { - if(!JsonFeedbackMessageIsIncoming) - Debug.Console(1, this, "RX: '{0}'", args.Text); - } - - if (args.Text == "{" + Delimiter) // Check for the beginning of a new JSON message - { - JsonFeedbackMessageIsIncoming = true; - - if (CommDebuggingIsOn) - Debug.Console(1, this, "Incoming JSON message..."); - - JsonMessage = new StringBuilder(); - } - else if (args.Text == "}" + Delimiter) // Check for the end of a JSON message - { - JsonFeedbackMessageIsIncoming = false; - - JsonMessage.Append(args.Text); - - if (CommDebuggingIsOn) - Debug.Console(1, this, "Complete JSON Received:\n{0}", JsonMessage.ToString()); - - // Forward the complete message to be deserialized - DeserializeResponse(JsonMessage.ToString()); - return; - } - - if(JsonFeedbackMessageIsIncoming) - { - JsonMessage.Append(args.Text); - - //Debug.Console(1, this, "Building JSON:\n{0}", JsonMessage.ToString()); - return; + } + + /// + /// Starts the HTTP feedback server and syncronizes state of codec + /// + /// + public override bool CustomActivate() + { + CrestronConsole.AddNewConsoleCommand(SendText, "send" + Key, "", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCiscoCommDebug", "0 for Off, 1 for on", ConsoleAccessLevelEnum.AccessOperator); + + Communication.Connect(); + var socket = Communication as ISocketStatus; + if (socket != null) + { + socket.ConnectionChange += new EventHandler(socket_ConnectionChange); + } + + InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this)); + InputPorts.Add(new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource2), this)); + + string prefix = "xFeedback register "; + + CliFeedbackRegistrationExpression = + prefix + "/Configuration" + Delimiter + + prefix + "/Status/Audio" + Delimiter + + prefix + "/Status/Call" + Delimiter + + prefix + "/Status/Conference/Presentation" + Delimiter + + prefix + "/Status/Cameras/SpeakerTrack" + Delimiter + + prefix + "/Status/RoomAnalytics" + Delimiter + + prefix + "/Status/Standby" + Delimiter + + prefix + "/Status/Video/Selfview" + Delimiter + + prefix + "/Bookings" + Delimiter + + prefix + "/Event/CallDisconnect" + Delimiter; + + return base.CustomActivate(); + } + + public void SetCommDebug(string s) + { + if (s == "1") + { + CommDebuggingIsOn = true; + Debug.Console(0, this, "Comm Debug Enabled."); + } + else + { + CommDebuggingIsOn = false; + Debug.Console(0, this, "Comm Debug Disabled."); + } + } + + void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) + { + if (!e.Client.IsConnected) + SyncState.CodecDisconnected(); + } + + /// + /// Gathers responses from the codec (including the delimiter. Responses are checked to see if they contain JSON data and if so, the data is collected until a complete JSON + /// message is received before forwarding the message to be deserialized. + /// + /// + /// + void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) + { + if (CommDebuggingIsOn) + { + if(!JsonFeedbackMessageIsIncoming) + Debug.Console(1, this, "RX: '{0}'", args.Text); + } + + if (args.Text == "{" + Delimiter) // Check for the beginning of a new JSON message + { + JsonFeedbackMessageIsIncoming = true; + + if (CommDebuggingIsOn) + Debug.Console(1, this, "Incoming JSON message..."); + + JsonMessage = new StringBuilder(); + } + else if (args.Text == "}" + Delimiter) // Check for the end of a JSON message + { + JsonFeedbackMessageIsIncoming = false; + + JsonMessage.Append(args.Text); + + if (CommDebuggingIsOn) + Debug.Console(1, this, "Complete JSON Received:\n{0}", JsonMessage.ToString()); + + // Forward the complete message to be deserialized + DeserializeResponse(JsonMessage.ToString()); + return; + } + + if(JsonFeedbackMessageIsIncoming) + { + JsonMessage.Append(args.Text); + + //Debug.Console(1, this, "Building JSON:\n{0}", JsonMessage.ToString()); + return; } if (!SyncState.InitialSyncComplete) @@ -376,282 +343,139 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco break; } } - } - - } - - public void SendText(string command) - { - if (CommDebuggingIsOn) - Debug.Console(1, this, "Sending: '{0}'", command); - - Communication.SendText(command + Delimiter); - } - - //private void StartHttpsSession() - //{ - // SendHttpCommand("", eCommandType.SessionStart); - //} - - //private void EndHttpsSession() - //{ - // SendHttpCommand("", eCommandType.SessionEnd); - //} - - //private void SendHttpCommand(string command, eCommandType commandType) - //{ - // //HttpsClientRequest request = new HttpsClientRequest(); - - // //string urlSuffix = null; - - // //Client.UserName = null; - // //Client.Password = null; - - // //Client.PeerVerification = false; - // //Client.HostVerification = false; - - // //request.RequestType = RequestType.Post; - - // //if(!string.IsNullOrEmpty(HttpSessionId)) - // // request.Header.SetHeaderValue("Cookie", HttpSessionId); - - // //switch (commandType) - // //{ - // // case eCommandType.Command: - // // { - // // urlSuffix = "/putxml"; - // // request.ContentString = command; - // // request.Header.SetHeaderValue("Content-Type", "text/xml"); - // // break; - // // } - // // case eCommandType.SessionStart: - // // { - - // // urlSuffix = "/xmlapi/session/begin"; - - // // Client.UserName = (Communication as GenericSshClient).Username; - // // Client.Password = (Communication as GenericSshClient).Password; - - // // break; - // // } - // // case eCommandType.SessionEnd: - // // { - // // urlSuffix = "/xmlapi/session/end"; - // // request.Header.SetHeaderValue("Cookie", HttpSessionId); - // // break; - // // } - // // case eCommandType.GetStatus: - // // { - // // request.RequestType = RequestType.Get; - // // request.Header.SetHeaderValue("Content-Type", "text/xml"); - // // urlSuffix = "/getxml?location=/Status"; - // // break; - // // } - // // case eCommandType.GetConfiguration: - // // { - // // request.RequestType = RequestType.Get; - // // request.Header.SetHeaderValue("Content-Type", "text/xml"); - // // urlSuffix = "/getxml?location=/Configuration"; - // // break; - // // } - // //} - - // //var requestUrl = CodecUrl + urlSuffix; - // //request.Header.RequestVersion = "HTTP/1.1"; - // //request.Url.Parse(requestUrl); - - // //Debug.Console(1, this, "Sending HTTP request to Cisco Codec at {0}\nHeader:\n{1}\nContent:\n{2}", requestUrl, request.Header, request.ContentString); - - // //Client.DispatchAsync(request, PostConnectionCallback); - //} - - //void PostConnectionCallback(HttpsClientResponse resp, HTTPS_CALLBACK_ERROR err) - //{ - // //try - // //{ - // // if (resp != null) - // // { - // // if (resp.Code == 200) - // // { - // // Debug.Console(1, this, "Http Post to Cisco Codec Successful. Code: {0}\nContent: {1}", resp.Code, resp.ContentString); - - // // if (resp.ContentString.IndexOf("") > 1) - // // { - // // // Get the initial configruation for sync purposes - // // SendHttpCommand("", eCommandType.GetConfiguration); - // // } - // // else - // // { - // // try - // // { - // // if (resp.ContentString.IndexOf("") > -1) - // // { - // // XmlReaderSettings settings = new XmlReaderSettings(); - - // // XmlReader reader = new XmlReader(resp.ContentString, settings); - - // // CodecConfiguration = CrestronXMLSerialization.DeSerializeObject(reader); - - // // //Debug.Console(1, this, "Product Name: {0} Software Version: {1} ApiVersion: {2}", CodecConfiguration.Configuration.Product, CodecConfiguration.Version, CodecConfiguration.ApiVersion); - - // // // Get the initial status for sync purposes - // // SendHttpCommand("", eCommandType.GetStatus); - // // } - // // else if (resp.ContentString.IndexOf("") > -1) - // // { - // // XmlReaderSettings settings = new XmlReaderSettings(); - - // // XmlReader reader = new XmlReader(resp.ContentString, settings); - - // // CodecStatus = CrestronXMLSerialization.DeSerializeObject(reader); - // // //Debug.Console(1, this, "Product Name: {0} Software Version: {1} ApiVersion: {2} Volume: {3}", CodecStatus.Product, CodecStatus.Version, CodecStatus.ApiVersion, CodecStatus.Audio.Volume); - // // } - // // } - // // catch (Exception ex) - // // { - // // Debug.Console(1, this, "Error Deserializing XML document from codec: {0}", ex); - // // } - // // } - // // } - // // else if (resp.Code == 204) - // // { - // // Debug.Console(1, this, "Response Code: {0}\nHeader:\n{1}Content:\n{1}", resp.Code, resp.Header, resp.ContentString); - - // // HttpSessionId = resp.Header.GetHeaderValue("Set-Cookie"); - // // //var chunks = HttpSessionId.Split(';'); - // // //HttpSessionId = chunks[0]; - // // //HttpSessionId = HttpSessionId.Substring(HttpSessionId.IndexOf("=") + 1); - - - // // // Register for feedbacks once we have a valid session - // // SendHttpCommand(FeedbackRegistrationExpression, eCommandType.Command); - // // } - // // else - // // { - // // Debug.Console(1, this, "Response Code: {0}\nHeader:\n{1}Content:\n{1}Err:\n{2}", resp.Code, resp.Header, resp.ContentString, err); - // // } - // // } - // // else - // // Debug.Console(1, this, "Null response received from server"); - // //} - // //catch (Exception e) - // //{ - // // Debug.Console(1, this, "Error Initializing HTTPS Client: {0}", e); - // //} - //} - - //void Server_ApiRequest(object sender, Crestron.SimplSharp.Net.Http.OnHttpRequestArgs e) - //{ - // Debug.Console(1, this, "Api Reqeust from Codec: {0}", e.Request.ContentString); - // e.Response.Code = 200; - // e.Response.ContentString = "OK"; - - // DeserializeResponse(e.Request.ContentString); - //} - - void DeserializeResponse(string response) - { - try - { - // Serializer settings. We want to ignore null values and mising members - JsonSerializerSettings settings = new JsonSerializerSettings(); - settings.NullValueHandling = NullValueHandling.Ignore; - settings.MissingMemberHandling = MissingMemberHandling.Ignore; - settings.ObjectCreationHandling = ObjectCreationHandling.Auto; - - if (response.IndexOf("\"Status\":{") > -1) - { - // Status Message - - // Check to see if this is a call status message received after the initial status message - if(SyncState.InitialStatusMessageWasReceived && response.IndexOf("\"Call\":{") > -1) - { - CiscoCodecStatus.RootObject callStatus = new CiscoCodecStatus.RootObject(); - - JsonConvert.PopulateObject(response, callStatus); - - // Iterate through the call objects in the response - foreach (CiscoCodecStatus.Call call in callStatus.Status.Call) - { - // Look for a matching call id in the existing status structure - var existingCall = CodecStatus.Status.Call.FirstOrDefault(c => c.id.Equals(call.id)); - - if (existingCall != null) - { - // If an existing call object is found with a matching ID, populate the existing call with the new data. - // (must reserialize the object so that we can use PopulateObject() to overlay the new or updated properties on the existing object) - JsonConvert.PopulateObject(JsonConvert.SerializeObject(call), existingCall); + } + + } - var tempActiveCall = ActiveCalls.FirstOrDefault(c => c.Id.Equals(call.id)); + public void SendText(string command) + { + if (CommDebuggingIsOn) + Debug.Console(1, this, "Sending: '{0}'", command); - // store previous status to pass to event handler - var previousStatus = tempActiveCall.Status; + Communication.SendText(command + Delimiter); + } + + void DeserializeResponse(string response) + { + try + { + // Serializer settings. We want to ignore null values and mising members + JsonSerializerSettings settings = new JsonSerializerSettings(); + settings.NullValueHandling = NullValueHandling.Ignore; + settings.MissingMemberHandling = MissingMemberHandling.Ignore; + settings.ObjectCreationHandling = ObjectCreationHandling.Auto; + + if (response.IndexOf("\"Status\":{") > -1) + { + // Status Message + + // Temp object so we can inpsect for call data before simply deserializing + CiscoCodecStatus.RootObject tempCodecStatus = new CiscoCodecStatus.RootObject(); + + JsonConvert.PopulateObject(response, tempCodecStatus); + + // Check to see if this is a call status message received after the initial status message + if (tempCodecStatus.Status.Call.Count > 0) + { + // Iterate through the call objects in the response + foreach (CiscoCodecStatus.Call call in tempCodecStatus.Status.Call) + { + var tempActiveCall = ActiveCalls.FirstOrDefault(c => c.Id.Equals(call.id)); + + if (tempActiveCall != null) + { + // Store previous status to pass to event handler + var previousStatus = tempActiveCall.Status; + + bool changeDetected = false; // Update properties of ActiveCallItem - tempActiveCall.Status = CodecCallStatus.ConvertToStatusEnum(call.Status.Value); - tempActiveCall.Type = CodecCallType.ConvertToTypeEnum(call.CallType.Value); - tempActiveCall.Name = call.DisplayName.Value; + if(call.Status != null) + if (!string.IsNullOrEmpty(call.Status.Value)) + { +#warning Something here is evaluating as Unknown when the Display Name changes.... + tempActiveCall.Status = CodecCallStatus.ConvertToStatusEnum(call.Status.Value); + changeDetected = true; + if(tempActiveCall.Status == eCodecCallStatus.Connected) + GetCallHistory(); + } + if (call.CallType != null) + if (!string.IsNullOrEmpty(call.CallType.Value)) + { + tempActiveCall.Type = CodecCallType.ConvertToTypeEnum(call.CallType.Value); + changeDetected = true; + } + if (call.DisplayName != null) + if (!string.IsNullOrEmpty(call.DisplayName.Value)) + { + tempActiveCall.Name = call.DisplayName.Value; + changeDetected = true; + } - SetNewCallStatusAndFireCallStatusChange(previousStatus, tempActiveCall); - } - else - { - // Add the call - callStatus.Status.Call.Add(call); - - var newCallItem = new CodecActiveCallItem() - { - Id = call.id, - Status = CodecCallStatus.ConvertToStatusEnum(call.Status.Value), - Name = call.DisplayName.Value, + if (changeDetected) + { + ListCalls(); + SetNewCallStatusAndFireCallStatusChange(previousStatus, tempActiveCall); + } + } + else if( call.ghost == null ) // if the ghost value is present the call has ended already + { + // Create a new call item + var newCallItem = new CodecActiveCallItem() + { + Id = call.id, + Status = CodecCallStatus.ConvertToStatusEnum(call.Status.Value), + Name = call.DisplayName.Value, Number = call.RemoteNumber.Value, - Type = CodecCallType.ConvertToTypeEnum(call.CallType.Value) - }; - - // Add a call to the ActiveCalls List - ActiveCalls.Add(newCallItem); - - SetNewCallStatusAndFireCallStatusChange(newCallItem.Status, newCallItem); - } - - // Handle call.status to determine if we need to fire an event notifying of an incoming call or a call disconnect - } - } - - JsonConvert.PopulateObject(response, CodecStatus); - - if (!SyncState.InitialStatusMessageWasReceived) - { - SyncState.InitialStatusMessageReceived(); - if(!SyncState.InitialConfigurationMessageWasReceived) - SendText("xConfiguration"); - } - } - else if (response.IndexOf("\"Configuration\":{") > -1) - { - // Configuration Message - - JsonConvert.PopulateObject(response, CodecConfiguration); - - if (!SyncState.InitialConfigurationMessageWasReceived) - { - SyncState.InitialConfigurationMessageReceived(); - if (!SyncState.FeedbackWasRegistered) - { - SendText(CliFeedbackRegistrationExpression); - } - } - - } - else if (response.IndexOf("\"Event\":{") > -1) - { - // Event Message - - CiscoCodecEvents.RootObject eventReceived = new CiscoCodecEvents.RootObject(); - - JsonConvert.PopulateObject(response, eventReceived); - - EvalutateEvent(eventReceived); + Type = CodecCallType.ConvertToTypeEnum(call.CallType.Value) + }; + + // Add it to the ActiveCalls List + ActiveCalls.Add(newCallItem); + + ListCalls(); + + SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Unknown, newCallItem); + } + + } + + } + + JsonConvert.PopulateObject(response, CodecStatus); + + if (!SyncState.InitialStatusMessageWasReceived) + { + SyncState.InitialStatusMessageReceived(); + if (!SyncState.InitialConfigurationMessageWasReceived) + SendText("xConfiguration"); + } + } + else if (response.IndexOf("\"Configuration\":{") > -1) + { + // Configuration Message + + JsonConvert.PopulateObject(response, CodecConfiguration); + + if (!SyncState.InitialConfigurationMessageWasReceived) + { + SyncState.InitialConfigurationMessageReceived(); + if (!SyncState.FeedbackWasRegistered) + { + SendText(CliFeedbackRegistrationExpression); + } + } + + } + else if (response.IndexOf("\"Event\":{") > -1) + { + // Event Message + + CiscoCodecEvents.RootObject eventReceived = new CiscoCodecEvents.RootObject(); + + JsonConvert.PopulateObject(response, eventReceived); + + EvalutateEvent(eventReceived); } else if (response.IndexOf("\"CommandResponse\":{") > -1) { @@ -659,274 +483,267 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco if (response.IndexOf("\"CallHistoryRecentsResult\":{") > -1) { - JsonConvert.PopulateObject(response, CodecCallHistory); + var codecCallHistory = new CiscoCallHistory.RootObject(); - RecentCalls = CallHistory.ConvertCiscoCallHistoryToGeneric(CodecCallHistory.CommandResponse.CallHistoryRecentsResult.Entry); + JsonConvert.PopulateObject(response, codecCallHistory); - if (Debug.Level == 1) - { - - Debug.Console(1, this, "RecentCalls:\n"); - - foreach (CallHistory.CallHistoryEntry entry in RecentCalls) - { - Debug.Console(1, this, "\nName: {0}\nNumber: {1}\nStartTime: {2}\nType: {3}\n", entry.Name, entry.Number, entry.StartTime.ToString(), entry.OccurenceType); - } - } + CallHistory.ConvertCiscoCallHistoryToGeneric(codecCallHistory.CommandResponse.CallHistoryRecentsResult.Entry); + } + else if (response.IndexOf("\"CallHistoryDeleteEntryResult\":{") > -1) + { + GetCallHistory(); } - } - - } - catch (Exception ex) - { - Debug.Console(1, this, "Error Deserializing feedback from codec: {0}", ex); - } + } + + } + catch (Exception ex) + { + Debug.Console(1, this, "Error Deserializing feedback from codec: {0}", ex); + } } - - /// - /// Evaluates an event received from the codec - /// - /// - void EvalutateEvent(CiscoCodecEvents.RootObject eventReceived) - { - if (eventReceived.Event.CallDisconnect != null) - { - var tempCall = CodecStatus.Status.Call.FirstOrDefault(c => c.id.Equals(eventReceived.Event.CallDisconnect.CallId.Value)); - - if(tempCall != null) - { - // Remove the call from the xStatus object - CodecStatus.Status.Call.Remove(tempCall); - var tempActiveCall = ActiveCalls.FirstOrDefault(c => c.Id.Equals(eventReceived.Event.CallDisconnect.CallId.Value)); + /// + /// Evaluates an event received from the codec + /// + /// + void EvalutateEvent(CiscoCodecEvents.RootObject eventReceived) + { + if (eventReceived.Event.CallDisconnect != null) + { + var tempActiveCall = ActiveCalls.FirstOrDefault(c => c.Id.Equals(eventReceived.Event.CallDisconnect.CallId.Value)); - // Remove the call from the Active calls list - if (tempActiveCall != null) - ActiveCalls.Remove(tempActiveCall); + // Remove the call from the Active calls list + if (tempActiveCall != null) + { + ActiveCalls.Remove(tempActiveCall); + + ListCalls(); // Notify of the call disconnection - SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, tempActiveCall); - } - } - } - - public override void ExecuteSwitch(object selector) - { - (selector as Action)(); - } - - //protected Func InCallFeedbackFunc { get { return () => false; } } - - protected override Func IncomingCallFeedbackFunc { get { return () => false; } } - - /// - /// Gets the first CallId or returns null - /// - /// - private string GetCallId() - { - string callId = null; - - if (CodecStatus.Status.Call.Count > 0) - callId = CodecStatus.Status.Call[0].id; - - return callId; - - } - - public override void Dial(string s) - { - SendText(string.Format("xCommand Dial Number: \"{0}\"", s)); - } - - public void DialBookingId(string s) - { - SendText(string.Format("xCommand Dial BookingId: {0}", s)); - } - - public override void EndCall(CodecActiveCallItem activeCall) - { - SendText(string.Format("xCommand Call Disconnect CallId: {0}", activeCall.Id)); - } - - public override void EndAllCalls() - { - foreach (CodecActiveCallItem activeCall in ActiveCalls) - { - SendText(string.Format("xCommand Call Disconnect CallId: {0}", activeCall.Id)); - } - } - - public override void AcceptCall(CodecActiveCallItem item) - { - SendText("xCommand Call Accept"); - } - - public override void RejectCall(CodecActiveCallItem item) - { - SendText("xCommand Call Reject"); - } - - public override void SendDtmf(string s) - { - SendText(string.Format("xCommand Call DTMFSend CallId: {0} DTMFString: \"{1}\"", GetCallId(), s)); - } - - public void SelectPresentationSource(int source) - { - PresentationSource = source; - - StartSharing(); - } - - /// - /// Select source 1 as the presetnation source - /// - public void SelectPresentationSource1() - { - SelectPresentationSource(1); - } - - /// - /// Select source 2 as the presetnation source - /// - public void SelectPresentationSource2() - { - SelectPresentationSource(2); - } - - public override void StartSharing() - { - string sendingMode = string.Empty; - - if (IsInCall) - sendingMode = "LocalRemote"; - else - sendingMode = "LocalOnly"; - - SendText(string.Format("xCommand Presentation Start PresentationSource: {0}", PresentationSource)); - } - - public override void StopSharing() - { - SendText(string.Format("xCommand Presentation Stop PresentationSource: {0}", PresentationSource)); - } - - public override void PrivacyModeOn() - { - SendText("xCommand Audio Microphones Mute"); - } - - public override void PrivacyModeOff() - { - SendText("xCommand Audio Microphones Unmute"); - } - - public override void PrivacyModeToggle() - { - SendText("xCommand Audio Microphones ToggleMute"); - } - - public override void MuteOff() - { - SendText("xCommand Audio Volume Unmute"); - } - - public override void MuteOn() - { - SendText("xCommand Audio Volume Mute"); - } - - public override void MuteToggle() - { - SendText("xCommand Audio Volume ToggleMute"); - } - - /// - /// Increments the voluem - /// - /// - public override void VolumeUp(bool pressRelease) - { - SendText("xCommand Audio Volume Increase"); - } - - /// - /// Decrements the volume - /// - /// - public override void VolumeDown(bool pressRelease) - { - SendText("xCommand Audio Volume Decrease"); - } - - /// - /// Scales the level and sets the codec to the specified level within its range - /// - /// level from slider (0-65535 range) - public override void SetVolume(ushort level) - { - var scaledLevel = CrestronEnvironment.ScaleWithLimits(level, 65535, 0, 100, 0); - SendText(string.Format("xCommand Audio Volume Set Level: {0}", scaledLevel)); - } - - /// - /// Recalls the default volume on the codec - /// - public void VolumeSetToDefault() - { - SendText("xCommand Audio Volume SetToDefault"); - } - - /// - /// Puts the codec in standby mode - /// - public void StandbyActivate() - { - SendText("xCommand Standby Activate"); - } - - /// - /// Wakes the codec from standby - /// - public void StandbyDeactivate() - { - SendText("xCommand Standby Deactivate"); - } - - /// - /// Reboots the codec - /// - public void Reboot() - { - SendText("xCommand SystemUnit Boot Action: Restart"); + SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, tempActiveCall); + + GetCallHistory(); + } + } } - public void RemoveEntry(CallHistory.CallHistoryEntry entry) + public override void ExecuteSwitch(object selector) { - if (RecentCalls != null) - { - RecentCalls.Remove(entry); - } - } - + (selector as Action)(); + } - } - - /// - /// Tracks the initial sycnronization state of the codec when making a connection - /// - public class CodecSyncState : IKeyed + //protected Func InCallFeedbackFunc { get { return () => false; } } + + protected override Func IncomingCallFeedbackFunc { get { return () => false; } } + + /// + /// Gets the first CallId or returns null + /// + /// + private string GetCallId() + { + string callId = null; + + if (CodecStatus.Status.Call.Count > 0) + callId = CodecStatus.Status.Call[0].id; + + return callId; + + } + + private void GetCallHistory() + { + SendText("xCommand CallHistory Recents Limit: 20 Order: OccurrenceTime"); + } + + public override void Dial(string s) + { + SendText(string.Format("xCommand Dial Number: \"{0}\"", s)); + } + + public void DialBookingId(string s) + { + SendText(string.Format("xCommand Dial BookingId: {0}", s)); + } + + public override void EndCall(CodecActiveCallItem activeCall) + { + SendText(string.Format("xCommand Call Disconnect CallId: {0}", activeCall.Id)); + } + + public override void EndAllCalls() + { + foreach (CodecActiveCallItem activeCall in ActiveCalls) + { + SendText(string.Format("xCommand Call Disconnect CallId: {0}", activeCall.Id)); + } + } + + public override void AcceptCall(CodecActiveCallItem item) + { + SendText("xCommand Call Accept"); + } + + public override void RejectCall(CodecActiveCallItem item) + { + SendText("xCommand Call Reject"); + } + + public override void SendDtmf(string s) + { + SendText(string.Format("xCommand Call DTMFSend CallId: {0} DTMFString: \"{1}\"", GetCallId(), s)); + } + + public void SelectPresentationSource(int source) + { + PresentationSource = source; + + StartSharing(); + } + + /// + /// Select source 1 as the presetnation source + /// + public void SelectPresentationSource1() + { + SelectPresentationSource(1); + } + + /// + /// Select source 2 as the presetnation source + /// + public void SelectPresentationSource2() + { + SelectPresentationSource(2); + } + + public override void StartSharing() + { + string sendingMode = string.Empty; + + if (IsInCall) + sendingMode = "LocalRemote"; + else + sendingMode = "LocalOnly"; + + SendText(string.Format("xCommand Presentation Start PresentationSource: {0}", PresentationSource)); + } + + public override void StopSharing() + { + SendText(string.Format("xCommand Presentation Stop PresentationSource: {0}", PresentationSource)); + } + + public override void PrivacyModeOn() + { + SendText("xCommand Audio Microphones Mute"); + } + + public override void PrivacyModeOff() + { + SendText("xCommand Audio Microphones Unmute"); + } + + public override void PrivacyModeToggle() + { + SendText("xCommand Audio Microphones ToggleMute"); + } + + public override void MuteOff() + { + SendText("xCommand Audio Volume Unmute"); + } + + public override void MuteOn() + { + SendText("xCommand Audio Volume Mute"); + } + + public override void MuteToggle() + { + SendText("xCommand Audio Volume ToggleMute"); + } + + /// + /// Increments the voluem + /// + /// + public override void VolumeUp(bool pressRelease) + { + SendText("xCommand Audio Volume Increase"); + } + + /// + /// Decrements the volume + /// + /// + public override void VolumeDown(bool pressRelease) + { + SendText("xCommand Audio Volume Decrease"); + } + + /// + /// Scales the level and sets the codec to the specified level within its range + /// + /// level from slider (0-65535 range) + public override void SetVolume(ushort level) + { + var scaledLevel = CrestronEnvironment.ScaleWithLimits(level, 65535, 0, 100, 0); + SendText(string.Format("xCommand Audio Volume Set Level: {0}", scaledLevel)); + } + + /// + /// Recalls the default volume on the codec + /// + public void VolumeSetToDefault() + { + SendText("xCommand Audio Volume SetToDefault"); + } + + /// + /// Puts the codec in standby mode + /// + public void StandbyActivate() + { + SendText("xCommand Standby Activate"); + } + + /// + /// Wakes the codec from standby + /// + public void StandbyDeactivate() + { + SendText("xCommand Standby Deactivate"); + } + + /// + /// Reboots the codec + /// + public void Reboot() + { + SendText("xCommand SystemUnit Boot Action: Restart"); + } + + public void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry) + { + SendText(string.Format("xCommand CallHistory DeleteEntry CallHistoryId: {0} AcknowledgeConsecutiveDuplicates: True", entry.OccurrenceHistoryId)); + } + } + + /// + /// Tracks the initial sycnronization state of the codec when making a connection + /// + public class CodecSyncState : IKeyed { - bool _InitialSyncComplete; - - public event EventHandler InitialSyncCompleted; - - public string Key { get; private set; } - - public bool InitialSyncComplete + bool _InitialSyncComplete; + + public event EventHandler InitialSyncCompleted; + + public string Key { get; private set; } + + public bool InitialSyncComplete { get { return _InitialSyncComplete; } private set @@ -938,59 +755,59 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco handler(this, new EventArgs()); } _InitialSyncComplete = value; - } - } - - public bool InitialStatusMessageWasReceived { get; private set; } - - public bool InitialConfigurationMessageWasReceived { get; private set; } - - public bool FeedbackWasRegistered { get; private set; } - - public CodecSyncState(string key) - { - Key = key; - CodecDisconnected(); - } - - public void InitialStatusMessageReceived() - { - InitialStatusMessageWasReceived = true; - Debug.Console(1, this, "Initial Codec Status Message Received."); - CheckSyncStatus(); - } - - public void InitialConfigurationMessageReceived() - { - InitialConfigurationMessageWasReceived = true; - Debug.Console(1, this, "Initial Codec Configuration Message Received."); - CheckSyncStatus(); - } - - public void FeedbackRegistered() - { - FeedbackWasRegistered = true; - Debug.Console(1, this, "Initial Codec Feedback Registration Successful."); - CheckSyncStatus(); - } - - public void CodecDisconnected() - { - InitialConfigurationMessageWasReceived = false; - InitialStatusMessageWasReceived = false; - FeedbackWasRegistered = false; - InitialSyncComplete = false; - } - - void CheckSyncStatus() - { - if (InitialConfigurationMessageWasReceived && InitialStatusMessageWasReceived && FeedbackWasRegistered) - { - InitialSyncComplete = true; - Debug.Console(1, this, "Initial Codec Sync Complete!"); - } - else - InitialSyncComplete = false; - } - } + } + } + + public bool InitialStatusMessageWasReceived { get; private set; } + + public bool InitialConfigurationMessageWasReceived { get; private set; } + + public bool FeedbackWasRegistered { get; private set; } + + public CodecSyncState(string key) + { + Key = key; + CodecDisconnected(); + } + + public void InitialStatusMessageReceived() + { + InitialStatusMessageWasReceived = true; + Debug.Console(1, this, "Initial Codec Status Message Received."); + CheckSyncStatus(); + } + + public void InitialConfigurationMessageReceived() + { + InitialConfigurationMessageWasReceived = true; + Debug.Console(1, this, "Initial Codec Configuration Message Received."); + CheckSyncStatus(); + } + + public void FeedbackRegistered() + { + FeedbackWasRegistered = true; + Debug.Console(1, this, "Initial Codec Feedback Registration Successful."); + CheckSyncStatus(); + } + + public void CodecDisconnected() + { + InitialConfigurationMessageWasReceived = false; + InitialStatusMessageWasReceived = false; + FeedbackWasRegistered = false; + InitialSyncComplete = false; + } + + void CheckSyncStatus() + { + if (InitialConfigurationMessageWasReceived && InitialStatusMessageWasReceived && FeedbackWasRegistered) + { + InitialSyncComplete = true; + Debug.Console(1, this, "Initial Codec Sync Complete!"); + } + else + InitialSyncComplete = false; + } + } } \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecPropertiesConfig.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecPropertiesConfig.cs new file mode 100644 index 00000000..5e1b88c4 --- /dev/null +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecPropertiesConfig.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + public class CiscoCodecPropertiesConfig + { + public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; } + + //public ControlPropertiesConfig Control { get; set; } + + public List Favorites { get; set; } + + /// + /// Valid values: "Local" or "Corporate" + /// + public string PhonebookMode { get; set; } + + } +} \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index 60857d91..5cb5abb5 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -1682,6 +1682,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public Duration Duration { get; set; } public Encryption Encryption { get; set; } public FacilityServiceId FacilityServiceId { get; set; } + public string ghost { get; set; } public HoldReason HoldReason { get; set; } public PlacedOnHold PlacedOnHold { get; set; } public Protocol Protocol { get; set; } diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs index a97e4ee0..ba8c57c1 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs @@ -1,186 +1,187 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Devices.Common; -using PepperDash.Essentials.Devices.Common.Codec; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec -{ - public abstract class VideoCodecBase : Device, IRoutingSinkWithSwitching, IUsageTracking, IHasDialer, IHasSharing, ICodecAudio - { - /// - /// Fires when the status of any active, dialing, or incoming call changes or is new - /// - public event EventHandler CallStatusChange; - - #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 IRoutingInputs Members - - public RoutingPortCollection InputPorts { get; private set; } - - #endregion - - /// - /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected - /// - public bool IsInCall { get { return ActiveCalls.Any(c => c.IsActiveCall); } } - - public BoolFeedback IncomingCallFeedback { get; private set; } - - //public IntFeedback ActiveCallCountFeedback { get; private set; } - - //abstract protected Func ActiveCallCountFeedbackFunc { get; } - abstract protected Func IncomingCallFeedbackFunc { get; } - abstract protected Func PrivacyModeIsOnFeedbackFunc { get; } - abstract protected Func VolumeLevelFeedbackFunc { get; } - abstract protected Func MuteFeedbackFunc { get; } - abstract protected Func SharingSourceFeedbackFunc { get; } - - public List ActiveCalls { get; set; } - - public VideoCodecBase(string key, string name) - : base(key, name) - { - IncomingCallFeedback = new BoolFeedback(IncomingCallFeedbackFunc); - PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); - VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); - MuteFeedback = new BoolFeedback(MuteFeedbackFunc); - SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); - - InputPorts = new RoutingPortCollection(); - - ActiveCalls = new List(); - } - - #region IHasDialer Members - - public abstract void Dial(string s); - 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 - - public virtual List Feedbacks - { - get - { - return new List - { - IncomingCallFeedback, - 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) - { - var prevStatus = call.Status; - call.Status = newStatus; - OnCallStatusChange(prevStatus, newStatus, call); - } - - /// - /// - /// - /// - /// - /// - protected void OnCallStatusChange(eCodecCallStatus previousStatus, eCodecCallStatus newStatus, CodecActiveCallItem item) - { - var handler = CallStatusChange; - if (handler != null) - handler(this, new CodecCallStatusItemChangeEventArgs(previousStatus, newStatus, item)); - } - - #region ICodecAudio Members - - public abstract void PrivacyModeOn(); - public abstract void PrivacyModeOff(); - public abstract void PrivacyModeToggle(); - public BoolFeedback PrivacyModeIsOnFeedback { get; private set; } - - - public BoolFeedback MuteFeedback { get; private set; } - - public abstract void MuteOff(); - - public abstract void MuteOn(); - - public abstract void SetVolume(ushort level); - - public IntFeedback VolumeLevelFeedback { get; private set; } - - public abstract void MuteToggle(); - - public abstract void VolumeDown(bool pressRelease); - - - public abstract void VolumeUp(bool pressRelease); - - #endregion - - #region IHasSharing Members - - public abstract void StartSharing(); - public abstract void StopSharing(); - - public StringFeedback SharingSourceFeedback { get; private set; } - - #endregion - - // **** DEBUGGING THINGS **** - /// - /// - /// - public virtual void ListCalls() - { - var sb = new StringBuilder(); - foreach (var c in ActiveCalls) - sb.AppendFormat("{0} {1} -- {2} {3}\r", c.Id, c.Number, c.Name, c.Status); - Debug.Console(1, "{0}", sb.ToString()); - } - } - - /// - /// - /// - public class CodecCallStatusItemChangeEventArgs : EventArgs - { - public CodecActiveCallItem CallItem { get; private set; } - - public eCodecCallStatus PreviousStatus { get; private set; } - - public eCodecCallStatus NewStatus { get; private set; } - - public CodecCallStatusItemChangeEventArgs(eCodecCallStatus previousStatus, - eCodecCallStatus newStatus, CodecActiveCallItem item) - { - PreviousStatus = previousStatus; - NewStatus = newStatus; - CallItem = item; - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common; +using PepperDash.Essentials.Devices.Common.Codec; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec +{ + public abstract class VideoCodecBase : Device, IRoutingSinkWithSwitching, IUsageTracking, IHasDialer, IHasSharing, ICodecAudio + { + /// + /// Fires when the status of any active, dialing, or incoming call changes or is new + /// + public event EventHandler CallStatusChange; + + #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 IRoutingInputs Members + + public RoutingPortCollection InputPorts { get; private set; } + + #endregion + + /// + /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected + /// + public bool IsInCall { get { return ActiveCalls.Any(c => c.IsActiveCall); } } + + public BoolFeedback IncomingCallFeedback { get; private set; } + + //public IntFeedback ActiveCallCountFeedback { get; private set; } + + //abstract protected Func ActiveCallCountFeedbackFunc { get; } + abstract protected Func IncomingCallFeedbackFunc { get; } + abstract protected Func PrivacyModeIsOnFeedbackFunc { get; } + abstract protected Func VolumeLevelFeedbackFunc { get; } + abstract protected Func MuteFeedbackFunc { get; } + abstract protected Func SharingSourceFeedbackFunc { get; } + + public List ActiveCalls { get; set; } + + public VideoCodecBase(string key, string name) + : base(key, name) + { + IncomingCallFeedback = new BoolFeedback(IncomingCallFeedbackFunc); + PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); + VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); + MuteFeedback = new BoolFeedback(MuteFeedbackFunc); + SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); + + InputPorts = new RoutingPortCollection(); + + ActiveCalls = new List(); + } + + #region IHasDialer Members + + public abstract void Dial(string s); + 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 + + public virtual List Feedbacks + { + get + { + return new List + { + IncomingCallFeedback, + 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) + { + var prevStatus = call.Status; + call.Status = newStatus; + OnCallStatusChange(prevStatus, newStatus, call); + } + + /// + /// + /// + /// + /// + /// + protected void OnCallStatusChange(eCodecCallStatus previousStatus, eCodecCallStatus newStatus, CodecActiveCallItem item) + { + var handler = CallStatusChange; + if (handler != null) + handler(this, new CodecCallStatusItemChangeEventArgs(previousStatus, newStatus, item)); + } + + #region ICodecAudio Members + + public abstract void PrivacyModeOn(); + public abstract void PrivacyModeOff(); + public abstract void PrivacyModeToggle(); + public BoolFeedback PrivacyModeIsOnFeedback { get; private set; } + + + public BoolFeedback MuteFeedback { get; private set; } + + public abstract void MuteOff(); + + public abstract void MuteOn(); + + public abstract void SetVolume(ushort level); + + public IntFeedback VolumeLevelFeedback { get; private set; } + + public abstract void MuteToggle(); + + public abstract void VolumeDown(bool pressRelease); + + + public abstract void VolumeUp(bool pressRelease); + + #endregion + + #region IHasSharing Members + + public abstract void StartSharing(); + public abstract void StopSharing(); + + public StringFeedback SharingSourceFeedback { get; private set; } + + #endregion + + // **** DEBUGGING THINGS **** + /// + /// + /// + public virtual void ListCalls() + { + Debug.Console(1, this, "Active Calls List:\n"); + var sb = new StringBuilder(); + foreach (var c in ActiveCalls) + sb.AppendFormat("{0} {1} -- {2} {3}\r", c.Id, c.Number, c.Name, c.Status); + Debug.Console(1, this, "{0}", sb.ToString()); + } + } + + /// + /// + /// + public class CodecCallStatusItemChangeEventArgs : EventArgs + { + public CodecActiveCallItem CallItem { get; private set; } + + public eCodecCallStatus PreviousStatus { get; private set; } + + public eCodecCallStatus NewStatus { get; private set; } + + public CodecCallStatusItemChangeEventArgs(eCodecCallStatus previousStatus, + eCodecCallStatus newStatus, CodecActiveCallItem item) + { + PreviousStatus = previousStatus; + NewStatus = newStatus; + CallItem = item; + } + } } \ No newline at end of file diff --git a/Essentials/PepperDashEssentials/ControlSystem.cs b/Essentials/PepperDashEssentials/ControlSystem.cs index ea17997f..ba15d68c 100644 --- a/Essentials/PepperDashEssentials/ControlSystem.cs +++ b/Essentials/PepperDashEssentials/ControlSystem.cs @@ -132,8 +132,14 @@ namespace PepperDash.Essentials { GenericSshClient TestCodecClient = new GenericSshClient("TestCodec-1--SshClient", "10.11.50.135", 22, "crestron", "2H3Zu&OvgXp6"); + var props = new PepperDash.Essentials.Devices.Common.Codec.CiscoCodecPropertiesConfig(); + + props.PhonebookMode = "Local"; + props.Favorites = new System.Collections.Generic.List(); + props.Favorites.Add(new PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem() { Name = "NYU Cisco Webex", Number = "10.11.50.211" }); + PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoCodec TestCodec = - new PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoCodec("TestCodec-1", "Cisco Spark Room Kit", TestCodecClient, 8080); + new PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoCodec("TestCodec-1", "Cisco Spark Room Kit", TestCodecClient, props); TestCodec.CommDebuggingIsOn = true;