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

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Thu Jul 14 16:34:43 CDT 2011


branch "transfer-improvements" has been created
        at  4154f52ef1a545783458dcc089d359dab49598b2 (commit)

- Log -----------------------------------------------------------------
commit 4154f52ef1a545783458dcc089d359dab49598b2
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Jul 14 16:04:25 2011 -0500

    Make helper functions for creating NOTIFY requests and their sipfrag bodies.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 1ce2612..d11176c 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -712,8 +712,6 @@ protected:
                     return Complete;
                 }
 
-                lg(Debug) << "to: " << to << " from: " << from << " replaces: " << replaces;
-
                 pj_str_t to_tag_str = pj_str((char*)to.c_str());
                 pj_str_t from_tag_str = pj_str((char*)from.c_str());
                 pj_str_t replaces_tag_str = pj_str((char*)replaces.c_str());
@@ -829,23 +827,9 @@ protected:
 
         // We need to send a NOTIFY to indicate how things went on the other leg.
         // XXX Once we have a subscription module written, we can actually use it.
-        pjsip_tx_data *tdata;
-        pjsip_dlg_create_request(mInv->dlg, pjsip_get_notify_method(), -1, &tdata);
-        pjsip_event_hdr *event = pjsip_event_hdr_create(tdata->pool);
-        pj_cstr(&event->event_type, "refer");
-        char idbuf[20];
-        pj_ansi_snprintf(idbuf, sizeof(idbuf), "%d", mReferCSeq);
-        pj_cstr(&event->id_param, idbuf);
-        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) event);
-        pjsip_sub_state_hdr *subState = pjsip_sub_state_hdr_create(tdata->pool);
-        pj_cstr(&subState->sub_state, "terminated");
-        pj_cstr(&subState->reason_param, "noresource");
-        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) subState);
 
-        pj_str_t type;
-        pj_cstr(&type, "message");
-        pj_str_t subtype;
-        pj_cstr(&subtype, "sipfrag;version=2.0");
+        pjsip_tx_data *tdata = createNotify();
+        
         try
         {
             if (mWasWithDestination)
@@ -861,10 +845,7 @@ protected:
         {
             lg(Debug) << "ConnectBridgedSessionsWithDestination sending 404 due to destination not found.";
 
-            pj_str_t bodyStr;
-            pj_cstr(&bodyStr, "SIP/2.0 404 Not Found");
-            pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
-            tdata->msg->body = body;
+            addNotifyBody(tdata, "SIP/2.0 404 Not Found");
             pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
             return Complete;
         }
@@ -872,18 +853,12 @@ protected:
         {
             lg(Debug) << "ConnectBridgedSessionsCallback sending 400 due to exception:  " << e.what();
 
-            pj_str_t bodyStr;
-            pj_cstr(&bodyStr, "SIP/2.0 400 Bad Request");
-            pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
-            tdata->msg->body = body;
+            addNotifyBody(tdata, "SIP/2.0 400 Bad Request");
             pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
             return Complete;
         }
 
-        pj_str_t bodyStr;
-        pj_cstr(&bodyStr, "SIP/2.0 200 OK");
-        pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
-        tdata->msg->body = body;
+        addNotifyBody(tdata, "SIP/2.0 200 OK");
         pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
         
         Ice::Current current;
@@ -893,6 +868,38 @@ protected:
     }
 
 private:
+
+    pjsip_tx_data* createNotify()
+    {
+        pjsip_tx_data *tdata;
+        pjsip_dlg_create_request(mInv->dlg, pjsip_get_notify_method(), -1, &tdata);
+
+        pjsip_event_hdr *event = pjsip_event_hdr_create(tdata->pool);
+        pj_strdup2(tdata->pool, &event->event_type, "refer");
+        char idbuf[20];
+        pj_ansi_snprintf(idbuf, sizeof(idbuf), "%d", mReferCSeq);
+        pj_strdup2(tdata->pool, &event->id_param, idbuf);
+        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) event);
+
+        pjsip_sub_state_hdr *subState = pjsip_sub_state_hdr_create(tdata->pool);
+        pj_strdup2(tdata->pool, &subState->sub_state, "terminated");
+        pj_strdup2(tdata->pool, &subState->reason_param, "noresource");
+        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) subState);
+
+        return tdata;
+    }
+    void addNotifyBody(pjsip_tx_data *tdata, const char *bodyText)
+    {
+        pj_str_t type;
+        pj_cstr(&type, "message");
+        pj_str_t subtype;
+        pj_cstr(&subtype, "sipfrag;version=2.0");
+
+        pj_str_t bodyStr;
+        pj_cstr(&bodyStr, bodyText);
+        pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
+        tdata->msg->body = body;
+    }
     /**
      * The INVITE session, which contains the dialog on which the
      * REFER was received.
@@ -1004,7 +1011,6 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
     // We only support SIP URIs, anything else is rubbish to us
     if (!PJSIP_URI_SCHEME_IS_SIP(target_uri) && !PJSIP_URI_SCHEME_IS_SIPS(target_uri))
     {
-        // TODO: Place proper response code in here
         lg(Debug) << "handleRefer() sending 400 due to non-SIP URI. ";
         pjsip_dlg_respond(inv->dlg, rdata, 400, NULL, NULL, NULL);
         return;

commit 932054f9fb6f0b1ecaaf309cc792c2e333c4cf8b
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Jul 14 15:28:37 2011 -0500

    Use boost::split to get the parameters.
    
    This makes the code a LOT cleaner and also reduces assumptions regarding
    the number of parameters and their placement in the replaces header.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 2003334..1ce2612 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -22,6 +22,7 @@
 #include "SipStateReplicator.h"
 
 #include <IceUtil/UUID.h>
+#include <boost/algorithm/string.hpp>
 
 #include <AsteriskSCF/Core/Endpoint/EndpointIf.h>
 #include <AsteriskSCF/Core/Routing/RoutingIf.h>
@@ -679,12 +680,31 @@ protected:
                 // parse it out
                 std::string replaces_value_tmp = std::string(pj_strbuf(&mReplacesParam->value),
                         pj_strlen(&mReplacesParam->value));
-                std::string fromTagParamName(";from-tag=");
-                std::string toTagParamName(";to-tag=");
-                size_t from_tag_pos = replaces_value_tmp.find(fromTagParamName);
-                size_t to_tag_pos = replaces_value_tmp.find(toTagParamName);
+                std::vector<std::string> params;
 
-                if (from_tag_pos == std::string::npos || to_tag_pos == std::string::npos)
+                boost::split(params, replaces_value_tmp, boost::is_any_of(";"));
+
+                //The first value will be the actual replaces value.
+                std::string replaces = params.front();
+
+                std::string to;
+                std::string from;
+                std::string fromTagParamName("from-tag=");
+                std::string toTagParamName("to-tag=");
+                for(std::vector<std::string>::iterator iter = params.begin();
+                        iter != params.end(); ++iter)
+                {
+                    if (iter->compare(0, toTagParamName.size(), toTagParamName) == 0)
+                    {
+                        to = iter->substr(toTagParamName.size());
+                    }
+                    if (iter->compare(0, fromTagParamName.size(), fromTagParamName) == 0)
+                    {
+                        from = iter->substr(fromTagParamName.size());
+                    }
+                }
+
+                if (from.empty() || to.empty())
                 {
                     lg(Debug) << "handleRefer() sending 400 due to From or To missing. ";
                     pjsip_dlg_modify_response(mInv->dlg, mTdata, 400, NULL);
@@ -692,36 +712,11 @@ protected:
                     return Complete;
                 }
 
-                size_t firstTagPos = std::min(from_tag_pos, to_tag_pos);
-
-                // The position in the string where the value of the from tag starts.
-                size_t fromTagValuePos = from_tag_pos + fromTagParamName.size();
-
-                // The position in the string where the value of the to tag starts
-                size_t toTagValuePos = to_tag_pos + toTagParamName.size();
-
-                // The size of the tags. This isn't so much an accurate size as it is
-                // what we need to pass in to the substr() function in order to extract
-                // the proper value.
-                //
-                // If the from tag comes after the to tag, then the from tag extends until the
-                // end of the string. Otherwise, it only extends as far as the beginning of the
-                // to tag.
-                size_t fromTagValueSize =
-                    from_tag_pos > to_tag_pos ? std::string::npos : to_tag_pos - fromTagValuePos;
-
-                size_t toTagValueSize =
-                    to_tag_pos > from_tag_pos ? std::string::npos : from_tag_pos - toTagValuePos;
-
-                std::string to_tag_value = replaces_value_tmp.substr(toTagValuePos, toTagValueSize);
-                std::string from_tag_value = replaces_value_tmp.substr(fromTagValuePos, fromTagValueSize);
-                std::string replaces_value = replaces_value_tmp.substr(0, firstTagPos);
-
-                lg(Debug) << "to: " << to_tag_value << "from: " << from_tag_value << "replaces: " << replaces_value;
+                lg(Debug) << "to: " << to << " from: " << from << " replaces: " << replaces;
 
-                pj_str_t to_tag_str = pj_str((char*)to_tag_value.c_str());
-                pj_str_t from_tag_str = pj_str((char*)from_tag_value.c_str());
-                pj_str_t replaces_tag_str = pj_str((char*)replaces_value.c_str());
+                pj_str_t to_tag_str = pj_str((char*)to.c_str());
+                pj_str_t from_tag_str = pj_str((char*)from.c_str());
+                pj_str_t replaces_tag_str = pj_str((char*)replaces.c_str());
 
                 other_dlg = pjsip_ua_find_dialog(&replaces_tag_str, &to_tag_str, &from_tag_str, PJ_TRUE);
             }

commit 99ba263d0ce9822a225af356a5938ac77fa6ed4c
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Jul 14 14:57:47 2011 -0500

    Allow for the to-tag and from-tag parameters in the replaces header to be in any order.
    
    This is my initial try at it, and I don't like it much. I think I'll try again using
    boost's string splitting algorithm.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 7c5bb78..2003334 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -679,8 +679,10 @@ protected:
                 // parse it out
                 std::string replaces_value_tmp = std::string(pj_strbuf(&mReplacesParam->value),
                         pj_strlen(&mReplacesParam->value));
-                size_t from_tag_pos = replaces_value_tmp.find(";from-tag=");
-                size_t to_tag_pos = replaces_value_tmp.find(";to-tag=");
+                std::string fromTagParamName(";from-tag=");
+                std::string toTagParamName(";to-tag=");
+                size_t from_tag_pos = replaces_value_tmp.find(fromTagParamName);
+                size_t to_tag_pos = replaces_value_tmp.find(toTagParamName);
 
                 if (from_tag_pos == std::string::npos || to_tag_pos == std::string::npos)
                 {
@@ -690,9 +692,32 @@ protected:
                     return Complete;
                 }
 
-                std::string to_tag_value = replaces_value_tmp.substr(to_tag_pos + 8, from_tag_pos - to_tag_pos - 8);
-                std::string from_tag_value = replaces_value_tmp.substr(from_tag_pos + 10);
-                std::string replaces_value = replaces_value_tmp.substr(0, to_tag_pos);
+                size_t firstTagPos = std::min(from_tag_pos, to_tag_pos);
+
+                // The position in the string where the value of the from tag starts.
+                size_t fromTagValuePos = from_tag_pos + fromTagParamName.size();
+
+                // The position in the string where the value of the to tag starts
+                size_t toTagValuePos = to_tag_pos + toTagParamName.size();
+
+                // The size of the tags. This isn't so much an accurate size as it is
+                // what we need to pass in to the substr() function in order to extract
+                // the proper value.
+                //
+                // If the from tag comes after the to tag, then the from tag extends until the
+                // end of the string. Otherwise, it only extends as far as the beginning of the
+                // to tag.
+                size_t fromTagValueSize =
+                    from_tag_pos > to_tag_pos ? std::string::npos : to_tag_pos - fromTagValuePos;
+
+                size_t toTagValueSize =
+                    to_tag_pos > from_tag_pos ? std::string::npos : from_tag_pos - toTagValuePos;
+
+                std::string to_tag_value = replaces_value_tmp.substr(toTagValuePos, toTagValueSize);
+                std::string from_tag_value = replaces_value_tmp.substr(fromTagValuePos, fromTagValueSize);
+                std::string replaces_value = replaces_value_tmp.substr(0, firstTagPos);
+
+                lg(Debug) << "to: " << to_tag_value << "from: " << from_tag_value << "replaces: " << replaces_value;
 
                 pj_str_t to_tag_str = pj_str((char*)to_tag_value.c_str());
                 pj_str_t from_tag_str = pj_str((char*)from_tag_value.c_str());

commit 4cfb1e755f34ac922d318dc803c031460f9fdc4e
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Jul 14 14:18:50 2011 -0500

    Couple of cleanup and error checking additions.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 8b029f2..7c5bb78 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -978,8 +978,6 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
     // So with what we have here, this will work 99.99% of the time. If someone
     // tries to do something like refresh a subscription though, that will fail.
 
-    // TODO: Provide method to send back suitable response
-
     // Now parse the URI to get the actual target they want to refer to
     pjsip_uri *target_uri = static_cast<pjsip_uri *>(pjsip_parse_uri(inv->dlg->pool, refer_to->hvalue.ptr, refer_to->hvalue.slen, 0));
 
@@ -1012,7 +1010,7 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
     }
     else
     {
-        target = std::string(pj_strbuf(&target_sip_uri->user), pj_strlen(&target_sip_uri->user));
+        target.assign(pj_strbuf(&target_sip_uri->user), pj_strlen(&target_sip_uri->user));
     }
 
     PJSipSessionModInfo *session_mod_info = (PJSipSessionModInfo*) inv->mod_data[mModule.id];
@@ -1020,7 +1018,15 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
 
     //Create our initial response that we can modify in the queueable operation.
     pjsip_tx_data *tdata = 0;
-    pjsip_dlg_create_response(inv->dlg, rdata, 202, NULL, &tdata);
+    pj_status_t status = pjsip_dlg_create_response(inv->dlg, rdata, 202, NULL, &tdata);
+
+    if (status != PJ_SUCCESS)
+    {
+        //Hm, we couldn't create a response. Let's hope this actually works...
+        lg(Error) << "Unable to create 202 Accepted response in response to REFER (Out of memory?)";
+        pjsip_dlg_respond(inv->dlg, rdata, 500, NULL, NULL, NULL);
+        return;
+    }
 
     lg(Debug) << "Queuing a HandleReferOperation";
     enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, referredByVal, target, session, mSessionRouter, mModule.id), inv);

commit 0d4efd17784e6999dcdfa1237444d43771952e25
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Jul 14 14:04:22 2011 -0500

    Parse and store the Referred-By header in a REFER.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 0d2b669..8b029f2 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -628,6 +628,7 @@ public:
             pjsip_param *replaces_param,
             pjsip_param *to_tag_param,
             pjsip_param *from_tag_param,
+            const std::string& referredBy,
             const std::string& target,
             const SipSessionPtr& session,
             const AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx>& sessionRouter,
@@ -635,7 +636,9 @@ public:
         : mInv(inv), mTsx(tsx), mTdata(tdata), 
         mReplacesParam(replaces_param ? new pjsip_param(*replaces_param) : NULL), 
         mToTagParam(to_tag_param ? new pjsip_param(*to_tag_param) : NULL),
-        mFromTagParam(from_tag_param ? new pjsip_param(*from_tag_param) : NULL), mTarget(target),
+        mFromTagParam(from_tag_param ? new pjsip_param(*from_tag_param) : NULL),
+        mReferredBy(referredBy),
+        mTarget(target),
         mSession(session), mSessionRouter(sessionRouter),
         mModuleId(moduleId), mReferCSeq(tsx->cseq), mWasWithDestination(false) {}
 
@@ -900,6 +903,13 @@ private:
      */
     pjsip_param *mFromTagParam;
     /**
+     * The content from the Referred-By header, if one existed.
+     * XXX We currently have this handy, but we don't actually do
+     * anything with it. This is because we don't have a way to place
+     * this information in the outgoing INVITE.
+     */
+    const std::string mReferredBy;
+    /**
      * The user portion of the URI in the Refer-To header of the
      * REFER that triggered this operation.
      */
