private SIPDialogue SendCallRequest(string forwardingNumber, string destinationNumber, int phoneType, int waitForCallbackTimeout, string contentType, string body) { try { int callbackTimeout = (waitForCallbackTimeout < MIN_CALLBACK_TIMEOUT || waitForCallbackTimeout > MAX_CALLBACK_TIMEOUT) ? WAIT_FOR_CALLBACK_TIMEOUT : waitForCallbackTimeout; CallbackWaiter callbackWaiter = new CallbackWaiter(m_username, CallbackWaiterEnum.GoogleVoice, forwardingNumber, MatchIncomingCall); m_callManager.AddWaitingApplication(callbackWaiter); string callData = "outgoingNumber=" + Uri.EscapeDataString(destinationNumber) + "&forwardingNumber=" + Uri.EscapeDataString(forwardingNumber) + "&subscriberNumber=undefined&remember=0&_rnr_se=" + Uri.EscapeDataString(m_rnrKey) + "&phoneType=" + phoneType; //logger.Debug("call data=" + callData + "."); // Build the call request. HttpWebRequest callRequest = (HttpWebRequest)WebRequest.Create(VOICE_CALL_URL); callRequest.ConnectionGroupName = "call"; callRequest.CookieContainer = m_cookies; callRequest.Method = "POST"; callRequest.ContentType = "application/x-www-form-urlencoded;charset=utf-8"; callRequest.ContentLength = callData.Length; callRequest.GetRequestStream().Write(Encoding.UTF8.GetBytes(callData), 0, callData.Length); callRequest.Timeout = HTTP_REQUEST_TIMEOUT * 1000; HttpWebResponse response = (HttpWebResponse)callRequest.GetResponse(); HttpStatusCode responseStatus = response.StatusCode; response.Close(); if (responseStatus != HttpStatusCode.OK) { throw new ApplicationException("The call request failed with a " + responseStatus + " response."); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Google Voice Call to " + destinationNumber + " initiated, callback #" + forwardingNumber + ", phone type " + phoneType + ", timeout " + callbackTimeout + "s.", m_username)); } if (m_waitForCallback.WaitOne(callbackTimeout * 1000)) { if (!m_hasBeenCancelled) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Google Voice Call callback received.", m_username)); return m_callbackCall.Answer(contentType, body, null, SIPDialogueTransferModesEnum.Default); } else { return null; } } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Google Voice Call timed out waiting for callback.", m_username)); CancelCall(); return null; } } catch (Exception excp) { logger.Error("Exception GoogleVoiceCall SendCallRequest. " + excp.Message); throw; } }
public void AddWaitingApplication(CallbackWaiter callbackWaiter) { lock (m_waitingForCallbacks) { if (m_waitingForCallbacks.ContainsKey(callbackWaiter.UniqueId)) { m_waitingForCallbacks[callbackWaiter.UniqueId] = callbackWaiter; } else { m_waitingForCallbacks.Add(callbackWaiter.UniqueId, callbackWaiter); } } if (m_dispatcherProxy.Count > 0) { // Register wil the SIP proxies to get the next call for the owning user directed to this application server. ThreadPool.QueueUserWorkItem(delegate { try { foreach (CallDispatcherProxy proxy in m_dispatcherProxy.Values) { if (proxy.State != CommunicationState.Faulted) { proxy.SetNextCallDest(callbackWaiter.Owner, m_sipTransport.GetDefaultSIPEndPoint().ToString()); } } } catch (Exception excp) { logger.Error("Exception SIPCallManager AddWaitingApplication. " + excp.Message); } }); } }