Removes essentials-framework as a submodule and brings the files back into the main repo

This commit is contained in:
Neil Dorin
2019-07-09 17:21:53 -06:00
parent 2cd68d40dc
commit 48c6bb78bc
362 changed files with 54624 additions and 5 deletions

View File

@@ -0,0 +1,379 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class CiscoCodecBookings
{
public class TotalRows
{
public string Value { get; set; }
}
public class ResultInfo
{
public TotalRows TotalRows { get; set; }
}
public class LastUpdated
{
string _value;
public DateTime Value {
get
{
DateTime _valueDateTime;
try
{
_valueDateTime = DateTime.Parse(_value);
return _valueDateTime;
}
catch
{
return new DateTime();
}
}
set
{
_value = value.ToString();
}
}
}
public class Id
{
public string Value { get; set; }
}
public class Title
{
public string Value { get; set; }
}
public class Agenda
{
public string Value { get; set; }
}
public class Privacy
{
public string Value { get; set; }
}
public class FirstName
{
public string Value { get; set; }
}
public class LastName
{
public string Value { get; set; }
}
public class Email
{
public string Value { get; set; }
}
public class Id2
{
public string Value { get; set; }
}
public class Organizer
{
public FirstName FirstName { get; set; }
public LastName LastName { get; set; }
public Email Email { get; set; }
public Id2 Id { get; set; }
public Organizer()
{
FirstName = new FirstName();
LastName = new LastName();
Email = new Email();
}
}
public class StartTime
{
public DateTime Value { get; set; }
}
public class StartTimeBuffer
{
public string Value { get; set; }
}
public class EndTime
{
public DateTime Value { get; set; }
}
public class EndTimeBuffer
{
public string Value { get; set; }
}
public class Time
{
public StartTime StartTime { get; set; }
public StartTimeBuffer StartTimeBuffer { get; set; }
public EndTime EndTime { get; set; }
public EndTimeBuffer EndTimeBuffer { get; set; }
public Time()
{
StartTime = new StartTime();
EndTime = new EndTime();
}
}
public class MaximumMeetingExtension
{
public string Value { get; set; }
}
public class MeetingExtensionAvailability
{
public string Value { get; set; }
}
public class BookingStatus
{
public string Value { get; set; }
}
public class BookingStatusMessage
{
public string Value { get; set; }
}
public class Enabled
{
public string Value { get; set; }
}
public class Url
{
public string Value { get; set; }
}
public class MeetingNumber
{
public string Value { get; set; }
}
public class Password
{
public string Value { get; set; }
}
public class HostKey
{
public string Value { get; set; }
}
public class DialInNumbers
{
}
public class Webex
{
public Enabled Enabled { get; set; }
public Url Url { get; set; }
public MeetingNumber MeetingNumber { get; set; }
public Password Password { get; set; }
public HostKey HostKey { get; set; }
public DialInNumbers DialInNumbers { get; set; }
}
public class Encryption
{
public string Value { get; set; }
}
public class Role
{
public string Value { get; set; }
}
public class Recording
{
public string Value { get; set; }
}
public class Number
{
public string Value { get; set; }
}
public class Protocol
{
public string Value { get; set; }
}
public class CallRate
{
public string Value { get; set; }
}
public class CallType
{
public string Value { get; set; }
}
public class Call
{
public string id { get; set; }
public Number Number { get; set; }
public Protocol Protocol { get; set; }
public CallRate CallRate { get; set; }
public CallType CallType { get; set; }
}
public class Calls
{
public List<Call> Call {get; set;}
}
public class ConnectMode
{
public string Value { get; set; }
}
public class DialInfo
{
public Calls Calls { get; set; }
public ConnectMode ConnectMode { get; set; }
public DialInfo()
{
Calls = new Calls();
ConnectMode = new ConnectMode();
}
}
public class Booking
{
public string id { get; set; }
public Id Id { get; set; }
public Title Title { get; set; }
public Agenda Agenda { get; set; }
public Privacy Privacy { get; set; }
public Organizer Organizer { get; set; }
public Time Time { get; set; }
public MaximumMeetingExtension MaximumMeetingExtension { get; set; }
public MeetingExtensionAvailability MeetingExtensionAvailability { get; set; }
public BookingStatus BookingStatus { get; set; }
public BookingStatusMessage BookingStatusMessage { get; set; }
public Webex Webex { get; set; }
public Encryption Encryption { get; set; }
public Role Role { get; set; }
public Recording Recording { get; set; }
public DialInfo DialInfo { get; set; }
public Booking()
{
Time = new Time();
Id = new Id();
Organizer = new Organizer();
Title = new Title();
Agenda = new Agenda();
Privacy = new Privacy();
DialInfo = new DialInfo();
}
}
public class BookingsListResult
{
public string status { get; set; }
public ResultInfo ResultInfo { get; set; }
//public LastUpdated LastUpdated { get; set; }
public List<Booking> Booking { get; set; }
}
public class CommandResponse
{
public BookingsListResult BookingsListResult { get; set; }
}
public class RootObject
{
public CommandResponse CommandResponse { get; set; }
}
/// <summary>
/// Extracts the necessary meeting values from the Cisco bookings response ans converts them to the generic class
/// </summary>
/// <param name="bookings"></param>
/// <returns></returns>
public static List<Meeting> GetGenericMeetingsFromBookingResult(List<Booking> bookings)
{
var meetings = new List<Meeting>();
if (Debug.Level > 0)
{
Debug.Console(1, "Meetings List:\n");
}
foreach(Booking b in bookings)
{
var meeting = new Meeting();
if(b.Id != null)
meeting.Id = b.Id.Value;
if(b.Organizer != null)
meeting.Organizer = string.Format("{0}, {1}", b.Organizer.LastName.Value, b.Organizer.FirstName.Value);
if(b.Title != null)
meeting.Title = b.Title.Value;
if(b.Agenda != null)
meeting.Agenda = b.Agenda.Value;
if(b.Time != null)
meeting.StartTime = b.Time.StartTime.Value;
meeting.EndTime = b.Time.EndTime.Value;
if(b.Privacy != null)
meeting.Privacy = CodecCallPrivacy.ConvertToDirectionEnum(b.Privacy.Value);
//#warning Update this ConnectMode conversion after testing onsite. Expected value is "OBTP", but in PD NYC Test scenarios, "Manual" is being returned for OBTP meetings
if (b.DialInfo.ConnectMode != null)
if (b.DialInfo.ConnectMode.Value.ToLower() == "obtp" || b.DialInfo.ConnectMode.Value.ToLower() == "manual")
meeting.IsOneButtonToPushMeeting = true;
if (b.DialInfo.Calls.Call != null)
{
foreach (Call c in b.DialInfo.Calls.Call)
{
meeting.Calls.Add(new PepperDash.Essentials.Devices.Common.Codec.Call()
{
Number = c.Number.Value,
Protocol = c.Protocol.Value,
CallRate = c.CallRate.Value,
CallType = c.CallType.Value
});
}
}
meetings.Add(meeting);
if(Debug.Level > 0)
{
Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}, Agenda: {3}", meeting.Title, meeting.Id, meeting.Organizer, meeting.Agenda);
Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration);
Debug.Console(1, " Joinable: {0}\n", meeting.Joinable);
}
}
meetings.OrderBy(m => m.StartTime);
return meetings;
}
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class CiscoCallHistory
{
public class CallbackNumber
{
public string Value { get; set; }
}
public class DisplayName
{
public string Value { get; set; }
}
public class LastOccurrenceStartTime
{
public DateTime Value { get; set; }
}
public class LastOccurrenceDaysAgo
{
public string Value { get; set; }
}
public class LastOccurrenceHistoryId
{
public string Value { get; set; }
}
public class OccurrenceType
{
public string Value { get; set; }
}
public class IsAcknowledged
{
public string Value { get; set; }
}
public class OccurrenceCount
{
public string Value { get; set; }
}
public class Entry
{
public string id { get; set; }
public CallbackNumber CallbackNumber { get; set; }
public DisplayName DisplayName { get; set; }
public LastOccurrenceStartTime LastOccurrenceStartTime { get; set; }
public LastOccurrenceDaysAgo LastOccurrenceDaysAgo { get; set; }
public LastOccurrenceHistoryId LastOccurrenceHistoryId { get; set; }
public OccurrenceType OccurrenceType { get; set; }
public IsAcknowledged IsAcknowledged { get; set; }
public OccurrenceCount OccurrenceCount { get; set; }
}
public class Offset
{
public string Value { get; set; }
}
public class Limit
{
public string Value { get; set; }
}
public class ResultInfo
{
public Offset Offset { get; set; }
public Limit Limit { get; set; }
}
public class CallHistoryRecentsResult
{
public string status { get; set; }
public List<Entry> Entry { get; set; }
public ResultInfo ResultInfo { get; set; }
}
public class CommandResponse
{
public CallHistoryRecentsResult CallHistoryRecentsResult { get; set; }
}
public class RootObject
{
public CommandResponse CommandResponse { get; set; }
}
}
}

View File

