[asterisk-scf-commits] asterisk-scf/integration/sip.git branch "transfer" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Tue Oct 12 11:56:44 CDT 2010


branch "transfer" has been updated
       via  58a709ad3534c0d3b24c0e19314e3937a2516eda (commit)
      from  c3810529cf0895fc62a7f72d6de4b35ae495e979 (commit)

Summary of changes:
 src/PJSipSessionModule.cpp |   97 +++++++++++++++++++++++++++++++++++++------
 1 files changed, 83 insertions(+), 14 deletions(-)


- Log -----------------------------------------------------------------
commit 58a709ad3534c0d3b24c0e19314e3937a2516eda
Author: Joshua Colp <jcolp at digium.com>
Date:   Tue Oct 12 13:54:31 2010 -0300

    Add support for REFER with replaces for attended transfers. The REFER is properly handled and the session router called, but something still seems to be amuck.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index f8900ad..b7c28e8 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -418,26 +418,95 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
       return;
    }
 
-   pjsip_sip_uri *target_sip_uri = (pjsip_sip_uri *)target_uri;
-   std::string target = std::string(pj_strbuf(&target_sip_uri->user), pj_strlen(&target_sip_uri->user));
+   pjsip_sip_uri *target_sip_uri = (pjsip_sip_uri *)pjsip_uri_get_uri(target_uri);
 
-   // Now that we have the target user we can pass this into routing and go on our marry way
-   try
+   // Determine if this is a blind transfer or an attended transfer
+   pj_str_t replaces = pj_str((char*)"Replaces");
+   pjsip_param *replaces_param = pjsip_param_find(&target_sip_uri->other_param, &replaces);
+
+   if (replaces_param)
    {
+      pj_str_t to_tag = pj_str((char*)"To-tag");
+      pj_str_t from_tag = pj_str((char*)"From-tag");
+      pjsip_param *to_tag_param = pjsip_param_find(&target_sip_uri->other_param, &to_tag);
+      pjsip_param *from_tag_param = pjsip_param_find(&target_sip_uri->other_param, &from_tag);
+
+      if (!to_tag_param || !from_tag_param)
+      {
+	 pjsip_dlg_respond(inv->dlg, rdata, 400, NULL, NULL, NULL);
+	 return;
+      }
+
+      pjsip_dialog *other_dlg = pjsip_ua_find_dialog(&replaces_param->value, &to_tag_param->value, &from_tag_param->value, PJ_TRUE);
+
+      if (!other_dlg)
+      {
+	 pjsip_dlg_respond(inv->dlg, rdata, PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, NULL, NULL, NULL);
+	 return;
+      }
+
+      pjsip_inv_session *other_inv = pjsip_dlg_get_inv_session(other_dlg);
+
+      if (!other_inv)
+      {
+	 pjsip_dlg_respond(inv->dlg, rdata, PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, NULL, NULL, NULL);
+	 pjsip_dlg_dec_lock(other_dlg);
+	 return;
+      }
+
+      if (other_inv->state >= PJSIP_INV_STATE_DISCONNECTED)
+      {
+	 pjsip_dlg_respond(inv->dlg, rdata, PJSIP_SC_DECLINE, NULL, NULL, NULL);
+	 pjsip_dlg_dec_lock(other_dlg);
+	 return;
+      }
+
+      if (other_inv->state <= PJSIP_INV_STATE_EARLY && other_inv->role != PJSIP_ROLE_UAC)
+      {
+	 pjsip_dlg_respond(inv->dlg, rdata, PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, NULL, NULL, NULL);
+	 pjsip_dlg_dec_lock(other_dlg);
+	 return;
+      }
+
       PJSipSessionModInfo *session_mod_info = (PJSipSessionModInfo*)inv->mod_data[mModule.id];
       SipSessionPtr session = session_mod_info->getSessionPtr();
-      mSessionRouter->replaceSessionWithDestination(session->getSessionProxy(), target);
-      pjsip_dlg_respond(inv->dlg, rdata, 200, NULL, NULL, NULL);
-   }
-   catch (AsteriskSCF::Core::Routing::V1::DestinationNotFoundException&)
-   {
-      pjsip_dlg_respond(inv->dlg, rdata, 404, NULL, NULL, NULL);
-      return;
+
+      PJSipSessionModInfo *other_session_mod_info = (PJSipSessionModInfo*)other_inv->mod_data[mModule.id];
+      SipSessionPtr other_session = other_session_mod_info->getSessionPtr();
+
+      try
+      {
+	 mSessionRouter->replaceSessionWithSession(session->getSessionProxy(), other_session->getSessionProxy());
+	 pjsip_dlg_respond(inv->dlg, rdata, 200, NULL, NULL, NULL);
+      }
+      catch (...)
+      {
+	 pjsip_dlg_respond(inv->dlg, rdata, 400, NULL, NULL, NULL);
+      }
+      pjsip_dlg_dec_lock(other_dlg);
    }
-   catch (...)
+   else
    {
-      pjsip_dlg_respond(inv->dlg, rdata, 400, NULL, NULL, NULL);
-      return;
+      std::string target = std::string(pj_strbuf(&target_sip_uri->user), pj_strlen(&target_sip_uri->user));
+
+      // Now that we have the target user we can pass this into routing and go on our marry way
+      try
+      {
+	 PJSipSessionModInfo *session_mod_info = (PJSipSessionModInfo*)inv->mod_data[mModule.id];
+	 SipSessionPtr session = session_mod_info->getSessionPtr();
+	 mSessionRouter->replaceSessionWithDestination(session->getSessionProxy(), target);
+	 pjsip_dlg_respond(inv->dlg, rdata, 200, NULL, NULL, NULL);
+      }
+      catch (AsteriskSCF::Core::Routing::V1::DestinationNotFoundException&)
+      {
+	 pjsip_dlg_respond(inv->dlg, rdata, 404, NULL, NULL, NULL);
+	 return;
+      }
+      catch (...)
+      {
+	 pjsip_dlg_respond(inv->dlg, rdata, 400, NULL, NULL, NULL);
+	 return;
+      }
    }
 }
 

-----------------------------------------------------------------------


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list