[asterisk-scf-commits] asterisk-scf/release/sip.git branch "master" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Mon Jan 9 09:52:15 CST 2012


branch "master" has been updated
       via  6095c35ec25ed1b6ac407a8514a266c40b6aa829 (commit)
       via  f9d1cbcbabc11e78b99c09ef39c6e288da921906 (commit)
       via  e422566158372ea12ce851dec4b12a7145eef168 (commit)
       via  bc37777aa09787707de1c05374cb7623656b3f98 (commit)
       via  6d5ab58d36d69052c2ea7b389ef90d09351b23ff (commit)
       via  75e4696143a153403a7236520fa71dc5de685899 (commit)
       via  9bbfae7224fea73e708f6cc980f75aa4d0f0c405 (commit)
       via  e8d23580c55b5b19f62c6990225ba60efd5b5f4a (commit)
       via  cb6a99642430f81cb67f26e69154648f36e04f8d (commit)
       via  ebd73dfcec878ee6d776aa8d2e55180dc9fc31c4 (commit)
       via  42cae73f7b36c51647d18de0c893bc32b2b3040f (commit)
       via  4a89ea9575ab09615b34115caf3c3eb026e760b3 (commit)
       via  13e4e6a3c7f90bb2bd53f9fe87bd51a957cc5742 (commit)
       via  83eca4eb339607702566d0a4f0eeb34081ed6f59 (commit)
      from  905620fd71c99fe276ebc6ed0922af49ae0a89af (commit)

Summary of changes:
 src/PJSIPRegistrarModule.cpp  |   45 +++++--
 src/PJSIPSessionModule.cpp    |  310 ++++++++++++++++++++++++++++-------------
 src/SIPClientRegistration.cpp |   53 +++++--
 src/SIPSession.cpp            |  129 ++++++++++++++---
 src/SIPTransfer.cpp           |   83 ++++++++----
 5 files changed, 447 insertions(+), 173 deletions(-)


- Log -----------------------------------------------------------------
commit 6095c35ec25ed1b6ac407a8514a266c40b6aa829
Merge: 905620f f9d1cbc
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Jan 9 09:46:29 2012 -0600

    Merge branch 'error-handling'


commit f9d1cbcbabc11e78b99c09ef39c6e288da921906
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jan 4 14:31:38 2012 -0600

    Add warning message and correct namespace error in SIPTransfer.cpp

diff --git a/src/SIPTransfer.cpp b/src/SIPTransfer.cpp
index 3f4a110..2620727 100644
--- a/src/SIPTransfer.cpp
+++ b/src/SIPTransfer.cpp
@@ -34,8 +34,9 @@ pjsip_tx_data* createNotify(pjsip_dialog *dlg, pj_int32_t cseq, bool active)
 {
     pjsip_tx_data *tdata;
     
-    if (AsteriskSCF::SipSessionManager::fail(pjsip_dlg_create_request(dlg, pjsip_get_notify_method(), -1, &tdata)))
+    if (AsteriskSCF::SIPSessionManager::fail(pjsip_dlg_create_request(dlg, pjsip_get_notify_method(), -1, &tdata)))
     {
+        lg(Warning) << "Unable to create NOTIFY request";
         return 0;
     }
 

commit e422566158372ea12ce851dec4b12a7145eef168
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jan 4 14:19:50 2012 -0600

    Add warning messages for SIPClientRegistration.cpp

diff --git a/src/SIPClientRegistration.cpp b/src/SIPClientRegistration.cpp
index c496f4d..91cc147 100644
--- a/src/SIPClientRegistration.cpp
+++ b/src/SIPClientRegistration.cpp
@@ -213,6 +213,10 @@ void SIPRegistrationClient::destroyPJSIPRegistration()
     {
         pjsip_regc_send(mReg, tdata);
     }
+    else
+    {
+        lg(Warning) << "Unable to create REGISTER request to unregister ourselves";
+    }
 
     pjsip_regc_destroy(mReg);
 }
@@ -336,6 +340,10 @@ void SIPRegistrationClient::authenticate(pjsip_rx_data *rdata)
         {
             sendRegister();
         }
+        else
+        {
+            lg(Warning) << "Unable to create REGISTER with authentication credentials";
+        }
     }
     return;
 }

commit bc37777aa09787707de1c05374cb7623656b3f98
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jan 4 14:16:46 2012 -0600

    Add log messages to PJSIPSessionModule.cpp for when PJSIP functions fail.

diff --git a/src/PJSIPSessionModule.cpp b/src/PJSIPSessionModule.cpp
index a78310b..7a9476e 100644
--- a/src/PJSIPSessionModule.cpp
+++ b/src/PJSIPSessionModule.cpp
@@ -402,6 +402,10 @@ protected:
             {
                 pjsip_inv_send_msg(mInv, mTdata);
             }
+            else
+            {
+                lg(Warning) << "Unable to create 500 response for INVITE";
+            }
             return Complete;
         }
 
@@ -436,6 +440,10 @@ protected:
             {
                 pjsip_inv_send_msg(mInv, mTdata);
             }
+            else
+            {
+                lg(Warning) << "Unable to create 488 response for INVITE";
+            }
             return Complete;
         }
 
@@ -482,6 +490,10 @@ protected:
             {
                 pjsip_inv_send_msg(mInv, mTdata);
             }
+            else
+            {
+                lg(Warning) << "Unable to create 500 response for INVITE";
+            }
         }
         return Complete;
     }
@@ -499,6 +511,10 @@ protected:
             {
                 pjsip_inv_send_msg(mInv, mTdata);
             }
+            else
+            {
+                lg(Warning) << "Unable to create 404 response for INVITE";
+            }
         }
         catch (...)
         {
@@ -506,6 +522,10 @@ protected:
             {
                 pjsip_inv_send_msg(mInv, mTdata);
             }
+            else
+            {
+                lg(Warning) << "Unable to create 500 response for INVITE";
+            }
         }
         return Complete;
     }
@@ -814,6 +834,7 @@ void PJSIPSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     // Verify we can handle this invite request and respond accordingly if we can not
     if (fail(pjsip_inv_verify_request(rdata, &options, NULL, NULL, mEndpoint, &tdata)))
     {
+        lg(Warning) << "Cannot verify that we are able to handle this INVITE";
         if (tdata)
         {
             pjsip_endpt_send_response2(mEndpoint, rdata, tdata, NULL, NULL);
@@ -830,6 +851,7 @@ void PJSIPSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     // If this is an attended transfer and something is amuck... respond accordingly
     if (fail(pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &tdata)))
     {
+        lg(Warning) << "Cannot verify that we can handle this INVITE with Replaces request";
         if (tdata)
         {
             pjsip_endpt_send_response2(mEndpoint, rdata, tdata, NULL, NULL);
@@ -922,6 +944,10 @@ void PJSIPSessionModule::handleNewInvite(pjsip_rx_data *rdata)
         {
             pjsip_inv_send_msg(inv_session, tdata);
         }
+        else
+        {
+            lg(Warning) << "Unable to create 403 response for INVITE";
+        }
         return;
     }
     SIPEndpointConfig &config = caller->getConfig();
@@ -932,6 +958,10 @@ void PJSIPSessionModule::handleNewInvite(pjsip_rx_data *rdata)
         {
             pjsip_inv_send_msg(inv_session, tdata);
         }
+        else
+        {
+            lg(Warning) << "Unable to create 403 response for INVITE";
+        }
         return;
     }
 
@@ -954,6 +984,10 @@ void PJSIPSessionModule::handleNewInvite(pjsip_rx_data *rdata)
         {
             pjsip_inv_send_msg(inv_session, tdata);
         }
+        else
+        {
+            lg(Warning) << "Unable to create 416 response for INVITE";
+        }
         return;
     }
 
@@ -1515,6 +1549,10 @@ void PJSIPSessionModule::handleInviteRejection(pjsip_inv_session* inv,
                 //a queued operation.
                 pjsip_inv_send_msg(inv, tdata);
             }
+            else
+            {
+                lg(Warning) << "Unable to create INVITE with authentication credentials";
+            }
             return;
         }
     }
@@ -1823,6 +1861,10 @@ void PJSIPSessionModule::handleNonInviteAuthentication(pjsip_inv_session* inv,
             //a queued operation.
             pjsip_dlg_send_request(dlg, tdata, -1, NULL);
         }
+        else
+        {
+            lg(Warning) << "Unable to create request with authentication credentials";
+        }
     }
     return;
 }
@@ -1913,6 +1955,10 @@ protected:
             {
                 pjsip_inv_send_msg(mInv, packet);
             }
+            else
+            {
+                lg(Warning) << "Unable to create 488 response";
+            }
             return Complete;
         }
 
@@ -2047,6 +2093,7 @@ protected:
         const pjmedia_sdp_session *offer_sdp;
         if (fail(pjmedia_sdp_neg_get_neg_remote(mInv->neg, &offer_sdp)))
         {
+            lg(Warning) << "Unable to negotiate media and create an offer SDP";
             return Complete;
         }
 

commit 6d5ab58d36d69052c2ea7b389ef90d09351b23ff
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jan 4 13:56:59 2012 -0600

    Add warning messages to SIPSession.cpp when PJSIP functions fail.

diff --git a/src/SIPSession.cpp b/src/SIPSession.cpp
index 51b7a7f..bc757ed 100755
--- a/src/SIPSession.cpp
+++ b/src/SIPSession.cpp
@@ -644,6 +644,10 @@ public:
             {
                 pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
             }
+            else
+            {
+                lg(Warning) << "Unable to create reinvite";
+            }
         }
 
         mCb->ice_response();
