using System; using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Cards; using Crestron.SimplSharpPro.DM.Blades; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM { /// /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions /// /// public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitchWithEndpointOnlineFeedback, IRoutingNumericWithFeedback { private const string NonePortKey = "inputCard0--None"; public DMChassisPropertiesConfig PropertiesConfig { get; set; } public Switch Chassis { get; private set; } //IroutingNumericEvent public event EventHandler NumericSwitchChange; // Feedbacks for EssentialDM public Dictionary VideoOutputFeedbacks { get; private set; } public Dictionary AudioOutputFeedbacks { get; private set; } public Dictionary VideoInputSyncFeedbacks { get; private set; } public Dictionary InputEndpointOnlineFeedbacks { get; private set; } public Dictionary OutputEndpointOnlineFeedbacks { get; private set; } public Dictionary InputNameFeedbacks { get; private set; } public Dictionary OutputNameFeedbacks { get; private set; } public Dictionary OutputVideoRouteNameFeedbacks { get; private set; } public Dictionary OutputAudioRouteNameFeedbacks { get; private set; } public Dictionary UsbOutputRoutedToFeebacks { get; private set; } public Dictionary UsbInputRoutedToFeebacks { get; private set; } public IntFeedback SystemIdFeebdack { get; private set; } public BoolFeedback SystemIdBusyFeedback { get; private set; } public Dictionary InputCardHdcpCapabilityFeedbacks { get; private set; } public Dictionary InputCardHdcpCapabilityTypes { get; private set; } // Need a couple Lists of generic Backplane ports public RoutingPortCollection InputPorts { get; private set; } public RoutingPortCollection OutputPorts { get; private set; } public Dictionary TxDictionary { get; set; } public Dictionary RxDictionary { get; set; } //public Dictionary InputCards { get; private set; } //public Dictionary OutputCards { get; private set; } public Dictionary InputNames { get; set; } public Dictionary OutputNames { get; set; } public Dictionary VolumeControls { get; private set; } public const int RouteOffTime = 500; Dictionary RouteOffTimers = new Dictionary(); /// /// Factory method to create a new chassis controller from config data. Limited to 8x8 right now /// public static DmBladeChassisController GetDmChassisController(string key, string name, string type, DMChassisPropertiesConfig properties) { try { type = type.ToLower(); uint ipid = properties.Control.IpIdInt; BladeSwitch chassis = null; if (type == "dmmd64x64") { chassis = new DmMd64x64(ipid, Global.ControlSystem); } else if (type == "dmmd128x128") { chassis = new DmMd128x128(ipid, Global.ControlSystem); } if (chassis == null) { return null; } var controller = new DmBladeChassisController(key, name, chassis); // add the cards and port names foreach (var kvp in properties.InputSlots) controller.AddInputBlade(kvp.Value, kvp.Key); foreach (var kvp in properties.OutputSlots) { controller.AddOutputBlade(kvp.Value, kvp.Key); } foreach (var kvp in properties.VolumeControls) { // get the card // check it for an audio-compatible type // make a something-something that will make it work // retire to mountain village var outNum = kvp.Key; var card = controller.Chassis.Outputs[outNum].Card; Audio.Output audio = null; if (card is DmHdmi4kOutputBladeCard) audio = (card as DmHdmi4kOutputBladeCard).Hdmi4kOutput.Audio; if (audio == null) continue; // wire up the audio to something here... controller.AddVolumeControl(outNum, audio); } controller.InputPorts.Add(new RoutingInputPort(NonePortKey, eRoutingSignalType.Video, eRoutingPortConnectionType.None, null, controller)); controller.InputNames = properties.InputNames; controller.OutputNames = properties.OutputNames; controller.PropertiesConfig = properties; return controller; } catch (System.Exception e) { Debug.Console(0, "Error creating DM chassis:\r{0}", e); } return null; } /// /// /// /// /// /// public DmBladeChassisController(string key, string name, BladeSwitch chassis) : base(key, name, chassis) { Chassis = chassis; InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); VolumeControls = new Dictionary(); TxDictionary = new Dictionary(); RxDictionary = new Dictionary(); IsOnline.OutputChange += new EventHandler(IsOnline_OutputChange); Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); VideoOutputFeedbacks = new Dictionary(); UsbOutputRoutedToFeebacks = new Dictionary(); UsbInputRoutedToFeebacks = new Dictionary(); VideoInputSyncFeedbacks = new Dictionary(); InputNameFeedbacks = new Dictionary(); OutputNameFeedbacks = new Dictionary(); OutputVideoRouteNameFeedbacks = new Dictionary(); OutputAudioRouteNameFeedbacks = new Dictionary(); InputEndpointOnlineFeedbacks = new Dictionary(); OutputEndpointOnlineFeedbacks = new Dictionary(); InputCardHdcpCapabilityFeedbacks = new Dictionary(); InputCardHdcpCapabilityTypes = new Dictionary(); for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) { var tempX = x; if (Chassis.Outputs[tempX] != null) { VideoOutputFeedbacks[tempX] = new IntFeedback(() => { if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; } else { return 0; }; }); OutputNameFeedbacks[tempX] = new StringFeedback(() => { if (Chassis.Outputs[tempX].NameFeedback != null) { return Chassis.Outputs[tempX].NameFeedback.StringValue; } else { return ""; } }); OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => { if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue; } else { return ""; } }); OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => { //if (Chassis.Outputs[tempX].Endpoint != null) // return Chassis.Outputs[tempX].Endpoint.IsOnline; //else return Chassis.Outputs[tempX].EndpointOnlineFeedback; }); } if (Chassis.Inputs[tempX] != null) { UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => { if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; } else { return 0; }; }); VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => { if (Chassis.Inputs[tempX].VideoDetectedFeedback != null) return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue; else return false; }); InputNameFeedbacks[tempX] = new StringFeedback(() => { if (Chassis.Inputs[tempX].NameFeedback != null) { return Chassis.Inputs[tempX].NameFeedback.StringValue; } else { return ""; } }); InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => { return Chassis.Inputs[tempX].EndpointOnlineFeedback; }); InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => { var inputCard = Chassis.Inputs[tempX]; if (inputCard.Card is DmHdmi4kInputBladeCard) { InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; if ((inputCard.Card as DmHdmi4kInputBladeCard).Hdmi4kInput.HdcpSupportOnFeedback.BoolValue) return 1; else return 0; } if (inputCard.Card is DmC4kInputBladeCard) { InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; if ((inputCard.Card as DmC4kInputBladeCard).DmInput.HdcpCapabilityFeedback.Equals(eHdcpCapabilityType.HdcpSupportOff)) return 0; else return 1; } else return 0; }); } } } /// /// /// /// /// public void AddInputBlade(string type, uint number) { Debug.Console(2, this, "Adding input blade '{0}', slot {1}", type, number); type = type.ToLower(); if (type == "dmb4kihd") { var inputBlade = new Dmb4kIHd(number, this.Chassis); foreach (var item in inputBlade.Inputs) { var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput; var cecPort = card as ICec; AddHdmiInBladePorts(item.Number, cecPort); } } else if (type == "dmb4kihddnt") { var inputBlade = new Dmb4kIHd(number, this.Chassis); foreach (var item in inputBlade.Inputs) { var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput; var cecPort = card as ICec; AddHdmiInBladePorts(item.Number, cecPort); } } else if (type == "dmb4kic") { var inputBlade = new Dmb4kIC(number, this.Chassis); foreach (var item in inputBlade.Inputs) { AddDmInBladePorts(item.Number); } } else if (type == "dmbis") { var inputBlade = new DmbIS(number, this.Chassis); foreach (var item in inputBlade.Inputs) { AddDmInMmFiberPorts(item.Number); } } else if (type == "dmbis2") { var inputBlade = new DmbIS2(number, this.Chassis); foreach (var item in inputBlade.Inputs) { AddDmInSmFiberPorts(item.Number); } } } /// /// Raise an event when the status of a switch object changes. /// /// Arguments defined as IKeyName sender, output, input, and eRoutingSignalType private void OnSwitchChange(RoutingNumericEventArgs e) { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); } void AddHdmiInBladePorts(uint number, ICec cecPort) { AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort); } void AddDmInBladePorts(uint number) { AddInputPortWithDebug(number, "dmCIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat); } void AddDmInMmFiberPorts(uint number) { AddInputPortWithDebug(number, "dmMmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); } void AddDmInSmFiberPorts(uint number) { AddInputPortWithDebug(number, "dmSmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); } /// /// /// /// /// public void AddOutputBlade(string type, uint number) { type = type.ToLower(); Debug.Console(2, this, "Adding output blade '{0}', slot {1}", type, number); if (type == "dmb4kohd") { var outputBlade = new Dmb4KOHD(number, Chassis); foreach (var item in outputBlade.Outputs) { AddHdmiOutBladePorts(item.Number); } } else if (type == "dmb4kohddnt") { var outputBlade = new Dmb4KOHD(number, Chassis); foreach (var item in outputBlade.Outputs) { AddHdmiOutBladePorts(item.Number); } } else if (type == "dmb4koc") { var outputBlade = new Dmb4KOC(number, Chassis); foreach (var item in outputBlade.Outputs) { AddDmOutBladePorts(item.Number); } } else if (type == "dmb4koc") { var outputBlade = new Dmb4KOC(number, Chassis); foreach (var item in outputBlade.Outputs) { AddDmOutBladePorts(item.Number); } } else if (type == "dmbos") { var outputBlade = new DmbOS(number, Chassis); foreach (var item in outputBlade.Outputs) { AddDmOutMmFiberBladePorts(item.Number); } } else if (type == "dmbos2") { var outputBlade = new DmbOS2(number, Chassis); foreach (var item in outputBlade.Outputs) { AddDmOutSmFiberBladePorts(item.Number); } } } void AddHdmiOutBladePorts(uint number) { AddOutputPortWithDebug(number, "hdmiOut", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]); } void AddDmOutBladePorts(uint number) { AddOutputPortWithDebug(number, "dmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]); } void AddDmOutMmFiberBladePorts(uint number) { AddOutputPortWithDebug(number, "dmMmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]); } void AddDmOutSmFiberBladePorts(uint number) { AddOutputPortWithDebug(number, "dmSmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]); } /// /// Adds InputPort /// void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) { AddInputPortWithDebug(cardNum, portName, sigType, portType, null); } /// /// Adds InputPort and sets Port as ICec object /// private void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) { var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); Debug.Console(2, this, "Adding input port '{0}'", portKey); var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this) { FeedbackMatchObject = Chassis.Inputs[cardNum] }; if (cecPort != null) inputPort.Port = cecPort; InputPorts.Add(inputPort); } /*void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) { var portKey = string.Format("{0}--{1}", cardName, portName); Debug.Console(2, this, "Adding output port '{0}'", portKey); OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this) { FeedbackMatchObject = selector }); }*/ /// /// Adds OutputPort /// void AddOutputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) { try { var portKey = string.Format("outputCard{0}--{1}", cardNum, portName); Debug.Console(2, this, "Adding output port '{0}'", portKey); var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this) { FeedbackMatchObject = Chassis.Outputs[cardNum] }; OutputPorts.Add(outputPort); } catch (Exception ex) { Debug.Console(0, this, "Exception : {0}", ex); } } /// /// /// void AddVolumeControl(uint number, Audio.Output audio) { VolumeControls.Add(number, new DmCardAudioOutputController(audio)); } //public void SetInputHdcpSupport(uint input, ePdtHdcpSupport hdcpSetting) //{ //} void Chassis_DMInputChange(Switch device, DMInputEventArgs args) { switch (args.EventId) { case DMInputEventIds.EndpointOnlineEventId: { Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); break; } case DMInputEventIds.OnlineFeedbackEventId: { Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); break; } case DMInputEventIds.VideoDetectedEventId: { Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); VideoInputSyncFeedbacks[args.Number].FireUpdate(); break; } case DMInputEventIds.InputNameEventId: { Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); InputNameFeedbacks[args.Number].FireUpdate(); break; } case DMInputEventIds.HdcpCapabilityFeedbackEventId: { Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number); InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate(); break; } default: { Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId); break; } } } /// /// private void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) { var output = args.Number; switch (args.EventId) { case DMOutputEventIds.VolumeEventId: { if (VolumeControls.ContainsKey(output)) { VolumeControls[args.Number].VolumeEventFromChassis(); } break; } case DMOutputEventIds.EndpointOnlineEventId: { Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}", args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); if (Chassis.Outputs[output].Endpoint != null) Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}", args.Number, Chassis.Outputs[output].Endpoint.IsOnline); OutputEndpointOnlineFeedbacks[output].FireUpdate(); break; } case DMOutputEventIds.OnlineFeedbackEventId: { Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); OutputEndpointOnlineFeedbacks[output].FireUpdate(); break; } case DMOutputEventIds.VideoOutEventId: { var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number; Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name, inputNumber, output); if (VideoOutputFeedbacks.ContainsKey(output)) { var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback); var localOutputPort = OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == Chassis.Outputs[output]); VideoOutputFeedbacks[output].FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo)); } if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) { OutputVideoRouteNameFeedbacks[output].FireUpdate(); } break; } case DMOutputEventIds.OutputNameEventId: { Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); OutputNameFeedbacks[output].FireUpdate(); break; } default: { Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId); break; } } } /// /// /// /// void StartOffTimer(PortNumberType pnt) { if (RouteOffTimers.ContainsKey(pnt)) return; RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime); } // Send out sigs when coming online void IsOnline_OutputChange(object sender, EventArgs e) { if (IsOnline.BoolValue) { Chassis.EnableUSBBreakaway.BoolValue = true; if (InputNames != null) foreach (var kvp in InputNames) Chassis.Inputs[kvp.Key].Name.StringValue = kvp.Value; if (OutputNames != null) foreach (var kvp in OutputNames) Chassis.Outputs[kvp.Key].Name.StringValue = kvp.Value; } } #region IRouting Members public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) { Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); var input = inputSelector as DMInput; // Cast can sometimes fail var output = outputSelector as DMOutput; if (output == null) { Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector, outputSelector); return; } // Check to see if there's an off timer waiting on this and if so, cancel var key = new PortNumberType(output, sigType); if (input == null) { StartOffTimer(key); } else { if (RouteOffTimers.ContainsKey(key)) { Debug.Console(2, this, "{0} cancelling route off due to new source", output); RouteOffTimers[key].Stop(); RouteOffTimers.Remove(key); } } /*var inCard = input == 0 ? null : Chassis.Inputs[input]; var outCard = input == 0 ? null : Chassis.Outputs[output];*/ // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES if ((sigType & eRoutingSignalType.Video) != eRoutingSignalType.Video) return; Chassis.VideoEnter.BoolValue = true; output.VideoOut = input; } #endregion #region IRoutingNumeric Members public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) { var input = inputSelector == 0 ? null : Chassis.Inputs[inputSelector]; var output = Chassis.Outputs[outputSelector]; ExecuteSwitch(input, output, sigType); } #endregion public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { var joinMap = new DmBladeChassisControllerJoinMap(joinStart); var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); if (bridge != null) { bridge.AddJoinMap(Key, joinMap); } else { Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); } Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); // Link up outputs for (uint i = 1; i <= Chassis.NumberOfOutputs; i++) { var ioSlot = i; var ioSlotJoin = ioSlot - 1; // Control trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort)ioSlot, eRoutingSignalType.Video)); if (TxDictionary.ContainsKey(ioSlot)) { Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); var txKey = TxDictionary[ioSlot]; var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase; var advancedTxDevice = basicTxDevice as DmTxControllerBase; if (Chassis is DmMd128x128 || Chassis is DmMd64x64) { InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); } else { if (advancedTxDevice != null) { advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); } else if (InputEndpointOnlineFeedbacks[ioSlot] != null) { Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); } } if (basicTxDevice != null && advancedTxDevice == null) trilist.BooleanInput[joinMap.TxAdvancedIsPresent.JoinNumber + ioSlotJoin].BoolValue = true; if (advancedTxDevice != null) { advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); } else { Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; if (inputPort != null) { Debug.Console(1, "Port value for input card {0} is set", ioSlot); var port = inputPort.Port; if (port != null) { if (port is HdmiInputWithCEC) { Debug.Console(1, "Port is HdmiInputWithCec"); var hdmiInPortWCec = port as HdmiInputWithCEC; if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown) { SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); } InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; else trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; } } } else { inputPort = InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; if (inputPort != null) { var port = inputPort.Port; if (port is DMInputPortWithCec) { Debug.Console(1, "Port is DMInputPortWithCec"); var dmInPortWCec = port as DMInputPortWithCec; SetHdcpStateAction(PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = (ushort)InputCardHdcpCapabilityTypes[ioSlot]; else trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; } } } } } else { VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; if (inputPort != null) { var hdmiPort = inputPort.Port as EndpointHdmiInput; if (hdmiPort != null) { SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); } } } if (RxDictionary.ContainsKey(ioSlot)) { Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); //var rxKey = RxDictionary[ioSlot]; //var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; //var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; //if (hdBaseTDevice != null) { OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); //} //else if (rxDevice != null) { // rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); //} } // Feedback VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]); OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]); InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]); } } private void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist) { if (hdcpTypeSimple) { trilist.SetUShortSigAction(join, s => { if (s == 0) { port.HdcpSupportOff(); } else if (s > 0) { port.HdcpSupportOn(); } }); } else { trilist.SetUShortSigAction(join, u => { port.HdcpReceiveCapability = (eHdcpCapabilityType)u; }); } } private void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) { if (hdcpTypeSimple) { trilist.SetUShortSigAction(join, s => { if (s == 0) { port.HdcpSupportOff(); } else if (s > 0) { port.HdcpSupportOn(); } }); } else { trilist.SetUShortSigAction(join, u => { port.HdcpCapability = (eHdcpCapabilityType)u; }); } } private void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) { if (!supportsHdcp2) { trilist.SetUShortSigAction(join, s => { if (s == 0) { port.HdcpSupportOff(); } else if (s > 0) { port.HdcpSupportOn(); } }); } else { trilist.SetUShortSigAction(join, u => { port.HdcpReceiveCapability = (eHdcpCapabilityType)u; }); } } } /* public struct PortNumberType { public uint Number { get; private set; } public eRoutingSignalType Type { get; private set; } public PortNumberType(uint number, eRoutingSignalType type) : this() { Number = number; Type = type; } }*/ }