diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs
index d8610047..a0729352 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs
@@ -342,6 +342,48 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
+ [JoinName("EndCallStart")]
+ public JoinDataComplete EndCallStart = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 81,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "End a specific call by call index. ",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("JoinAllCalls")]
+ public JoinDataComplete JoinAllCalls = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 90,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "End a specific call by call index. ",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("JoinCallStart")]
+ public JoinDataComplete JoinCallStart = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 91,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "End a specific call by call index. ",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
[JoinName("DirectorySearchBusy")]
public JoinDataComplete DirectorySearchBusy = new JoinDataComplete(
new JoinData
@@ -931,6 +973,34 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
+ [JoinName("HoldCallsStart")]
+ public JoinDataComplete HoldCallsStart = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 221,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "Holds Call at specified index",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("ResumeCallsStart")]
+ public JoinDataComplete ResumeCallsStart = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 231,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "Resume Call at specified index",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
[JoinName("ParticipantAudioMuteToggleStart")]
public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
new JoinData
@@ -989,24 +1059,11 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
- Description = "Sets the selected Call. Valid values 1-8",
+ Description = "Sets the selected Call for DTMF commands. Valid values 1-8",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Analog
});
- [JoinName("EndCall")]
- public JoinDataComplete EndCall = new JoinDataComplete(
- new JoinData
- {
- JoinNumber = 24,
- JoinSpan = 1
- },
- new JoinMetadata
- {
- Description = "End a specific call by call index. Valid values 1-8",
- JoinCapabilities = eJoinCapabilities.FromSIMPL,
- JoinType = eJoinType.Analog
- });
[JoinName("ConnectedCallCount")]
public JoinDataComplete ConnectedCallCount = new JoinDataComplete(
@@ -1045,11 +1102,25 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
},
new JoinMetadata
{
- Description = "Camera Number Select/FB",
+ Description = "Camera Number Select/FB. 1 based index. Valid range is 1 to the value reported by CameraCount.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Analog
});
+ [JoinName("CameraCount")]
+ public JoinDataComplete CameraCount = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 61,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "Reports the number of cameras",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Analog
+ });
+
[JoinName("DirectoryRowCount")]
public JoinDataComplete DirectoryRowCount = new JoinDataComplete(
new JoinData
@@ -1323,6 +1394,20 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Serial
});
+ [JoinName("CameraNamesFb")]
+ public JoinDataComplete CameraNamesFb = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 161,
+ JoinSpan = 10
+ },
+ new JoinMetadata
+ {
+ Description = "Camera Name Fb",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Serial
+ });
+
[JoinName("CurrentSource")]
public JoinDataComplete CurrentSource = new JoinDataComplete(
new JoinData
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCamera.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCamera.cs
index 6f68b369..67312df8 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCamera.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCamera.cs
@@ -116,7 +116,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
/// The ID of the camera on the codec
///
- protected uint CameraId { get; private set; }
+ public uint CameraId { get; private set; }
///
/// Valid range 1-15
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs
index e4945ce8..44256ca4 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs
@@ -9,6 +9,34 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
#region Digital
+ [JoinName("PresentationLocalOnly")]
+ public JoinDataComplete PresentationLocalOnly = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 205,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "Presentation Local Only Feedback",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("PresentationLocalRemote")]
+ public JoinDataComplete PresentationLocalRemote = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 206,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "Presentation Local Only Feedback",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
[JoinName("ActivateDoNotDisturbMode")]
public JoinDataComplete ActivateDoNotDisturbMode = new JoinDataComplete(
new JoinData
@@ -112,6 +140,34 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
#region Analog
+ [JoinName("RingtoneVolume")]
+ public JoinDataComplete RingtoneVolume = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 21,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "Ringtone volume set/FB. Valid values are 0 - 100 in increments of 5 (5, 10, 15, 20, etc.)",
+ JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
+ JoinType = eJoinType.Analog
+ });
+
+ [JoinName("PresentationSource")]
+ public JoinDataComplete PresentationSource = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 201,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "Presentation set/FB. Valid values are 0 - 6 depending on the codec model.",
+ JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
+ JoinType = eJoinType.Analog
+ });
+
#endregion
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs
index 7b44b47a..4c842f22 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs
@@ -42,11 +42,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public StatusMonitorBase CommunicationMonitor { get; private set; }
- private GenericQueue ReceiveQueue;
+ private GenericQueue _receiveQueue;
public BoolFeedback PresentationViewMaximizedFeedback { get; private set; }
- string CurrentPresentationView;
+ private string _currentPresentationView;
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
@@ -66,9 +66,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public IntFeedback RingtoneVolumeFeedback { get; private set; }
- private CodecCommandWithLabel CurrentSelfviewPipPosition;
+ private CodecCommandWithLabel _currentSelfviewPipPosition;
- private CodecCommandWithLabel CurrentLocalLayout;
+ private CodecCommandWithLabel _currentLocalLayout;
///
/// List the available positions for the selfview PIP window
@@ -167,7 +167,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
get
{
- return () => PresentationSourceKey;
+ return () => _presentationSourceKey;
}
}
@@ -231,7 +231,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
get
{
- return () => CurrentSelfviewPipPosition.Label;
+ return () => _currentSelfviewPipPosition.Label;
}
}
@@ -239,7 +239,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
get
{
- return () => CurrentLocalLayout.Label;
+ return () => _currentLocalLayout.Label;
}
}
@@ -247,43 +247,58 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
get
{
- return () => CurrentLocalLayout.Label == "Prominent";
+ return () => _currentLocalLayout.Label == "Prominent";
}
}
- private string CliFeedbackRegistrationExpression;
+ private string _cliFeedbackRegistrationExpression;
- private CodecSyncState SyncState;
+ private CodecSyncState _syncState;
public CodecPhonebookSyncState PhonebookSyncState { get; private set; }
- private StringBuilder JsonMessage;
+ private StringBuilder _jsonMessage;
- private bool JsonFeedbackMessageIsIncoming;
+ private bool _jsonFeedbackMessageIsIncoming;
public bool CommDebuggingIsOn;
string Delimiter = "\r\n";
+ public IntFeedback PresentationSourceFeedback { get; private set; }
+
+ public BoolFeedback PresentationSendingLocalOnlyFeedback { get; private set; }
+
+ public BoolFeedback PresentationSendingLocalRemoteFeedback { get; private set; }
+
///
/// Used to track the current connector used for the presentation source
///
- int PresentationSource;
+ private int _presentationSource;
- string PresentationSourceKey;
+ ///
+ /// Used to track the connector that is desired to be the current presentation source (until the command is send)
+ ///
+ private int _desiredPresentationSource;
- string PhonebookMode = "Local"; // Default to Local
+ private string _presentationSourceKey;
- uint PhonebookResultsLimit = 255; // Could be set later by config.
+ private bool _presentationLocalOnly;
- CTimer LoginMessageReceivedTimer;
- CTimer RetryConnectionTimer;
+ private bool _presentationLocalRemote;
+
+ private string _phonebookMode = "Local"; // Default to Local
+
+ private uint _phonebookResultsLimit = 255; // Could be set later by config.
+
+ private CTimer _loginMessageReceivedTimer;
+ private CTimer _retryConnectionTimer;
// **___________________________________________________________________**
// Timers to be moved to the global system timer at a later point....
- CTimer BookingsRefreshTimer;
- CTimer PhonebookRefreshTimer;
+ private CTimer BookingsRefreshTimer;
+ private CTimer PhonebookRefreshTimer;
// **___________________________________________________________________**
public RoutingInputPort CodecOsdIn { get; private set; }
@@ -302,11 +317,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
// Use the configured phonebook results limit if present
if (props.PhonebookResultsLimit > 0)
{
- PhonebookResultsLimit = props.PhonebookResultsLimit;
+ _phonebookResultsLimit = props.PhonebookResultsLimit;
}
// The queue that will collect the repsonses in the order they are received
- ReceiveQueue = new GenericQueue(this.Key + "-rxQueue", 25);
+ _receiveQueue = new GenericQueue(this.Key + "-rxQueue", 25);
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
PeopleCountFeedback = new IntFeedback(PeopleCountFeedbackFunc);
@@ -324,10 +339,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
HalfWakeModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Standby.State.Value.ToLower() == "halfwake");
EnteringStandbyModeFeedback = new BoolFeedback(() => CodecStatus.Status.Standby.State.Value.ToLower() == "enteringstandby");
- PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized");
+ PresentationViewMaximizedFeedback = new BoolFeedback(() => _currentPresentationView == "Maximized");
RingtoneVolumeFeedback = new IntFeedback(() => CodecConfiguration.Configuration.Audio.SoundsAndAlerts.RingVolume.Volume);
+ PresentationSourceFeedback = new IntFeedback(() => _presentationSource);
+ PresentationSendingLocalOnlyFeedback = new BoolFeedback(() => _presentationLocalOnly);
+ PresentationSendingLocalRemoteFeedback = new BoolFeedback(() => _presentationLocalRemote);
+
Communication = comm;
if (props.CommunicationMonitorProperties != null)
@@ -346,13 +365,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
DeviceManager.AddDevice(CommunicationMonitor);
- PhonebookMode = props.PhonebookMode;
+ _phonebookMode = props.PhonebookMode;
- SyncState = new CodecSyncState(Key + "--Sync");
+ _syncState = new CodecSyncState(Key + "--Sync");
PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync");
- SyncState.InitialSyncCompleted += new EventHandler(SyncState_InitialSyncCompleted);
+ _syncState.InitialSyncCompleted += new EventHandler(SyncState_InitialSyncCompleted);
PortGather = new CommunicationGather(Communication, Delimiter);
PortGather.IncludeDelimiter = true;
@@ -399,7 +418,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
InputPorts.Add(HdmiIn3);
OutputPorts.Add(HdmiOut1);
- SetUpCameras();
+ SetUpCameras(props.CameraInfo);
CreateOsdSource();
@@ -589,7 +608,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
const string prefix = "xFeedback register ";
- CliFeedbackRegistrationExpression =
+ _cliFeedbackRegistrationExpression =
prefix + "/Configuration" + Delimiter +
prefix + "/Status/Audio" + Delimiter +
prefix + "/Status/Call" + Delimiter +
@@ -651,12 +670,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Debug.Console(1, this, "Socket status change {0}", e.Client.ClientStatus);
if (e.Client.IsConnected)
{
- if(!SyncState.LoginMessageWasReceived)
- LoginMessageReceivedTimer = new CTimer(o => DisconnectClientAndReconnect(), 5000);
+ if(!_syncState.LoginMessageWasReceived)
+ _loginMessageReceivedTimer = new CTimer(o => DisconnectClientAndReconnect(), 5000);
}
else
{
- SyncState.CodecDisconnected();
+ _syncState.CodecDisconnected();
PhonebookSyncState.CodecDisconnected();
if (PhonebookRefreshTimer != null)
@@ -679,7 +698,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Communication.Disconnect();
- RetryConnectionTimer = new CTimer(o => Communication.Connect(), 2000);
+ _retryConnectionTimer = new CTimer(o => Communication.Connect(), 2000);
//CrestronEnvironment.Sleep(2000);
@@ -696,66 +715,66 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
if (CommDebuggingIsOn)
{
- if (!JsonFeedbackMessageIsIncoming)
+ 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;
+ _jsonFeedbackMessageIsIncoming = true;
if (CommDebuggingIsOn)
Debug.Console(1, this, "Incoming JSON message...");
- JsonMessage = new StringBuilder();
+ _jsonMessage = new StringBuilder();
}
else if (args.Text == "}" + Delimiter) // Check for the end of a JSON message
{
- JsonFeedbackMessageIsIncoming = false;
+ _jsonFeedbackMessageIsIncoming = false;
- JsonMessage.Append(args.Text);
+ _jsonMessage.Append(args.Text);
if (CommDebuggingIsOn)
- Debug.Console(1, this, "Complete JSON Received:\n{0}", JsonMessage.ToString());
+ Debug.Console(1, this, "Complete JSON Received:\n{0}", _jsonMessage.ToString());
// Enqueue the complete message to be deserialized
- ReceiveQueue.Enqueue(new ProcessStringMessage(JsonMessage.ToString(), DeserializeResponse));
+ _receiveQueue.Enqueue(new ProcessStringMessage(_jsonMessage.ToString(), DeserializeResponse));
return;
}
- if(JsonFeedbackMessageIsIncoming)
+ if(_jsonFeedbackMessageIsIncoming)
{
- JsonMessage.Append(args.Text);
+ _jsonMessage.Append(args.Text);
//Debug.Console(1, this, "Building JSON:\n{0}", JsonMessage.ToString());
return;
}
- if (!SyncState.InitialSyncComplete)
+ if (!_syncState.InitialSyncComplete)
{
switch (args.Text.Trim().ToLower()) // remove the whitespace
{
case "*r login successful":
{
- SyncState.LoginMessageReceived();
+ _syncState.LoginMessageReceived();
- if(LoginMessageReceivedTimer != null)
- LoginMessageReceivedTimer.Stop();
+ if(_loginMessageReceivedTimer != null)
+ _loginMessageReceivedTimer.Stop();
SendText("xPreferences outputmode json");
break;
}
case "xpreferences outputmode json":
{
- if (!SyncState.InitialStatusMessageWasReceived)
+ if (!_syncState.InitialStatusMessageWasReceived)
SendText("xStatus");
break;
}
case "xfeedback register /event/calldisconnect":
{
- SyncState.FeedbackRegistered();
+ _syncState.FeedbackRegistered();
break;
}
}
@@ -801,11 +820,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
if (conference.Presentation.LocalInstance.Count > 0)
{
if (!string.IsNullOrEmpty(conference.Presentation.LocalInstance[0].ghost))
- PresentationSource = 0;
+ _presentationSource = 0;
else if (conference.Presentation.LocalInstance[0].Source != null)
{
- PresentationSource = conference.Presentation.LocalInstance[0].Source.IntValue;
+ _presentationSource = conference.Presentation.LocalInstance[0].Source.IntValue;
}
+
+ _presentationLocalOnly = conference.Presentation.LocalInstance.Any((i) => i.SendingMode.LocalOnly);
+ _presentationLocalRemote = conference.Presentation.LocalInstance.Any((i) => i.SendingMode.LocalRemote);
+
+ PresentationSourceFeedback.FireUpdate();
+ PresentationSendingLocalOnlyFeedback.FireUpdate();
+ PresentationSendingLocalRemoteFeedback.FireUpdate();
}
// Check to see if this is a call status message received after the initial status message
@@ -966,11 +992,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
JsonConvert.PopulateObject(response, CodecStatus);
}
- if (!SyncState.InitialStatusMessageWasReceived)
+ if (!_syncState.InitialStatusMessageWasReceived)
{
- SyncState.InitialStatusMessageReceived();
+ _syncState.InitialStatusMessageReceived();
- if (!SyncState.InitialConfigurationMessageWasReceived)
+ if (!_syncState.InitialConfigurationMessageWasReceived)
SendText("xConfiguration");
}
}
@@ -980,12 +1006,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
JsonConvert.PopulateObject(response, CodecConfiguration);
- if (!SyncState.InitialConfigurationMessageWasReceived)
+ if (!_syncState.InitialConfigurationMessageWasReceived)
{
- SyncState.InitialConfigurationMessageReceived();
- if (!SyncState.FeedbackWasRegistered)
+ _syncState.InitialConfigurationMessageReceived();
+ if (!_syncState.FeedbackWasRegistered)
{
- SendText(CliFeedbackRegistrationExpression);
+ SendText(_cliFeedbackRegistrationExpression);
}
}
@@ -1158,7 +1184,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public override void ExecuteSwitch(object selector)
{
(selector as Action)();
- PresentationSourceKey = selector.ToString();
+ _presentationSourceKey = selector.ToString();
}
///
@@ -1168,7 +1194,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
ExecuteSwitch(inputSelector);
- PresentationSourceKey = inputSelector.ToString();
+ _presentationSourceKey = inputSelector.ToString();
}
@@ -1247,13 +1273,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
private void GetPhonebookFolders()
{
// Get Phonebook Folders (determine local/corporate from config, and set results limit)
- SendText(string.Format("xCommand Phonebook Search PhonebookType: {0} ContactType: Folder", PhonebookMode));
+ SendText(string.Format("xCommand Phonebook Search PhonebookType: {0} ContactType: Folder", _phonebookMode));
}
private void GetPhonebookContacts()
{
// Get Phonebook Folders (determine local/corporate from config, and set results limit)
- SendText(string.Format("xCommand Phonebook Search PhonebookType: {0} ContactType: Contact Limit: {1}", PhonebookMode, PhonebookResultsLimit));
+ SendText(string.Format("xCommand Phonebook Search PhonebookType: {0} ContactType: Contact Limit: {1}", _phonebookMode, _phonebookResultsLimit));
}
///
@@ -1262,7 +1288,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
public void SearchDirectory(string searchString)
{
- SendText(string.Format("xCommand Phonebook Search SearchString: \"{0}\" PhonebookType: {1} ContactType: Contact Limit: {2}", searchString, PhonebookMode, PhonebookResultsLimit));
+ SendText(string.Format("xCommand Phonebook Search SearchString: \"{0}\" PhonebookType: {1} ContactType: Contact Limit: {2}", searchString, _phonebookMode, _phonebookResultsLimit));
}
///
@@ -1271,7 +1297,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
public void GetDirectoryFolderContents(string folderId)
{
- SendText(string.Format("xCommand Phonebook Search FolderId: {0} PhonebookType: {1} ContactType: Any Limit: {2}", folderId, PhonebookMode, PhonebookResultsLimit));
+ SendText(string.Format("xCommand Phonebook Search FolderId: {0} PhonebookType: {1} ContactType: Any Limit: {2}", folderId, _phonebookMode, _phonebookResultsLimit));
}
///
@@ -1449,14 +1475,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
///
///
- public void SendDtmf(string s, CodecActiveCallItem activeCall)
+ public override void SendDtmf(string s, CodecActiveCallItem activeCall)
{
SendText(string.Format("xCommand Call DTMFSend CallId: {0} DTMFString: \"{1}\"", activeCall.Id, s));
}
public void SelectPresentationSource(int source)
{
- PresentationSource = source;
+ _desiredPresentationSource = source;
StartSharing();
}
@@ -1467,6 +1493,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
/// level from 0 - 100 in increments of 5
public void SetRingtoneVolume(int volume)
{
+ if (volume < 0 || volume > 100)
+ {
+ Debug.Console(0, this, "Cannot set ringtone volume to '{0}'. Value must be between 0 - 100", volume);
+ return;
+ }
+
+ if (volume % 5 != 0)
+ {
+ Debug.Console(0, this, "Cannot set ringtone volume to '{0}'. Value must be between 0 - 100 and a multiple of 5", volume);
+ return;
+ }
+
SendText(string.Format("xConfiguration Audio SoundsAndAlerts RingVolume: [0]", volume));
}
@@ -1500,8 +1538,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
else
sendingMode = "LocalOnly";
- if(PresentationSource > 0)
- SendText(string.Format("xCommand Presentation Start PresentationSource: {0} SendingMode: {1}", PresentationSource, sendingMode));
+ if (_desiredPresentationSource > 0)
+ SendText(string.Format("xCommand Presentation Start PresentationSource: {0} SendingMode: {1}", _desiredPresentationSource, sendingMode));
}
///
@@ -1509,7 +1547,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
public override void StopSharing()
{
- PresentationSource = 0;
+ _desiredPresentationSource = 0;
SendText("xCommand Presentation Stop");
}
@@ -1645,7 +1683,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
trilist.SetSigFalseAction(joinMap.ActivateHalfWakeMode.JoinNumber, () => halfwakeCodec.HalfwakeActivate());
}
- // TODO: Add mechanism to select a call instance to be able to direct DTMF tones to...
+ // Ringtone volume
+ trilist.SetUShortSigAction(joinMap.RingtoneVolume.JoinNumber, (u) => SetRingtoneVolume(u));
+ RingtoneVolumeFeedback.LinkInputSig(trilist.UShortInput[joinMap.RingtoneVolume.JoinNumber]);
+
+ // Presentation Source
+ trilist.SetUShortSigAction(joinMap.PresentationSource.JoinNumber, (u) => SelectPresentationSource(u));
+ PresentationSourceFeedback.LinkInputSig(trilist.UShortInput[joinMap.PresentationSource.JoinNumber]);
+
+ PresentationSendingLocalOnlyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PresentationLocalOnly.JoinNumber]);
+ PresentationSendingLocalRemoteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PresentationLocalRemote.JoinNumber]);
}
///
@@ -1719,9 +1766,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
public void SelfviewPipPositionToggle()
{
- if (CurrentSelfviewPipPosition != null)
+ if (_currentSelfviewPipPosition != null)
{
- var nextPipPositionIndex = SelfviewPipPositions.IndexOf(CurrentSelfviewPipPosition) + 1;
+ var nextPipPositionIndex = SelfviewPipPositions.IndexOf(_currentSelfviewPipPosition) + 1;
if (nextPipPositionIndex >= SelfviewPipPositions.Count) // Check if we need to loop back to the first item in the list
nextPipPositionIndex = 0;
@@ -1744,9 +1791,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
public void LocalLayoutToggle()
{
- if(CurrentLocalLayout != null)
+ if(_currentLocalLayout != null)
{
- var nextLocalLayoutIndex = LocalLayouts.IndexOf(CurrentLocalLayout) + 1;
+ var nextLocalLayoutIndex = LocalLayouts.IndexOf(_currentLocalLayout) + 1;
if (nextLocalLayoutIndex >= LocalLayouts.Count) // Check if we need to loop back to the first item in the list
nextLocalLayoutIndex = 0;
@@ -1760,9 +1807,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
public void LocalLayoutToggleSingleProminent()
{
- if (CurrentLocalLayout != null)
+ if (_currentLocalLayout != null)
{
- if (CurrentLocalLayout.Label != "Prominent")
+ if (_currentLocalLayout.Label != "Prominent")
LocalLayoutSet(LocalLayouts.FirstOrDefault(l => l.Label.Equals("Prominent")));
else
LocalLayoutSet(LocalLayouts.FirstOrDefault(l => l.Label.Equals("Single")));
@@ -1776,11 +1823,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public void MinMaxLayoutToggle()
{
if (PresentationViewMaximizedFeedback.BoolValue)
- CurrentPresentationView = "Minimized";
+ _currentPresentationView = "Minimized";
else
- CurrentPresentationView = "Maximized";
+ _currentPresentationView = "Maximized";
- SendText(string.Format("xCommand Video PresentationView Set View: {0}", CurrentPresentationView));
+ SendText(string.Format("xCommand Video PresentationView Set View: {0}", _currentPresentationView));
PresentationViewMaximizedFeedback.FireUpdate();
}
@@ -1789,9 +1836,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
void ComputeSelfviewPipStatus()
{
- CurrentSelfviewPipPosition = SelfviewPipPositions.FirstOrDefault(p => p.Command.ToLower().Equals(CodecStatus.Status.Video.Selfview.PIPPosition.Value.ToLower()));
+ _currentSelfviewPipPosition = SelfviewPipPositions.FirstOrDefault(p => p.Command.ToLower().Equals(CodecStatus.Status.Video.Selfview.PIPPosition.Value.ToLower()));
- if(CurrentSelfviewPipPosition != null)
+ if(_currentSelfviewPipPosition != null)
SelfviewIsOnFeedback.FireUpdate();
}
@@ -1800,9 +1847,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
void ComputeLocalLayout()
{
- CurrentLocalLayout = LocalLayouts.FirstOrDefault(l => l.Command.ToLower().Equals(CodecStatus.Status.Video.Layout.LayoutFamily.Local.Value.ToLower()));
+ _currentLocalLayout = LocalLayouts.FirstOrDefault(l => l.Command.ToLower().Equals(CodecStatus.Status.Video.Layout.LayoutFamily.Local.Value.ToLower()));
- if (CurrentLocalLayout != null)
+ if (_currentLocalLayout != null)
LocalLayoutFeedback.FireUpdate();
}
@@ -1850,19 +1897,59 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
///
/// Builds the cameras List. Could later be modified to build from config data
///
- void SetUpCameras()
+ void SetUpCameras(List cameraInfo)
{
// Add the internal camera
Cameras = new List();
- var internalCamera = new CiscoSparkCamera(Key + "-camera1", "Near End", this, 1);
+ var camCount = CodecStatus.Status.Cameras.Camera.Count;
- if(CodecStatus.Status.Cameras.Camera.Count > 0)
- internalCamera.SetCapabilites(CodecStatus.Status.Cameras.Camera[0].Capabilities.Options.Value);
+ Debug.Console(0, this, "Codec reports {0} cameras", camCount);
+
+
+ // Deal with the case of 1 or no reported cameras
+ if (camCount <= 1)
+ {
+ var internalCamera = new CiscoSparkCamera(Key + "-camera1", "Near End", this, 1);
+
+ if (CodecStatus.Status.Cameras.Camera[0] != null && CodecStatus.Status.Cameras.Camera[0].Capabilities != null)
+ {
+ internalCamera.SetCapabilites(CodecStatus.Status.Cameras.Camera[0].Capabilities.Options.Value);
+ }
+
+ Cameras.Add(internalCamera);
+ DeviceManager.AddDevice(internalCamera);
+ }
else
- // Somehow subscribe to the event on the Options.Value property and update when it changes.
+ {
+ // Setup all the cameras
+ for (int i = 0; i < camCount; i++)
+ {
+ var cam = CodecStatus.Status.Cameras.Camera[i];
- Cameras.Add(internalCamera);
+ var id = (uint)i;
+ var name = string.Format("Camera {0}", id);
+
+ // Check for a config object that matches the camera number
+ var camInfo = cameraInfo.FirstOrDefault(c => c.CameraNumber == i + 1);
+ if (camInfo != null)
+ {
+ id = (uint)camInfo.SourceId;
+ name = camInfo.Name;
+ }
+
+ var key = string.Format("{0}-camera{1}", Key, id);
+ var camera = new CiscoSparkCamera(key, name, this, id);
+
+ if (cam.Capabilities != null)
+ {
+ camera.SetCapabilites(cam.Capabilities.Options.Value);
+ }
+
+ Cameras.Add(camera);
+ DeviceManager.AddDevice(camera);
+ }
+ }
// Add the far end camera
var farEndCamera = new CiscoFarEndCamera(Key + "-cameraFar", "Far End", this);
@@ -1872,7 +1959,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
ControllingFarEndCameraFeedback = new BoolFeedback(() => SelectedCamera is IAmFarEndCamera);
- DeviceManager.AddDevice(internalCamera);
DeviceManager.AddDevice(farEndCamera);
NearEndPresets = new List(15);
@@ -1886,7 +1972,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
FarEndRoomPresets.Add(new CodecRoomPreset(i, label, true, false));
}
- SelectedCamera = internalCamera; ; // call the method to select the camera and ensure the feedbacks get updated.
+ SelectedCamera = Cameras[0]; ; // call the method to select the camera and ensure the feedbacks get updated.
}
#region IHasCodecCameras Members
@@ -1934,6 +2020,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
}
else
Debug.Console(2, this, "Unable to select camera with key: '{0}'", key);
+
+ var ciscoCam = camera as CiscoSparkCamera;
+ if (ciscoCam != null)
+ {
+ SendText(string.Format("xCommand Video Input SetMainVideoSource SourceId: {0}", ciscoCam.CameraId));
+ }
}
public CameraBase FarEndCamera { get; private set; }
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodecPropertiesConfig.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodecPropertiesConfig.cs
index 1836bafb..7f36b0bf 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodecPropertiesConfig.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodecPropertiesConfig.cs
@@ -50,8 +50,16 @@ namespace PepperDash.Essentials.Devices.Common.Codec
public uint PhonebookResultsLimit { get; set; }
[JsonProperty("UiBranding")]
- public BrandingLogoProperties UiBranding { get; set; }
+ public BrandingLogoProperties UiBranding { get; set; }
+ [JsonProperty("cameraInfo")]
+ public List CameraInfo { get; set; }
+
+
+ public CiscoSparkCodecPropertiesConfig()
+ {
+ CameraInfo = new List();
+ }
}
public class SharingProperties
@@ -68,4 +76,14 @@ namespace PepperDash.Essentials.Devices.Common.Codec
[JsonProperty("brandingUrl")]
public string BrandingUrl { get; set; }
}
+
+ ///
+ /// Describes configuration information for the near end cameras
+ ///
+ public class CameraInfo
+ {
+ public int CameraNumber { get; set; }
+ public string Name { get; set; }
+ public int SourceId { get; set; }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs
index ca98c1fc..6db3c2e3 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs
@@ -558,9 +558,41 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
}
}
- public class SendingMode
+ public class SendingMode : ValueProperty
{
- public string Value { get; set; }
+ string _Value;
+
+ ///
+ /// Sets Value and triggers the action when set
+ ///
+ public string Value
+ {
+ get
+ {
+ return _Value;
+ }
+ set
+ {
+ _Value = value;
+ OnValueChanged();
+ }
+ }
+
+ public bool LocalOnly
+ {
+ get
+ {
+ return _Value.ToLower() == "localonly";
+ }
+ }
+
+ public bool LocalRemote
+ {
+ get
+ {
+ return _Value.ToLower() == "localremote";
+ }
+ }
}
public class LocalInstance
@@ -573,6 +605,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public LocalInstance()
{
Source = new Source2();
+ SendingMode = new SendingMode();
}
}
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
index 5771d868..b87e47f6 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
@@ -982,18 +982,22 @@ ScreenIndexIsPinnedTo: {8} (a{17})
//End All calls
trilist.SetSigFalseAction(joinMap.EndAllCalls.JoinNumber, EndAllCalls);
- //End a specific call, specified by index
- trilist.SetUShortSigAction(joinMap.EndCall.JoinNumber, (i) =>
- {
- if (i > 0 && i <= 8)
+ //End a specific call, specified by index. Maximum 8 calls supported
+ for (int i = 0; i < joinMap.EndCallStart.JoinSpan; i++)
+ {
+ trilist.SetSigFalseAction((uint)(joinMap.EndCallStart.JoinNumber + i), () =>
{
- var call = ActiveCalls[i - 1];
+ var call = ActiveCalls[i];
if (call != null)
{
EndCall(call);
}
- }
- });
+ else
+ {
+ Debug.Console(0, this, "[End Call] Unable to find call at index '{0}'", i);
+ }
+ });
+ }
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
@@ -1015,6 +1019,61 @@ ScreenIndexIsPinnedTo: {8} (a{17})
trilist.SetUshort(joinMap.ConnectedCallCount.JoinNumber, (ushort)ActiveCalls.Count);
};
+
+ var joinCodec = this as IJoinCalls;
+ if (joinCodec != null)
+ {
+ trilist.SetSigFalseAction(joinMap.JoinAllCalls.JoinNumber, () => joinCodec.JoinAllCalls());
+
+ for (int i = 0; i < joinMap.JoinCallStart.JoinSpan; i++)
+ {
+ trilist.SetSigFalseAction((uint)(joinMap.JoinCallStart.JoinNumber + i), () =>
+ {
+ var call = ActiveCalls[i];
+ if (call != null)
+ {
+ joinCodec.JoinCall(call);
+ }
+ else
+ {
+ Debug.Console(0, this, "[Join Call] Unable to find call at index '{0}'", i);
+ }
+ });
+ }
+ }
+
+ var holdCodec = this as IHasCallHold;
+ if (holdCodec != null)
+ {
+ for (int i = 0; i < joinMap.JoinCallStart.JoinSpan; i++)
+ {
+ trilist.SetSigFalseAction((uint)(joinMap.HoldCallsStart.JoinNumber + i), () =>
+ {
+ var call = ActiveCalls[i];
+ if (call != null)
+ {
+ holdCodec.HoldCall(call);
+ }
+ else
+ {
+ Debug.Console(0, this, "[Hold Call] Unable to find call at index '{0}'", i);
+ }
+ });
+
+ trilist.SetSigFalseAction((uint)(joinMap.ResumeCallsStart.JoinNumber + i), () =>
+ {
+ var call = ActiveCalls[i];
+ if (call != null)
+ {
+ holdCodec.ResumeCall(call);
+ }
+ else
+ {
+ Debug.Console(0, this, "[Resume Call] Unable to find call at index '{0}'", i);
+ }
+ });
+ }
+ }
}
private string UpdateCallStatusXSig()
@@ -1296,18 +1355,47 @@ ScreenIndexIsPinnedTo: {8} (a{17})
camera.TriggerAutoFocus();
});
+ // Camera count
+ trilist.SetUshort(joinMap.CameraCount.JoinNumber, (ushort)codec.Cameras.Count);
+
+ // Camera names
+ for (uint i = 0; i < joinMap.CameraNamesFb.JoinSpan; i++)
+ {
+ if (codec.Cameras[(int)i] != null)
+ {
+ trilist.SetString(joinMap.CameraNamesFb.JoinNumber + i, codec.Cameras[(int)i].Name);
+ }
+ else
+ {
+ trilist.SetString(joinMap.CameraNamesFb.JoinNumber + i, "");
+ }
+ }
+
//Camera Select
trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) =>
{
- if (codec.SelectedCamera == null) return;
-
- codec.SelectCamera(codec.Cameras[i].Key);
+ if (i > 0 && i <= codec.Cameras.Count)
+ {
+ codec.SelectCamera(codec.Cameras[i - 1].Key);
+ }
+ else
+ {
+ Debug.Console(0, this, "Unable to select. No camera found at index {0}", i);
+ }
});
+ // Set initial selected camera feedback
+ if (codec.SelectedCamera != null)
+ {
+ trilist.SetUshort(joinMap.CameraNumberSelect.JoinNumber, (ushort)codec.Cameras.FindIndex((c) => c.Key == codec.SelectedCamera.Key));
+ }
+
codec.CameraSelected += (sender, args) =>
{
var i = (ushort)codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key);
+ trilist.SetUshort(joinMap.CameraNumberSelect.JoinNumber, (ushort)(i + 1));
+
if (codec is IHasCodecRoomPresets)
{
return;