@@ -703,8 +707,10 @@ public:
         else
         {
             // If we couldn't create the reinvite no streams were added
-            mCb->ice_response(StreamInformationDict());
+            lg(Warning) << "Unable to create reinvite when adding streams";
         }
+        
+        mCb->ice_response(StreamInformationDict());
 
         return Complete;
     }
@@ -741,6 +747,10 @@ public:
             {
                 pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
             }
+            else
+            {
+                lg(Warning) << "Unable to create reinvite to remove streams";
+            }
         }
         else
         {
@@ -953,6 +963,10 @@ public:
         {
             pjsip_inv_send_msg(mSession->getInviteSession(), packet);
         }
+        else
+        {
+            lg(Warning) << "Unable to create reinvite to connect streams";
+        }
 
         mCb->ice_response();
 
@@ -983,6 +997,10 @@ public:
         {
             pjsip_inv_send_msg(mSession->getInviteSession(), packet);
         }
+        else
+        {
+            lg(Warning) << "Unable to create reinvite to disconnect streams";
+        }
 
         mCb->ice_response();
 
@@ -1125,6 +1143,7 @@ void SIPSession::initializePJSIPStructs()
                 // We could just roll along and see if the default transport selection in pjsip
                 // hooks us up.
                 //
+                lg(Warning) << "Unable to set transport for INVITE UAC dialog";
             }
         }
     }
@@ -2033,6 +2052,7 @@ public:
         pjsip_tx_data *packet;
         if (fail(pjsip_inv_invite(mImplPriv->mInviteSession, &packet)))
         {
+            lg(Warning) << "Unable to create INVITE for outbound call";
             pjsip_inv_terminate(mImplPriv->mInviteSession, 500, 0);
             pjsip_dlg_terminate(mImplPriv->mInviteSession->dlg);
             // What should we do here? Throw an exception?
@@ -3683,6 +3703,10 @@ pjmedia_sdp_session *SIPSession::createSDPAnswer(const pjmedia_sdp_session* offe
                 {
                     pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
                 }
+                else
+                {
+                    lg(Warning) << "Unable to create 488 response for INVITE";
+                }
                 return 0;
             }
         }
@@ -3822,6 +3846,10 @@ pjmedia_sdp_session *SIPSession::createSDPAnswer(const pjmedia_sdp_session* offe
                 {
                     pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
                 }
+                else
+                {
+                    lg(Warning) << "Unable to create 488 response for INVITE";
+                }
                 return 0;
             }
 
@@ -4121,6 +4149,10 @@ void SIPSession::startMedia(const pjmedia_sdp_session*, const pjmedia_sdp_sessio
                 {
                     pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
                 }
+                else
+                {
+                    lg(Warning) << "Unable to create 488 response for INVITE";
+                }
                 return;
             }
 

commit 75e4696143a153403a7236520fa71dc5de685899
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jan 4 13:42:23 2012 -0600

    Add some warning messages for when PJSIP calls fail.

diff --git a/src/PJSIPRegistrarModule.cpp b/src/PJSIPRegistrarModule.cpp
index a04256b..590c584 100644
--- a/src/PJSIPRegistrarModule.cpp
+++ b/src/PJSIPRegistrarModule.cpp
@@ -730,6 +730,7 @@ bool PJSIPRegistrarModule::checkAuth(pjsip_rx_data *rdata, pjsip_transaction *ts
     pjsip_tx_data *tdata;
     if (fail(pjsip_endpt_create_response(tsx->endpt, rdata, 401, NULL, &tdata)))
     {
+        lg(Warning) << "Unable to create 401 response to challenge REGISTER";
         return false;
     }
     
@@ -737,6 +738,7 @@ bool PJSIPRegistrarModule::checkAuth(pjsip_rx_data *rdata, pjsip_transaction *ts
     
     if (fail(pjsip_tsx_send_msg(tsx, tdata)))
     {
+        lg(Warning) << "Unable to send 401 response to REGISTER";
         return false;
     }
     
@@ -761,6 +763,7 @@ pj_bool_t PJSIPRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
     pjsip_transaction *tsx;
     if (fail(pjsip_tsx_create_uas(&mModule, rdata, &tsx)))
     {
+        lg(Warning) << "Unable to create server transaction for inbound REGISTER";
         return PJ_TRUE;
     }
 
@@ -795,6 +798,10 @@ pj_bool_t PJSIPRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
         {
             pjsip_tsx_send_msg(tsx, tdata);
         }
+        else
+        {
+            lg(Warning) << "Unable to create 400 error response for inbound REGISTER";
+        }
         return PJ_TRUE;
     }
 
@@ -833,15 +840,16 @@ pj_bool_t PJSIPRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
     // We enqueue the SIP response to make sure we send it and replicate state AFTER we have updated
     // our internal bindings.
     pjsip_tx_data *tdata;
-    if (success(pjsip_endpt_create_response(tsx->endpt, rdata, 200, NULL, &tdata)))
+    if (fail(pjsip_endpt_create_response(tsx->endpt, rdata, 200, NULL, &tdata)))
     {
-        mRegistrar->addAndRemoveBindings(aor, newBindings, removedBindings, mRegistrar->getQueue());
-
-        mRegistrar->getQueue()->enqueueWork(new Response(tsx, tdata, aor, mRegistrar));
-
-        replicateState(aor, existingBindings, newBindings, removedBindings);
+        lg(Warning) << "Unable to create final REGISTER response";
+        return PJ_TRUE;
     }
 
+    mRegistrar->addAndRemoveBindings(aor, newBindings, removedBindings, mRegistrar->getQueue());
+    mRegistrar->getQueue()->enqueueWork(new Response(tsx, tdata, aor, mRegistrar));
+    replicateState(aor, existingBindings, newBindings, removedBindings);
+
     return PJ_TRUE;
 }
 

commit 9bbfae7224fea73e708f6cc980f75aa4d0f0c405
Merge: e8d2358 872c1fc
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Jan 4 13:20:39 2012 -0600

    Merge branch 'master' into error-handling
    
    Conflicts:
    	src/PJSIPRegistrarModule.cpp
    	src/PJSIPSessionModule.cpp
    	src/SIPClientRegistration.cpp
    	src/SIPSession.cpp
    	src/SIPTransfer.cpp

diff --cc src/PJSIPRegistrarModule.cpp
index 0b4f8ed,3a35e25..a04256b
--- a/src/PJSIPRegistrarModule.cpp
+++ b/src/PJSIPRegistrarModule.cpp
@@@ -19,12 -19,11 +19,12 @@@
  #include <AsteriskSCF/System/WorkQueue/WorkQueueIf.h>
  #include <AsteriskSCF/WorkQueue/WorkQueue.h>
  #include <AsteriskSCF/WorkQueue/DefaultQueueListener.h>
- #include <AsteriskSCF/PJLib/ThreadHook.h>
+ #include <AsteriskSCF/PJLIB/ThreadHook.h>
  
- #include "PJSipRegistrarModule.h"
- #include "PJSipManager.h"
- #include "SipReplicationContext.h"
+ #include "PJSIPRegistrarModule.h"
+ #include "PJSIPManager.h"
+ #include "SIPReplicationContext.h"
 +#include "PJUtil.h"
  
  using namespace AsteriskSCF::SIP::Registration::V1;
  using namespace AsteriskSCF::System::Logging;
diff --cc src/PJSIPSessionModule.cpp
index a111209,fabcaf3..a78310b
--- a/src/PJSIPSessionModule.cpp
+++ b/src/PJSIPSessionModule.cpp
@@@ -14,16 -14,15 +14,16 @@@
   * at the top of the source tree.
   */
  
- #include "PJSipSessionModule.h"
- #include "SipTransfer.h"
- #include "SipEndpoint.h"
- #include "SipEndpointFactory.h"
- #include "SipSession.h"
- #include "PJSipManager.h"
- #include "SipStateReplicator.h"
- #include "SipTelephonyEventSource.h"
- #include "SipReplicationContext.h"
+ #include "PJSIPSessionModule.h"
+ #include "SIPTransfer.h"
+ #include "SIPEndpoint.h"
+ #include "SIPEndpointFactory.h"
+ #include "SIPSession.h"
+ #include "PJSIPManager.h"
+ #include "SIPStateReplicator.h"
+ #include "SIPTelephonyEventSource.h"
+ #include "SIPReplicationContext.h"
 +#include "PJUtil.h"
  
  #include <IceUtil/UUID.h>
  #include <boost/lexical_cast.hpp>
@@@ -351,20 -350,17 +351,20 @@@ bool PJSIPSessionModule::checkAuth(pjsi
      }
  
      pjsip_tx_data *tdata;
 -    pjsip_inv_end_session(inv, 401, NULL, &tdata);
 -
 -    authInstance->addDigests(tdata, digests);
 +    if (success(pjsip_inv_end_session(inv, 401, NULL, &tdata)))
 +    {
 +        authInstance->addDigests(tdata, digests);
  
 -    pjsip_inv_send_msg(inv, tdata);
 +        pjsip_inv_send_msg(inv, tdata);
  
 -    mAuthManager->scheduleAuthTimeout(authInstance, sessionAuthTimeout);
 -    return true;
 +        mAuthManager->scheduleAuthTimeout(authInstance, sessionAuthTimeout);
 +        return true;
 +    }
 +    lg(Warning) << "Failed to create authentication challenge";
 +    return false;
  }
  
