diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs
index 50813700..8054a077 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs
@@ -760,6 +760,46 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
+ [JoinName("DialPhoneCall")]
+ public JoinDataComplete DialPhone =
+ new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 },
+ new JoinMetadata
+ {
+ Description = "Dial Phone",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("PhoneHookState")]
+ public JoinDataComplete PhoneHookState =
+ new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 },
+ new JoinMetadata
+ {
+ Description = "Dial Phone",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("EndPhoneCall")]
+ public JoinDataComplete HangUpPhone =
+ new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 },
+ new JoinMetadata
+ {
+ Description = "Hang Up PHone",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("PhoneString")]
+ public JoinDataComplete PhoneDialString =
+ new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
+ new JoinMetadata
+ {
+ Description = "Phone Dial String",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Serial
+ });
+
public VideoCodecControllerJoinMap(uint joinStart) : base(joinStart, typeof (VideoCodecControllerJoinMap))
{
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs
new file mode 100644
index 00000000..2b7af8ad
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs
@@ -0,0 +1,14 @@
+using PepperDash.Essentials.Core;
+
+namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
+{
+ public interface IHasPhoneDialing
+ {
+ BoolFeedback PhoneOffHookFeedback { get; }
+ StringFeedback CallerIdNameFeedback { get; }
+ StringFeedback CallerIdNumberFeedback { get; }
+ void DialPhoneCall(string number);
+ void EndPhoneCall();
+ void SendDtmfToPhone(string digit);
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
index 7524c8d7..9cc4365f 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
@@ -197,6 +197,7 @@
+
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 b0f6395d..8b7b3bce 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
@@ -19,6 +19,7 @@ using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
using PepperDash_Essentials_Core.Bridges.JoinMaps;
+using PepperDash_Essentials_Core.DeviceTypeInterfaces;
using Feedback = PepperDash.Essentials.Core.Feedback;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
@@ -348,6 +349,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
(codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]);
}
+ if (codec is IHasPhoneDialing)
+ {
+ LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap);
+ }
+
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine) return;
@@ -389,6 +395,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
(codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate();
}
+ if (codec is IHasPhoneDialing)
+ {
+ (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate();
+ }
+
SharingContentIsOnFeedback.FireUpdate();
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
@@ -397,6 +408,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
};
}
+ private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
+ {
+ codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber,
+ () => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue));
+
+ trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall);
+ }
+
private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
{
trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle);
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
index 5f316523..45c4193c 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
@@ -58,6 +58,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public List AudioInputs { get; set; }
public List AudioOuputs { get; set; }
public List Cameras { get; set; }
+ public zEvent.PhoneCallStatus PhoneCall { get; set; }
public ZoomRoomStatus()
{
@@ -74,6 +75,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
AudioInputs = new List();
AudioOuputs = new List();
Cameras = new List();
+ PhoneCall = new zEvent.PhoneCallStatus();
}
}
@@ -700,6 +702,84 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
[JsonProperty("why_cannot_pin_share")]
public string WhyCannotPinShare { get; set; }
}
+
+ public class PhoneCallStatus:NotifiableObject
+ {
+ private bool _isIncomingCall;
+ private string _peerDisplayName;
+ private string _peerNumber;
+
+ private bool _offHook;
+
+ public string CallId { get; set; }
+ public bool IsIncomingCall {
+ get { return _isIncomingCall; }
+ set
+ {
+ if(value == _isIncomingCall) return;
+
+ _isIncomingCall = value;
+ NotifyPropertyChanged("IsIncomingCall");
+ } }
+
+ public string PeerDisplayName
+ {
+ get { return _peerDisplayName; }
+ set
+ {
+ if (value == _peerDisplayName) return;
+ _peerDisplayName = value;
+ NotifyPropertyChanged("PeerDisplayName");
+ }
+ }
+
+ public string PeerNumber
+ {
+ get { return _peerNumber; }
+ set
+ {
+ if (value == _peerNumber) return;
+
+ _peerNumber = value;
+ NotifyPropertyChanged("PeerNumber");
+ }
+ }
+
+ public string PeerUri { get; set; }
+
+ private ePhoneCallStatus _status;
+ public ePhoneCallStatus Status
+ {
+ get { return _status; }
+ set
+ {
+ _status = value;
+ OffHook = _status == ePhoneCallStatus.PhoneCallStatus_Accepted ||
+ _status == ePhoneCallStatus.PhoneCallStatus_InCall ||
+ _status == ePhoneCallStatus.PhoneCallStatus_Init;
+ }
+ }
+
+ public bool OffHook
+ {
+ get { return _offHook; }
+ set
+ {
+ if (value == _offHook) return;
+
+ _offHook = value;
+ NotifyPropertyChanged("OffHook");
+ }
+ }
+ }
+
+ public enum ePhoneCallStatus
+ {
+ PhoneCallStatus_Terminated,
+ PhoneCallStatus_Accepted,
+ PhoneCallStatus_InCall,
+ PhoneCallStatus_Init,
+ }
}
///
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
index 578e3dae..b8d29077 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
@@ -17,12 +17,14 @@ using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
+using PepperDash_Essentials_Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
IRouting,
- IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraAutoMode, IHasFarEndContentStatus, IHasSelfviewPosition
+ IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraAutoMode,
+ IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing
{
private const long MeetingRefreshTimer = 60000;
private const uint DefaultMeetingDurationMin = 30;
@@ -114,6 +116,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
SupportsCameraOff = _props.SupportsCameraOff;
SupportsCameraAutoMode = _props.SupportsCameraAutoMode;
+
+ PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
+ CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc);
+ CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc);
}
public CommunicationGather PortGather { get; private set; }
@@ -195,7 +201,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
protected Func CameraAutoModeIsOnFeedbackFunc
{
get { return () => false; }
- }
+ }
protected Func SelfviewPipPositionFeedbackFunc
{
@@ -506,6 +512,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
break;
}
};
+
+ Status.PhoneCall.PropertyChanged += (o, a) =>
+ {
+ switch (a.PropertyName)
+ {
+ case "IsIncomingCall":
+ Debug.Console(1, this, "Incoming Phone Call: {0}", Status.PhoneCall.IsIncomingCall);
+ break;
+ case "PeerDisplayName":
+ Debug.Console(1, this, "Peer Display Name: {0}", Status.PhoneCall.PeerDisplayName);
+ CallerIdNameFeedback.FireUpdate();
+ break;
+ case "PeerNumber":
+ Debug.Console(1, this, "Peer Number: {0}", Status.PhoneCall.PeerNumber);
+ CallerIdNumberFeedback.FireUpdate();
+ break;
+ case "OffHook":
+ Debug.Console(1, this, "Phone is OffHook: {0}", Status.PhoneCall.OffHook);
+ PhoneOffHookFeedback.FireUpdate();
+ break;
+ }
+ };
}
private void SetUpDirectory()
@@ -555,8 +583,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
if (!_props.DisablePhonebookAutoDownload)
{
CrestronConsole.AddNewConsoleCommand(s => SendText("zCommand Phonebook List Offset: 0 Limit: 512"),
- "GetZoomRoomContacts", "Triggers a refresh of the codec phonebook",
- ConsoleAccessLevelEnum.AccessOperator);
+ "GetZoomRoomContacts", "Triggers a refresh of the codec phonebook",
+ ConsoleAccessLevelEnum.AccessOperator);
}
CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings",
@@ -1066,7 +1094,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
case "sharingstate":
{
JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Sharing);
-
+
SetLayout();
break;
@@ -1181,6 +1209,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
break;
}
+ case "phonecallstatus":
+ {
+ JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
+ break;
+ }
default:
{
break;
@@ -1294,8 +1327,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
private void SetLayout()
{
- if(!_props.AutoDefaultLayouts) return;
-
+ if (!_props.AutoDefaultLayouts) return;
+
if (
(Status.Call.Sharing.State == zEvent.eSharingState.Receiving ||
Status.Call.Sharing.State == zEvent.eSharingState.Sending))
@@ -1354,7 +1387,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
if (ActiveCalls.Count == 0)
{
- if (callStatus == zStatus.eCallStatus.CONNECTING_MEETING || callStatus == zStatus.eCallStatus.IN_MEETING )
+ if (callStatus == zStatus.eCallStatus.CONNECTING_MEETING ||
+ callStatus == zStatus.eCallStatus.IN_MEETING)
{
var newStatus = eCodecCallStatus.Unknown;
@@ -1431,6 +1465,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
SetLayout();
}
}
+
public override void StartSharing()
{
SendText("zCommand Call Sharing HDMI Start");
@@ -1633,7 +1668,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public override void SendDtmf(string s)
{
- throw new NotImplementedException();
+ SendDtmfToPhone(s);
}
///
@@ -1713,6 +1748,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
#endregion
#region Implementation of IHasCameraAutoMode
+
//Zoom doesn't support camera auto modes. Setting this to just unmute video
public void CameraAutoModeOn()
{
@@ -1757,7 +1793,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
var nextPipPositionIndex = SelfviewPipPositions.IndexOf(_currentSelfviewPipPosition) + 1;
- if (nextPipPositionIndex >= SelfviewPipPositions.Count) // Check if we need to loop back to the first item in the list
+ if (nextPipPositionIndex >= SelfviewPipPositions.Count)
+ // Check if we need to loop back to the first item in the list
nextPipPositionIndex = 0;
SelfviewPipPositionSet(SelfviewPipPositions[nextPipPositionIndex]);
@@ -1772,12 +1809,40 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
new CodecCommandWithLabel("DownLeft", "Lower Left")
};
- void ComputeSelfviewPipStatus()
+ private void ComputeSelfviewPipStatus()
{
_currentSelfviewPipPosition =
SelfviewPipPositions.FirstOrDefault(
p => p.Command.ToLower().Equals(Configuration.Call.Layout.Position.ToString().ToLower()));
}
+
+ #endregion
+
+ #region Implementation of IHasPhoneDialing
+
+ private Func PhoneOffHookFeedbackFunc {get {return () => Status.PhoneCall.OffHook; }}
+ private Func CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } }
+ private Func CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } }
+
+ public BoolFeedback PhoneOffHookFeedback { get; private set; }
+ public StringFeedback CallerIdNameFeedback { get; private set; }
+ public StringFeedback CallerIdNumberFeedback { get; private set; }
+
+ public void DialPhoneCall(string number)
+ {
+ SendText(String.Format("zCommand Dial PhoneCallOut Number: {0}", number));
+ }
+
+ public void EndPhoneCall()
+ {
+ SendText(String.Format("zCommand Dial PhoneHangUp CallId: {0}", Status.PhoneCall.CallId));
+ }
+
+ public void SendDtmfToPhone(string digit)
+ {
+ SendText(String.Format("zCommand SendSipDTMF CallId: {0} Key: {1}", Status.PhoneCall.CallId, digit));
+ }
+
#endregion
}