@@ -946,7 +956,27 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
         return;
     }
 
+    pj_str_t referredBy;
+    pj_cstr(&referredBy, "Referred-By");
+    pjsip_generic_string_hdr *referredByHdr =
+        static_cast<pjsip_generic_string_hdr*>(pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &referredBy, NULL));
+
+    std::string referredByVal;
+    if (referredByHdr)
+    {
+        referredByVal.assign(pj_strbuf(&referredByHdr->hvalue), pj_strlen(&referredByHdr->hvalue));
+    }
+
     // TODO: Add support for subscription
+    //
+    // Currently, we send a NOTIFY as we are supposed to, but we don't actually
+    // have a full-blown subscription in use. This is for 2 reasons:
+    //
+    // 1. We don't have A subscription API defined yet.
+    // 2. REFERs are sort of fake subscriptions anyway.
+    //
+    // So with what we have here, this will work 99.99% of the time. If someone
+    // tries to do something like refresh a subscription though, that will fail.
 
     // TODO: Provide method to send back suitable response
 
@@ -993,7 +1023,7 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
     pjsip_dlg_create_response(inv->dlg, rdata, 202, NULL, &tdata);
 
     lg(Debug) << "Queuing a HandleReferOperation";
-    enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, target, session, mSessionRouter, mModule.id), inv);
+    enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, referredByVal, target, session, mSessionRouter, mModule.id), inv);
 }
 
 pj_bool_t PJSipSessionModule::on_rx_request(pjsip_rx_data *rdata)