- class SessionCreationOperation : public SipQueueableOperation
+ class SessionCreationOperation : public SIPQueueableOperation
  {
  public:
      SessionCreationOperation(
@@@ -803,8 -789,21 +803,8 @@@ ConnectedLinePtr PJSIPSessionModule::ge
      return connected;
  }
  
- void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
+ void PJSIPSessionModule::handleNewInvite(pjsip_rx_data *rdata)
  {
 -    //What do we do here?
 -    //
 -    //First we need to identify who this is coming from.
 -    //If it's someone we recognize, then we can figure
 -    //out whether we need to send a 401/407 request.
 -    //For now, we don't have any sort of configured users,
 -    //so we skip this step. Instead, we'll skip ahead to
 -    //creating an endpoint, creating the invite session,
 -    //sending a 100 trying, finding the remote endpoint
 -    //to call, and placing a call to it.
 -
 -    //XXX Put caller identification code in here!
 -
      //We handle most of the processing here synchronously since
      //at this point there is no associated session, plus the lead-up
      //to creating a session is not especially intensive.
@@@ -848,11 -851,13 +848,11 @@@
      }
  
      pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
-     PJSipTransactionModInfo *tsx_mod_info = new PJSipTransactionModInfo(tsx);
+     PJSIPTransactionModInfo *tsx_mod_info = new PJSIPTransactionModInfo(tsx);
      tsx->mod_data[mModule.id] = (void *)tsx_mod_info;
  
 -    //XXX The sdp argument is NULL for now, but can be changed if we
 -    //know what has been configured for this particular caller.
      pjsip_inv_session *inv_session;
 -    if (pjsip_inv_create_uas(dlg, rdata, NULL, 0, &inv_session) != PJ_SUCCESS)
 +    if (fail(pjsip_inv_create_uas(dlg, rdata, NULL, 0, &inv_session)))
      {
          lg(Warning) << "Unable to create INVITE session";
          //Since the inv_session was not created, we need to access the base dialog
@@@ -862,13 -867,9 +862,13 @@@
      }
  
      // Add our own module as a dialog usage
 -    pjsip_dlg_add_usage(dlg, &mModule, NULL);
 +    if (fail(pjsip_dlg_add_usage(dlg, &mModule, NULL)))
 +    {
 +        lg(Warning) << "Unable to establish dialog usage";
 +        pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
 +    }
      
-     PJSipDialogModInfo *dlg_mod_info(new PJSipDialogModInfo(dlg));
+     PJSIPDialogModInfo *dlg_mod_info(new PJSIPDialogModInfo(dlg));
      dlg->mod_data[mModule.id] = (void *)dlg_mod_info;
  
      pjsip_timer_setting session_timer_settings;
@@@ -918,13 -923,11 +918,13 @@@
      if (caller == 0)
      {
          lg(Warning) << "Unknown calling endpoint " << callerName;
 -        pjsip_inv_end_session(inv_session, 403, NULL, &tdata);
 -        pjsip_inv_send_msg(inv_session, tdata);
 +        if (success(pjsip_inv_end_session(inv_session, 403, NULL, &tdata)))
 +        {
 +            pjsip_inv_send_msg(inv_session, tdata);
 +        }
          return;
      }
-     SipEndpointConfig &config = caller->getConfig();
+     SIPEndpointConfig &config = caller->getConfig();
      if (config.sessionConfig.callDirection != BOTH && config.sessionConfig.callDirection != INBOUND)
      {
          lg(Warning) << "Caller " << callerName << " does not have permission to make inbound calls.";
@@@ -1487,10 -1489,7 +1487,10 @@@ void PJSIPSessionModule::handleInviteRe
  
  //There are some rejection codes that we can actually do something with other than
  //just kill the code.
 +//
 +//Codes that may not possibly result in retrying the call should not be handled in this
 +//function.
- void PJSipSessionModule::handleInviteRejection(pjsip_inv_session* inv,
+ void PJSIPSessionModule::handleInviteRejection(pjsip_inv_session* inv,
      pjsip_rx_data* rdata, pjsip_transaction* tsx)
  {
      int respCode = rdata->msg_info.msg->line.status.code;
@@@ -1602,81 -1599,22 +1602,81 @@@ protected
              {
                  return Complete;
              }
-             SipSessionPtr session = session_mod_info->getSessionPtr();
+             SIPSessionPtr session = session_mod_info->getSessionPtr();
              AsteriskSCF::SessionCommunications::V1::ResponseCodePtr response =
                  new AsteriskSCF::SessionCommunications::V1::ResponseCode();
 -            if (mInv->cause == 486)
 +
 +            //Cause codes for each SIP response are taken from RFC 3398 Section 8.2.6.1 (plus errata ID 2161)
 +            switch (mInv->cause)
              {
 +            case 404: // Not Found
 +            case 485: // Ambiguous
 +            case 604: // Does Not Exist Anymore
 +                response->isdnCode = 1;
 +                break;
 +            case 486: // Busy Here
 +            case 600: // Busy Everywhere
                  response->isdnCode = 17;
 -            }
 -            else if (PJSIP_IS_STATUS_IN_CLASS(mInv->cause, 500))
 -            {
 -                response->isdnCode = 34;
 -            }
 -            else
 -            {
 -                // TODO: See what cause is on a normal call completion
 +                break;
 +            case 480: // Temporarily Unavailable
 +                response->isdnCode = 18;
 +                break;
 +            case 401: // Unauthorized
 +            case 402: // Payment Required
 +            case 403: // Forbidden
 +            case 407: // Proxy Authentication Required
 +            case 603: // Decline
 +                response->isdnCode = 21;
 +                break;
 +            case 410: // Gone
 +                response->isdnCode = 22;
 +                break;
 +            case 482: // Loop Detected
 +            case 483: // Too Many Hops
 +                response->isdnCode = 25;
 +                break;
 +            case 484: // Address Incomplete
 +                response->isdnCode = 28;
 +                break;
 +            case 502: // Bad Gateway
 +                response->isdnCode = 38;
 +                break;
 +            case 400: // Bad Request
 +            case 481: // Call/Transaction Does Not Exist
 +            case 500: // Server Internal Error
 +            case 503: // Service Unavailable
 +                response->isdnCode = 41;
 +                break;
 +            case 405: // Method not allowed
 +                response->isdnCode = 63;
 +                break;
 +            case 406: // Not Acceptable
 +            case 415: // Unsupported Media Type
 +            case 501: // Not Implemented
 +                response->isdnCode = 79;
 +                break;
 +            case 408: // Request Timeout
 +            case 504: // Server Time-out
 +                response->isdnCode = 102;
 +                break;
 +            case 413: // Request Entity Too Long
 +            case 414: // Request-URI Too Long
 +            case 416: // Unsupported URI Scheme
 +            case 420: // Bad Extension
 +            case 421: // Extension Required
 +            case 423: // Interval Too Brief
 +            case 505: // Version Not Supported
 +            case 513: // Message Too Large
 +                response->isdnCode = 127;
 +                break;
 +            default:
 +                // 487, 488, and 606 have no mapping. Also,
 +                // other types of ends to sessions (like normal clearing)
 +                // will end up here.
                  response->isdnCode = 0;
 +                break;
              }
 +
              if (session)
              {
                  std::vector<AsteriskSCF::SessionCommunications::V1::SessionListenerPrx> listeners = session->getListeners();
@@@ -1906,18 -1842,18 +1906,18 @@@ protected
      {
          const pjmedia_sdp_session *remote_sdp;
          pj_status_t status;
 -        if ((status = pjmedia_sdp_neg_get_active_remote(mInv->neg, &remote_sdp)) != PJ_SUCCESS)
 +        if (fail(pjmedia_sdp_neg_get_active_remote(mInv->neg, &remote_sdp)))
          {
 -	    pjsip_tx_data *packet;
 -	    if (pjsip_inv_end_session(mInv, 488, NULL, &packet) == PJ_SUCCESS)
 -	    {
 -		pjsip_inv_send_msg(mInv, packet);
 -	    }
 -	    return Complete;
 +            pjsip_tx_data *packet;
 +            if (success(pjsip_inv_end_session(mInv, 488, NULL, &packet)))
 +            {
 +                pjsip_inv_send_msg(mInv, packet);
 +            }
 +            return Complete;
          }
  
-         PJSipSessionModInfo *session_mod_info = (PJSipSessionModInfo*)mInv->mod_data[mModuleId];
-         SipSessionPtr session = session_mod_info->getSessionPtr();
+         PJSIPSessionModInfo *session_mod_info = (PJSIPSessionModInfo*)mInv->mod_data[mModuleId];
+         SIPSessionPtr session = session_mod_info->getSessionPtr();
  
          StreamInformationDict added;
          session->createSDPAnswer(remote_sdp, added);
diff --cc src/SIPClientRegistration.cpp
index 25e2bed,aa51dba..c496f4d
--- a/src/SIPClientRegistration.cpp
+++ b/src/SIPClientRegistration.cpp
@@@ -14,8 -14,7 +14,8 @@@
   * at the top of the source tree.
   */
  
- #include "SipClientRegistration.h"
+ #include "SIPClientRegistration.h"
 +#include "PJUtil.h"
  #include <boost/numeric/conversion/cast.hpp>
  
  using namespace AsteriskSCF::System::Logging;
@@@ -153,16 -152,12 +153,16 @@@ void SIPRegistrationClient::activate(
      mReplica->addListener(mReplicaListenerProxy);
  }
  
- void SipRegistrationClient::createPJSIPRegistration(
-         const SipClientRegistrationItemPtr& confItem,
+ void SIPRegistrationClient::createPJSIPRegistration(
+         const SIPClientRegistrationItemPtr& confItem,
          pjsip_endpoint *pjEndpoint,
-         const SipEndpointPtr& sipEndpoint)
+         const SIPEndpointPtr& sipEndpoint)
  {
 -    pjsip_regc_create(pjEndpoint, this, regCallback, &mReg);
 +    if (fail(pjsip_regc_create(pjEndpoint, this, regCallback, &mReg)))
 +    {
 +        lg(Warning) << "Unable to create client registration for endpoint " << sipEndpoint->getName();
 +        return;
 +    }
  
      std::vector<pj_str_t> pjContacts;
      std::transform(confItem->contacts.begin(), confItem->contacts.end(), std::back_inserter(pjContacts), MakeContact(mReg));
@@@ -206,13 -198,11 +206,13 @@@ void SIPRegistrationClient::destroy(
      destroyPJSIPRegistration();
  }
  
- void SipRegistrationClient::destroyPJSIPRegistration()
+ void SIPRegistrationClient::destroyPJSIPRegistration()
  {
      pjsip_tx_data *tdata;
 -    pjsip_regc_unregister(mReg, &tdata);
 -    pjsip_regc_send(mReg, tdata);
 +    if (success(pjsip_regc_unregister(mReg, &tdata)))
 +    {
 +        pjsip_regc_send(mReg, tdata);
 +    }
  
      pjsip_regc_destroy(mReg);
  }
@@@ -270,23 -260,14 +270,23 @@@ void SIPRegistrationClient::sendRegiste
      std::vector<pj_str_t> contacts;
      std::transform(mContacts.begin(), mContacts.end(), std::back_inserter(contacts), MakeContact(mReg));
  
 -    pjsip_regc_update_contact(mReg, boost::numeric_cast<int>(contacts.size()), &contacts.front());
 +    if (fail(pjsip_regc_update_contact(mReg, boost::numeric_cast<int>(contacts.size()), &contacts.front())))
 +    {
 +        lg(Warning) << "Unable to update contacts for client registration for endpoint " << mEndpointName;
 +    }
  
      pjsip_tx_data *tdata;
 -    pjsip_regc_register(mReg, PJ_TRUE, &tdata);
 -    pjsip_regc_send(mReg, tdata);
 +    if (success(pjsip_regc_register(mReg, PJ_TRUE, &tdata)))
 +    {
 +        pjsip_regc_send(mReg, tdata);
 +    }
 +    else
 +    {
 +        lg(Warning) << "Unable to create outbound REGISTER request for endpoint " << mEndpointName;
 +    }
  }
  
- void SipRegistrationClient::handleRegisterResponse(pjsip_regc_cbparam *param)
+ void SIPRegistrationClient::handleRegisterResponse(pjsip_regc_cbparam *param)
  {
      switch (param->code)
      {
@@@ -326,7 -307,11 +326,7 @@@
      }
  }
  
- void SipRegistrationClient::authenticate(pjsip_rx_data *rdata)
 -//XXX This function seems like it may fit better into AuthManager
 -//or some more central place since it could be useful for authentication
 -//responses for any type of request. This is mostly not REGISTER-specific, in
 -//other words.
+ void SIPRegistrationClient::authenticate(pjsip_rx_data *rdata)
  {
      std::vector<pjsip_cred_info> creds;
      mManager->getAuthCredentials(rdata, creds, mEndpointName);
diff --cc src/SIPSession.cpp
index 01d4426,d8a1f73..51b7a7f
--- a/src/SIPSession.cpp
+++ b/src/SIPSession.cpp
@@@ -14,13 -14,12 +14,13 @@@
   * at the top of the source tree.
   */
  
- #include "PJSipManager.h"
- #include "SipEndpointFactory.h"
- #include "SipEndpoint.h"
- #include "SipSession.h"
- #include "SipTelephonyEventSource.h"
- #include "SipTelephonyEventSink.h"
+ #include "PJSIPManager.h"
+ #include "SIPEndpointFactory.h"
+ #include "SIPEndpoint.h"
+ #include "SIPSession.h"
+ #include "SIPTelephonyEventSource.h"
+ #include "SIPTelephonyEventSink.h"
 +#include "PJUtil.h"
  
  #include <Ice/Ice.h>
  #include <IceUtil/UUID.h>
diff --cc src/SIPTransfer.cpp
index 9ff5140,494b0b7..3f4a110
--- a/src/SIPTransfer.cpp
+++ b/src/SIPTransfer.cpp
@@@ -14,8 -14,7 +14,8 @@@
   * at the top of the source tree.
   */
  
- #include "SipTransfer.h"
+ #include "SIPTransfer.h"
 +#include "PJUtil.h"
  
  #include <boost/algorithm/string.hpp>
  #include <IceUtil/UUID.h>
@@@ -532,13 -516,10 +532,13 @@@ SuspendableWorkResult HandleReferOperat
              
              //Go ahead and send the 100 Trying sipfrag
              pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, true);
 -            addNotifyBody(tdata, "SIP/2.0 100 Trying");
 -            pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
 +            if (tdata)
 +            {
 +                addNotifyBody(tdata, "SIP/2.0 100 Trying");
 +                pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
 +            }
  
-             mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, false, mHook->getProxy(), d);
+             mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, true, mHook->getProxy(), d);
              return Complete;
          }
          catch (const Ice::CommunicatorDestroyedException &)

commit e8d23580c55b5b19f62c6990225ba60efd5b5f4a
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Dec 22 15:53:16 2011 -0600

    Handle PJSIP errors in PJSipSessionModule.cpp

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index e1766ee..a111209 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -23,6 +23,7 @@
 #include "SipStateReplicator.h"
 #include "SipTelephonyEventSource.h"
 #include "SipReplicationContext.h"
+#include "PJUtil.h"
 
 #include <IceUtil/UUID.h>
 #include <boost/lexical_cast.hpp>
@@ -350,14 +351,17 @@ bool PJSipSessionModule::checkAuth(pjsip_rx_data *rdata, pjsip_inv_session *inv,
     }
 
     pjsip_tx_data *tdata;
-    pjsip_inv_end_session(inv, 401, NULL, &tdata);
-
-    authInstance->addDigests(tdata, digests);
+    if (success(pjsip_inv_end_session(inv, 401, NULL, &tdata)))
+    {
+        authInstance->addDigests(tdata, digests);
 
-    pjsip_inv_send_msg(inv, tdata);
+        pjsip_inv_send_msg(inv, tdata);
 
-    mAuthManager->scheduleAuthTimeout(authInstance, sessionAuthTimeout);
-    return true;
+        mAuthManager->scheduleAuthTimeout(authInstance, sessionAuthTimeout);
+        return true;
+    }
+    lg(Warning) << "Failed to create authentication challenge";
+    return false;
 }
 
 class SessionCreationOperation : public SipQueueableOperation
@@ -394,8 +398,10 @@ protected:
         catch (const Ice::Exception& ex)
         {
             lg(Error) << "Exception caught while trying to create SIP session\n" << ex.what();
-            pjsip_inv_end_session(mInv, 500, NULL, &mTdata);
-            pjsip_inv_send_msg(mInv, mTdata);
+            if (success(pjsip_inv_end_session(mInv, 500, NULL, &mTdata)))
+            {
+                pjsip_inv_send_msg(mInv, mTdata);
+            }
             return Complete;
         }
 
@@ -411,7 +417,7 @@ protected:
         pjmedia_sdp_session *sdp;
         StreamInformationDict streams;
 
-        if (!mInv->neg || (pjmedia_sdp_neg_get_neg_remote(mInv->neg, &remote_sdp) != PJ_SUCCESS))
+        if (!mInv->neg || fail(pjmedia_sdp_neg_get_neg_remote(mInv->neg, &remote_sdp)))
         {
             // No SDP was present in the INVITE so we need to create an offer
             sdp = mSession->createSDPOffer(StreamInformationDict(), streams);
@@ -426,8 +432,10 @@ protected:
         {
             // If no SDP was created we can not accept this INVITE
             lg(Error) << "No compatible formats found in offer\n";
-            pjsip_inv_end_session(mInv, 488, NULL, &mTdata);
-            pjsip_inv_send_msg(mInv, mTdata);
+            if (success(pjsip_inv_end_session(mInv, 488, NULL, &mTdata)))
+            {
+                pjsip_inv_send_msg(mInv, mTdata);
+            }
             return Complete;
         }
 
@@ -470,8 +478,10 @@ protected:
         catch (const Ice::CommunicatorDestroyedException &)
         {
             // Everything else doesn't really map so they just become internal server errors
-            pjsip_inv_end_session(mInv, 500, NULL, &mTdata);
-            pjsip_inv_send_msg(mInv, mTdata);
+            if (success(pjsip_inv_end_session(mInv, 500, NULL, &mTdata)))
+            {
+                pjsip_inv_send_msg(mInv, mTdata);
+            }
         }
         return Complete;
     }
@@ -485,13 +495,17 @@ protected:
         }
         catch (const DestinationNotFoundException &)
         {
-            pjsip_inv_end_session(mInv, 404, NULL, &mTdata);
-            pjsip_inv_send_msg(mInv, mTdata);
+            if (success(pjsip_inv_end_session(mInv, 404, NULL, &mTdata)))
+            {
+                pjsip_inv_send_msg(mInv, mTdata);
+            }
         }
         catch (...)
         {
-            pjsip_inv_end_session(mInv, 500, NULL, &mTdata);
-            pjsip_inv_send_msg(mInv, mTdata);
+            if (success(pjsip_inv_end_session(mInv, 500, NULL, &mTdata)))
+            {
+                pjsip_inv_send_msg(mInv, mTdata);
+            }
         }
         return Complete;
     }