@@ -0,0 +1,312 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Devices.Common.Cameras;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
public class CiscoFarEndCamera : CameraBase, IHasCameraPtzControl, IAmFarEndCamera
{
protected CiscoSparkCodec ParentCodec { get; private set; }
protected string CallId {
get
{
return (ParentCodec as CiscoSparkCodec).GetCallId();
}
}
public CiscoFarEndCamera(string key, string name, CiscoSparkCodec codec)
: base(key, name)
{
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom;
ParentCodec = codec;
}
#region IHasCameraPtzControl Members
public void PositionHome()
{
// Not supported on far end camera
}
#endregion
#region IHasCameraPanControl Members
public void PanLeft()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: Left CallId: {0}", CallId));
}
public void PanRight()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: Right CallId: {0}", CallId));
}
public void PanStop()
{
Stop();
}
#endregion
#region IHasCameraTiltControl Members
public void TiltDown()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: Down CallId: {0}", CallId));
}
public void TiltUp()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: Up CallId: {0}", CallId));
}
public void TiltStop()
{
Stop();
}
#endregion
#region IHasCameraZoomControl Members
public void ZoomIn()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: ZoomIn CallId: {0}", CallId));
}
public void ZoomOut()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Move Value: ZoomOut CallId: {0}", CallId));
}
public void ZoomStop()
{
Stop();
}
#endregion
void Stop()
{
ParentCodec.SendText(string.Format("xCommand Call FarEndControl Camera Stop CallId: {0}", CallId));
}
}
public class CiscoSparkCamera : CameraBase, IHasCameraPtzControl, IHasCameraFocusControl
{
/// <summary>
/// The codec this camera belongs to
/// </summary>
protected CiscoSparkCodec ParentCodec { get; private set; }
/// <summary>
/// The ID of the camera on the codec
/// </summary>
protected uint CameraId { get; private set; }
/// <summary>
/// Valid range 1-15
/// </summary>
protected uint PanSpeed { get; private set; }
/// <summary>
/// Valid range 1-15
/// </summary>
protected uint TiltSpeed { get; private set; }
/// <summary>
/// Valid range 1-15
/// </summary>
protected uint ZoomSpeed { get; private set; }
private bool isPanning;
private bool isTilting;
private bool isZooming;
private bool isFocusing;
private bool isMoving
{
get
{
return isPanning || isTilting || isZooming || isFocusing;
}
}
public CiscoSparkCamera(string key, string name, CiscoSparkCodec codec, uint id)
: base(key, name)
{
// Default to all capabilties
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus;
ParentCodec = codec;
CameraId = id;
// Set default speeds
PanSpeed = 7;
TiltSpeed = 7;
ZoomSpeed = 7;
}
// Takes a string from the camera capabilities value and converts from "ptzf" to enum bitmask
public void SetCapabilites(string capabilites)
{
var c = capabilites.ToLower();
if (c.Contains("p"))
Capabilities = Capabilities | eCameraCapabilities.Pan;
if (c.Contains("t"))
Capabilities = Capabilities | eCameraCapabilities.Tilt;
if (c.Contains("z"))
Capabilities = Capabilities | eCameraCapabilities.Zoom;
if (c.Contains("f"))
Capabilities = Capabilities | eCameraCapabilities.Focus;
}
#region IHasCameraPtzControl Members
public void PositionHome()
{
// Not supported on Internal Spark Camera
}
#endregion
#region IHasCameraPanControl Members
public void PanLeft()
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Left PanSpeed: {1}", CameraId, PanSpeed));
isPanning = true;
}
}
public void PanRight()
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Right PanSpeed: {1}", CameraId, PanSpeed));
isPanning = true;
}
}
public void PanStop()
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Pan: Stop", CameraId));
isPanning = false;
}
#endregion
#region IHasCameraTiltControl Members
public void TiltDown()
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Down TiltSpeed: {1}", CameraId, TiltSpeed));
isTilting = true;
}
}
public void TiltUp()
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Up TiltSpeed: {1}", CameraId, TiltSpeed));
isTilting = true;
}
}
public void TiltStop()
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Tilt: Stop", CameraId));
isTilting = false;
}
#endregion
#region IHasCameraZoomControl Members
public void ZoomIn()
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: In ZoomSpeed: {1}", CameraId, ZoomSpeed));
isZooming = true;
}
}
public void ZoomOut()
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: Out ZoomSpeed: {1}", CameraId, ZoomSpeed));
isZooming = true;
}
}
public void ZoomStop()
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Zoom: Stop", CameraId));
isZooming = false;
}
#endregion
#region IHasCameraFocusControl Members
public void FocusNear()
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Near", CameraId));
isFocusing = true;
}
}
public void FocusFar()
{
if (!isMoving)
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Far", CameraId));
isFocusing = true;
}
}
public void FocusStop()
{
ParentCodec.SendText(string.Format("xCommand Camera Ramp CameraId: {0} Focus: Stop", CameraId));
isFocusing = false;
}
public void TriggerAutoFocus()
{
ParentCodec.SendText(string.Format("xCommand Camera TriggerAutofocus CameraId: {0}", CameraId));
}
#endregion
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Codec
{
public class CiscoSparkCodecPropertiesConfig
{
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
public List<CodecActiveCallItem> Favorites { get; set; }
/// <summary>
/// Valid values: "Local" or "Corporate"
/// </summary>
public string PhonebookMode { get; set; }
public bool ShowSelfViewByDefault { get; set; }
public SharingProperties Sharing { get; set; }
}
public class SharingProperties
{
public bool AutoShareContentWhileInCall { get; set; }
}
}

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Net.Http;
using PepperDash.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
public class HttpApiServer
{
public static Dictionary<string, string> ExtensionContentTypes;
public event EventHandler<OnHttpRequestArgs> ApiRequest;
public Crestron.SimplSharp.Net.Http.HttpServer HttpServer { get; private set; }
public string HtmlRoot { get; set; }
/// <summary>
/// SIMPL+ can only execute the default constructor. If you have variables that require initialization, please
/// use an Initialize method
/// </summary>
public HttpApiServer()
{
ExtensionContentTypes = new Dictionary<string, string>
{
{ ".css", "text/css" },
{ ".htm", "text/html" },
{ ".html", "text/html" },
{ ".jpg", "image/jpeg" },
{ ".jpeg", "image/jpeg" },
{ ".js", "application/javascript" },
{ ".json", "application/json" },
{ ".xml", "text/xml" },
{ ".map", "application/x-navimap" },
{ ".pdf", "application.pdf" },
{ ".png", "image/png" },
{ ".txt", "text/plain" },
};
HtmlRoot = @"\HTML";
}
public void Start(int port)
{
// TEMP - this should be inserted by configuring class
HttpServer = new Crestron.SimplSharp.Net.Http.HttpServer();
HttpServer.ServerName = "Cisco API Server";
HttpServer.KeepAlive = true;
HttpServer.Port = port;
HttpServer.OnHttpRequest += Server_Request;
HttpServer.Open();
CrestronEnvironment.ProgramStatusEventHandler += (a) =>
{
if (a == eProgramStatusEventType.Stopping)
{
HttpServer.Close();
Debug.Console(1, "Shutting down HTTP Server on port {0}", HttpServer.Port);
}
};
}
void Server_Request(object sender, OnHttpRequestArgs args)
{
if (args.Request.Header.RequestType == "OPTIONS")
{
Debug.Console(2, "Asking for OPTIONS");
args.Response.Header.SetHeaderValue("Access-Control-Allow-Origin", "*");
args.Response.Header.SetHeaderValue("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
return;
}
string path = Uri.UnescapeDataString(args.Request.Path);
var host = args.Request.DataConnection.RemoteEndPointAddress;
//string authToken;
Debug.Console(2, "HTTP Request: {2}: Path='{0}' ?'{1}'", path, args.Request.QueryString, host);
// ----------------------------------- ADD AUTH HERE
if (path.StartsWith("/cisco/api"))
{
var handler = ApiRequest;
if (ApiRequest != null)
ApiRequest(this, args);
}
}
public static string GetContentType(string extension)
{
string type;
if (ExtensionContentTypes.ContainsKey(extension))
type = ExtensionContentTypes[extension];
else
type = "text/plain";
return type;
}
}
}

View File

