diff --git a/Essentials Core/PepperDashEssentialsBase/Devices/CodecInterfaces.cs.orig b/Essentials Core/PepperDashEssentialsBase/Devices/CodecInterfaces.cs.orig new file mode 100644 index 00000000..04d5aac9 --- /dev/null +++ b/Essentials Core/PepperDashEssentialsBase/Devices/CodecInterfaces.cs.orig @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Core +{ + /// + /// Requirements for a device that has dialing capabilities + /// + public interface IHasDialer + { + // Add requirements for Dialer functionality + + void Dial(string number); +<<<<<<< HEAD + void EndCall(string number); +======= + void EndCall(object activeCall); + void EndAllCalls(); +>>>>>>> origin/feature/cisco-spark-2 + void AcceptCall(); + void RejectCall(); + void SendDtmf(string digit); + + IntFeedback ActiveCallCountFeedback { get; } + BoolFeedback IncomingCallFeedback { get; } + } + + /// + /// Defines minimum volume controls for a codec device with dialing capabilities + /// + public interface ICodecAudio : IBasicVolumeWithFeedback, IPrivacy + { + + } + + /// + /// Adds control of codec receive volume + /// + public interface IReceiveVolume + { + // Break this out into 3 interfaces + void SetReceiveVolume(ushort level); + void ReceiveMuteOn(); + void ReceiveMuteOff(); + void ReceiveMuteToggle(); + IntFeedback ReceiveLevelFeedback { get; } + BoolFeedback ReceiveMuteIsOnFeedback { get; } + } + + /// + /// Adds control of codec transmit volume + /// + public interface ITransmitVolume + { + void SetTransmitVolume(ushort level); + void TransmitMuteOn(); + void TransmitMuteOff(); + void TransmitMuteToggle(); + IntFeedback TransmitLevelFeedback { get; } + BoolFeedback TransmitMuteIsOnFeedback { get; } + } + + /// + /// Adds control of codec privacy function (microphone mute) + /// + public interface IPrivacy + { + void PrivacyModeOn(); + void PrivacyModeOff(); + void PrivacyModeToggle(); + BoolFeedback PrivacyModeIsOnFeedback { get; } + } + + public interface IHasCallHistory + { + // Add recent calls list + } + + public interface IHasDirectory + { + + } + + public interface IHasObtp + { + + // Upcoming Meeting warning event + } +} \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs.orig b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs.orig new file mode 100644 index 00000000..b29dad03 --- /dev/null +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs.orig @@ -0,0 +1,785 @@ +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; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco +{ + enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; + + public class CiscoCodec : VideoCodecBase + { + 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; } + + private CiscoOneButtonToPush CodecObtp; + + private Corporate_Phone_Book PhoneBook; + + private CiscoCodecConfiguration.RootObject CodecConfiguration; + + private CiscoCodecStatus.RootObject CodecStatus; + + 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; + } + } + + protected override Func SharingSourceFeedbackFunc + { + get { return () => "Fix me fuckers"; } + } + + protected override Func MuteFeedbackFunc + { + get { return () => false; } + } + + //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) + { + StandbyIsOnFeedback = new BoolFeedback(StandbyStateFeedbackFunc); + + Communication = comm; + + SyncState = new CodecSyncState(key + "--sync"); + + PortGather = new CommunicationGather(Communication, Delimiter); + PortGather.IncludeDelimiter = true; + PortGather.LineReceived += this.Port_LineReceived; + + //ServerPort = serverPort; + + CodecObtp = new CiscoOneButtonToPush(); + + PhoneBook = new Corporate_Phone_Book(); + + CodecConfiguration = new CiscoCodecConfiguration.RootObject(); + + CodecStatus = new CiscoCodecStatus.RootObject(); + + CodecEvent = new CiscoCodecEvents.RootObject(); + + CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate; + CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate; + CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate; + CodecStatus.Status.Standby.State.ValueChangedAction = StandbyIsOnFeedback.FireUpdate; + + //Client = new HttpsClient(); + + //Server = new HttpApiServer(); + } + + /// + /// 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/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; + } + + if (!SyncState.InitialSyncComplete) + { + switch (args.Text.Trim().ToLower()) // remove the whitespace + { + case "*r login successful": + { + SendText("xPreferences outputmode json"); + break; + } + case "xpreferences outputmode json": + { + if(!SyncState.InitialStatusMessageWasReceived) + SendText("xStatus"); + break; + } + case "xfeedback register": + { + SyncState.FeedbackRegistered(); + 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) + { + JsonConvert.PopulateObject(response, CodecStatus); + + if (!SyncState.InitialStatusMessageWasReceived) + { + SyncState.InitialStatusMessageReceived(); + if(!SyncState.InitialConfigurationMessageWasReceived) + SendText("xConfiguration"); + } + } + else if (response.IndexOf("\"Configuration\":{") > -1) + { + JsonConvert.PopulateObject(response, CodecConfiguration); + + if (!SyncState.InitialConfigurationMessageWasReceived) + { + SyncState.InitialConfigurationMessageReceived(); + if (!SyncState.FeedbackWasRegistered) + { + SendText(CliFeedbackRegistrationExpression); + } + } + + } + else if (response.IndexOf("\"Event\":{") > -1) + { + JsonConvert.PopulateObject(response, CodecEvent); + } + + } + catch (Exception ex) + { + Debug.Console(1, this, "Error Deserializing feedback from codec: {0}", ex); + } + } + + 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)); + } + +<<<<<<< HEAD + public override void EndCall(string s) + { + SendText(string.Format("xCommand Call Disconnect CallId: {0}", GetCallId())); +======= + 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)); + } +>>>>>>> origin/feature/cisco-spark-2 + } + + public override void AcceptCall() + { + SendText("xCommand Call Accept"); + } + + public override void RejectCall() + { + 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"); + } + + protected override Func ActiveCallCountFeedbackFunc + { + get { return () => 0; } + } + } + + /// + /// Tracks the initial sycnronization state of the codec when making a connection + /// + public class CodecSyncState : IKeyed + { + public string Key { get; private set; } + + public bool InitialSyncComplete { get; private set; } + + 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/CodecActiveCallItem.cs.orig b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CodecActiveCallItem.cs.orig new file mode 100644 index 00000000..4b47d127 --- /dev/null +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CodecActiveCallItem.cs.orig @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec + +{ + public class CodecActiveCallItem + { + public string Name { get; set; } + + public string Number { get; set; } + +<<<<<<< HEAD + public eCodecCallType Type { get; private set; } + + public CodecActiveCallItem(string name, string number, eCodecCallType type) + { + Name = name; + Number = number; + Type = type; + } +======= + public eCodecCallType Type { get; set; } + + public eCodecCallStatus Status { get; set; } + + public string Id { get; set; } +>>>>>>> origin/feature/cisco-spark-2 + } + + public enum eCodecCallType + { + None, Audio, Video + } + + public enum eCodecCallStatus + { + Dialing, Established, Incoming + } +} \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index f70988dd..9e1d383f 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -6,10 +6,11 @@ using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials.Devices.Common.VideoCodec { - public class MockVC : VideoCodecBase + public class MockVC : VideoCodecBase, IRoutingOutputs { public MockVC(string key, string name) : base(key, name) @@ -64,7 +65,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public override void Dial(string s) { Debug.Console(1, this, "Dial: {0}", s); - ActiveCalls.Add(new CodecActiveCallItem(s,s, eCodecCallType.Video)); + ActiveCalls.Add(new CodecActiveCallItem() { Name = s, Number = s }); ActiveCallCountFeedback.FireUpdate(); } @@ -74,15 +75,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public override void EndCall(CodecActiveCallItem activeCall) { Debug.Console(1, this, "EndCall"); - ActiveCalls.RemoveAll(i => i.Name == s); + ActiveCalls.Remove(activeCall); ActiveCallCountFeedback.FireUpdate(); - //_InCall = false; - //IsInCall.FireUpdate(); } + /// + /// + /// public override void EndAllCalls() { - + Debug.Console(1, this, "EndAllCalls"); + ActiveCalls.Clear(); + ActiveCallCountFeedback.FireUpdate(); } /// @@ -132,7 +136,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { Debug.Console(1, this, "ExecuteSwitch"); _SharingSource = selector.ToString(); - } /// @@ -198,7 +201,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec return; _PrivacyModeIsOn = true; PrivacyModeIsOnFeedback.FireUpdate(); - } /// diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs.orig b/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs.orig index 9699d0ae..f70988dd 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs.orig +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs.orig @@ -14,25 +14,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public MockVC(string key, string name) : base(key, name) { - MuteFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Mute={0}", _IsMuted); - VolumeLevelFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Volume={0}", _VolumeLevel); - InCallFeedback.OutputChange += (o, a) => Debug.Console(1, this, "InCall={0}", _InCall); + // Debug helpers + ActiveCallCountFeedback.OutputChange += (o, a) => Debug.Console(1, this, "InCall={0}", ActiveCallCountFeedback.IntValue); IncomingCallFeedback.OutputChange += (o, a) => Debug.Console(1, this, "IncomingCall={0}", _IncomingCall); -<<<<<<< HEAD - ReceiveLevelFeedback.OutputChange += (o, a) => Debug.Console(1, this, "ReceiveLevel={0}", _ReceiveLevel); - ReceiveMuteIsOnFeedback.OutputChange += (o, a) => Debug.Console(1, this, "ReceiveMute={0}", _ReceiveMute); - TransmitLevelFeedback.OutputChange += (o, a) => Debug.Console(1, this, "TransmitLevel={0}", _TransmitLevel); - TransmitMuteIsOnFeedback.OutputChange += (o, a) => Debug.Console(1, this, "TransmitMute={0}", _TransmitMute); + MuteFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Mute={0}", _IsMuted); + PrivacyModeIsOnFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Privacy={0}", _PrivacyModeIsOn); SharingSourceFeedback.OutputChange += (o, a) => Debug.Console(1, this, "SharingSource={0}", _SharingSource); -======= ->>>>>>> origin/feature/cisco-spark - } + VolumeLevelFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Volume={0}", _VolumeLevel); + } - protected override Func InCallFeedbackFunc + protected override Func ActiveCallCountFeedbackFunc { - get { return () => _InCall; } + get { return () => ActiveCalls.Count; } } - bool _InCall; protected override Func IncomingCallFeedbackFunc { @@ -40,38 +34,23 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } bool _IncomingCall; -<<<<<<< HEAD - protected override Func TransmitLevelFeedbackFunc + protected override Func MuteFeedbackFunc { - get { return () => _TransmitLevel; } + get { return () => _IsMuted; } } - int _TransmitLevel; + bool _IsMuted; - protected override Func TransmitMuteFeedbackFunc - { - get { return () => _TransmitMute; } - } - bool _TransmitMute; - - protected override Func ReceiveLevelFeedbackFunc - { - get { return () => _ReceiveLevel; } - } - int _ReceiveLevel; - - protected override Func ReceiveMuteFeedbackFunc - { - get { return () => _ReceiveMute; } - } - bool _ReceiveMute; -======= ->>>>>>> origin/feature/cisco-spark - - protected override Func PrivacyModeFeedbackFunc + protected override Func PrivacyModeIsOnFeedbackFunc { get { return () => _PrivacyModeIsOn; } } bool _PrivacyModeIsOn; + + protected override Func SharingSourceFeedbackFunc + { + get { return () => _SharingSource; } + } + string _SharingSource; protected override Func VolumeLevelFeedbackFunc { @@ -79,37 +58,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } int _VolumeLevel; - protected override Func MuteFeedbackFunc - { - get { return () => _IsMuted; } - } - bool _IsMuted; - - protected override Func SharingSourceFeedbackFunc - { - get { return () => _SharingSource; } - } - string _SharingSource; - /// /// Dials, yo! /// public override void Dial(string s) { Debug.Console(1, this, "Dial: {0}", s); - - _InCall = true; - InCallFeedback.FireUpdate(); + ActiveCalls.Add(new CodecActiveCallItem(s,s, eCodecCallType.Video)); + ActiveCallCountFeedback.FireUpdate(); } /// /// /// - public override void EndCall() + public override void EndCall(CodecActiveCallItem activeCall) { Debug.Console(1, this, "EndCall"); - _InCall = false; - InCallFeedback.FireUpdate(); + ActiveCalls.RemoveAll(i => i.Name == s); + ActiveCallCountFeedback.FireUpdate(); + //_InCall = false; + //IsInCall.FireUpdate(); + } + + public override void EndAllCalls() + { + } /// @@ -137,14 +110,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Debug.Console(1, this, "SendDTMF: {0}", s); } + /// + /// + /// public override void StartSharing() { - } + /// + /// + /// public override void StopSharing() { - } /// @@ -154,124 +131,66 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public override void ExecuteSwitch(object selector) { Debug.Console(1, this, "ExecuteSwitch"); + _SharingSource = selector.ToString(); } + /// + /// + /// public override void MuteOff() { _IsMuted = false; MuteFeedback.FireUpdate(); } + /// + /// + /// public override void MuteOn() { _IsMuted = true; MuteFeedback.FireUpdate(); } + /// + /// + /// public override void MuteToggle() { _IsMuted = !_IsMuted; MuteFeedback.FireUpdate(); } + /// + /// + /// + /// public override void SetVolume(ushort level) { _VolumeLevel = level; VolumeLevelFeedback.FireUpdate(); } + /// + /// + /// + /// public override void VolumeDown(bool pressRelease) -<<<<<<< HEAD { } + /// + /// + /// + /// public override void VolumeUp(bool pressRelease) { } - /// /// /// - public override void ReceiveMuteOff() - { - Debug.Console(1, this, "ReceiveMuteOff"); - - if (!_ReceiveMute) - return; - _ReceiveMute = false; - ReceiveMuteIsOnFeedback.FireUpdate(); - } - - /// - /// - /// - public override void ReceiveMuteOn() - { - Debug.Console(1, this, "ReceiveMuteOn"); - if (_ReceiveMute) - return; - ReceiveMuteIsOnFeedback.FireUpdate(); - } - - /// - /// - /// - public override void ReceiveMuteToggle() - { - Debug.Console(1, this, "ReceiveMuteToggle"); - - _ReceiveMute = !_ReceiveMute; - ReceiveMuteIsOnFeedback.FireUpdate(); - } - - /// - /// - /// - /// - public override void SetReceiveVolume(ushort level) - { - Debug.Console(1, this, "SetReceiveVolume: {0}", level); - - } - - /// - /// - /// - public override void TransmitMuteOff() - { - Debug.Console(1, this, "TransmitMuteOff"); - - if (!_TransmitMute) - return; - _TransmitMute = false; - TransmitMuteIsOnFeedback.FireUpdate(); - } - - /// - /// - /// - public override void TransmitMuteOn() - { - Debug.Console(1, this, "TransmitMuteOn"); - if (_TransmitMute) - return; - TransmitMuteIsOnFeedback.FireUpdate(); - } - - public override void TransmitMuteToggle() -======= ->>>>>>> origin/feature/cisco-spark - { - - } - - public override void VolumeUp(bool pressRelease) - { - - } - public override void PrivacyModeOn() { Debug.Console(1, this, "PrivacyMuteOn"); @@ -282,6 +201,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } + /// + /// + /// public override void PrivacyModeOff() { Debug.Console(1, this, "PrivacyMuteOff"); @@ -291,6 +213,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec PrivacyModeIsOnFeedback.FireUpdate(); } + /// + /// + /// public override void PrivacyModeToggle() { _PrivacyModeIsOn = !_PrivacyModeIsOn; @@ -301,6 +226,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec //******************************************************** // SIMULATION METHODS + /// + /// + /// + /// public void TestIncomingCall(string url) { Debug.Console(1, this, "TestIncomingCall"); @@ -309,11 +238,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec IncomingCallFeedback.FireUpdate(); } + /// + /// + /// public void TestFarEndHangup() { Debug.Console(1, this, "TestFarEndHangup"); } - } } \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs.orig b/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs.orig index a7d17c52..e13bb133 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs.orig +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs.orig @@ -13,6 +13,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { #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 @@ -23,50 +27,51 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec #endregion - public BoolFeedback InCallFeedback { get; protected set; } - public BoolFeedback IncomingCallFeedback { get; protected set; } + /// + /// Returns true when ActiveCallCountFeedback is > 0 + /// + public bool IsInCall { get { return ActiveCallCountFeedback.IntValue > 0; } } - abstract protected Func InCallFeedbackFunc { get; } + public BoolFeedback IncomingCallFeedback { get; private set; } + + public IntFeedback ActiveCallCountFeedback { get; private set; } + + abstract protected Func ActiveCallCountFeedbackFunc { get; } abstract protected Func IncomingCallFeedbackFunc { get; } -<<<<<<< HEAD - abstract protected Func TransmitMuteFeedbackFunc { get; } - abstract protected Func TransmitLevelFeedbackFunc { get; } - abstract protected Func ReceiveMuteFeedbackFunc { get; } - abstract protected Func ReceiveLevelFeedbackFunc { get; } -======= ->>>>>>> origin/feature/cisco-spark - abstract protected Func PrivacyModeFeedbackFunc { 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) { - InCallFeedback = new BoolFeedback(InCallFeedbackFunc); + ActiveCallCountFeedback = new IntFeedback(ActiveCallCountFeedbackFunc); IncomingCallFeedback = new BoolFeedback(IncomingCallFeedbackFunc); -<<<<<<< HEAD - ReceiveLevelFeedback = new IntFeedback(ReceiveLevelFeedbackFunc); - ReceiveMuteIsOnFeedback = new BoolFeedback(ReceiveMuteFeedbackFunc); - TransmitMuteIsOnFeedback = new BoolFeedback(TransmitMuteFeedbackFunc); - TransmitLevelFeedback = new IntFeedback(TransmitLevelFeedbackFunc); -======= ->>>>>>> origin/feature/cisco-spark - PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeFeedbackFunc); + PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); MuteFeedback = new BoolFeedback(MuteFeedbackFunc); SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); InputPorts = new RoutingPortCollection(); - InCallFeedback.OutputChange += new EventHandler(InCallFeedback_OutputChange); + ActiveCallCountFeedback.OutputChange += new EventHandler(ActiveCallCountFeedback_OutputChange); + + ActiveCalls = new List(); } - void InCallFeedback_OutputChange(object sender, EventArgs e) + /// + /// + /// + /// + /// + void ActiveCallCountFeedback_OutputChange(object sender, EventArgs e) { if (UsageTracker != null) { - if (InCallFeedback.BoolValue) + if (IsInCall) UsageTracker.StartDeviceUsage(); else UsageTracker.EndDeviceUsage(); @@ -75,7 +80,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec #region IHasDialer Members public abstract void Dial(string s); - public abstract void EndCall(); +<<<<<<< HEAD + public abstract void EndCall(string s); +======= + public void EndCall(object activeCall) + { + + } + public abstract void EndCall(CodecActiveCallItem activeCall); + public abstract void EndAllCalls(); +>>>>>>> origin/feature/cisco-spark-2 public abstract void AcceptCall(); public abstract void RejectCall(); public abstract void SendDtmf(string s); @@ -88,9 +102,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { return new List { - InCallFeedback, IncomingCallFeedback, - PrivacyModeIsOnFeedback + PrivacyModeIsOnFeedback, + SharingSourceFeedback }; } } diff --git a/Essentials/PepperDashEssentials/PepperDashEssentials.csproj b/Essentials/PepperDashEssentials/PepperDashEssentials.csproj index 800d772c..e19cb51f 100644 --- a/Essentials/PepperDashEssentials/PepperDashEssentials.csproj +++ b/Essentials/PepperDashEssentials/PepperDashEssentials.csproj @@ -164,6 +164,7 @@ + diff --git a/Essentials/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/Essentials/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index b8800d60..83df42e8 100644 --- a/Essentials/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/Essentials/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -246,12 +246,13 @@ namespace PepperDash.Essentials } /// - /// Routes the default source item, if any + /// Routes the default source item, if any. Returns true when default route exists /// - public void RunDefaultRoute() + public bool RunDefaultRoute() { if (DefaultSourceItem != null) RunRouteAction(DefaultSourceItem); + return DefaultSourceItem != null; } /// diff --git a/Essentials/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddlePresentationUiDriver.cs b/Essentials/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddlePresentationUiDriver.cs new file mode 100644 index 00000000..c573310f --- /dev/null +++ b/Essentials/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddlePresentationUiDriver.cs @@ -0,0 +1,49 @@ +//using System; +//using System.Linq; +//using System.Collections.Generic; +//using Crestron.SimplSharp; +//using Crestron.SimplSharpPro; +//using Crestron.SimplSharpPro.DeviceSupport; +//using Crestron.SimplSharpPro.UI; + +//using PepperDash.Core; +//using PepperDash.Essentials.Core; +//using PepperDash.Essentials.Core.SmartObjects; +//using PepperDash.Essentials.Core.PageManagers; +//using PepperDash.Essentials.Room.Config; + +//namespace PepperDash.Essentials +//{ +// public class EssentialsHuddleVtc1PresentationUiDriver : PanelDriverBase +// { +// /// +// /// +// /// +// EssentialsHuddleVtc1Room CurrentRoom; + + +// public EssentialsHuddleVtc1PresentationUiDriver(BasicTriListWithSmartObject triList, +// EssentialsHuddleVtc1Room room) +// : base(triList) +// { +// CurrentRoom = room; +// } + +// /// +// /// Smart Object 3200 +// /// +// SubpageReferenceList SourceStagingSrl; + +// /// +// /// The AV page mangagers that have been used, to keep them alive for later +// /// +// Dictionary PageManagers = new Dictionary(); + +// /// +// /// Current page manager running for a source +// /// +// PageManager CurrentSourcePageManager; + + +// } +//} \ No newline at end of file diff --git a/Essentials/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/HuddleVTCPanelAvFunctionsDriver.cs b/Essentials/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/HuddleVTCPanelAvFunctionsDriver.cs index 7bfcf805..91f9b401 100644 --- a/Essentials/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/HuddleVTCPanelAvFunctionsDriver.cs +++ b/Essentials/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/HuddleVTCPanelAvFunctionsDriver.cs @@ -11,6 +11,12 @@ using PepperDash.Essentials.Core.SmartObjects; using PepperDash.Essentials.Core.PageManagers; using PepperDash.Essentials.Room.Config; + + +#warning END MEETING on call page doesn't clear call mode +#warning END MEETING doesn't restore logo page + + namespace PepperDash.Essentials { /// @@ -301,33 +307,33 @@ namespace PepperDash.Essentials base.Show(); } - /// - /// Puts the UI into the "start" mode. System is off. Logo shows. Activity SRL is clear - /// - void ShowStartMode() - { - SetupActivityFooterWhenRoomOff(); + ///// + ///// Puts the UI into the "start" mode. System is off. Logo shows. Activity SRL is clear + ///// + //void ShowStartMode() + //{ + // SetupActivityFooterWhenRoomOff(); - ShareButtonSig.BoolValue = false; - CallButtonSig.BoolValue = false; - ShowLogo(); - StagingBarInterlock.ShowInterlocked(UIBoolJoin.StartPageVisible); - StagingBarInterlock.HideAndClear(); - } + // ShareButtonSig.BoolValue = false; + // CallButtonSig.BoolValue = false; + // ShowLogo(); + // StagingBarInterlock.ShowInterlocked(UIBoolJoin.StartPageVisible); + // StagingBarInterlock.HideAndClear(); + //} - void ShowShareMode() - { - ShareButtonSig.BoolValue = true; - CallButtonSig.BoolValue = false; - StagingBarInterlock.ShowInterlocked(UIBoolJoin.SourceStagingBarVisible); - } + //void ShowShareMode() + //{ + // ShareButtonSig.BoolValue = true; + // CallButtonSig.BoolValue = false; + // StagingBarInterlock.ShowInterlocked(UIBoolJoin.SourceStagingBarVisible); + //} - void ShowVideoCallMode() - { - ShareButtonSig.BoolValue = false; - CallButtonSig.BoolValue = true; - StagingBarInterlock.ShowInterlocked(UIBoolJoin.CallStagingBarVisible); - } + //void ShowVideoCallMode() + //{ + // ShareButtonSig.BoolValue = false; + // CallButtonSig.BoolValue = true; + // StagingBarInterlock.ShowInterlocked(UIBoolJoin.CallStagingBarVisible); + //} /// /// @@ -347,6 +353,15 @@ namespace PepperDash.Essentials } } + /// + /// + /// + void HideLogo() + { + TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false); + TriList.SetBool(UIBoolJoin.LogoUrlVisible, false); + } + /// /// /// @@ -404,9 +419,12 @@ namespace PepperDash.Essentials return; CallButtonSig.BoolValue = true; ShareButtonSig.BoolValue = false; + HideLogo(); TriList.SetBool(UIBoolJoin.StartPageVisible, false); TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + if (CurrentSourcePageManager != null) + CurrentSourcePageManager.Hide(); VCDriver.Show(); } @@ -421,10 +439,18 @@ namespace PepperDash.Essentials CallButtonSig.BoolValue = false; TriList.SetBool(UIBoolJoin.StartPageVisible, false); TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, true); - TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); // Run default source when room is off and share is pressed if (!CurrentRoom.OnFeedback.BoolValue) - CurrentRoom.RunDefaultRoute(); + { + // If there's no default, show UI elements + if(!CurrentRoom.RunDefaultRoute()) + TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); + } + else // show what's active + { + if (CurrentSourcePageManager != null) + CurrentSourcePageManager.Show(); + } } /// @@ -729,7 +755,10 @@ namespace PepperDash.Essentials } else { + if (VCDriver.IsVisible) + VCDriver.Hide(); SetupActivityFooterWhenRoomOff(); + ShowLogo(); TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true; TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; diff --git a/Essentials/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs.orig b/Essentials/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs.orig new file mode 100644 index 00000000..7d0301e7 --- /dev/null +++ b/Essentials/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs.orig @@ -0,0 +1,250 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; + +using PepperDash.Core; +using PepperDash.Essentials; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.SmartObjects; +using PepperDash.Essentials.Devices.Common.VideoCodec; + +namespace PepperDash.Essentials.UIDrivers.VC +{ + + /// + /// This fella will likely need to interact with the room's source, although that is routed via the spark... + /// Probably needs event or FB to feed AV driver - to show two-mute volume when appropriate. + /// + /// + public class EssentialsVideoCodecUiDriver : PanelDriverBase + { + /// + /// + /// + VideoCodecBase Codec; + + /// + /// + /// + SmartObjectDynamicList DirectorySrl; // ***************** SRL ??? + + + /// + /// To drive UI elements outside of this driver that may be dependent on this. + /// + BoolFeedback InCall; + BoolFeedback LocalPrivacyIsMuted; + + /// + /// For the subpages above the bar + /// + JoinedSigInterlock VCControlsInterlock; + + /// + /// For the different staging bars: Active, inactive + /// + JoinedSigInterlock StagingBarInterlock; + + /// + /// For the staging button feedbacks + /// + JoinedSigInterlock StagingButtonFeedbackInterlock; + + SmartObjectNumeric DialKeypad; + + // These are likely temp until we get a keyboard built + StringFeedback DialStringFeedback; + StringBuilder DialStringBuilder = new StringBuilder(); + BoolFeedback DialStringBackspaceVisibleFeedback; + + /// + /// + /// + /// + /// + public EssentialsVideoCodecUiDriver(BasicTriListWithSmartObject triList, VideoCodecBase codec) + : base(triList) + { + Codec = codec; + SetupCallStagingPopover(); + SetupDialKeypad(); + + InCall = new BoolFeedback(() => false); + LocalPrivacyIsMuted = new BoolFeedback(() => false); + + //DirectorySrl = new SubpageReferenceList(triList, UISmartObjectJoin.VCDirectoryList, 3, 3, 3); + + VCControlsInterlock = new JoinedSigInterlock(triList); + VCControlsInterlock.SetButDontShow(UIBoolJoin.VCDirectoryVisible); + + StagingBarInterlock = new JoinedSigInterlock(triList); + StagingBarInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverVisible); + + StagingButtonFeedbackInterlock = new JoinedSigInterlock(triList); + StagingButtonFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCRecentsVisible); + + DialStringFeedback = new StringFeedback(() => DialStringBuilder.ToString()); + DialStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.KeyboardText]); + + DialStringBackspaceVisibleFeedback = new BoolFeedback(() => DialStringBuilder.Length > 0); + DialStringBackspaceVisibleFeedback + .LinkInputSig(TriList.BooleanInput[UIBoolJoin.KeyboardClearVisible]); + + Codec.ActiveCallCountFeedback.OutputChange += new EventHandler(InCallFeedback_OutputChange); + } + + /// + /// + /// + public override void Show() + { + VCControlsInterlock.Show(); + StagingBarInterlock.Show(); + base.Show(); + } + + /// + /// + /// + public override void Hide() + { + VCControlsInterlock.Hide(); + StagingBarInterlock.Hide(); + base.Hide(); + } + + /// + /// Builds the call stage + /// + void SetupCallStagingPopover() + { + TriList.SetSigFalseAction(UIBoolJoin.VCStagingDirectoryPress, ShowDirectory); + TriList.SetSigFalseAction(UIBoolJoin.VCStagingConnectPress, ConnectPress); + TriList.SetSigFalseAction(UIBoolJoin.VCStagingKeypadPress, ShowKeypad); + TriList.SetSigFalseAction(UIBoolJoin.VCStagingRecentsPress, ShowRecents); + } + + /// + /// + /// + void SetupDialKeypad() + { + if(TriList.SmartObjects.Contains(UISmartObjectJoin.VCDialKeypad)) + { + DialKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.VCDialKeypad], true); + DialKeypad.Digit0.SetSigFalseAction(() => DialKeypadPress("0")); + DialKeypad.Digit1.SetSigFalseAction(() => DialKeypadPress("1")); + DialKeypad.Digit2.SetSigFalseAction(() => DialKeypadPress("2")); + DialKeypad.Digit3.SetSigFalseAction(() => DialKeypadPress("3")); + DialKeypad.Digit4.SetSigFalseAction(() => DialKeypadPress("4")); + DialKeypad.Digit5.SetSigFalseAction(() => DialKeypadPress("5")); + DialKeypad.Digit6.SetSigFalseAction(() => DialKeypadPress("6")); + DialKeypad.Digit7.SetSigFalseAction(() => DialKeypadPress("7")); + DialKeypad.Digit8.SetSigFalseAction(() => DialKeypadPress("8")); + DialKeypad.Digit9.SetSigFalseAction(() => DialKeypadPress("9")); + DialKeypad.Misc1SigName = "*"; + DialKeypad.Misc1.SetSigFalseAction(() => DialKeypadPress("*")); + DialKeypad.Misc2SigName = "#"; + DialKeypad.Misc2.SetSigFalseAction(() => DialKeypadPress("#")); + TriList.SetSigFalseAction(UIBoolJoin.KeyboardClearPress, DialKeypadBackspacePress); + } + else + Debug.Console(0, "Trilist {0:x2}, VC dial keypad object {1} not found. Check SGD file or VTP", + TriList.ID, UISmartObjectJoin.VCDialKeypad); + } + + /// + /// + /// + void ShowCameraControls() + { + VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCCameraVisible); + StagingButtonFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingCameraPress); + } + + void ShowKeypad() + { + VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadVisible); + StagingButtonFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress); + } + + void ShowDirectory() + { + // populate directory + VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCDirectoryVisible); + StagingButtonFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingDirectoryPress); + } + + void ShowRecents() + { + //populate recents + VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCDirectoryVisible); + StagingButtonFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingRecentsPress); + } + + /// + /// + /// + void ConnectPress() + { + if (Codec.IsInCall) +<<<<<<< HEAD + Codec.EndCall("end whatever is selected"); +======= + Codec.EndAllCalls(); +>>>>>>> origin/feature/cisco-spark-2 + else + Codec.Dial(DialStringBuilder.ToString()); + } + + /// + /// + /// + void InCallFeedback_OutputChange(object sender, EventArgs e) + { + var inCall = Codec.IsInCall; + Debug.Console(1, "*#* Codec Driver InCallFeedback change={0}", InCall); + TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(inCall ? 1 : 0); + StagingBarInterlock.ShowInterlocked( + inCall ? UIBoolJoin.VCStagingActivePopoverVisible : UIBoolJoin.VCStagingInactivePopoverVisible); + + if (Codec.IsInCall) // Call is starting + { + // Header icon + // Volume bar needs to have mic mute + } + else // ending + { + // Header icon + // Volume bar no mic mute (or hidden if no source?) + } + } + + /// + /// + /// + /// + void DialKeypadPress(string i) + { + DialStringBuilder.Append(i); + DialStringFeedback.FireUpdate(); + TriList.BooleanInput[UIBoolJoin.KeyboardClearVisible].BoolValue = + DialStringBuilder.Length > 0; + } + + /// + /// + /// + void DialKeypadBackspacePress() + { + DialStringBuilder.Remove(DialStringBuilder.Length - 1, 1); + DialStringFeedback.FireUpdate(); + TriList.BooleanInput[UIBoolJoin.KeyboardClearVisible].BoolValue = + DialStringBuilder.Length > 0; + TriList.SetBool(UIBoolJoin.VCStagingConnectEnable, DialStringBuilder.Length > 0); + } + } +} \ No newline at end of file diff --git a/Release Package/PepperDashEssentials.cpz b/Release Package/PepperDashEssentials.cpz index d37ea309..04abe864 100644 Binary files a/Release Package/PepperDashEssentials.cpz and b/Release Package/PepperDashEssentials.cpz differ diff --git a/Release Package/PepperDashEssentials.dll b/Release Package/PepperDashEssentials.dll index 3b28f501..c82d72a2 100644 Binary files a/Release Package/PepperDashEssentials.dll and b/Release Package/PepperDashEssentials.dll differ