/// <summary> /// Matches specified SIP response to SIP dialog. If no matching dialog found, returns null. /// </summary> /// <param name="response">SIP response.</param> /// <returns>Returns matched SIP dialog or null in no match found.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>response</b> is null.</exception> internal SIP_Dialog MatchDialog(SIP_Response response) { if (response == null) { throw new ArgumentNullException("response"); } SIP_Dialog dialog = null; try{ string callID = response.CallID; string fromTag = response.From.Tag; string toTag = response.To.Tag; if (callID != null && fromTag != null && toTag != null) { string dialogID = callID + "-" + fromTag + "-" + toTag; lock (m_pDialogs){ m_pDialogs.TryGetValue(dialogID, out dialog); } } } catch { } return(dialog); }
/// <summary> /// Matches specified SIP request to SIP dialog. If no matching dialog found, returns null. /// </summary> /// <param name="request">SIP request.</param> /// <returns>Returns matched SIP dialog or null in no match found.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>request</b> is null.</exception> internal SIP_Dialog MatchDialog(SIP_Request request) { if (request == null) { throw new ArgumentNullException("request"); } SIP_Dialog dialog = null; try{ string callID = request.CallID; string localTag = request.To.Tag; string remoteTag = request.From.Tag; if (callID != null && localTag != null && remoteTag != null) { string dialogID = callID + "-" + localTag + "-" + remoteTag; lock (m_pDialogs){ m_pDialogs.TryGetValue(dialogID, out dialog); } } } catch { } return(dialog); }
/// <summary> /// Gets existing or creates new dialog. /// </summary> /// <param name="transaction">Owner transaction what forces to create dialog.</param> /// <param name="response">Response what forces to create dialog.</param> /// <returns>Returns dialog.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>transaction</b> or <b>response</b> is null.</exception> public SIP_Dialog GetOrCreateDialog(SIP_Transaction transaction, SIP_Response response) { if (transaction == null) { throw new ArgumentNullException("transaction"); } if (response == null) { throw new ArgumentNullException("response"); } string dialogID = ""; if (transaction is SIP_ServerTransaction) { dialogID = response.CallID + "-" + response.To.Tag + "-" + response.From.Tag; } else { dialogID = response.CallID + "-" + response.From.Tag + "-" + response.To.Tag; } lock (m_pDialogs){ SIP_Dialog dialog = null; m_pDialogs.TryGetValue(dialogID, out dialog); // Dialog doesn't exist, create it. if (dialog == null) { if (response.CSeq.RequestMethod.ToUpper() == SIP_Methods.INVITE) { dialog = new SIP_Dialog_Invite(); } else if (response.CSeq.RequestMethod.ToUpper() == SIP_Methods.REFER) { dialog = new SIP_Dialog_Refer(); } else { throw new ArgumentException("Method '" + response.CSeq.RequestMethod + "' has no dialog handler."); } dialog.Init(m_pStack, transaction, response); dialog.StateChanged += delegate(object s, EventArgs a){ if (dialog.State == SIP_DialogState.Terminated) { m_pDialogs.Remove(dialog.ID); } }; m_pDialogs.Add(dialog.ID, dialog); } return(dialog); } }
/// <summary> /// Creates new client transaction. /// </summary> /// <param name="flow">SIP data flow which is used to send request.</param> /// <param name="request">SIP request that transaction will handle.</param> /// <param name="addVia">If true, transaction will add <b>Via:</b> header, otherwise it's user responsibility.</param> /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>flow</b> or <b>request</b> is null reference.</exception> /// <returns>Returns created transaction.</returns> public SIP_ClientTransaction CreateClientTransaction(SIP_Flow flow, SIP_Request request, bool addVia) { if (m_IsDisposed) { throw new ObjectDisposedException(this.GetType().Name); } if (flow == null) { throw new ArgumentNullException("flow"); } if (request == null) { throw new ArgumentNullException("request"); } // Add Via: if (addVia) { SIP_t_ViaParm via = new SIP_t_ViaParm(); via.ProtocolName = "SIP"; via.ProtocolVersion = "2.0"; via.ProtocolTransport = flow.Transport; via.SentBy = new HostEndPoint("transport_layer_will_replace_it", -1); via.Branch = SIP_t_ViaParm.CreateBranch(); via.RPort = 0; request.Via.AddToTop(via.ToStringValue()); } lock (m_pClientTransactions){ SIP_ClientTransaction transaction = new SIP_ClientTransaction(m_pStack, flow, request); m_pClientTransactions.Add(transaction.Key, transaction); transaction.StateChanged += new EventHandler(delegate(object s, EventArgs e){ if (transaction.State == SIP_TransactionState.Terminated) { lock (m_pClientTransactions){ m_pClientTransactions.Remove(transaction.Key); } } }); SIP_Dialog dialog = MatchDialog(request); if (dialog != null) { dialog.AddTransaction(transaction); } return(transaction); } }
/// <summary> /// Creates new SIP server transaction for specified request. /// </summary> /// <param name="flow">SIP data flow which is used to receive request.</param> /// <param name="request">SIP request.</param> /// <returns>Returns added server transaction.</returns> /// <exception cref="ObjectDisposedException">Is raised when this class is Disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>flow</b> or <b>request</b> is null reference.</exception> public SIP_ServerTransaction CreateServerTransaction(SIP_Flow flow, SIP_Request request) { if (m_IsDisposed) { throw new ObjectDisposedException(this.GetType().Name); } if (flow == null) { throw new ArgumentNullException("flow"); } if (request == null) { throw new ArgumentNullException("request"); } lock (m_pServerTransactions){ SIP_ServerTransaction transaction = new SIP_ServerTransaction(m_pStack, flow, request); m_pServerTransactions.Add(transaction.Key, transaction); transaction.StateChanged += new EventHandler(delegate(object s, EventArgs e){ if (transaction.State == SIP_TransactionState.Terminated) { lock (m_pClientTransactions){ m_pServerTransactions.Remove(transaction.Key); } } }); SIP_Dialog dialog = MatchDialog(request); if (dialog != null) { dialog.AddTransaction(transaction); } return(transaction); } }
/// <summary> /// Removes specified dialog from dialogs collection. /// </summary> /// <param name="dialog">SIP dialog to remove.</param> internal void RemoveDialog(SIP_Dialog dialog) { lock (m_pDialogs){ m_pDialogs.Remove(dialog.ID); } }