@@ -0,0 +1,397 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class CiscoCodecPhonebook
{
public class Offset
{
public string Value { get; set; }
}
public class Limit
{
public string Value { get; set; }
}
public class TotalRows
{
public string Value { get; set; }
}
public class ResultInfo
{
public Offset Offset { get; set; }
public Limit Limit { get; set; }
public TotalRows TotalRows { get; set; }
}
public class LocalId
{
public string Value { get; set; }
}
public class FolderId
{
public string Value { get; set; }
}
public class ParentFolderId
{
public string Value { get; set; }
}
public class Name
{
public string Value { get; set; }
}
public class Folder
{
public string id { get; set; }
public LocalId LocalId { get; set; }
public FolderId FolderId { get; set; }
public Name Name { get; set; }
public ParentFolderId ParentFolderId { get; set; }
}
public class Name2
{
public string Value { get; set; }
}
public class ContactId
{
public string Value { get; set; }
}
public class FolderId2
{
public string Value { get; set; }
}
public class Title
{
public string Value { get; set; }
}
public class ContactMethodId
{
public string Value { get; set; }
}
public class Number
{
public string Value { get; set; }
}
public class Device
{
public string Value { get; set; }
}
public class CallType
{
public string Value { get; set; }
}
public class ContactMethod
{
public string id { get; set; }
public ContactMethodId ContactMethodId { get; set; }
public Number Number { get; set; }
public Device Device { get; set; }
public CallType CallType { get; set; }
public ContactMethod()
{
ContactMethodId = new ContactMethodId();
Number = new Number();
Device = new Device();
CallType = new CallType();
}
}
public class Contact
{
public string id { get; set; }
public Name2 Name { get; set; }
public ContactId ContactId { get; set; }
public FolderId2 FolderId { get; set; }
public Title Title { get; set; }
public List<ContactMethod> ContactMethod { get; set; }
public Contact()
{
Name = new Name2();
ContactId = new ContactId();
FolderId = new FolderId2();
Title = new Title();
ContactMethod = new List<ContactMethod>();
}
}
public class PhonebookSearchResult
{
public string status { get; set; }
public ResultInfo ResultInfo { get; set; }
public List<Folder> Folder { get; set; }
public List<Contact> Contact { get; set; }
public PhonebookSearchResult()
{
Folder = new List<Folder>();
Contact = new List<Contact>();
ResultInfo = new ResultInfo();
}
}
public class CommandResponse
{
public PhonebookSearchResult PhonebookSearchResult { get; set; }
}
public class RootObject
{
public CommandResponse CommandResponse { get; set; }
}
/// <summary>
/// Extracts the folders with no ParentFolder and returns them sorted alphabetically
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
public static List<DirectoryItem> GetRootFoldersFromSearchResult(PhonebookSearchResult result)
{
var rootFolders = new List<DirectoryItem>();
if (result.Folder.Count == 0)
{
return null;
}
else if (result.Folder.Count > 0)
{
if (Debug.Level > 0)
Debug.Console(1, "Phonebook Folders:\n");
foreach (Folder f in result.Folder)
{
var folder = new DirectoryFolder();
folder.Name = f.Name.Value;
folder.FolderId = f.FolderId.Value;
if (f.ParentFolderId == null)
rootFolders.Add(folder);
if (Debug.Level > 0)
Debug.Console(1, "+ {0}", folder.Name);
}
}
rootFolders.OrderBy(f => f.Name);
return rootFolders;
}
/// <summary>
/// Extracts the contacts with no FolderId and returns them sorted alphabetically
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
public static List<DirectoryItem> GetRootContactsFromSearchResult(PhonebookSearchResult result)
{
var rootContacts = new List<DirectoryItem>();
if (result.Contact.Count == 0)
{
return null;
}
else if (result.Contact.Count > 0)
{
if (Debug.Level > 0)
Debug.Console(1, "Root Contacts:\n");
foreach (Contact c in result.Contact)
{
var contact = new DirectoryContact();
if (string.IsNullOrEmpty(c.FolderId.Value))
{
contact.Name = c.Name.Value;
contact.ContactId = c.ContactId.Value;
if(!string.IsNullOrEmpty(c.Title.Value))
contact.Title = c.Title.Value;
if (Debug.Level > 0)
Debug.Console(1, "{0}\nContact Methods:", contact.Name);
foreach (ContactMethod m in c.ContactMethod)
{
var tempContactMethod = new PepperDash.Essentials.Devices.Common.Codec.ContactMethod();
eContactMethodCallType callType = eContactMethodCallType.Unknown;
if (!string.IsNullOrEmpty(m.CallType.Value))
{
if (!string.IsNullOrEmpty(m.CallType.Value))
{
if (m.CallType.Value.ToLower() == "audio")
callType = eContactMethodCallType.Audio;
else if (m.CallType.Value.ToLower() == "video")
callType = eContactMethodCallType.Video;
tempContactMethod.CallType = callType;
}
}
eContactMethodDevice device = eContactMethodDevice.Unknown;
if (!string.IsNullOrEmpty(m.Device.Value))
{
if (m.Device.Value.ToLower() == "mobile")
device = eContactMethodDevice.Mobile;
else if (m.Device.Value.ToLower() == "telephone")
device = eContactMethodDevice.Telephone;
else if (m.Device.Value.ToLower() == "video")
device = eContactMethodDevice.Video;
else if (m.Device.Value.ToLower() == "other")
device = eContactMethodDevice.Other;
tempContactMethod.Device = device;
}
if (Debug.Level > 0)
Debug.Console(1, "Number: {0}", m.Number.Value);
tempContactMethod.Number = m.Number.Value;
tempContactMethod.ContactMethodId = m.ContactMethodId.Value;
contact.ContactMethods.Add(tempContactMethod);
}
rootContacts.Add(contact);
}
}
}
rootContacts.OrderBy(f => f.Name);
return rootContacts;
}
/// <summary>
/// Converts data returned from a cisco codec to the generic Directory format.
/// </summary>
/// <param name="result"></param>
/// <param name="resultFolder"></param>
/// <returns></returns>
public static CodecDirectory ConvertCiscoPhonebookToGeneric(PhonebookSearchResult result)
{
var directory = new Codec.CodecDirectory();
var folders = new List<Codec.DirectoryItem>();
var contacts = new List<Codec.DirectoryItem>();
try
{
if (result.Folder.Count > 0)
{
foreach (Folder f in result.Folder)
{
var folder = new DirectoryFolder();
folder.Name = f.Name.Value;
folder.FolderId = f.FolderId.Value;
if (f.ParentFolderId != null)
{
folder.ParentFolderId = f.ParentFolderId.Value;
}
folders.Add(folder);
}
folders.OrderBy(f => f.Name);
directory.AddFoldersToDirectory(folders);
}
if (result.Contact.Count > 0)
{
foreach (Contact c in result.Contact)
{
var contact = new DirectoryContact();
contact.Name = c.Name.Value;
contact.ContactId = c.ContactId.Value;
if (!string.IsNullOrEmpty(c.Title.Value))
contact.Title = c.Title.Value;
if (c.FolderId != null)
{
contact.FolderId = c.FolderId.Value;
}
foreach (ContactMethod m in c.ContactMethod)
{
eContactMethodCallType callType = eContactMethodCallType.Unknown;
if (!string.IsNullOrEmpty(m.CallType.Value))
{
if (m.CallType.Value.ToLower() == "audio")
callType = eContactMethodCallType.Audio;
else if (m.CallType.Value.ToLower() == "video")
callType = eContactMethodCallType.Video;
}
eContactMethodDevice device = eContactMethodDevice.Unknown;
if (!string.IsNullOrEmpty(m.Device.Value))
{
if (m.Device.Value.ToLower() == "mobile")
device = eContactMethodDevice.Mobile;
else if (m.Device.Value.ToLower() == "telephone")
device = eContactMethodDevice.Telephone;
else if (m.Device.Value.ToLower() == "video")
device = eContactMethodDevice.Video;
else if (m.Device.Value.ToLower() == "other")
device = eContactMethodDevice.Other;
}
contact.ContactMethods.Add(new PepperDash.Essentials.Devices.Common.Codec.ContactMethod()
{
Number = m.Number.Value,
ContactMethodId = m.ContactMethodId.Value,
CallType = callType,
Device = device
});
}
contacts.Add(contact);
}
contacts.OrderBy(c => c.Name);
directory.AddContactsToDirectory(contacts);
}
}
catch (Exception e)
{
Debug.Console(1, "Error converting Cisco Phonebook results to generic: {0}", e);
}
return directory;
}
}
}

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// Interface for camera presets
/// </summary>
public interface IHasCodecRoomPresets
{
event EventHandler<EventArgs> CodecRoomPresetsListHasChanged;
List<CodecRoomPreset> NearEndPresets { get; }
List<CodecRoomPreset> FarEndRoomPresets { get; }
void CodecRoomPresetSelect(int preset);
void CodecRoomPresetStore(int preset, string description);
}
public static class RoomPresets
{
/// <summary>
/// Converts Cisco RoomPresets to generic CameraPresets
/// </summary>
/// <param name="presets"></param>
/// <returns></returns>
public static List<CodecRoomPreset> GetGenericPresets(List<CiscoCodecStatus.RoomPreset> presets)
{
var cameraPresets = new List<CodecRoomPreset>();
if (Debug.Level > 0)
{
Debug.Console(1, "Presets List:");
}
foreach (CiscoCodecStatus.RoomPreset preset in presets)
{
try
{
var cameraPreset = new CodecRoomPreset(UInt16.Parse(preset.id), preset.Description.Value, preset.Defined.BoolValue, true);
cameraPresets.Add(cameraPreset);
if (Debug.Level > 0)
{
Debug.Console(1, "Added Preset ID: {0}, Description: {1}, IsDefined: {2}, isDefinable: {3}", cameraPreset.ID, cameraPreset.Description, cameraPreset.Defined, cameraPreset.IsDefinable);
}
}
catch (Exception e)
{
Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", preset.id, e);
}
}
return cameraPresets;
}
}
/// <summary>
/// Represents a room preset on a video coded. Typically stores camera position(s) and video routing. Can be recalled by Far End if enabled.
/// </summary>
public class CodecRoomPreset
{
[JsonProperty("id")]
public int ID { get; set; }
/// <summary>
/// Used to store the name of the preset
/// </summary>
[JsonProperty("description")]
public string Description { get; set; }
/// <summary>
/// Indicates if the preset is defined(stored) in the codec
/// </summary>
[JsonProperty("defined")]
public bool Defined { get; set; }
/// <summary>
/// Indicates if the preset has the capability to be defined
/// </summary>
[JsonProperty("isDefinable")]
public bool IsDefinable { get; set; }
public CodecRoomPreset(int id, string description, bool def, bool isDef)
{
ID = id;
Description = description;
Defined = def;
IsDefinable = isDef;
}
}
}

View File

@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
/// <summary>
/// This class exists to capture serialized data sent back by a Cisco codec in JSON output mode
/// </summary>
public class CiscoCodecEvents
{
public class CauseValue
{
public string id { get; set; }
public string Value { get; set; }
}
public class CauseType
{
public string id { get; set; }
public string Value { get; set; }
}
public class CauseString
{
public string id { get; set; }
public string Value { get; set; }
}
public class OrigCallDirection
{
public string id { get; set; }
public string Value { get; set; }
}
public class RemoteURI
{
public string id { get; set; }
public string Value { get; set; }
}
public class DisplayName
{
public string id { get; set; }
public string Value { get; set; }
}
public class CallId
{
public string id { get; set; }
public string Value { get; set; }
}
public class CauseCode
{
public string id { get; set; }
public string Value { get; set; }
}
public class CauseOrigin
{
public string id { get; set; }
public string Value { get; set; }
}
public class Protocol
{
public string id { get; set; }
public string Value { get; set; }
}
public class Duration
{
public string id { get; set; }
public string Value { get; set; }
}
public class CallType
{
public string id { get; set; }
public string Value { get; set; }
}
public class CallRate
{
public string id { get; set; }
public string Value { get; set; }
}
public class Encryption
{
public string id { get; set; }
public string Value { get; set; }
}
public class RequestedURI
{
public string id { get; set; }
public string Value { get; set; }
}
public class PeopleCountAverage
{
public string id { get; set; }
public string Value { get; set; }
}
public class CallDisconnect
{
public string id { get; set; }
public CauseValue CauseValue { get; set; }
public CauseType CauseType { get; set; }
public CauseString CauseString { get; set; }
public OrigCallDirection OrigCallDirection { get; set; }
public RemoteURI RemoteURI { get; set; }
public DisplayName DisplayName { get; set; }
public CallId CallId { get; set; }
public CauseCode CauseCode { get; set; }
public CauseOrigin CauseOrigin { get; set; }
public Protocol Protocol { get; set; }
public Duration Duration { get; set; }
public CallType CallType { get; set; }
public CallRate CallRate { get; set; }
public Encryption Encryption { get; set; }
public RequestedURI RequestedURI { get; set; }
public PeopleCountAverage PeopleCountAverage { get; set; }
}
public class Event
{
public CallDisconnect CallDisconnect { get; set; }
}
public class RootObject
{
public Event Event { get; set; }
}
}
}

View File

