public void AddHandler(CSTACommand handler) { lock (commands) { commands.Add(handler.commandName, handler); } }
public async Task <int> ExecuteHandler(string cmdName, Dictionary <string, string> parameters) { object cmd; if (commands.TryGetValue(cmdName, out cmd)) { CSTACommand command = (CSTACommand)cmd; command.parameters = parameters; int sequence = await sendText(command.cmdBody()); return(sequence); } return(-1); }
/// <summary> /// Find registered CSTA command handler /// </summary> /// <param name="cmdName">CSTA command name</param> /// <returns>A CSTA command handler or null</returns> private CSTACommand findCommand(string cmdName) { foreach (var pair in commands) { CSTACommand cmd = (CSTACommand)pair.Value; if (cmd.events != null && cmd.events.ContainsKey(cmdName)) { cmd.eventName = cmdName; cmd.events[cmdName] = new Dictionary <string, object>(); return(cmd); } } return(null); }
/// <summary> /// Internal function for processing incomming CSTA messages /// </summary> /// <param name="squenceStr">CSTA command squence number string</param> /// <param name="messageStr">CSTA command message string</param> /// <returns></returns> private async Task parseMessage(string sequnceStr, string messageStr) { Debug.WriteLine("CSTA", messageStr); using (XmlReader reader = XmlReader.Create(new System.IO.StringReader(messageStr))) { CSTACommand command = null; string nodeName = null; string closedName = null; Dictionary <string, object> elementValues = null; List <object> list = new List <object>(); List <object> curList = null; while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: // Debug.WriteLine("Start Element", reader.Name); if (command == null) { command = findCommand(reader.Name); if (command != null) { if (command.events != null) { elementValues = (Dictionary <string, object>)command.events[command.eventName]; } else { elementValues = null; } } else { elementValues = null; } } else { if (elementValues != null) { if (list.Count == 0 || curList == null) { curList = new List <object>(); elementValues.Add(reader.Name, curList); list.Add(elementValues); closedName = reader.Name; } if (reader.Name == closedName) { Dictionary <string, object> newValues = new Dictionary <string, object>(); curList.Add(newValues); elementValues = newValues; closedName = null; } } } if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { if (elementValues != null) { elementValues.Add(reader.Name, reader.Value); } // Debug.WriteLine(String.Format(" {0} = {1}", reader.Name, reader.Value)); } // Move the reader back to the element node. reader.MoveToElement(); } nodeName = reader.Name; break; case XmlNodeType.Text: if (elementValues != null) { elementValues.Add(nodeName, reader.Value); } // Debug.WriteLine("Text Node", reader.Value); break; case XmlNodeType.EndElement: closedName = reader.Name; if (elementValues != null) { if (list.Count > 0 && curList[curList.Count - 1] != elementValues) { elementValues = (Dictionary <string, object>)list[list.Count - 1]; list.RemoveAt(list.Count - 1); } } // Debug.WriteLine("End Element", reader.Name); break; // default: // Debug.WriteLine(String.Format("Other node {0} with value {1}", // reader.NodeType, reader.Value)); // break; } } if (command != null) { if (command.eventName == "loginFailed") // Internal processing for special case of loginFailed { LoginCommand loginCmd = (LoginCommand)command; elementValues = (Dictionary <string, object>)command.events[command.eventName]; if (!loginCmd.clearTextPassword && elementValues.ContainsKey("apilevel") && elementValues.ContainsKey("Code")) { int apiversion = 0; int code = -1; bool parsed = Int32.TryParse(elementValues["apiversion"].ToString(), out apiversion); parsed = parsed & Int32.TryParse(elementValues["Code"].ToString(), out code); if (parsed && apiversion >= 2 && code == 4) // Handle cleartext login for LDAP integration { // clear old results loginCmd.eventName = null; loginCmd.events["loginFailed"] = null; // set cleartext flag loginCmd.clearTextPassword = true; await sendText(loginCmd.cmdBody()); return; // do not send envent until second login attempt will be done } } } else if (command.eventName == "Logout") { elementValues = (Dictionary <string, object>)command.events[command.eventName]; if (elementValues.ContainsKey("mode") && (elementValues["mode"].ToString() == "forced")) { await Disconnect(); throw new ApplicationException("Socket disconnected by server"); } } /////////////////////////////////////////////////////////////// // Best place to notify UI regarding new message is here... EventHandler handler = cstaEvent; if (handler != null && command != null) { int numValue; bool parsed = Int32.TryParse(sequnceStr, out numValue); if (!parsed) { numValue = 9999; } handler(this, new CSTAEventArgs(command.eventName, numValue, (Dictionary <string, object>)command.events[command.eventName])); } } } }