@@ -798,7 +812,7 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     unsigned options = PJSIP_INV_SUPPORT_100REL;
 
     // Verify we can handle this invite request and respond accordingly if we can not
-    if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, mEndpoint, &tdata) != PJ_SUCCESS)
+    if (fail(pjsip_inv_verify_request(rdata, &options, NULL, NULL, mEndpoint, &tdata)))
     {
         if (tdata)
         {
@@ -814,7 +828,7 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     pjsip_dialog *dlg, *replaced_dlg;
 
     // If this is an attended transfer and something is amuck... respond accordingly
-    if (pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &tdata) != PJ_SUCCESS)
+    if (fail(pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &tdata)))
     {
         if (tdata)
         {
@@ -827,11 +841,7 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
         return;
     }
 
-    //XXX The NULL parameter should be replaced with
-    //An appropriate Contact header. Leaving it NULL makes
-    //PJSIP create the contact header for responses based
-    //on the To header of the incoming Invite.
-    if (pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dlg) != PJ_SUCCESS)
+    if (fail(pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dlg)))
     {
         lg(Warning) << "Unable to create UAS dialog on incoming INVITE";
         return;
@@ -842,7 +852,7 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     tsx->mod_data[mModule.id] = (void *)tsx_mod_info;
 
     pjsip_inv_session *inv_session;
-    if (pjsip_inv_create_uas(dlg, rdata, NULL, 0, &inv_session) != PJ_SUCCESS)
+    if (fail(pjsip_inv_create_uas(dlg, rdata, NULL, 0, &inv_session)))
     {
         lg(Warning) << "Unable to create INVITE session";
         //Since the inv_session was not created, we need to access the base dialog
@@ -852,7 +862,11 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     }
 
     // Add our own module as a dialog usage
-    pjsip_dlg_add_usage(dlg, &mModule, NULL);
+    if (fail(pjsip_dlg_add_usage(dlg, &mModule, NULL)))
+    {
+        lg(Warning) << "Unable to establish dialog usage";
+        pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
+    }
     
     PJSipDialogModInfo *dlg_mod_info(new PJSipDialogModInfo(dlg));
     dlg->mod_data[mModule.id] = (void *)dlg_mod_info;
@@ -861,7 +875,7 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     pjsip_timer_setting_default(&session_timer_settings);
     pjsip_timer_init_session(inv_session, &session_timer_settings);
 
-    if (pjsip_inv_initial_answer(inv_session, rdata, 100, NULL, NULL, &tdata) != PJ_SUCCESS)
+    if (fail(pjsip_inv_initial_answer(inv_session, rdata, 100, NULL, NULL, &tdata)))
     {
         lg(Warning) << "Failed to create 100 Trying response";
         pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
@@ -876,7 +890,7 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     dlg_mod_info->mDialogState->sessionId = session_mod_info->mSessionState->sessionId;
     tsx_mod_info->mTransactionState->sessionId = session_mod_info->mSessionState->sessionId;
 
-    if (pjsip_inv_send_msg(inv_session, tdata) != PJ_SUCCESS)
+    if (fail(pjsip_inv_send_msg(inv_session, tdata)))
     {
         lg(Warning) << "Failed to send 100 Trying response";
         pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
@@ -904,16 +918,20 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     if (caller == 0)
     {
         lg(Warning) << "Unknown calling endpoint " << callerName;
-        pjsip_inv_end_session(inv_session, 403, NULL, &tdata);
-        pjsip_inv_send_msg(inv_session, tdata);
+        if (success(pjsip_inv_end_session(inv_session, 403, NULL, &tdata)))
+        {
+            pjsip_inv_send_msg(inv_session, tdata);
+        }
         return;
     }
     SipEndpointConfig &config = caller->getConfig();
     if (config.sessionConfig.callDirection != BOTH && config.sessionConfig.callDirection != INBOUND)
     {
         lg(Warning) << "Caller " << callerName << " does not have permission to make inbound calls.";
-        pjsip_inv_end_session(inv_session, 403, NULL, &tdata);
-        pjsip_inv_send_msg(inv_session, tdata);
+        if (success(pjsip_inv_end_session(inv_session, 403, NULL, &tdata)))
+        {
+            pjsip_inv_send_msg(inv_session, tdata);
+        }
         return;
     }
 
@@ -932,8 +950,10 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     else
     {
         //We don't support non-SIP URIs.
-        pjsip_inv_end_session(inv_session, 500, NULL, &tdata);
-        pjsip_inv_send_msg(inv_session, tdata);
+        if (success(pjsip_inv_end_session(inv_session, 416, NULL, &tdata)))
+        {
+            pjsip_inv_send_msg(inv_session, tdata);
+        }
         return;
     }
 
@@ -998,8 +1018,8 @@ 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))
     {
-        lg(Debug) << "handleRefer() sending 400 due to non-SIP URI. ";
-        pjsip_dlg_respond(inv->dlg, rdata, 400, NULL, NULL, NULL);
+        lg(Debug) << "handleRefer() sending 416 due to non-SIP URI. ";
+        pjsip_dlg_respond(inv->dlg, rdata, 416, NULL, NULL, NULL);
         return;
     }
 
@@ -1031,9 +1051,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;
-    pj_status_t status = pjsip_dlg_create_response(inv->dlg, rdata, 202, NULL, &tdata);
-
-    if (status != PJ_SUCCESS)
+    if (fail(pjsip_dlg_create_response(inv->dlg, rdata, 202, NULL, &tdata)))
     {
         //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?)";
@@ -1259,8 +1277,15 @@ void PJSipSessionModule::handleInfo(pjsip_inv_session *inv, pjsip_rx_data *rdata
 
     pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
     pjsip_tx_data *tdata;
-    pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata);
-    enqueueSessionWork(new HandleInfoDTMFOperation(inv, tsx, tdata, session, dtmf, duration), inv);
+    if (success(pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata)))
+    {
+        enqueueSessionWork(new HandleInfoDTMFOperation(inv, tsx, tdata, session, dtmf, duration), inv);
+    }
+    else
+    {
+        lg(Error) << "Unable to create response message for INFO";
+        pjsip_dlg_respond(inv->dlg, rdata, 500, NULL, NULL, NULL);
+    }
     return;
 }
 
