diff --git a/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs b/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs index 6a920e82..75c28f7e 100644 --- a/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs +++ b/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs @@ -15,16 +15,16 @@ namespace PepperDash.Essentials.Devices.Common.Codec void SearchDirectory(string searchString); - void GetFolderContents(string folderId); + void GetDirectoryFolderContents(string folderId); } public class CodecDirectory { public List DirectoryResults { get; private set; } - public int Offset { get; private set; } + //public int Offset { get; private set; } - public int Limit { get; private set; } + //public int Limit { get; private set; } public CodecDirectory() { @@ -79,12 +79,11 @@ namespace PepperDash.Essentials.Devices.Common.Codec { public List Contacts { get; set; } public string FolderId { get; set; } - public DirectoryFolder ParentFolder { get; set; } + public string ParentFolderId { get; set; } public DirectoryFolder() { Contacts = new List(); - ParentFolder = new DirectoryFolder(); } } @@ -94,6 +93,11 @@ namespace PepperDash.Essentials.Devices.Common.Codec public string FolderId { get; set; } public string Title { get; set; } public List ContactMethods { get; set; } + + public DirectoryContact() + { + ContactMethods = new List(); + } } public class ContactMethod diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs index 55bf355c..8548be4a 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodec.cs @@ -162,6 +162,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco int PhonebookResultsLimit = 255; // Could be set later by config. + CTimer LoginMessageReceived; + // Constructor for IBasicCommunication public CiscoCodec(string key, string name, IBasicCommunication comm, CiscoCodecPropertiesConfig props ) : base(key, name) @@ -173,6 +175,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco Communication = comm; + LoginMessageReceived = new CTimer(DisconnectClientAndReconnect, 5000); + if (props.CommunicationMonitorProperties != null) { CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties); @@ -228,7 +232,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { CrestronConsole.AddNewConsoleCommand(SendText, "send" + Key, "", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCiscoCommDebug", "0 for Off, 1 for on", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(GetPhonebook, "GetCodecPhonebook", "Triggers a refresh of the codec phonebook", ConsoleAccessLevelEnum.AccessOperator); + CommDebuggingIsOn = true; Communication.Connect(); var socket = Communication as ISocketStatus; if (socket != null) @@ -265,12 +271,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// void SyncState_InitialSyncCompleted(object sender, EventArgs e) { + CommDebuggingIsOn = false; + GetCallHistory(); // Get bookings for the day //SendText("xCommand Bookings List Days: 1 DayOffset: 0"); - GetPhonebookFolders(); + GetPhonebook(null); } public void SetCommDebug(string s) @@ -289,13 +297,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) { - if (!e.Client.IsConnected) + if (e.Client.IsConnected) + { + //LoginMessageReceived.Reset(); + } + else { SyncState.CodecDisconnected(); PhonebookSyncState.CodecDisconnected(); } } + void DisconnectClientAndReconnect(object o) + { + Debug.Console(0, this, "Disconnecting and Reconnecting to codec."); + + Communication.Disconnect(); + + CrestronEnvironment.Sleep(2000); + + Communication.Connect(); + } + /// /// Gathers responses from the codec (including the delimiter. Responses are checked to see if they contain JSON data and if so, the data is collected until a complete JSON /// message is received before forwarding the message to be deserialized. @@ -347,6 +370,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { case "*r login successful": { + //LoginMessageReceived.Stop(); SendText("xPreferences outputmode json"); break; } @@ -514,18 +538,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } else if (response.IndexOf("\"PhonebookSearchResult\":{") > -1) { - var codecPhonebook = new CiscoCodecPhonebook.RootObject(); + var codecPhonebookResponse = new CiscoCodecPhonebook.RootObject(); - if (!PhonebookSyncState.InitialPhonebookMessageWasReceived) + JsonConvert.PopulateObject(response, codecPhonebookResponse); + + if (!PhonebookSyncState.InitialPhonebookFoldersWasReceived) { // Check if the phonebook has any folders - PhonebookSyncState.InitialPhonebookMessageReceived(); + PhonebookSyncState.InitialPhonebookFoldersReceived(); - PhonebookSyncState.SetPhonebookHasFolders(codecPhonebook.CommandResponse.PhonebookSearchResult.Folder.Count > 0); + PhonebookSyncState.SetPhonebookHasFolders(codecPhonebookResponse.CommandResponse.PhonebookSearchResult.Folder.Count > 0); if (PhonebookSyncState.PhonebookHasFolders) { - DirectoryRoot.AddFoldersToDirectory(CiscoCodecPhonebook.GetRootFoldersFromSearchResult(codecPhonebook.CommandResponse.PhonebookSearchResult)); + DirectoryRoot.AddFoldersToDirectory(CiscoCodecPhonebook.GetRootFoldersFromSearchResult(codecPhonebookResponse.CommandResponse.PhonebookSearchResult)); } // Get the number of contacts in the phonebook @@ -534,18 +560,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco else if (!PhonebookSyncState.NumberOfContactsWasReceived) { // Store the total number of contacts in the phonebook - PhonebookSyncState.SetNumberOfContacts(Int32.Parse(codecPhonebook.CommandResponse.PhonebookSearchResult.ResultInfo.TotalRows.Value)); + PhonebookSyncState.SetNumberOfContacts(Int32.Parse(codecPhonebookResponse.CommandResponse.PhonebookSearchResult.ResultInfo.TotalRows.Value)); - DirectoryRoot.AddContactsToDirectory(CiscoCodecPhonebook.GetRootContactsFromSearchResult(codecPhonebook.CommandResponse.PhonebookSearchResult)); + DirectoryRoot.AddContactsToDirectory(CiscoCodecPhonebook.GetRootContactsFromSearchResult(codecPhonebookResponse.CommandResponse.PhonebookSearchResult)); + + PhonebookSyncState.PhonebookRootEntriesReceived(); + + PrintPhonebook(DirectoryRoot); } else if (PhonebookSyncState.InitialSyncComplete) { - JsonConvert.PopulateObject(response, codecPhonebook); + var directoryResults = new CodecDirectory(); - if (Debug.Level > 1) - { - //Print phonebook contents - } + directoryResults = CiscoCodecPhonebook.ConvertCiscoPhonebookToGeneric(codecPhonebookResponse.CommandResponse.PhonebookSearchResult); + + PrintPhonebook(directoryResults); // Fire some sort of callback delegate to the UI that requested the directory search results } @@ -620,6 +649,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco SendText("xCommand CallHistory Recents Limit: 20 Order: OccurrenceTime"); } + /// + /// Triggers a refresh of the codec phonebook + /// + /// Just to allow this method to be called from a console command + public void GetPhonebook(string command) + { + PhonebookSyncState.CodecDisconnected(); + + GetPhonebookFolders(); + } + private void GetPhonebookFolders() { // Get Phonebook Folders (determine local/corporate from config, and set results limit) @@ -638,16 +678,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public void SearchDirectory(string searchString) { - SendText(string.Format("xCommand Phonebook Search SearchString: \"{0}\" PhonebookType: {1} ContactType: Contact, Limit: {2}", searchString, PhonebookMode, PhonebookResultsLimit)); + SendText(string.Format("xCommand Phonebook Search SearchString: \"{0}\" PhonebookType: {1} ContactType: Contact Limit: {2}", searchString, PhonebookMode, PhonebookResultsLimit)); } /// /// // Get contents of a specific folder in the phonebook /// /// - public void GetFolderContents(string folderId) + public void GetDirectoryFolderContents(string folderId) { - SendText(string.Format("xCommand Phonebook Search FolderId: {0} PhonebookType: {1} ContactType: Contact, Limit: {2}", folderId, PhonebookMode, PhonebookResultsLimit)); + SendText(string.Format("xCommand Phonebook Search FolderId: {0} PhonebookType: {1} ContactType: Contact Limit: {2}", folderId, PhonebookMode, PhonebookResultsLimit)); + } + + void PrintPhonebook(CodecDirectory directory) + { + if (Debug.Level > 0) + { + Debug.Console(1, this, "Directory Results:\n"); + + foreach (DirectoryItem item in directory.DirectoryResults) + { + if (item is DirectoryFolder) + { + Debug.Console(1, this, "+ {0}", item.Name); + } + else if (item is DirectoryContact) + { + Debug.Console(1, this, "{0}", item.Name); + } + } + } } public override void Dial(string s) @@ -929,11 +989,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } - - public bool InitialPhonebookMessageWasReceived { get; private set; } + 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; } @@ -945,9 +1006,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecDisconnected(); } - public void InitialPhonebookMessageReceived() + public void InitialPhonebookFoldersReceived() { - InitialPhonebookMessageWasReceived = true; + InitialPhonebookFoldersWasReceived = true; + + CheckSyncStatus(); + } + + public void PhonebookRootEntriesReceived() + { + PhonebookRootEntriesWasRecieved = true; + + CheckSyncStatus(); } public void SetPhonebookHasFolders(bool value) @@ -963,15 +1033,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco NumberOfContactsWasReceived = true; Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts); + + CheckSyncStatus(); } public void CodecDisconnected() { - InitialPhonebookMessageWasReceived = false; + 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; + } } } \ No newline at end of file diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/PhonebookDataClasses.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/PhonebookDataClasses.cs index a5be6309..c5e47d31 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/PhonebookDataClasses.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/PhonebookDataClasses.cs @@ -157,13 +157,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { var rootFolders = new List(); - if (result.Folder.Count > 0) + if (result.Folder.Count == 0) { return null; } else if (result.Folder.Count > 0) { - if (Debug.Level > 1) + if (Debug.Level > 0) Debug.Console(1, "Phonebook Folders:\n"); foreach (Folder f in result.Folder) @@ -176,7 +176,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec if (f.ParentFolderId == null) rootFolders.Add(folder); - if (Debug.Level > 1) + if (Debug.Level > 0) Debug.Console(1, "+ {0}", folder.Name); } } @@ -187,6 +187,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } + /// + /// Extracts the contacts with no FolderId and returns them sorted alphabetically + /// + /// + /// public static List GetRootContactsFromSearchResult(PhonebookSearchResult result) { var rootContacts = new List(); @@ -197,22 +202,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } else if (result.Contact.Count > 0) { - if (Debug.Level > 1) + if (Debug.Level > 0) Debug.Console(1, "Root Contacts:\n"); foreach (Contact c in result.Contact) { var contact = new DirectoryContact(); - if (c.FolderId == null) { contact.Name = c.Name.Value; contact.ContactId = c.ContactId.Value; contact.Title = c.Title.Value; - contact.FolderId = c.FolderId.Value; - if (Debug.Level == 1) + if (Debug.Level > 0) Debug.Console(1, "{0}\nContact Methods:", contact.Name); foreach (ContactMethod m in c.ContactMethod) @@ -237,7 +240,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec else if (m.Device.Value.ToLower() == "other") device = eContactMethodDevice.Other; - if (Debug.Level > 1) + if (Debug.Level > 0) Debug.Console(1, "Number: {0} CallType: {1} Device: {2}", m.Number.Value, callType, device); contact.ContactMethods.Add(new PepperDash.Essentials.Devices.Common.Codec.ContactMethod() @@ -248,12 +251,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Device = device }); } - rootContacts.Add(contact); } - - if (Debug.Level == 1) - Debug.Console(1, "{0}", contact.Name); } } @@ -274,9 +273,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec #warning Modify this to return a flat list of mixed folders/contacts var directory = new Codec.CodecDirectory(); - var folders = new List(); + var folders = new List(); - var contacts = new List(); + var contacts = new List(); if (result.Folder.Count > 0) { @@ -290,11 +289,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec if (f.ParentFolderId != null) { // - folder.ParentFolder = folders.FirstOrDefault(fld => fld.FolderId.Equals(f.ParentFolderId.Value)); + folder.ParentFolderId = f.ParentFolderId.Value; } folders.Add(folder); } + + folders.OrderBy(f => f.Name); + + directory.AddFoldersToDirectory(folders); } if (result.Contact.Count > 0) @@ -343,9 +346,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Device = device }); } - //directory.Contacts.Add(contact); + contacts.Add(contact); } + contacts.OrderBy(c => c.Name); + + directory.AddContactsToDirectory(contacts); } return directory;