@@ -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
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
public enum eCameraControlMode
{
Off = 0,
Manual,
Auto
}
public interface IHasCameras
{
event EventHandler<CameraSelectedEventArgs> CameraSelected;
List<CameraBase> Cameras { get; }
CameraBase SelectedCamera { get; }
StringFeedback SelectedCameraFeedback { get; }
void SelectCamera(string key);
}
/// <summary>
/// Aggregates far end cameras with near end cameras
/// </summary>
public interface IHasCodecCameras : IHasCameras, IHasFarEndCameraControl
{
}
/// <summary>
/// To be implmented on codecs that can disable their camera(s) to blank the near end video
/// </summary>
public interface IHasCameraOff
{
BoolFeedback CameraIsOffFeedback { get; }
void CameraOff();
}
public class CameraSelectedEventArgs : EventArgs
{
public CameraBase SelectedCamera { get; private set; }
public CameraSelectedEventArgs(CameraBase camera)
{
SelectedCamera = camera;
}
}
public interface IHasFarEndCameraControl
{
CameraBase FarEndCamera { get; }
BoolFeedback ControllingFarEndCameraFeedback { get; }
}
/// <summary>
/// Used to decorate a camera as a far end
/// </summary>
public interface IAmFarEndCamera
{
}
/// <summary>
/// Aggregates the pan, tilt and zoom interfaces
/// </summary>
public interface IHasCameraPtzControl : IHasCameraPanControl, IHasCameraTiltControl, IHasCameraZoomControl
{
/// <summary>
/// Resets the camera position
/// </summary>
void PositionHome();
}
/// <summary>
/// Interface for camera pan control
/// </summary>
public interface IHasCameraPanControl
{
void PanLeft();
void PanRight();
void PanStop();
}
/// <summary>
/// Interface for camera tilt control
/// </summary>
public interface IHasCameraTiltControl
{
void TiltDown();
void TiltUp();
void TiltStop();
}
/// <summary>
/// Interface for camera zoom control
/// </summary>
public interface IHasCameraZoomControl
{
void ZoomIn();
void ZoomOut();
void ZoomStop();
}
/// <summary>
/// Interface for camera focus control
/// </summary>
public interface IHasCameraFocusControl
{
void FocusNear();
void FocusFar();
void FocusStop();
void TriggerAutoFocus();
}
public interface IHasCameraAutoMode
{
void CameraAutoModeOn();
void CameraAutoModeOff();
void CameraAutoModeToggle();
BoolFeedback CameraAutoModeIsOnFeedback { get; }
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// Defines the required elements for layout control
/// </summary>
public interface IHasCodecLayouts
{
StringFeedback LocalLayoutFeedback { get; }
void LocalLayoutToggle();
void LocalLayoutToggleSingleProminent();
void MinMaxLayoutToggle();
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// Defines the requred elements for selfview control
/// </summary>
public interface IHasCodecSelfView
{
BoolFeedback SelfviewIsOnFeedback { get; }
bool ShowSelfViewByDefault { get; }
void SelfViewModeOn();
void SelfViewModeOff();
void SelfViewModeToggle();
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// For rooms that have video codec
/// </summary>
public interface IHasVideoCodec
{
VideoCodecBase VideoCodec { get; }
BoolFeedback InCallFeedback { get; }
///// <summary>
///// Make this more specific
///// </summary>
//List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem> ActiveCalls { get; }
/// <summary>
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
/// </summary>
IntFeedback CallTypeFeedback { get; }
/// <summary>
///
/// </summary>
BoolFeedback PrivacyModeIsOnFeedback { get; }
/// <summary>
/// When something in the room is sharing with the far end or through other means
/// </summary>
BoolFeedback IsSharingFeedback { get; }
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Implements a common set of data about a codec
/// </summary>
public interface iVideoCodecInfo
{
VideoCodecInfo CodecInfo { get; }
}
/// <summary>
/// Stores general information about a codec
/// </summary>
public abstract class VideoCodecInfo
{
public abstract bool MultiSiteOptionIsEnabled { get; }
public abstract string IpAddress { get; }
public abstract string SipPhoneNumber { get; }
public abstract string E164Alias { get; }
public abstract string H323Id { get; }
public abstract string SipUri { get; }
public abstract bool AutoAnswerEnabled { get; }
}
}

View File

@@ -0,0 +1,419 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public static class MockVideoCodecDirectory
{
public enum eFolderId
{
UnitedStates,
Canada,
NewYork,
Boston,
SanFrancisco,
Denver,
Austin,
Calgary
}
/// <summary>
/// Aggregates the directory items for all directories into a single directory for searching purposes
/// </summary>
public static CodecDirectory CompleteDirectory
{
get
{
var completeDirectory = new CodecDirectory();
completeDirectory.AddContactsToDirectory(DirectoryRoot.CurrentDirectoryResults);
completeDirectory.AddContactsToDirectory(UnitedStatesFolderContents.CurrentDirectoryResults);
completeDirectory.AddContactsToDirectory(CanadaFolderContents.CurrentDirectoryResults);
completeDirectory.AddContactsToDirectory(NewYorkFolderContents.CurrentDirectoryResults);
completeDirectory.AddContactsToDirectory(BostonFolderContents.CurrentDirectoryResults);
completeDirectory.AddContactsToDirectory(DenverFolderContents.CurrentDirectoryResults);
completeDirectory.AddContactsToDirectory(AustinFolderContents.CurrentDirectoryResults);
completeDirectory.AddContactsToDirectory(CalgaryFolderContents.CurrentDirectoryResults);
return completeDirectory;
}
}
public static CodecDirectory DirectoryRoot
{
get
{
var directory = new CodecDirectory();
directory.AddFoldersToDirectory
(
new List<DirectoryItem>()
{
new DirectoryFolder()
{
FolderId = eFolderId.UnitedStates.ToString(),
Name = "United States",
ParentFolderId = "",
Contacts = null
},
new DirectoryFolder()
{
FolderId = eFolderId.Canada.ToString(),
Name = "Canada",
ParentFolderId = "",
Contacts = null
}
}
);
directory.AddContactsToDirectory
(
new List<DirectoryItem>()
{
new DirectoryContact()
{
Name = "Corporate Bridge",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "c_1",
Number = "site.corp.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
}
}
);
return directory;
}
}
public static CodecDirectory UnitedStatesFolderContents
{
get
{
var directory = new CodecDirectory();
directory.ResultsFolderId = eFolderId.UnitedStates.ToString();
directory.AddFoldersToDirectory
(
new List<DirectoryItem>()
{
new DirectoryFolder()
{
FolderId = eFolderId.NewYork.ToString(),
Name = "New York",
ParentFolderId = eFolderId.UnitedStates.ToString(),
Contacts = null
},
new DirectoryFolder()
{
FolderId = eFolderId.Boston.ToString(),
Name = "Boston",
ParentFolderId = eFolderId.UnitedStates.ToString(),
Contacts = null
},
new DirectoryFolder()
{
FolderId = eFolderId.SanFrancisco.ToString(),
Name = "San Francisco",
ParentFolderId = eFolderId.UnitedStates.ToString(),
Contacts = null
},
new DirectoryFolder()
{
FolderId = eFolderId.Denver.ToString(),
Name = "Denver",
ParentFolderId = eFolderId.UnitedStates.ToString(),
Contacts = null
},
new DirectoryFolder()
{
FolderId = eFolderId.Austin.ToString(),
Name = "Austin",
ParentFolderId = eFolderId.UnitedStates.ToString(),
Contacts = null
}
}
);
return directory;
}
}
public static CodecDirectory NewYorkFolderContents
{
get
{
var directory = new CodecDirectory();
directory.ResultsFolderId = eFolderId.NewYork.ToString();
directory.AddContactsToDirectory
(
new List<DirectoryItem>()
{
new DirectoryContact()
{
ContactId = "nyc_1",
Name = "Meeting Room",
Title = @"",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "cid_1",
Number = "nycmeetingroom.pepperdash.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
},
new DirectoryContact()
{
ContactId = "nyc_2",
Name = "Sumanth Rayancha",
Title = @"CTO",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "cid_1",
Number = "srayancha.pepperdash.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
},
new DirectoryContact()
{
ContactId = "nyc_3",
Name = "Justin Gordon",
Title = @"Software Developer",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "cid_1",
Number = "jgordon.pepperdash.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
}
}
);
return directory;
}
}
public static CodecDirectory BostonFolderContents
{
get
{
var directory = new CodecDirectory();
directory.ResultsFolderId = eFolderId.Boston.ToString();
directory.AddContactsToDirectory
(
new List<DirectoryItem>()
{
new DirectoryContact()
{
ContactId = "bos_1",
Name = "Board Room",
Title = @"",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "cid_1",
Number = "bosboardroom.pepperdash.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
}
}
);
return directory;
}
}
public static CodecDirectory SanFranciscoFolderContents
{
get
{
var directory = new CodecDirectory();
directory.ResultsFolderId = eFolderId.SanFrancisco.ToString();
directory.AddContactsToDirectory
(
new List<DirectoryItem>()
{
new DirectoryContact()
{
ContactId = "sfo_1",
Name = "David Huselid",
Title = @"Cive President, COO",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "cid_1",
Number = "dhuselid.pepperdash.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
}
}
);
return directory;
}
}
public static CodecDirectory DenverFolderContents
{
get
{
var directory = new CodecDirectory();
directory.ResultsFolderId = eFolderId.Denver.ToString();
directory.AddContactsToDirectory
(
new List<DirectoryItem>()
{
new DirectoryContact()
{
ContactId = "den_1",
Name = "Heath Volmer",
Title = @"Software Developer",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "cid_1",
Number = "hvolmer.pepperdash.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
}
}
);
return directory;
}
}
public static CodecDirectory AustinFolderContents
{
get
{
var directory = new CodecDirectory();
directory.ResultsFolderId = eFolderId.Austin.ToString();
directory.AddContactsToDirectory
(
new List<DirectoryItem>()
{
new DirectoryContact()
{
ContactId = "atx_1",
Name = "Vincent Longano",
Title = @"Product Development Manager",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "cid_1",
Number = "vlongano.pepperdash.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
}
}
);
return directory;
}
}
public static CodecDirectory CanadaFolderContents
{
get
{
var directory = new CodecDirectory();
directory.ResultsFolderId = eFolderId.Canada.ToString();
directory.AddFoldersToDirectory
(
new List<DirectoryItem>()
{
new DirectoryFolder()
{
FolderId = eFolderId.Calgary.ToString(),
Name = "Calgary",
ParentFolderId = eFolderId.Canada.ToString(),
Contacts = null
}
}
);
return directory;
}
}
public static CodecDirectory CalgaryFolderContents
{
get
{
var directory = new CodecDirectory();
directory.ResultsFolderId = eFolderId.Calgary.ToString();
directory.AddContactsToDirectory
(
new List<DirectoryItem>()
{
new DirectoryContact()
{
ContactId = "cdn_1",
Name = "Neil Dorin",
Title = @"Software Developer /SC",
ContactMethods = new List<ContactMethod>()
{
new ContactMethod()
{
ContactMethodId = "cid_1",
Number = "ndorin@pepperdash.com",
Device = eContactMethodDevice.Video,
CallType = eContactMethodCallType.Video
}
}
}
}
);
return directory;
}
}
}
}

View File

@@ -0,0 +1,773 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Routing;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.Cameras;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class MockVC : VideoCodecBase, IRoutingSource, IHasCallHistory, IHasScheduleAwareness, IHasCallFavorites, IHasDirectory, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets
{
public MockVcPropertiesConfig PropertiesConfig;
public RoutingInputPort CodecOsdIn { get; private set; }
public RoutingInputPort HdmiIn1 { get; private set; }
public RoutingInputPort HdmiIn2 { get; private set; }
public RoutingOutputPort HdmiOut { get; private set; }
public CodecCallFavorites CallFavorites { get; private set; }
/// <summary>
///
/// </summary>
public MockVC(DeviceConfig config)
: base(config)
{
PropertiesConfig = JsonConvert.DeserializeObject<VideoCodec.MockVcPropertiesConfig>(config.Properties.ToString());
CodecInfo = new MockCodecInfo();
// Get favoritesw
if (PropertiesConfig.Favorites != null)
{
CallFavorites = new CodecCallFavorites();
CallFavorites.Favorites = PropertiesConfig.Favorites;
}
DirectoryBrowseHistory = new List<CodecDirectory>();
// Debug helpers
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);
VolumeLevelFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Volume={0}", _VolumeLevel);
CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => DirectoryBrowseHistory.Count > 0);
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 0, this);
InputPorts.Add(CodecOsdIn);
HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 1, this);
InputPorts.Add(HdmiIn1);
HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, 2, this);
InputPorts.Add(HdmiIn2);
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
OutputPorts.Add(HdmiOut);
CallHistory = new CodecCallHistory();
for (int i = 0; i < 10; i++)
{
var call = new CodecCallHistory.CallHistoryEntry();
call.Name = "Call " + i;
call.Number = i + "@call.com";
CallHistory.RecentCalls.Add(call);
}
// eventually fire history event here
SetupCameras();
SetIsReady();
}
protected override Func<bool> MuteFeedbackFunc
{
get { return () => _IsMuted; }
}
bool _IsMuted;
protected override Func<bool> PrivacyModeIsOnFeedbackFunc
{
get { return () => _PrivacyModeIsOn; }
}
bool _PrivacyModeIsOn;
protected override Func<string> SharingSourceFeedbackFunc
{
get { return () => _SharingSource; }
}
string _SharingSource;
protected override Func<bool> SharingContentIsOnFeedbackFunc
{
get { return () => _SharingIsOn; }
}
bool _SharingIsOn;
protected override Func<int> VolumeLevelFeedbackFunc
{
get { return () => _VolumeLevel; }
}
int _VolumeLevel;
protected override Func<bool> StandbyIsOnFeedbackFunc
{
get { return () => _StandbyIsOn; }
}
bool _StandbyIsOn;
/// <summary>
/// Dials, yo!
/// </summary>
public override void Dial(string number)
{
Debug.Console(1, this, "Dial: {0}", number);
var call = new CodecActiveCallItem() { Name = number, Number = number, Id = number, Status = eCodecCallStatus.Dialing, Direction = eCodecCallDirection.Outgoing, Type = eCodecCallType.Video };
ActiveCalls.Add(call);
OnCallStatusChange(call);
//ActiveCallCountFeedback.FireUpdate();
// Simulate 2-second ring, then connecting, then connected
new CTimer(o =>
{
call.Type = eCodecCallType.Video;
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call);
new CTimer(oo => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000);
}, 2000);
}
public override void Dial(Meeting meeting)
{
throw new NotImplementedException();
}
/// <summary>
///
/// </summary>
public override void EndCall(CodecActiveCallItem call)
{
Debug.Console(1, this, "EndCall");
ActiveCalls.Remove(call);
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call);
//ActiveCallCountFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void EndAllCalls()
{
Debug.Console(1, this, "EndAllCalls");
for(int i = ActiveCalls.Count - 1; i >= 0; i--)
{
var call = ActiveCalls[i];
ActiveCalls.Remove(call);
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call);
}
//ActiveCallCountFeedback.FireUpdate();
}
/// <summary>
/// For a call from the test methods below
/// </summary>
public override void AcceptCall(CodecActiveCallItem call)
{
Debug.Console(1, this, "AcceptCall");
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call);
new CTimer(o => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000);
// should already be in active list
}
/// <summary>
/// For a call from the test methods below
/// </summary>
public override void RejectCall(CodecActiveCallItem call)
{
Debug.Console(1, this, "RejectCall");
ActiveCalls.Remove(call);
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Disconnected, call);
//ActiveCallCountFeedback.FireUpdate();
}
/// <summary>
/// Makes horrible tones go out on the wire!
/// </summary>
/// <param name="s"></param>
public override void SendDtmf(string s)
{
Debug.Console(1, this, "SendDTMF: {0}", s);
}
/// <summary>
///
/// </summary>
public override void StartSharing()
{
_SharingIsOn = true;
SharingContentIsOnFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void StopSharing()
{
_SharingIsOn = false;
SharingContentIsOnFeedback.FireUpdate();
}
public override void StandbyActivate()
{
_StandbyIsOn = true;
}
public override void StandbyDeactivate()
{
_StandbyIsOn = false;
}
/// <summary>
/// Called by routing to make it happen
/// </summary>
/// <param name="selector"></param>
public override void ExecuteSwitch(object selector)
{
Debug.Console(1, this, "ExecuteSwitch: {0}", selector);
_SharingSource = selector.ToString();
}
/// <summary>
///
/// </summary>
public override void MuteOff()
{
_IsMuted = false;
MuteFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void MuteOn()
{
_IsMuted = true;
MuteFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void MuteToggle()
{
_IsMuted = !_IsMuted;
MuteFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
/// <param name="level"></param>
public override void SetVolume(ushort level)
{
_VolumeLevel = level;
VolumeLevelFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
/// <param name="pressRelease"></param>
public override void VolumeDown(bool pressRelease)
{
}
/// <summary>
///
/// </summary>
/// <param name="pressRelease"></param>
public override void VolumeUp(bool pressRelease)
{
}
/// <summary>
///
/// </summary>
public override void PrivacyModeOn()
{
Debug.Console(1, this, "PrivacyMuteOn");
if (_PrivacyModeIsOn)
return;
_PrivacyModeIsOn = true;
PrivacyModeIsOnFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void PrivacyModeOff()
{
Debug.Console(1, this, "PrivacyMuteOff");
if (!_PrivacyModeIsOn)
return;
_PrivacyModeIsOn = false;
PrivacyModeIsOnFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void PrivacyModeToggle()
{
_PrivacyModeIsOn = !_PrivacyModeIsOn;
Debug.Console(1, this, "PrivacyMuteToggle: {0}", _PrivacyModeIsOn);
PrivacyModeIsOnFeedback.FireUpdate();
}
//********************************************************
// SIMULATION METHODS
/// <summary>
///
/// </summary>
/// <param name="url"></param>
public void TestIncomingVideoCall(string url)
{
Debug.Console(1, this, "TestIncomingVideoCall from {0}", url);
var call = new CodecActiveCallItem() { Name = url, Id = url, Number = url, Type= eCodecCallType.Video, Direction = eCodecCallDirection.Incoming };
ActiveCalls.Add(call);
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Ringing, call);
//OnCallStatusChange(eCodecCallStatus.Unknown, eCodecCallStatus.Ringing, call);
}
/// <summary>
///
/// </summary>
/// <param name="url"></param>
public void TestIncomingAudioCall(string url)
{
Debug.Console(1, this, "TestIncomingAudioCall from {0}", url);
var call = new CodecActiveCallItem() { Name = url, Id = url, Number = url, Type = eCodecCallType.Audio, Direction = eCodecCallDirection.Incoming };
ActiveCalls.Add(call);
SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Ringing, call);
//OnCallStatusChange(eCodecCallStatus.Unknown, eCodecCallStatus.Ringing, call);
}
/// <summary>
///
/// </summary>
public void TestFarEndHangup()
{
Debug.Console(1, this, "TestFarEndHangup");
}
#region IHasCallHistory Members
public CodecCallHistory CallHistory { get; private set; }
public void RemoveCallHistoryEntry(CodecCallHistory.CallHistoryEntry entry)
{
}
#endregion
#region IHasScheduleAwareness Members
public void GetSchedule()
{
}
public CodecScheduleAwareness CodecSchedule
{
get {
// if the last meeting has past, generate a new list
if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0
|| _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now)
{
_CodecSchedule = new CodecScheduleAwareness();
for (int i = 0; i < 5; i++)
{
var m = new Meeting();
m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i);
m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30);
m.Title = "Meeting " + i;
m.Calls.Add(new Call() { Number = i + "meeting@fake.com"});
_CodecSchedule.Meetings.Add(m);
}
}
return _CodecSchedule;
}
}
CodecScheduleAwareness _CodecSchedule;
#endregion
#region IHasDirectory Members
public event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
public CodecDirectory DirectoryRoot
{
get
{
return MockVideoCodecDirectory.DirectoryRoot;
}
}
public CodecDirectory CurrentDirectoryResult
{
get
{
if (DirectoryBrowseHistory.Count > 0)
return DirectoryBrowseHistory[DirectoryBrowseHistory.Count - 1];
else
return DirectoryRoot;
}
}
public CodecPhonebookSyncState PhonebookSyncState
{
get
{
var syncState = new CodecPhonebookSyncState(Key + "PhonebookSync");
syncState.InitialPhonebookFoldersReceived();
syncState.PhonebookRootEntriesReceived();
syncState.SetPhonebookHasFolders(true);
syncState.SetNumberOfContacts(0); // just need to call this method for the sync to complete
return syncState;
}
}
public void SearchDirectory(string searchString)
{
var searchResults = new CodecDirectory();
searchResults.ResultsFolderId = "searchResult";
// Search mock directory for contacts that contain the search string, ignoring case
List<DirectoryItem> matches = MockVideoCodecDirectory.CompleteDirectory.CurrentDirectoryResults.FindAll(
s => s is DirectoryContact && s.Name.ToLower().Contains(searchString.ToLower()));
if (matches != null)
{
searchResults.AddContactsToDirectory(matches);
DirectoryBrowseHistory.Add(searchResults);
}
OnDirectoryResultReturned(searchResults);
}
public void GetDirectoryFolderContents(string folderId)
{
var folderDirectory = new CodecDirectory();
if (folderId == MockVideoCodecDirectory.eFolderId.UnitedStates.ToString())
folderDirectory = MockVideoCodecDirectory.UnitedStatesFolderContents;
else if (folderId == MockVideoCodecDirectory.eFolderId.Canada.ToString())
folderDirectory = MockVideoCodecDirectory.CanadaFolderContents;
else if (folderId == MockVideoCodecDirectory.eFolderId.NewYork.ToString())
folderDirectory = MockVideoCodecDirectory.NewYorkFolderContents;
else if (folderId == MockVideoCodecDirectory.eFolderId.Boston.ToString())
folderDirectory = MockVideoCodecDirectory.BostonFolderContents;
else if (folderId == MockVideoCodecDirectory.eFolderId.SanFrancisco.ToString())
folderDirectory = MockVideoCodecDirectory.SanFranciscoFolderContents;
else if (folderId == MockVideoCodecDirectory.eFolderId.Denver.ToString())
folderDirectory = MockVideoCodecDirectory.DenverFolderContents;
else if (folderId == MockVideoCodecDirectory.eFolderId.Austin.ToString())
folderDirectory = MockVideoCodecDirectory.AustinFolderContents;
else if (folderId == MockVideoCodecDirectory.eFolderId.Calgary.ToString())
folderDirectory = MockVideoCodecDirectory.CalgaryFolderContents;
DirectoryBrowseHistory.Add(folderDirectory);
OnDirectoryResultReturned(folderDirectory);
}
public void SetCurrentDirectoryToRoot()
{
DirectoryBrowseHistory.Clear();
OnDirectoryResultReturned(DirectoryRoot);
}
public void GetDirectoryParentFolderContents()
{
var currentDirectory = new CodecDirectory();
if (DirectoryBrowseHistory.Count > 0)
{
var lastItemIndex = DirectoryBrowseHistory.Count - 1;
var parentDirectoryContents = DirectoryBrowseHistory[lastItemIndex];
DirectoryBrowseHistory.Remove(DirectoryBrowseHistory[lastItemIndex]);
currentDirectory = parentDirectoryContents;
}
else
{
currentDirectory = DirectoryRoot;
}
OnDirectoryResultReturned(currentDirectory);
}
public BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; private set; }
public List<CodecDirectory> DirectoryBrowseHistory { get; private set; }
public void OnDirectoryResultReturned(CodecDirectory result)
{
CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate();
var handler = DirectoryResultReturned;
if (handler != null)
{
handler(this, new DirectoryEventArgs()
{
Directory = result,
DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue
});
}
}
#endregion
void SetupCameras()
{
Cameras = new List<CameraBase>();
var internalCamera = new MockVCCamera(Key + "-camera1", "Near End", this);
Cameras.Add(internalCamera);
var farEndCamera = new MockFarEndVCCamera(Key + "-cameraFar", "Far End", this);
Cameras.Add(farEndCamera);
SelectedCameraFeedback = new StringFeedback(() => SelectedCamera.Key);
ControllingFarEndCameraFeedback = new BoolFeedback(() => SelectedCamera is IAmFarEndCamera);
CameraAutoModeIsOnFeedback = new BoolFeedback(() => _CameraAutoModeIsOn);
CameraAutoModeIsOnFeedback.FireUpdate();
DeviceManager.AddDevice(internalCamera);
DeviceManager.AddDevice(farEndCamera);
NearEndPresets = new List<CodecRoomPreset>(15); // Fix the capacity to emulate Cisco
NearEndPresets = PropertiesConfig.Presets;
FarEndRoomPresets = new List<CodecRoomPreset>(15); // Fix the capacity to emulate Cisco
// Add the far end presets
for (int i = 1; i <= FarEndRoomPresets.Capacity; i++)
{
var label = string.Format("Far End Preset {0}", i);
FarEndRoomPresets.Add(new CodecRoomPreset(i, label, true, false));
}
SelectedCamera = internalCamera; ; // call the method to select the camera and ensure the feedbacks get updated.
}
#region IHasCameras Members
public event EventHandler<CameraSelectedEventArgs> CameraSelected;
public List<CameraBase> Cameras { get; private set; }
private CameraBase _selectedCamera;
/// <summary>
/// Returns the selected camera
/// </summary>
public CameraBase SelectedCamera
{
get
{
return _selectedCamera;
}
private set
{
_selectedCamera = value;
SelectedCameraFeedback.FireUpdate();
ControllingFarEndCameraFeedback.FireUpdate();
var handler = CameraSelected;
if (handler != null)
{
handler(this, new CameraSelectedEventArgs(SelectedCamera));
}
}
}
public StringFeedback SelectedCameraFeedback { get; private set; }
public void SelectCamera(string key)
{
var camera = Cameras.FirstOrDefault(c => c.Key.ToLower().IndexOf(key.ToLower()) > -1);
if (camera != null)
{
Debug.Console(2, this, "Selected Camera with key: '{0}'", camera.Key);
SelectedCamera = camera;
}
else
Debug.Console(2, this, "Unable to select camera with key: '{0}'", key);
}
#endregion
#region IHasFarEndCameraControl Members
public CameraBase FarEndCamera { get; private set; }
public BoolFeedback ControllingFarEndCameraFeedback { get; private set; }
#endregion
#region IHasCameraAutoMode Members
private bool _CameraAutoModeIsOn;
public void CameraAutoModeOn()
{
_CameraAutoModeIsOn = true;
CameraAutoModeIsOnFeedback.FireUpdate();
}
public void CameraAutoModeOff()
{
_CameraAutoModeIsOn = false;
CameraAutoModeIsOnFeedback.FireUpdate();
}
public void CameraAutoModeToggle()
{
if(_CameraAutoModeIsOn)
_CameraAutoModeIsOn = false;
else
_CameraAutoModeIsOn = true;
CameraAutoModeIsOnFeedback.FireUpdate();
}
public BoolFeedback CameraAutoModeIsOnFeedback {get; private set;}
#endregion
#region IHasCameraPresets Members
public event EventHandler<EventArgs> CodecRoomPresetsListHasChanged;
public List<CodecRoomPreset> NearEndPresets { get; private set; }
public List<CodecRoomPreset> FarEndRoomPresets { get; private set; }
public void CodecRoomPresetSelect(int preset)
{
if (SelectedCamera is IAmFarEndCamera)
{
Debug.Console(1, this, "Selecting Far End Preset: {0}", preset);
}
else
{
Debug.Console(1, this, "Selecting Near End Preset: {0}", preset);
}
}
public void CodecRoomPresetStore(int preset, string description)
{
var editPreset = NearEndPresets.FirstOrDefault(p => p.ID.Equals(preset));
if (editPreset != null)
{
editPreset.Defined = true;
editPreset.Description = description;
}
else
NearEndPresets.Add(new CodecRoomPreset(preset, description, true, true));
var handler = CodecRoomPresetsListHasChanged;
if (handler != null)
{
handler(this, new EventArgs());
}
// Update the config
SetConfig(Config);
}
#endregion
protected override void CustomSetConfig(DeviceConfig config)
{
PropertiesConfig.Presets = NearEndPresets;
Config.Properties = JToken.FromObject(PropertiesConfig);
ConfigWriter.UpdateDeviceConfig(config);
}
}
/// <summary>
/// Implementation for the mock VC
/// </summary>
public class MockCodecInfo : VideoCodecInfo
{
public override bool MultiSiteOptionIsEnabled
{
get { return true; }
}
public override string E164Alias
{
get { return "someE164alias"; }
}
public override string H323Id
{
get { return "someH323Id"; }
}
public override string IpAddress
{
get { return "xxx.xxx.xxx.xxx"; }
}
public override string SipPhoneNumber
{
get { return "333-444-5555"; }
}
public override string SipUri
{
get { return "mock@someurl.com"; }
}
public override bool AutoAnswerEnabled
{
get { return _AutoAnswerEnabled; }
}
bool _AutoAnswerEnabled;
public void SetAutoAnswer(bool value)
{
_AutoAnswerEnabled = value;
}
}
}