commit fabda081351cfbacbf2f21056741884b03ed9e68
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Jul 14 13:02:40 2011 -0500

    Add Subscription-State header to outbound NOTIFY.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index b9d1a8d..0d2b669 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -813,7 +813,11 @@ protected:
         char idbuf[20];
         pj_ansi_snprintf(idbuf, sizeof(idbuf), "%d", mReferCSeq);
         pj_cstr(&event->id_param, idbuf);
-        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) event);
+        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) event);
+        pjsip_sub_state_hdr *subState = pjsip_sub_state_hdr_create(tdata->pool);
+        pj_cstr(&subState->sub_state, "terminated");
+        pj_cstr(&subState->reason_param, "noresource");
+        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) subState);
 
         pj_str_t type;
         pj_cstr(&type, "message");

commit f67f2b872d728995520bcec97a3f7282f9d467e6
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Jul 14 10:51:15 2011 -0500

    Add the ;id parameter to the event header in the NOTIFY we send.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 5753ed5..b9d1a8d 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -637,7 +637,7 @@ public:
         mToTagParam(to_tag_param ? new pjsip_param(*to_tag_param) : NULL),
         mFromTagParam(from_tag_param ? new pjsip_param(*from_tag_param) : NULL), mTarget(target),
         mSession(session), mSessionRouter(sessionRouter),
