/// <summary> /// Constructs an instance of ManagerResponse based on a map of attributes. /// </summary> /// <param name="attributes">the attributes and their values. The keys of this map must be all lower case.</param> /// <returns>the response with the given attributes.</returns> internal static ManagerResponse BuildResponse(Dictionary<string, string> attributes) { ManagerResponse response; string responseType = ((string)attributes["response"]).ToLower(Helper.CultureInfo); // Determine type if (responseType == "error") response = new ManagerError(); else if (attributes.ContainsKey("challenge")) response = new ChallengeResponse(); else if (attributes.ContainsKey("mailbox") && attributes.ContainsKey("waiting")) response = new MailboxStatusResponse(); else if (attributes.ContainsKey("mailbox") && attributes.ContainsKey("newmessages") && attributes.ContainsKey("oldmessages")) response = new MailboxCountResponse(); else if (attributes.ContainsKey("exten") && attributes.ContainsKey("context") && attributes.ContainsKey("hint") && attributes.ContainsKey("status")) response = new ExtensionStateResponse(); else response = new ManagerResponse(); Helper.SetAttributes(response, attributes); return response; }
internal void DispatchResponse(Dictionary<string, string> buffer, ManagerResponse response) { string responseActionId = string.Empty; string actionId = string.Empty; IResponseHandler responseHandler = null; if (buffer != null) { if (buffer["response"].ToLower(Helper.CultureInfo) == "error") response = new ManagerError(buffer); else if (buffer.ContainsKey("actionid")) actionId = buffer["actionid"]; } if (response != null) actionId = response.ActionId; if (!string.IsNullOrEmpty(actionId)) { int hash = Helper.GetInternalActionId(actionId).GetHashCode(); responseActionId = Helper.StripInternalActionId(actionId); responseHandler = GetRemoveResponseHandler(hash); if (response != null) response.ActionId = responseActionId; if (responseHandler != null) { if (response == null) { ManagerActionResponse action = responseHandler.Action as ManagerActionResponse; if (action == null || (response = action.ActionCompleteResponseClass() as ManagerResponse) == null) response = Helper.BuildResponse(buffer); else Helper.SetAttributes(response, buffer); response.ActionId = responseActionId; } try { responseHandler.HandleResponse(response); } catch (Exception ex) { #if LOGGER logger.Error("Unexpected exception in responseHandler {0}\n{1}", response, ex); #else throw new ManagerException("Unexpected exception in responseHandler " + responseHandler.GetType().FullName, ex); #endif } } } if (response == null && buffer.ContainsKey("ping") && buffer["ping"] == "Pong") { response = Helper.BuildResponse(buffer); foreach (ResponseHandler pingHandler in pingHandlers.Values) pingHandler.HandleResponse(response); pingHandlers.Clear(); } if (!reconnected) return; if (response == null) { response = Helper.BuildResponse(buffer); response.ActionId = responseActionId; } #if LOGGER logger.Info("Reconnected - DispatchEvent : " + response); #endif #region Support background reconnect if (response is ChallengeResponse) { string key = null; if (response.IsSuccess()) { ChallengeResponse challengeResponse = (ChallengeResponse)response; string challenge = challengeResponse.Challenge; try { Util.MD5Support md = Util.MD5Support.GetInstance(); if (challenge != null) md.Update(UTF8Encoding.UTF8.GetBytes(challenge)); if (password != null) md.Update(UTF8Encoding.UTF8.GetBytes(password)); key = Helper.ToHexString(md.DigestData); } #if LOGGER catch (Exception ex) { logger.Error("Unable to create login key using MD5 Message Digest", ex); #else catch { #endif key = null; } } bool fail = true; if (!string.IsNullOrEmpty(key)) try { Action.LoginAction loginAction = new Action.LoginAction(username, "MD5", key); SendAction(loginAction, null); fail = false; } catch { } if (fail) if (keepAliveAfterAuthenticationFailure) reconnect(true); else disconnect(true); } else if (response is ManagerError) { if (keepAliveAfterAuthenticationFailure) reconnect(true); else disconnect(true); } else if (response is ManagerResponse) { if (response.IsSuccess()) { reconnected = false; enableEvents = true; reconnectEnable = keepAlive; ConnectEvent ce = new ConnectEvent(this); ce.Reconnect = true; ce.ProtocolIdentifier = protocolIdentifier; fireEvent(ce); } else if (keepAliveAfterAuthenticationFailure) reconnect(true); else disconnect(true); } #endregion }