@@ -1483,11 +1508,13 @@ void PJSipSessionModule::handleInviteRejection(pjsip_inv_session* inv,
             pjsip_auth_clt_set_credentials(&inv->dlg->auth_sess,
                     boost::numeric_cast<int>(creds.size()), &creds.front());
             pjsip_tx_data *tdata;
-            pjsip_auth_clt_reinit_req(&inv->dlg->auth_sess,
-                    rdata, tsx->last_tx, &tdata);
-            //XXX The actual sending of the message should probably be done as
-            //a queued operation.
-            pjsip_inv_send_msg(inv, tdata);
+            if (success(pjsip_auth_clt_reinit_req(&inv->dlg->auth_sess,
+                    rdata, tsx->last_tx, &tdata)))
+            {
+                //XXX The actual sending of the message should probably be done as
+                //a queued operation.
+                pjsip_inv_send_msg(inv, tdata);
+            }
             return;
         }
     }
@@ -1789,11 +1816,13 @@ void PJSipSessionModule::handleNonInviteAuthentication(pjsip_inv_session* inv,
         pjsip_auth_clt_set_credentials(&dlg->auth_sess,
                 boost::numeric_cast<int>(creds.size()), &creds.front());
         pjsip_tx_data *tdata;
-        pjsip_auth_clt_reinit_req(&dlg->auth_sess,
-                rdata, tsx->last_tx, &tdata);
-        //XXX The actual sending of the message should probably be done as
-        //a queued operation.
-        pjsip_dlg_send_request(dlg, tdata, -1, NULL);
+        if (success(pjsip_auth_clt_reinit_req(&dlg->auth_sess,
+                rdata, tsx->last_tx, &tdata)))
+        {
+            //XXX The actual sending of the message should probably be done as
+            //a queued operation.
+            pjsip_dlg_send_request(dlg, tdata, -1, NULL);
+        }
     }
     return;
 }
@@ -1877,14 +1906,14 @@ protected:
     {
         const pjmedia_sdp_session *remote_sdp;
         pj_status_t status;
-        if ((status = pjmedia_sdp_neg_get_active_remote(mInv->neg, &remote_sdp)) != PJ_SUCCESS)
+        if (fail(pjmedia_sdp_neg_get_active_remote(mInv->neg, &remote_sdp)))
         {
-	    pjsip_tx_data *packet;
-	    if (pjsip_inv_end_session(mInv, 488, NULL, &packet) == PJ_SUCCESS)
-	    {
-		pjsip_inv_send_msg(mInv, packet);
-	    }
-	    return Complete;
+            pjsip_tx_data *packet;
+            if (success(pjsip_inv_end_session(mInv, 488, NULL, &packet)))
+            {
+                pjsip_inv_send_msg(mInv, packet);
+            }
+            return Complete;
         }
 
         PJSipSessionModInfo *session_mod_info = (PJSipSessionModInfo*)mInv->mod_data[mModuleId];
@@ -2016,14 +2045,13 @@ protected:
         }
 
         const pjmedia_sdp_session *offer_sdp;
-        pj_status_t status;
-        if ((status = pjmedia_sdp_neg_get_neg_remote(mInv->neg, &offer_sdp)) != PJ_SUCCESS)
+        if (fail(pjmedia_sdp_neg_get_neg_remote(mInv->neg, &offer_sdp)))
         {
             return Complete;
         }
 
         // Call into the session for the serious work
-	session->createSDPAnswer(offer_sdp, mStreamsAdded);
+        session->createSDPAnswer(offer_sdp, mStreamsAdded);
 
         // If no streams were added we can respond to the offer with the SDP we had previously and move on
         if (mStreamsAdded.empty())
@@ -2066,7 +2094,7 @@ protected:
 
         // Since that is now done we can set this new SDP as our answer and send a response to the reinvite
         pjsip_inv_set_sdp_answer(mInv, sdp);