-        mModuleId(moduleId), mWasWithDestination(false) {}
+        mModuleId(moduleId), mReferCSeq(tsx->cseq), mWasWithDestination(false) {}
 
     ~HandleReferOperation()
     {
@@ -810,6 +810,9 @@ protected:
         pjsip_dlg_create_request(mInv->dlg, pjsip_get_notify_method(), -1, &tdata);
         pjsip_event_hdr *event = pjsip_event_hdr_create(tdata->pool);
         pj_cstr(&event->event_type, "refer");
+        char idbuf[20];
+        pj_ansi_snprintf(idbuf, sizeof(idbuf), "%d", mReferCSeq);
+        pj_cstr(&event->id_param, idbuf);
         pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) event);
 
         pj_str_t type;
@@ -910,6 +913,10 @@ private:
      */
     const int mModuleId;
     /**
+     * The CSeq of the REFER
+     */
+    pj_int32_t mReferCSeq;
+    /**
      * Helps determine which end_* method to call on the session router when AMI completes.
      * XXX It may be more elegant to handle this by sending a cookie to the AMI method
      * instead.

commit 510efa060b46739398dd3b166862210c4666d48d
Merge: cc5f441 fc8f711
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jul 11 15:52:20 2011 -0500

    Merge branch 'master' into transfer-improvements


commit cc5f44159e22c0870ded5bbd4d5e928650063cac
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jul 11 15:46:06 2011 -0500

    Add version to sipfrag content type and remove unnecessary CRLFs.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 661141d..7d55af9 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -773,7 +773,7 @@ protected:
         pj_str_t type;
         pj_cstr(&type, "message");
         pj_str_t subtype;
-        pj_cstr(&subtype, "sipfrag");
+        pj_cstr(&subtype, "sipfrag;version=2.0");
         try
         {
             if (mWasWithDestination)
@@ -790,7 +790,7 @@ protected:
             lg(Debug) << "ConnectBridgedSessionsWithDestination sending 404 due to destination not found.";
 
             pj_str_t bodyStr;
-            pj_cstr(&bodyStr, "SIP/2.0 404 Not Found\r\n\r\n");
+            pj_cstr(&bodyStr, "SIP/2.0 404 Not Found");
             pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
             tdata->msg->body = body;
             pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
@@ -801,7 +801,7 @@ protected:
             lg(Debug) << "ConnectBridgedSessionsCallback sending 400 due to exception:  " << e.what();
 
             pj_str_t bodyStr;
-            pj_cstr(&bodyStr, "SIP/2.0 400 Bad Request\r\n\r\n");
+            pj_cstr(&bodyStr, "SIP/2.0 400 Bad Request");
             pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
             tdata->msg->body = body;
             pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
@@ -809,7 +809,7 @@ protected:
         }
 
         pj_str_t bodyStr;
-        pj_cstr(&bodyStr, "SIP/2.0 200 OK\r\n\r\n");
+        pj_cstr(&bodyStr, "SIP/2.0 200 OK");
         pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
         tdata->msg->body = body;
         pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);

commit b7d5022904f5a7c6342d077b28530f8eaae95d11
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jul 11 15:26:19 2011 -0500

    Send an early 202 and then send a NOTIFY later...like you're supposed to do.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index b6719d5..661141d 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -698,6 +698,9 @@ protected:
             PJSipSessionModInfo *other_session_mod_info = (PJSipSessionModInfo*)other_inv->mod_data[mModuleId];
             SipSessionPtr other_session = other_session_mod_info->getSessionPtr();
 
+            //Go ahead and send a 202 for the REFER. We can send a NOTIFY later to indicate if something
+            //on the outbound leg went awry.
+            pjsip_dlg_send_response(mInv->dlg, mTsx, mTdata);
             try
             {
                 std::string operationId = ::IceUtil::generateUUID();
@@ -720,6 +723,10 @@ protected:
         }
         else
         {
+            //Go ahead and send a 202 for the REFER. We can send a NOTIFY later to indicate if something
+            //on the outbound leg went awry.
+            pjsip_dlg_send_response(mInv->dlg, mTsx, mTdata);
+
             // Now that we have the target user we can pass this into routing and go on our marry way
             try
             {
@@ -754,6 +761,19 @@ protected:
     {
         assert(mAsyncResult);
         SessionRouterPrx router = SessionRouterPrx::uncheckedCast(mAsyncResult->getProxy());
+
+        // We need to send a NOTIFY to indicate how things went on the other leg.
+        // XXX Once we have a subscription module written, we can actually use it.
+        pjsip_tx_data *tdata;
+        pjsip_dlg_create_request(mInv->dlg, pjsip_get_notify_method(), -1, &tdata);
+        pjsip_event_hdr *event = pjsip_event_hdr_create(tdata->pool);
+        pj_cstr(&event->event_type, "refer");
+        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) event);
+
+        pj_str_t type;
+        pj_cstr(&type, "message");
+        pj_str_t subtype;
+        pj_cstr(&subtype, "sipfrag");
         try
         {
             if (mWasWithDestination)
@@ -769,18 +789,30 @@ protected:
         {
             lg(Debug) << "ConnectBridgedSessionsWithDestination sending 404 due to destination not found.";
 
-            pjsip_dlg_modify_response(mInv->dlg, mTdata, 404, NULL);
-            pjsip_dlg_send_response(mInv->dlg, mTsx, mTdata);
+            pj_str_t bodyStr;
+            pj_cstr(&bodyStr, "SIP/2.0 404 Not Found\r\n\r\n");
+            pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
+            tdata->msg->body = body;
+            pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
             return Complete;
         }
         catch (const std::exception &e)
         {
             lg(Debug) << "ConnectBridgedSessionsCallback sending 400 due to exception:  " << e.what();
-            pjsip_dlg_modify_response(mInv->dlg, mTdata, 400, NULL);
-            pjsip_dlg_send_response(mInv->dlg, mTsx, mTdata);
+
+            pj_str_t bodyStr;
+            pj_cstr(&bodyStr, "SIP/2.0 400 Bad Request\r\n\r\n");
+            pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
+            tdata->msg->body = body;
+            pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
             return Complete;
         }
-        pjsip_dlg_send_response(mInv->dlg, mTsx, mTdata);
+
+        pj_str_t bodyStr;
+        pj_cstr(&bodyStr, "SIP/2.0 200 OK\r\n\r\n");
+        pjsip_msg_body *body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &bodyStr);
+        tdata->msg->body = body;
+        pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
         
         Ice::Current current;
         lg(Debug) << "ConnectBridgedSessionsCallback calling session->stop(). ";
@@ -905,7 +937,7 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
 
     //Create our initial response that we can modify in the queueable operation.
     pjsip_tx_data *tdata = 0;
-    pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata);
+    pjsip_dlg_create_response(inv->dlg, rdata, 202, NULL, &tdata);
 
     lg(Debug) << "Queuing a HandleReferOperation";
     enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, target, session, mSessionRouter, mModule.id), inv);

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


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list