View File

@@ -0,0 +1,250 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class MockVC : VideoCodecBase
{
public MockVC(string key, string name)
: base(key, name)
{
// 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);
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);
VolumeLevelFeedback.OutputChange += (o, a) => Debug.Console(1, this, "Volume={0}", _VolumeLevel);
}
protected override Func<int> ActiveCallCountFeedbackFunc
{
get { return () => ActiveCalls.Count; }
}
protected override Func<bool> IncomingCallFeedbackFunc
{
get { return () => _IncomingCall; }
}
bool _IncomingCall;
protected override Func<bool> MuteFeedbackFunc
{
get { return () => _IsMuted; }
}
bool _IsMuted;
protected override Func<bool> PrivacyModeIsOnFeedbackFunc
{
get { return () => _PrivacyModeIsOn; }
}
bool _PrivacyModeIsOn;
protected override Func<string> SharingSourceFeedbackFunc
{
get { return () => _SharingSource; }
}
string _SharingSource;
protected override Func<int> VolumeLevelFeedbackFunc
{
get { return () => _VolumeLevel; }
}
int _VolumeLevel;
/// <summary>
/// Dials, yo!
/// </summary>
public override void Dial(string s)
{
Debug.Console(1, this, "Dial: {0}", s);
ActiveCalls.Add(new CodecActiveCallItem(s,s, eCodecCallType.Video));
ActiveCallCountFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void EndCall(CodecActiveCallItem activeCall)
{
Debug.Console(1, this, "EndCall");
ActiveCalls.RemoveAll(i => i.Name == s);
ActiveCallCountFeedback.FireUpdate();
//_InCall = false;
//IsInCall.FireUpdate();
}
public override void EndAllCalls()
{
}
/// <summary>
/// For a call from the test methods below
/// </summary>
public override void AcceptCall()
{
Debug.Console(1, this, "AcceptCall");
}
/// <summary>
/// For a call from the test methods below
/// </summary>
public override void RejectCall()
{
Debug.Console(1, this, "RejectCall");
}
/// <summary>
/// Makes horrible tones go out on the wire!
/// </summary>
/// <param name="s"></param>
public override void SendDtmf(string s)
{
Debug.Console(1, this, "SendDTMF: {0}", s);
}
/// <summary>
///
/// </summary>
public override void StartSharing()
{
}
/// <summary>
///
/// </summary>
public override void StopSharing()
{
}
/// <summary>
/// Called by routing to make it happen
/// </summary>
/// <param name="selector"></param>
public override void ExecuteSwitch(object selector)
{
Debug.Console(1, this, "ExecuteSwitch");
_SharingSource = selector.ToString();
}
/// <summary>
///
/// </summary>
public override void MuteOff()
{
_IsMuted = false;
MuteFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void MuteOn()
{
_IsMuted = true;
MuteFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void MuteToggle()
{
_IsMuted = !_IsMuted;
MuteFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
/// <param name="level"></param>
public override void SetVolume(ushort level)
{
_VolumeLevel = level;
VolumeLevelFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
/// <param name="pressRelease"></param>
public override void VolumeDown(bool pressRelease)
{
}
/// <summary>
///
/// </summary>
/// <param name="pressRelease"></param>
public override void VolumeUp(bool pressRelease)
{
}
/// <summary>
///
/// </summary>
public override void PrivacyModeOn()
{
Debug.Console(1, this, "PrivacyMuteOn");
if (_PrivacyModeIsOn)
return;
_PrivacyModeIsOn = true;
PrivacyModeIsOnFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void PrivacyModeOff()
{
Debug.Console(1, this, "PrivacyMuteOff");
if (!_PrivacyModeIsOn)
return;
_PrivacyModeIsOn = false;
PrivacyModeIsOnFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public override void PrivacyModeToggle()
{
_PrivacyModeIsOn = !_PrivacyModeIsOn;
Debug.Console(1, this, "PrivacyMuteToggle: {0}", _PrivacyModeIsOn);
PrivacyModeIsOnFeedback.FireUpdate();
}
//********************************************************
// SIMULATION METHODS
/// <summary>
///
/// </summary>
/// <param name="url"></param>
public void TestIncomingCall(string url)
{
Debug.Console(1, this, "TestIncomingCall");
_IncomingCall = true;
IncomingCallFeedback.FireUpdate();
}
/// <summary>
///
/// </summary>
public void TestFarEndHangup()
{
Debug.Console(1, this, "TestFarEndHangup");
}
}
}

View File

@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
public class MockVCCamera : CameraBase, IHasCameraPtzControl, IHasCameraFocusControl
{
protected VideoCodecBase ParentCodec { get; private set; }
public MockVCCamera(string key, string name, VideoCodecBase codec)
: base(key, name)
{
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom | eCameraCapabilities.Focus;
ParentCodec = codec;
}
#region IHasCameraPtzControl Members
public void PositionHome()
{
Debug.Console(1, this, "Resetting to home position");
}
#endregion
#region IHasCameraPanControl Members
public void PanLeft()
{
Debug.Console(1, this, "Panning Left");
}
public void PanRight()
{
Debug.Console(1, this, "Panning Right");
}
public void PanStop()
{
Debug.Console(1, this, "Stopping Pan");
}
#endregion
#region IHasCameraTiltControl Members
public void TiltDown()
{
Debug.Console(1, this, "Tilting Down");
}
public void TiltUp()
{
Debug.Console(1, this, "Tilting Up");
}
public void TiltStop()
{
Debug.Console(1, this, "Stopping Tilt");
}
#endregion
#region IHasCameraZoomControl Members
public void ZoomIn()
{
Debug.Console(1, this, "Zooming In");
}
public void ZoomOut()
{
Debug.Console(1, this, "Zooming Out");
}
public void ZoomStop()
{
Debug.Console(1, this, "Stopping Zoom");
}
#endregion
#region IHasCameraFocusControl Members
public void FocusNear()
{
Debug.Console(1, this, "Focusing Near");
}
public void FocusFar()
{
Debug.Console(1, this, "Focusing Far");
}
public void FocusStop()
{
Debug.Console(1, this, "Stopping Focus");
}
public void TriggerAutoFocus()
{
Debug.Console(1, this, "AutoFocus Triggered");
}
#endregion
}
public class MockFarEndVCCamera : CameraBase, IHasCameraPtzControl, IAmFarEndCamera
{
protected VideoCodecBase ParentCodec { get; private set; }
public MockFarEndVCCamera(string key, string name, VideoCodecBase codec)
: base(key, name)
{
Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom;
ParentCodec = codec;
}
#region IHasCameraPtzControl Members
public void PositionHome()
{
Debug.Console(1, this, "Resetting to home position");
}
#endregion
#region IHasCameraPanControl Members
public void PanLeft()
{
Debug.Console(1, this, "Panning Left");
}
public void PanRight()
{
Debug.Console(1, this, "Panning Right");
}
public void PanStop()
{
Debug.Console(1, this, "Stopping Pan");
}
#endregion
#region IHasCameraTiltControl Members
public void TiltDown()
{
Debug.Console(1, this, "Tilting Down");
}
public void TiltUp()
{
Debug.Console(1, this, "Tilting Up");
}
public void TiltStop()
{
Debug.Console(1, this, "Stopping Tilt");
}
#endregion
#region IHasCameraZoomControl Members
public void ZoomIn()
{
Debug.Console(1, this, "Zooming In");
}
public void ZoomOut()
{
Debug.Console(1, this, "Zooming Out");
}
public void ZoomStop()
{
Debug.Console(1, this, "Stopping Zoom");
}
#endregion
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public class MockVcPropertiesConfig
{
[JsonProperty("favorites")]
public List<CodecActiveCallItem> Favorites { get; set; }
[JsonProperty("presets")]
public List<CodecRoomPreset> Presets { get; set; }
}
}

View File

@@ -0,0 +1,328 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Routing;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo
{
/// <summary>
/// Fires when the status of any active, dialing, or incoming call changes or is new
/// </summary>
public event EventHandler<CodecCallStatusItemChangeEventArgs> CallStatusChange;
public event EventHandler<EventArgs> IsReadyChange;
public IBasicCommunication Communication { get; protected set; }
#region IUsageTracking Members
/// <summary>
/// This object can be added by outside users of this class to provide usage tracking
/// for various services
/// </summary>
public UsageTracking UsageTracker { get; set; }
#endregion
/// <summary>
/// An internal pseudo-source that is routable and connected to the osd input
/// </summary>
public DummyRoutingInputsDevice OsdSource { get; protected set; }
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
/// <summary>
/// Returns true when any call is not in state Unknown, Disconnecting, Disconnected
/// </summary>
public bool IsInCall
{
get
{
bool value;
if (ActiveCalls != null)
value = ActiveCalls.Any(c => c.IsActiveCall);
else
value = false;
return value;
}
}
public BoolFeedback StandbyIsOnFeedback { get; private set; }
abstract protected Func<bool> PrivacyModeIsOnFeedbackFunc { get; }
abstract protected Func<int> VolumeLevelFeedbackFunc { get; }
abstract protected Func<bool> MuteFeedbackFunc { get; }
abstract protected Func<bool> StandbyIsOnFeedbackFunc { get; }
public List<CodecActiveCallItem> ActiveCalls { get; set; }
public VideoCodecInfo CodecInfo { get; protected set; }
public bool ShowSelfViewByDefault { get; protected set; }
public bool IsReady { get; protected set; }
public VideoCodecBase(DeviceConfig config)
: base(config)
{
StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc);
PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc);
VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc);
MuteFeedback = new BoolFeedback(MuteFeedbackFunc);
SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc);
SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc);
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
ActiveCalls = new List<CodecActiveCallItem>();
}
#region IHasDialer Members
public abstract void Dial(string number);
public abstract void Dial(Meeting meeting);
public virtual void Dial(IInvitableContact contact)
{
}
public abstract void EndCall(CodecActiveCallItem call);
public abstract void EndAllCalls();
public abstract void AcceptCall(CodecActiveCallItem call);
public abstract void RejectCall(CodecActiveCallItem call);
public abstract void SendDtmf(string s);
#endregion
public virtual List<Feedback> Feedbacks
{
get
{
return new List<Feedback>
{
PrivacyModeIsOnFeedback,
SharingSourceFeedback
};
}
}
public abstract void ExecuteSwitch(object selector);
/// <summary>
/// Helper method to fire CallStatusChange event with old and new status
/// </summary>
protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call)
{
call.Status = newStatus;
OnCallStatusChange(call);
}
/// <summary>
///
/// </summary>
/// <param name="previousStatus"></param>
/// <param name="newStatus"></param>
/// <param name="item"></param>
protected void OnCallStatusChange(CodecActiveCallItem item)
{
var handler = CallStatusChange;
if (handler != null)
handler(this, new CodecCallStatusItemChangeEventArgs(item));
if (AutoShareContentWhileInCall)
StartSharing();
if (UsageTracker != null)
{
if (IsInCall && !UsageTracker.UsageTrackingStarted)
UsageTracker.StartDeviceUsage();
else if (UsageTracker.UsageTrackingStarted && !IsInCall)
UsageTracker.EndDeviceUsage();
}
}
/// <summary>
/// Sets IsReady property and fires the event. Used for dependent classes to sync up their data.
/// </summary>
protected void SetIsReady()
{
IsReady = true;
var h = IsReadyChange;
if(h != null)
h(this, new EventArgs());
}
#region ICodecAudio Members
public abstract void PrivacyModeOn();
public abstract void PrivacyModeOff();
public abstract void PrivacyModeToggle();
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
public BoolFeedback MuteFeedback { get; private set; }
public abstract void MuteOff();
public abstract void MuteOn();
public abstract void SetVolume(ushort level);
public IntFeedback VolumeLevelFeedback { get; private set; }
public abstract void MuteToggle();
public abstract void VolumeDown(bool pressRelease);
public abstract void VolumeUp(bool pressRelease);
#endregion
#region IHasSharing Members
public abstract void StartSharing();
public abstract void StopSharing();
public bool AutoShareContentWhileInCall { get; protected set; }
public StringFeedback SharingSourceFeedback { get; private set; }
public BoolFeedback SharingContentIsOnFeedback { get; private set; }
abstract protected Func<string> SharingSourceFeedbackFunc { get; }
abstract protected Func<bool> SharingContentIsOnFeedbackFunc { get; }
#endregion
// **** DEBUGGING THINGS ****
/// <summary>
///
/// </summary>
public virtual void ListCalls()
{
var sb = new StringBuilder();
foreach (var c in ActiveCalls)
sb.AppendFormat("{0} {1} -- {2} {3}\n", c.Id, c.Number, c.Name, c.Status);
Debug.Console(1, this, "\n{0}\n", sb.ToString());
}
public abstract void StandbyActivate();
public abstract void StandbyDeactivate();
}
/// <summary>
/// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info
/// </summary>
public class CodecPhonebookSyncState : IKeyed
{
bool _InitialSyncComplete;
public event EventHandler<EventArgs> InitialSyncCompleted;
public string Key { get; private set; }
public bool InitialSyncComplete
{
get { return _InitialSyncComplete; }
private set
{
if (value == true)
{
var handler = InitialSyncCompleted;
if (handler != null)
handler(this, new EventArgs());
}
_InitialSyncComplete = value;
}
}
public bool InitialPhonebookFoldersWasReceived { get; private set; }
public bool NumberOfContactsWasReceived { get; private set; }
public bool PhonebookRootEntriesWasRecieved { get; private set; }
public bool PhonebookHasFolders { get; private set; }
public int NumberOfContacts { get; private set; }
public CodecPhonebookSyncState(string key)
{
Key = key;
CodecDisconnected();
}
public void InitialPhonebookFoldersReceived()
{
InitialPhonebookFoldersWasReceived = true;
CheckSyncStatus();
}
public void PhonebookRootEntriesReceived()
{
PhonebookRootEntriesWasRecieved = true;
CheckSyncStatus();
}
public void SetPhonebookHasFolders(bool value)
{
PhonebookHasFolders = value;
Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders);
}
public void SetNumberOfContacts(int contacts)
{
NumberOfContacts = contacts;
NumberOfContactsWasReceived = true;
Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts);
CheckSyncStatus();
}
public void CodecDisconnected()
{
InitialPhonebookFoldersWasReceived = false;
PhonebookHasFolders = false;
NumberOfContacts = 0;
NumberOfContactsWasReceived = false;
}
void CheckSyncStatus()
{
if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved)
{
InitialSyncComplete = true;
Debug.Console(1, this, "Initial Phonebook Sync Complete!");
}
else
InitialSyncComplete = false;
}
}
}