-	pjsip_inv_send_reinvite_response(mInv, mResponse);
+        pjsip_inv_send_reinvite_response(mInv, mResponse);
 
         return Complete;
     }

commit cb6a99642430f81cb67f26e69154648f36e04f8d
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Dec 22 10:32:05 2011 -0600

    Use the PJUtil error checking methods in SipSession.cpp

diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index e3fda77..01d4426 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -20,6 +20,7 @@
 #include "SipSession.h"
 #include "SipTelephonyEventSource.h"
 #include "SipTelephonyEventSink.h"
+#include "PJUtil.h"
 
 #include <Ice/Ice.h>
 #include <IceUtil/UUID.h>
@@ -639,7 +640,7 @@ public:
             // what we really want to do is just update our answer SDP
             pjsip_tx_data *packet = NULL;
 
-            if ((pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, mImplPriv->mSDP, &packet)) == PJ_SUCCESS)
+            if (success(pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, mImplPriv->mSDP, &packet)))
             {
                 pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
             }
@@ -695,7 +696,7 @@ public:
         // Okay, create and send the reinvite!
         pjsip_tx_data *packet = NULL;
             
-        if ((pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, sdp, &packet)) == PJ_SUCCESS)
+        if (success(pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, sdp, &packet)))
         {
             pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
         }
@@ -736,7 +737,7 @@ public:
         {
             pjsip_tx_data *packet = NULL;
 
-            if ((pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, mImplPriv->mSDP, &packet)) == PJ_SUCCESS)
+            if (success(pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, mImplPriv->mSDP, &packet)))
             {
                 pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
             }
@@ -948,7 +949,7 @@ public:
         pjmedia_sdp_session *sdp = mSession->modifySDPforDirectConnections(mConnections);
         pjsip_tx_data *packet = NULL;
 
-        if ((pjsip_inv_reinvite(mSession->getInviteSession(), NULL, sdp, &packet)) == PJ_SUCCESS)
+        if (success(pjsip_inv_reinvite(mSession->getInviteSession(), NULL, sdp, &packet)))
         {
             pjsip_inv_send_msg(mSession->getInviteSession(), packet);
         }
@@ -978,7 +979,7 @@ public:
         pjmedia_sdp_session *sdp = mSession->modifySDP(mStreams);
         pjsip_tx_data *packet = NULL;
 
-        if ((pjsip_inv_reinvite(mSession->getInviteSession(), NULL, sdp, &packet)) == PJ_SUCCESS)
+        if (success(pjsip_inv_reinvite(mSession->getInviteSession(), NULL, sdp, &packet)))
         {
             pjsip_inv_send_msg(mSession->getInviteSession(), packet);
         }
@@ -1105,8 +1106,7 @@ void SipSession::initializePJSIPStructs()
     pj_str_t remote_uri(pj_str(remote));
 
     pjsip_dialog *dialog;