View File

@@ -0,0 +1,152 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public abstract class VideoCodecBase : Device, IRoutingSinkWithSwitching, IUsageTracking, IHasDialer, IHasSharing, ICodecAudio
{
#region IUsageTracking Members
/// <summary>
/// This object can be added by outside users of this class to provide usage tracking
/// for various services
/// </summary>
public UsageTracking UsageTracker { get; set; }
#endregion
#region IRoutingInputs Members
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
#endregion
/// <summary>
/// Returns true when ActiveCallCountFeedback is > 0
/// </summary>
public bool IsInCall { get { return ActiveCallCountFeedback.IntValue > 0; } }
public BoolFeedback IncomingCallFeedback { get; private set; }
public IntFeedback ActiveCallCountFeedback { get; private set; }
abstract protected Func<int> ActiveCallCountFeedbackFunc { get; }
abstract protected Func<bool> IncomingCallFeedbackFunc { get; }
abstract protected Func<bool> PrivacyModeIsOnFeedbackFunc { get; }
abstract protected Func<int> VolumeLevelFeedbackFunc { get; }
abstract protected Func<bool> MuteFeedbackFunc { get; }
abstract protected Func<string> SharingSourceFeedbackFunc { get; }
public List<CodecActiveCallItem> ActiveCalls { get; set; }
public VideoCodecBase(string key, string name)
: base(key, name)
{
ActiveCallCountFeedback = new IntFeedback(ActiveCallCountFeedbackFunc);
IncomingCallFeedback = new BoolFeedback(IncomingCallFeedbackFunc);
PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc);
VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc);
MuteFeedback = new BoolFeedback(MuteFeedbackFunc);
SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc);
InputPorts = new RoutingPortCollection<RoutingInputPort>();
ActiveCallCountFeedback.OutputChange += new EventHandler<EventArgs>(ActiveCallCountFeedback_OutputChange);
ActiveCalls = new List<CodecActiveCallItem>();
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ActiveCallCountFeedback_OutputChange(object sender, EventArgs e)
{
if (UsageTracker != null)
{
if (IsInCall)
UsageTracker.StartDeviceUsage();
else
UsageTracker.EndDeviceUsage();
}
}
#region IHasDialer Members
public abstract void Dial(string s);
<<<<<<< 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);
#endregion
public virtual List<Feedback> Feedbacks
{
get
{
return new List<Feedback>
{
IncomingCallFeedback,
PrivacyModeIsOnFeedback,
SharingSourceFeedback
};
}
}
public abstract void ExecuteSwitch(object selector);
#region ICodecAudio Members
public abstract void PrivacyModeOn();
public abstract void PrivacyModeOff();
public abstract void PrivacyModeToggle();
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
public BoolFeedback MuteFeedback { get; private set; }
public abstract void MuteOff();
public abstract void MuteOn();
public abstract void SetVolume(ushort level);
public IntFeedback VolumeLevelFeedback { get; private set; }
public abstract void MuteToggle();
public abstract void VolumeDown(bool pressRelease);
public abstract void VolumeUp(bool pressRelease);
#endregion
#region IHasSharing Members
public abstract void StartSharing();
public abstract void StopSharing();
public StringFeedback SharingSourceFeedback { get; private set; }
#endregion
}
}