-    if ((pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, &contact_uri, &remote_uri, &remote_uri, &dialog)) !=
-            PJ_SUCCESS)
+    if (fail(pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, &contact_uri, &remote_uri, &remote_uri, &dialog)))
     {
         // What should we do here? Throw an exception?
         lg(Error) << "Failed to create a UAC dialog!";
@@ -1118,7 +1118,7 @@ void SipSession::initializePJSIPStructs()
         pjsip_tpselector selector;
         if (transport->initSelector(selector))
         {
-            if(pjsip_dlg_set_transport(dialog, &selector) != PJ_SUCCESS)
+            if (fail(pjsip_dlg_set_transport(dialog, &selector)))
             {
                 //
                 // This would be pretty weird.. I guess if the transport no longer exists at this point.
@@ -1137,7 +1137,7 @@ void SipSession::initializePJSIPStructs()
     StreamInformationDict added;
     pjmedia_sdp_session *sdp = createSDPOffer(StreamInformationDict(), added);
 
-    if ((pjsip_inv_create_uac(dialog, sdp, 0, &inviteSession)) != PJ_SUCCESS)
+    if (fail(pjsip_inv_create_uac(dialog, sdp, 0, &inviteSession)))
     {
         lg(Error) << "Failed to create a UAC INVITE session!";
         pjsip_dlg_terminate(dialog);
@@ -2035,7 +2035,7 @@ public:
 
         // Create the actual INVITE packet
         pjsip_tx_data *packet;
-        if ((pjsip_inv_invite(mImplPriv->mInviteSession, &packet)) != PJ_SUCCESS)
+        if (fail(pjsip_inv_invite(mImplPriv->mInviteSession, &packet)))
         {
             pjsip_inv_terminate(mImplPriv->mInviteSession, 500, 0);
             pjsip_dlg_terminate(mImplPriv->mInviteSession->dlg);
@@ -2304,7 +2304,7 @@ public:
         // On an outbound call, if we have not received a provisional response yet, then PJSIP will
         // set packet NULL but still return PJ_SUCCESS. In this case, if we attempt to call pjsip_inv_send_msg,
         // then we will trigger an assertion since the packet we pass in is NULL.
-        if (mInviteSession && (pjsip_inv_end_session(mInviteSession, code, NULL, &packet) == PJ_SUCCESS) && packet)
+        if (mInviteSession && success(pjsip_inv_end_session(mInviteSession, code, NULL, &packet)) && packet)
         {
             pjsip_inv_send_msg(mInviteSession, packet);
         }
@@ -3683,7 +3683,7 @@ pjmedia_sdp_session *SipSession::createSDPAnswer(const pjmedia_sdp_session* offe
             catch (const AsteriskSCF::Media::RTP::V1::InvalidAddress&)
             {
                 pjsip_tx_data *packet;
-                if (pjsip_inv_end_session(mImplPriv->mInviteSession, 488, NULL, &packet) == PJ_SUCCESS)
+                if (success(pjsip_inv_end_session(mImplPriv->mInviteSession, 488, NULL, &packet)))
                 {
                     pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
                 }
@@ -3822,7 +3822,7 @@ pjmedia_sdp_session *SipSession::createSDPAnswer(const pjmedia_sdp_session* offe
             catch (const AsteriskSCF::Network::V1::InvalidAddress&)
             {
                 pjsip_tx_data *packet;
-                if (pjsip_inv_end_session(mImplPriv->mInviteSession, 488, NULL, &packet) == PJ_SUCCESS)
+                if (success(pjsip_inv_end_session(mImplPriv->mInviteSession, 488, NULL, &packet)))
                 {
                     pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
                 }
@@ -4121,7 +4121,7 @@ void SipSession::startMedia(const pjmedia_sdp_session*, const pjmedia_sdp_sessio
                 // or the client is not supporting it. Let's tear down the session and get out of here.
                 //
                 pjsip_tx_data* packet;
-                if (pjsip_inv_end_session(mImplPriv->mInviteSession, 488, NULL, &packet) == PJ_SUCCESS)
+                if (success(pjsip_inv_end_session(mImplPriv->mInviteSession, 488, NULL, &packet)))
                 {
                     pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
                 }

commit ebd73dfcec878ee6d776aa8d2e55180dc9fc31c4
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Dec 21 16:33:18 2011 -0600

    Add handling to the client registration code.

diff --git a/src/SipClientRegistration.cpp b/src/SipClientRegistration.cpp
index 7bd036c..25e2bed 100644
--- a/src/SipClientRegistration.cpp
+++ b/src/SipClientRegistration.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "SipClientRegistration.h"
+#include "PJUtil.h"
 #include <boost/numeric/conversion/cast.hpp>
 
 using namespace AsteriskSCF::System::Logging;
@@ -157,7 +158,11 @@ void SipRegistrationClient::createPJSIPRegistration(
         pjsip_endpoint *pjEndpoint,
         const SipEndpointPtr& sipEndpoint)
 {
-    pjsip_regc_create(pjEndpoint, this, regCallback, &mReg);
+    if (fail(pjsip_regc_create(pjEndpoint, this, regCallback, &mReg)))
+    {
+        lg(Warning) << "Unable to create client registration for endpoint " << sipEndpoint->getName();
+        return;
+    }
 
     std::vector<pj_str_t> pjContacts;
     std::transform(confItem->contacts.begin(), confItem->contacts.end(), std::back_inserter(pjContacts), MakeContact(mReg));
@@ -178,7 +183,7 @@ void SipRegistrationClient::createPJSIPRegistration(
     pj_str_t fromURL;
     pj_strdup2(pjsip_regc_get_pool(mReg), &fromURL, confItem->aor.c_str());
 
-    pjsip_regc_init(
+    if (fail(pjsip_regc_init(
             mReg,
             &serverURL,
             &fromURL,
@@ -186,7 +191,10 @@ void SipRegistrationClient::createPJSIPRegistration(
             boost::numeric_cast<int>(pjContacts.size()),
             &pjContacts.front(),
             confItem->defaultExpiration
-            );
+            )))
+    {
+        lg(Warning) << "Unable to initialize client registration for endpoint " << sipEndpoint->getName();
+    }
 
     setContacts(confItem->contacts);
 }
@@ -201,8 +209,10 @@ void SipRegistrationClient::destroy()
 void SipRegistrationClient::destroyPJSIPRegistration()
 {
     pjsip_tx_data *tdata;
-    pjsip_regc_unregister(mReg, &tdata);
-    pjsip_regc_send(mReg, tdata);
+    if (success(pjsip_regc_unregister(mReg, &tdata)))
+    {
+        pjsip_regc_send(mReg, tdata);
+    }
 
     pjsip_regc_destroy(mReg);
 }
@@ -260,11 +270,20 @@ void SipRegistrationClient::sendRegister()
     std::vector<pj_str_t> contacts;
     std::transform(mContacts.begin(), mContacts.end(), std::back_inserter(contacts), MakeContact(mReg));
 
-    pjsip_regc_update_contact(mReg, boost::numeric_cast<int>(contacts.size()), &contacts.front());
+    if (fail(pjsip_regc_update_contact(mReg, boost::numeric_cast<int>(contacts.size()), &contacts.front())))
+    {
+        lg(Warning) << "Unable to update contacts for client registration for endpoint " << mEndpointName;
+    }
 
     pjsip_tx_data *tdata;
-    pjsip_regc_register(mReg, PJ_TRUE, &tdata);
-    pjsip_regc_send(mReg, tdata);
+    if (success(pjsip_regc_register(mReg, PJ_TRUE, &tdata)))
+    {
+        pjsip_regc_send(mReg, tdata);
+    }
+    else
+    {
+        lg(Warning) << "Unable to create outbound REGISTER request for endpoint " << mEndpointName;
+    }
 }
 
 void SipRegistrationClient::handleRegisterResponse(pjsip_regc_cbparam *param)
@@ -307,18 +326,16 @@ void SipRegistrationClient::handleRegisterResponse(pjsip_regc_cbparam *param)
     }
 }
 
-//XXX This function seems like it may fit better into AuthManager
-//or some more central place since it could be useful for authentication
-//responses for any type of request. This is mostly not REGISTER-specific, in
-//other words.
 void SipRegistrationClient::authenticate(pjsip_rx_data *rdata)
 {
     std::vector<pjsip_cred_info> creds;
     mManager->getAuthCredentials(rdata, creds, mEndpointName);
     if (!creds.empty())
     {
-        pjsip_regc_set_credentials(mReg, boost::numeric_cast<int>(creds.size()), &creds.front());
-        sendRegister();
+        if (success(pjsip_regc_set_credentials(mReg, boost::numeric_cast<int>(creds.size()), &creds.front())))
+        {
+            sendRegister();
+        }
     }
     return;
 }
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 4aab2f5..9ff5140 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -138,9 +138,8 @@ void TransferListener::indicated(
         pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
         if (tdata)
         {
-            //XXX We could stand to add more possible responses here, but for now
-            //just getting things working is my top priority, and we conform to
-            //RFC 3515.
+            //We could stand to add more possible responses here, but these
+            //are enough to conform to RFC 3515.
             switch (stopped->response->isdnCode)
             {
                 //Busy

commit 42cae73f7b36c51647d18de0c893bc32b2b3040f
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Dec 21 15:18:14 2011 -0600

    Add some error handling in the transfer code.

diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index bb35b4b..4aab2f5 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "SipTransfer.h"
+#include "PJUtil.h"
 
 #include <boost/algorithm/string.hpp>
 #include <IceUtil/UUID.h>
@@ -32,7 +33,11 @@ Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionGateway");
 pjsip_tx_data* createNotify(pjsip_dialog *dlg, pj_int32_t cseq, bool active)
 {
     pjsip_tx_data *tdata;
-    pjsip_dlg_create_request(dlg, pjsip_get_notify_method(), -1, &tdata);
+    
+    if (AsteriskSCF::SipSessionManager::fail(pjsip_dlg_create_request(dlg, pjsip_get_notify_method(), -1, &tdata)))
+    {
+        return 0;
+    }
 
     pjsip_event_hdr *event = pjsip_event_hdr_create(tdata->pool);
     pj_strdup2(tdata->pool, &event->event_type, "refer");
@@ -120,43 +125,55 @@ void TransferListener::indicated(
     {
         lg(Debug) << "Got the connected indication. Should send a 200 sipfrag NOTIFY";
         pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
-        addNotifyBody(tdata, "SIP/2.0 200 OK");
-        pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+        if (tdata)
+        {
+            addNotifyBody(tdata, "SIP/2.0 200 OK");
+            pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+        }
         shutdown(source);
     }
     else if ((stopped = StoppedIndicationPtr::dynamicCast(event)))
     {
         lg(Debug) << "Got the stopped indication. Should send some sort of final response sipfrag NOTIFY";
         pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
-        //XXX We could stand to add more possible responses here, but for now
-        //just getting things working is my top priority, and we conform to
-        //RFC 3515.
-        switch (stopped->response->isdnCode)
+        if (tdata)
         {
-            //Busy
-            case 17:
-                addNotifyBody(tdata, "SIP/2.0 486 Busy Here");
-            //RFC 3515 section 2.4.5 says that we can send a 503 for any reference
-            //that fails.
-            default:
-                addNotifyBody(tdata, "SIP/2.0 503 Service Unavailable");
+            //XXX We could stand to add more possible responses here, but for now
+            //just getting things working is my top priority, and we conform to
+            //RFC 3515.
+            switch (stopped->response->isdnCode)
+            {
+                //Busy
+                case 17:
+                    addNotifyBody(tdata, "SIP/2.0 486 Busy Here");
+                //RFC 3515 section 2.4.5 says that we can send a 503 for any reference
+                //that fails.
+                default:
+                    addNotifyBody(tdata, "SIP/2.0 503 Service Unavailable");
+            }
+            pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
         }
-        pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
         shutdown(source);
     }
     else if ((ringing = RingingIndicationPtr::dynamicCast(event)))
     {
         lg(Debug) << "Got a ringing indication. Should send a 180 sipfrag NOTIFY";
         pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, true);
-        addNotifyBody(tdata, "SIP/2.0 180 Ringing");
-        pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+        if (tdata)
+        {
+            addNotifyBody(tdata, "SIP/2.0 180 Ringing");
+            pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+        }
     }
     else if ((progressing = ProgressingIndicationPtr::dynamicCast(event)))
     {
         lg(Debug) << "Got a progressing indication. Should send a 183 sipfrag NOTIFY";
         pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, true);
-        addNotifyBody(tdata, "SIP/2.0 183 Session Progress");
-        pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+        if (tdata)
+        {
+            addNotifyBody(tdata, "SIP/2.0 183 Session Progress");
+            pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+        }
     }
 }
 
@@ -516,8 +533,11 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
             
             //Go ahead and send the 100 Trying sipfrag
             pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, true);
-            addNotifyBody(tdata, "SIP/2.0 100 Trying");
-            pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+            if (tdata)
+            {
+                addNotifyBody(tdata, "SIP/2.0 100 Trying");
+                pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+            }
 
             mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, false, mHook->getProxy(), d);
             return Complete;
@@ -551,8 +571,11 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
     {
         lg(Debug) << "ConnectBridgedSessionsWithDestination sending 404 due to destination not found.";
         pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, false);
-        addNotifyBody(tdata, "SIP/2.0 404 Not Found");
-        pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+        if (tdata)
+        {
+            addNotifyBody(tdata, "SIP/2.0 404 Not Found");
+            pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+        }
         //Only blind transfers have the session creation hook to get rid of
         if (mBlindTransfer)
         {
@@ -564,8 +587,11 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
     {
         lg(Debug) << "ConnectBridgedSessionsCallback sending 400 due to exception:  " << e.what();
         pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, false);
-        addNotifyBody(tdata, "SIP/2.0 400 Bad Request");
-        pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+        if (tdata)
+        {
+            addNotifyBody(tdata, "SIP/2.0 400 Bad Request");
+            pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+        }
         //Only blind transfers have the session creation hook to get rid of
         if (mBlindTransfer)
         {
@@ -581,8 +607,11 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
     if (!mBlindTransfer)
     {
         pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, false);
-        addNotifyBody(tdata, "SIP/2.0 200 OK");
-        pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+        if (tdata)
+        {
+            addNotifyBody(tdata, "SIP/2.0 200 OK");
+            pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
+        }
     }
     return Complete;
 }

commit 4a89ea9575ab09615b34115caf3c3eb026e760b3
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Dec 21 14:47:22 2011 -0600

    Add some protection against failure returns from PJSIP calls in the registrar.

diff --git a/src/PJSipRegistrarModule.cpp b/src/PJSipRegistrarModule.cpp
index 99704d1..0b4f8ed 100644
--- a/src/PJSipRegistrarModule.cpp
+++ b/src/PJSipRegistrarModule.cpp
@@ -24,6 +24,7 @@
 #include "PJSipRegistrarModule.h"
 #include "PJSipManager.h"
 #include "SipReplicationContext.h"
+#include "PJUtil.h"
 
 using namespace AsteriskSCF::SIP::Registration::V1;
 using namespace AsteriskSCF::System::Logging;
@@ -465,9 +466,6 @@ void PJSipRegistrarModule::replicateState(
     mRegistrar->getQueue()->enqueueWork(new ReplicateState(mReplicationContext, aor, existingBindings, newBindings, removedBindings, mRegistrar));
 }
 
-//XXX This and the method that queues this work should
-//have different names. It's easy to get confused with
-//UpdateBinding, and this could stand to be more descriptive
 class AddAndRemoveBindings : public Work
 {
 public:
@@ -730,11 +728,17 @@ bool PJSipRegistrarModule::checkAuth(pjsip_rx_data *rdata, pjsip_transaction *ts
     }
 
     pjsip_tx_data *tdata;
-    pjsip_endpt_create_response(tsx->endpt, rdata, 401, NULL, &tdata);
+    if (fail(pjsip_endpt_create_response(tsx->endpt, rdata, 401, NULL, &tdata)))
+    {
+        return false;
+    }
     
     authInstance->addDigests(tdata, digests);
     
-    pjsip_tsx_send_msg(tsx, tdata);
+    if (fail(pjsip_tsx_send_msg(tsx, tdata)))
+    {
+        return false;
+    }
     
     mAuthManager->scheduleAuthTimeout(authInstance, registrarAuthTimeout);
     return true;
@@ -755,7 +759,11 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
     lg(Debug) << "Registrar Module handling a new incoming REGISTER request";
 
     pjsip_transaction *tsx;
-    pjsip_tsx_create_uas(&mModule, rdata, &tsx);
+    if (fail(pjsip_tsx_create_uas(&mModule, rdata, &tsx)))
+    {
+        return PJ_TRUE;
+    }
+
     pjsip_tsx_recv_msg(tsx, rdata);
 
     if (checkAuth(rdata, tsx, NonDialog))
@@ -783,8 +791,11 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
     if (!verifyContacts(registerContacts))
     {
         pjsip_tx_data *tdata;
-        pjsip_endpt_create_response(tsx->endpt, rdata, 400, NULL, &tdata);
-        pjsip_tsx_send_msg(tsx, tdata);
+        if (success(pjsip_endpt_create_response(tsx->endpt, rdata, 400, NULL, &tdata)))
+        {
+            pjsip_tsx_send_msg(tsx, tdata);
+        }
+        return PJ_TRUE;
     }
 
     BindingWrapperSeq newBindings;
@@ -819,15 +830,17 @@ pj_bool_t PJSipRegistrarModule::on_rx_request(pjsip_rx_data *rdata)
         }
     }
 
-    mRegistrar->addAndRemoveBindings(aor, newBindings, removedBindings, mRegistrar->getQueue());
-
     // We enqueue the SIP response to make sure we send it and replicate state AFTER we have updated
     // our internal bindings.
     pjsip_tx_data *tdata;
-    pjsip_endpt_create_response(tsx->endpt, rdata, 200, NULL, &tdata);
-    mRegistrar->getQueue()->enqueueWork(new Response(tsx, tdata, aor, mRegistrar));
+    if (success(pjsip_endpt_create_response(tsx->endpt, rdata, 200, NULL, &tdata)))
+    {
+        mRegistrar->addAndRemoveBindings(aor, newBindings, removedBindings, mRegistrar->getQueue());
 
-    replicateState(aor, existingBindings, newBindings, removedBindings);
+        mRegistrar->getQueue()->enqueueWork(new Response(tsx, tdata, aor, mRegistrar));
+
+        replicateState(aor, existingBindings, newBindings, removedBindings);
+    }
 
     return PJ_TRUE;
 }

commit 13e4e6a3c7f90bb2bd53f9fe87bd51a957cc5742
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Dec 21 11:31:56 2011 -0600

    * Add proper interpretation of SIP response codes
    * Regroup the switch statement in PJSipSessionModule.cpp to be a bit more compact

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 7682e7d..e1766ee 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -1456,20 +1456,15 @@ void PJSipSessionModule::handleInviteResponse(pjsip_inv_session* inv,
 
     ConnectedLinePtr connected = getConnectedID(rdata);
 
-    //Commented because they are currently unused. They
-    //will be once the individual cases are mapped out.
-    //pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
-    //pjsip_module *module = pjsip_ua_instance();
-    //
-    //XXX There are a BUNCH of response codes we need
-    //to add code to handle.
-
     lg(Debug) << "Queuing a HandleInviteResponseOperation";
     enqueueSessionWork(new HandleInviteResponseOperation(respCode, inv->state, session, connected), inv);
 }
 
 //There are some rejection codes that we can actually do something with other than
 //just kill the code.
+//
+//Codes that may not possibly result in retrying the call should not be handled in this
+//function.
 void PJSipSessionModule::handleInviteRejection(pjsip_inv_session* inv,
     pjsip_rx_data* rdata, pjsip_transaction* tsx)
 {
@@ -1587,113 +1582,72 @@ protected:
             //Cause codes for each SIP response are taken from RFC 3398 Section 8.2.6.1 (plus errata ID 2161)
             switch (mInv->cause)
             {
-            case 400: // Bad Request
-                response->isdnCode = 41;
-                break;
-            case 401: // Unauthorized
-                response->isdnCode = 21;
-                break;
-            case 402: // Payment Required
-                response->isdnCode = 21;
-                break;
-            case 403: // Forbidden
-                response->isdnCode = 21;
-                break;
             case 404: // Not Found
+            case 485: // Ambiguous
+            case 604: // Does Not Exist Anymore
                 response->isdnCode = 1;
                 break;
-            case 405: // Method not allowed
-                response->isdnCode = 63;
+            case 486: // Busy Here
+            case 600: // Busy Everywhere
+                response->isdnCode = 17;
                 break;
-            case 406: // Not Acceptable
-                response->isdnCode = 79;
+            case 480: // Temporarily Unavailable
+                response->isdnCode = 18;
                 break;
+            case 401: // Unauthorized
+            case 402: // Payment Required
+            case 403: // Forbidden
             case 407: // Proxy Authentication Required
+            case 603: // Decline
                 response->isdnCode = 21;
                 break;
-            case 408: // Request Timeout
-                response->isdnCode = 102;
-                break;
             case 410: // Gone
                 response->isdnCode = 22;
                 break;
-            case 413: // Request Entity Too Long
-                response->isdnCode = 127;
-                break;
-            case 414: // Request-URI Too Long
-                response->isdnCode = 127;
-                break;
-            case 415: // Unsupported Media Type
-                response->isdnCode = 79;
-                break;
-            case 416: // Unsupported URI Scheme
-                response->isdnCode = 127;
-                break;
-            case 420: // Bad Extension
-                response->isdnCode = 127;
-                break;
-            case 421: // Extension Required
-                response->isdnCode = 127;
-                break;
-            case 423: // Interval Too Brief
-                response->isdnCode = 127;
-                break;
-            case 480: // Temporarily Unavailable
-                response->isdnCode = 18;
-                break;
-            case 481: // Call/Transaction Does Not Exist
-                response->isdnCode = 41;
-                break;
             case 482: // Loop Detected
-                response->isdnCode = 25;
-                break;
             case 483: // Too Many Hops
                 response->isdnCode = 25;
                 break;
             case 484: // Address Incomplete
                 response->isdnCode = 28;
                 break;
-            case 485: // Ambiguous
-                response->isdnCode = 1;
-                break;
-            case 486: // Busy Here
-                response->isdnCode = 17;
+            case 502: // Bad Gateway
+                response->isdnCode = 38;
                 break;
+            case 400: // Bad Request
+            case 481: // Call/Transaction Does Not Exist
             case 500: // Server Internal Error
+            case 503: // Service Unavailable
                 response->isdnCode = 41;
                 break;
+            case 405: // Method not allowed
+                response->isdnCode = 63;
+                break;
+            case 406: // Not Acceptable
+            case 415: // Unsupported Media Type
             case 501: // Not Implemented
                 response->isdnCode = 79;
                 break;
-            case 502: // Bad Gateway
-                response->isdnCode = 38;
-                break;
-            case 503: // Service Unavailable
-                response->isdnCode = 41;
-                break;
+            case 408: // Request Timeout
             case 504: // Server Time-out
                 response->isdnCode = 102;
                 break;
+            case 413: // Request Entity Too Long
+            case 414: // Request-URI Too Long
+            case 416: // Unsupported URI Scheme
+            case 420: // Bad Extension
+            case 421: // Extension Required
+            case 423: // Interval Too Brief
             case 505: // Version Not Supported
-                response->isdnCode = 127;
-                break;
             case 513: // Message Too Large
                 response->isdnCode = 127;
                 break;
-            case 600: // Busy Everywhere
-                response->isdnCode = 17;
-                break;
-            case 603: // Decline
-                response->isdnCode = 21;
-                break;
-            case 604: // Does Not Exist Anymore
-                response->isdnCode = 1;
-                break;
             default:
                 // 487, 488, and 606 have no mapping. Also,
                 // other types of ends to sessions (like normal clearing)
                 // will end up here.
                 response->isdnCode = 0;
+                break;
             }
 
             if (session)
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 2bb6eda..e3fda77 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -2234,13 +2234,70 @@ public:
     SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
     {
         pjsip_tx_data *packet;
-        // Assume a 503 until proven otherwise
-        unsigned int code = 503;
+        unsigned int code;
 
-        // TODO: Convert ALL response codes to equivalent SIP ones, and allow configuration to change it
-        if (mResponse->isdnCode == 17)
+        switch (mResponse->isdnCode)
         {
-            code = 486;
+            case 1: // unallocated number
+            case 2: // no route to network
+            case 3: // no route to destination
+            case 26: // non-selected user clearing
+                code = 404;
+                break;
+            case 18: // no user responding
+                code = 408;
+                break;
+            case 21: // call rejected
+            case 55: // incoming calls barred within CUG
+            case 57: // bearer capability not authorized
+            case 87: // user not member of CUG
+                code = 403;
+                break;
+            case 22: // number changed
+            case 23: // redirection to new destination
+                code = 410;
+                break;
+            case 19: // no answer from the user
+            case 20: // subscriber absent
+            case 31: // normal unspecified
+                code = 480;
+                break;
+            case 28: // address incomplete
+                code = 484;
+                break;
+            case 17: // user busy
+                code = 486;
+                break;
+            case 65: // bearer capability not implemented
+            case 70: // only restricted digital avail
+                code = 488;
+                break;
+            case 111: // protocol error
+            case 127: // interworking unspecified
+                code = 500;
+                break;
+            case 29: // facility rejected
+            case 79: // service or option not implemented
+                code = 501;
+                break;
+            case 27: // destination out of order
+                code = 502;
+                break;
+            case 34: // no circuit available
+            case 38: // network out of order
+            case 41: // temporary failure
+            case 42: // switching equipment congestion
+            case 47: // resource unavailable
+            case 58: // bearer capability not presently available
+            case 88: // incompatible destination
+                code = 503;
+                break;
... 210 lines suppressed ...


-- 
asterisk-scf/release/sip.git



More information about the asterisk-scf-commits mailing list