View File

@@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Devices.Common.Cameras;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
public enum eZoomRoomCameraState
{
Start,
Continue,
Stop,
RequestRemote,
GiveupRemote,
RequestedByFarEnd
}
public enum eZoomRoomCameraAction
{
Left,
Right,
Up,
Down,
In,
Out
}
public class ZoomRoomCamera : CameraBase, IHasCameraPtzControl
{
protected ZoomRoom ParentCodec { get; private set; }
public int Id = 0; // ID of near end selected camara is always 0
private int ContinueTime = 10; // number of milliseconds between issuing continue commands
private CTimer ContinueTimer;
eZoomRoomCameraAction LastAction;
private bool isPanning;
private bool isTilting;
private bool isZooming;
private bool isFocusing;
private bool isMoving
{
get
{
return isPanning || isTilting || isZooming || isFocusing;
}
}
public ZoomRoomCamera(string key, string name, ZoomRoom codec)
: base(key, name)
{
ParentCodec = codec;
}
/// <summary>
/// Builds the command and triggers the parent ZoomRoom to send it
/// </summary>
/// <param name="id"></param>
/// <param name="state"></param>
/// <param name="action"></param>
void SendCommand(eZoomRoomCameraState state, eZoomRoomCameraAction action)
{
LastAction = action;
ParentCodec.SendText(string.Format("zCommand Call CameraControl Id: {0} State: {1} Action: {2}", Id, state, action));
}
void StartContinueTimer()
{
if(ContinueTimer == null)
ContinueTimer = new CTimer((o) => SendContinueAction(LastAction), ContinueTime);
}
void SendContinueAction(eZoomRoomCameraAction action)
{
SendCommand(eZoomRoomCameraState.Continue, action);
ContinueTimer.Reset();
}
void StopContinueTimer()
{
if (ContinueTimer != null)
{
ContinueTimer.Stop();
ContinueTimer.Dispose();
}
}
#region IHasCameraPtzControl Members
public void PositionHome()
{
throw new NotImplementedException();
}
#endregion
#region IHasCameraPanControl Members
public void PanLeft()
{
if (!isMoving)
{
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Left);
StartContinueTimer();
isPanning = true;
}
}
public void PanRight()
{
if (!isMoving)
{
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Right);
StartContinueTimer();
isPanning = true;
}
}
public void PanStop()
{
StopContinueTimer();
SendCommand(eZoomRoomCameraState.Stop, LastAction);
isPanning = false;
}
#endregion
#region IHasCameraTiltControl Members
public void TiltDown()
{
if (!isMoving)
{
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Down);
StartContinueTimer();
isTilting = true;
}
}
public void TiltUp()
{
if (!isMoving)
{
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Up);
StartContinueTimer();
isTilting = true;
}
}
public void TiltStop()
{
StopContinueTimer();
SendCommand(eZoomRoomCameraState.Stop, LastAction);
isTilting = false;
}
#endregion
#region IHasCameraZoomControl Members
public void ZoomIn()
{
if (!isMoving)
{
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.In);
StartContinueTimer();
isZooming = true;
}
}
public void ZoomOut()
{
if (!isMoving)
{
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Out);
StartContinueTimer();
isZooming = true;
}
}
public void ZoomStop()
{
StopContinueTimer();
SendCommand(eZoomRoomCameraState.Stop, LastAction);
isZooming = false;
}
#endregion
}
public class ZoomRoomFarEndCamera : ZoomRoomCamera, IAmFarEndCamera
{
public ZoomRoomFarEndCamera(string key, string name, ZoomRoom codec, int id)
: base(key, name, codec)
{
Id = id;
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
public class ZoomRoomPropertiesConfig
{
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
}
}