[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 Dec 19 16:10:41 CST 2011


branch "master" has been updated
       via  2862a336044a0f52462db837cc4b03660d2bb253 (commit)
       via  4a1aef04a21ab0c33493b745b2123bcea00ff073 (commit)
       via  fa4ad6ffcb5786b086e07b5d81845be5bb2e91bd (commit)
       via  e9bef7f80aa63e9b09c9c63c481cbd7f7d69d271 (commit)
       via  ddf99b1e738d692d8b82b77006e5890180fc4d09 (commit)
       via  60758ac259a1f15fcbb8d8293085215a808d0c51 (commit)
       via  cb74d1811198e4b47d128852a887bd2aef79dc67 (commit)
       via  acc52bcd5208a0f34d86da53f78194cd5b19dd31 (commit)
       via  d03e55a9a03a9fd63ac7a236859552ab215af8a7 (commit)
       via  a4414ee3a8b0ee71bbf703e7c31f66995ad45005 (commit)
       via  79b290400e05f79f049b5b5cc087092f34813662 (commit)
       via  9625afe1685db25068b894fcbbe87bd6586e749c (commit)
       via  74e6bddde07e381181f09c6fd9091f223fb0b615 (commit)
       via  bf350ea67b03b6acaba27ae3f3e4a2f2b88fb6f9 (commit)
       via  62c5c1710036c4212f605088b7ae150fda0be6fc (commit)
       via  3fff8394ae39b9151fc277e18e8249fca07b6882 (commit)
       via  e80f5d91f5454462a110a261eca4038112124b02 (commit)
       via  9d4f48a5bf3fe0be58fcd0c0eb4260be64de6005 (commit)
       via  bc4bd784fbed179b74e0d37926ac3601fb4577d5 (commit)
       via  cf506fd0d7be69ef2e8b061387b21e92d36afc2a (commit)
       via  621bee585d88c664857a403cc9eb4022dcb504db (commit)
       via  b6d1c108babdd3564101ddc567182860e75a99e3 (commit)
      from  1a97744ee7f2f88feb3b50df841da9735a8330d7 (commit)

Summary of changes:
 src/PJSipSessionModule.cpp |  333 +++++++++++++++++++++++++++++++-
 src/PJSipSessionModule.h   |   71 +++++++
 src/SipConfiguration.cpp   |    5 +-
 src/SipSession.cpp         |  458 ++++++++++++++++++++++++++++++++++----------
 src/SipSession.h           |   26 +++
 src/SipTransfer.cpp        |    1 +
 6 files changed, 785 insertions(+), 109 deletions(-)


- Log -----------------------------------------------------------------
commit 2862a336044a0f52462db837cc4b03660d2bb253
Merge: 1a97744 4a1aef0
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Dec 19 15:47:38 2011 -0600

    Merge branch 'party-id'


commit 4a1aef04a21ab0c33493b745b2123bcea00ff073
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Dec 2 15:57:43 2011 -0600

    Adjust so that getInfo() gets identity information.
    
    This meant that things bled out a bit, but it'll be all right.

diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 0763f35..2bb6eda 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -137,59 +137,6 @@ public:
 
     }
 
-    AsteriskSCF::SessionCommunications::V1::SessionInfoPtr getInfo()
-    {
-        AsteriskSCF::SessionCommunications::V1::SessionInfoPtr sessioninfo =
-            new AsteriskSCF::SessionCommunications::V1::SessionInfo();
-        
-        /* TODO: Utilize locking so this becomes safe
-           if (!mImplPriv->mInviteSession || mImplPriv->mInviteSession->state == PJSIP_INV_STATE_NULL)
-           {
-           sessioninfo->currentState = "ready";
-           }
-           else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_CALLING)
-           {
-           sessioninfo->currentState = "outbound";
-           }
-           else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_INCOMING)
-           {
-           sessioninfo->currentState = "inbound";
-           }
-           else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_EARLY)
-           {
-           sessioninfo->currentState = "early";
-           }
-           else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_CONNECTING)
-           {
-           sessioninfo->currentState = "connecting";
-           }
-           else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_CONFIRMED)
-           {
-           sessioninfo->currentState = "connected";
-           }
-           else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_DISCONNECTED)
-           {
-           sessioninfo->currentState = "disconnected";
-           }
-        */
-        return sessioninfo;
-    }
-
-    void addListener(const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener)
-    {
-        mListeners.push_back(listener);
-        if (mInviteSession)
-        {
-            PJSipSessionModInfo *session_mod_info =
-                static_cast<PJSipSessionModInfo*>(
-                    mInviteSession->mod_data[mManager->getSessionModule()->getModule().id]);
-            if (session_mod_info)
-            {
-                session_mod_info->updateSessionState(mInviteSession);
-            }
-            mManager->getSessionModule()->replicateState(NULL, NULL, session_mod_info);
-        }
-    }
 
     void removeListener(const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener)
     {
@@ -1454,22 +1401,20 @@ public:
     AddListenerOperation(
             const AsteriskSCF::SessionCommunications::V1::AMD_Session_addListenerPtr& cb,
             const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener,
-            const boost::shared_ptr<SipSessionPriv>& sessionPriv)
-        : mCb(cb), mListener(listener), mImplPriv(sessionPriv) { }
+            const SipSessionPtr& session)
+        : mCb(cb), mListener(listener), mSession(session) { }
 
     SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
     {
         lg(Debug) << "Executing addListener operation";
-        mImplPriv->addListener(mListener);
-        AsteriskSCF::SessionCommunications::V1::SessionInfoPtr sessionInfo =
-            mImplPriv->getInfo();
-        mCb->ice_response(sessionInfo);
+        mSession->addListener(mListener);
+        mCb->ice_response(mSession->getInfo());
         return Complete;
     }
 private:
     AsteriskSCF::SessionCommunications::V1::AMD_Session_addListenerPtr mCb;
     AsteriskSCF::SessionCommunications::V1::SessionListenerPrx mListener;
-    boost::shared_ptr<SipSessionPriv> mImplPriv;
+    SipSessionPtr mSession;
 };
 
 void SipSession::addListener_async(
@@ -1478,7 +1423,23 @@ void SipSession::addListener_async(
         const Ice::Current&)
 {
     lg(Debug) << "Queueing addListener operation";
-    enqueueSessionWork(new AddListenerOperation(cb, listener, mImplPriv));
+    enqueueSessionWork(new AddListenerOperation(cb, listener, this));
+}
+
+void SipSession::addListener(const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener)
+{
+    mImplPriv->mListeners.push_back(listener);
+    if (mImplPriv->mInviteSession)
+    {
+        PJSipSessionModInfo *session_mod_info =
+            static_cast<PJSipSessionModInfo*>(
+                mImplPriv->mInviteSession->mod_data[mImplPriv->mManager->getSessionModule()->getModule().id]);
+        if (session_mod_info)
+        {
+            session_mod_info->updateSessionState(mImplPriv->mInviteSession);
+        }
+        mImplPriv->mManager->getSessionModule()->replicateState(NULL, NULL, session_mod_info);
+    }
 }
 
 class IndicateOperation : public SuspendableWork
@@ -1661,22 +1622,19 @@ class GetInfoOperation : public SuspendableWork
 public:
     GetInfoOperation(
             const AsteriskSCF::SessionCommunications::V1::AMD_Session_getInfoPtr& cb,
-            const boost::shared_ptr<SipSessionPriv>& sessionPriv)
-        : mCb(cb), mImplPriv(sessionPriv) { }
+            const SipSessionPtr& session)
+        : mCb(cb), mSession(session) { }
 
     SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
     {
         lg(Debug) << "Executing a GetInfo operation";
-        AsteriskSCF::SessionCommunications::V1::SessionInfoPtr sessionInfo =
-            mImplPriv->getInfo();
-
-        mCb->ice_response(sessionInfo);
+        mCb->ice_response(mSession->getInfo());
         return Complete;
     }
 
 private:
     AsteriskSCF::SessionCommunications::V1::AMD_Session_getInfoPtr mCb;
-    boost::shared_ptr<SipSessionPriv> mImplPriv;
+    SipSessionPtr mSession;
 };
 
 /**
@@ -1687,7 +1645,50 @@ void SipSession::getInfo_async(
         const Ice::Current&)
 {
     lg(Debug) << "queuing a getInfo operation";
-    enqueueSessionWork(new GetInfoOperation(cb, mImplPriv));
+    enqueueSessionWork(new GetInfoOperation(cb, this));
+}
+
+AsteriskSCF::SessionCommunications::V1::SessionInfoPtr SipSession::getInfo()
+{
+    AsteriskSCF::SessionCommunications::V1::SessionInfoPtr sessioninfo =
+        new AsteriskSCF::SessionCommunications::V1::SessionInfo();
+    
+    /*
+       if (!mImplPriv->mInviteSession || mImplPriv->mInviteSession->state == PJSIP_INV_STATE_NULL)
+       {
+       sessioninfo->currentState = "ready";
+       }
+       else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_CALLING)
+       {
+       sessioninfo->currentState = "outbound";
+       }
+       else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_INCOMING)
+       {
+       sessioninfo->currentState = "inbound";
+       }
+       else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_EARLY)
+       {
+       sessioninfo->currentState = "early";
+       }
+       else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_CONNECTING)
+       {
+       sessioninfo->currentState = "connecting";
+       }
+       else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_CONFIRMED)
+       {
+       sessioninfo->currentState = "connected";
+       }
+       else if (mImplPriv->mInviteSession->state == PJSIP_INV_STATE_DISCONNECTED)
+       {
+       sessioninfo->currentState = "disconnected";
+       }
+    */
+
+    sessioninfo->connectedLine = getConnectedLine();
+    sessioninfo->sessionOwner = getSessionOwnerId();
+    sessioninfo->callerID = getCaller();
+
+    return sessioninfo;
 }
 
 class GetMediaSessionOperation : public SuspendableWork
@@ -1897,25 +1898,23 @@ public:
     SetBridgeOperation(
             const AsteriskSCF::SessionCommunications::V1::AMD_Session_setBridgePtr& cb,
             const SipSessionPtr& session,
-            const boost::shared_ptr<SipSessionPriv>& sessionPriv,
             const AsteriskSCF::SessionCommunications::V1::BridgePrx& bridge,
             const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener,
             const Ice::Current& current)
-        : mCb(cb), mSession(session), mImplPriv(sessionPriv), mBridge(bridge), mListener(listener), mCurrent(current) { }
+        : mCb(cb), mSession(session), mBridge(bridge), mListener(listener), mCurrent(current) { }
     
     SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
     {
         lg(Debug) << "Executing a SetBridge operation";
         mSession->setBridge(mBridge);
-        mImplPriv->addListener(mListener);
-        mCb->ice_response(mImplPriv->getInfo());
+        mSession->addListener(mListener);
+        mCb->ice_response(mSession->getInfo());
         return Complete;
     }
 
 private:
     AsteriskSCF::SessionCommunications::V1::AMD_Session_setBridgePtr mCb;
     SipSessionPtr mSession;
-    boost::shared_ptr<SipSessionPriv> mImplPriv;
     AsteriskSCF::SessionCommunications::V1::BridgePrx mBridge;
     AsteriskSCF::SessionCommunications::V1::SessionListenerPrx mListener;
     Ice::Current mCurrent;
@@ -1931,7 +1930,7 @@ void SipSession::setBridge_async(
     const Ice::Current& current)
 {
     lg(Debug) << "queuing a setBridge operation";
-    enqueueSessionWork(new SetBridgeOperation(cb, this, mImplPriv, bridge, listener, current));
+    enqueueSessionWork(new SetBridgeOperation(cb, this, bridge, listener, current));
 }
 
 /**
@@ -2397,6 +2396,43 @@ ConnectedLinePtr SipSession::getConnectedLine()
     return id;
 }
 
+/**
+ * Gets the SessionOwnerId party identification record for this Session.
+ * This is an internal method, intended to be called from within a queued operation.
+ */
+SessionOwnerIdPtr SipSession::getSessionOwnerId()
+{
+    SessionOwnerIdPtr id = 0;
+    AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
+    cookies.push_back(new SessionOwnerId());
+    AsteriskSCF::SessionCommunications::V1::SessionCookies results = getCookies(cookies);
+
+    if (!results.empty())
+    {
+        id = SessionOwnerIdPtr::dynamicCast(results.front());
+    }
+
+    return id;
+}
+
+/**
+ * Gets the Caller party identification record for this Session.
+ * This is an internal method, intended to be called from within a queued operation.
+ */
+CallerPtr SipSession::getCaller()
+{
+    CallerPtr id = 0;
+    AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
+    cookies.push_back(new Caller());
+    AsteriskSCF::SessionCommunications::V1::SessionCookies results = getCookies(cookies);
+
+    if (!results.empty())
+    {
+        id = CallerPtr::dynamicCast(results.front());
+    }
+
+    return id;
+}
 /** 
  * Gets the ConnectedLine party identification record for this Session.
  */
diff --git a/src/SipSession.h b/src/SipSession.h
index 9dfe0a3..31073d6 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -162,6 +162,8 @@ public:
             const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx&,
             const Ice::Current&);
 
+    void addListener(const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener);
+
     void indicate_async(
             const AsteriskSCF::SessionCommunications::V1::AMD_Session_indicatePtr& cb,
             const AsteriskSCF::SessionCommunications::V1::IndicationPtr&, const Ice::Current&);
@@ -174,6 +176,8 @@ public:
             const AsteriskSCF::SessionCommunications::V1::AMD_Session_getInfoPtr& cb,
             const Ice::Current&);
 
+    AsteriskSCF::SessionCommunications::V1::SessionInfoPtr getInfo();
+
     void getMediaSession_async(
             const AsteriskSCF::SessionCommunications::V1::AMD_Session_getMediaSessionPtr& cb,
             const Ice::Current&);
@@ -234,6 +238,16 @@ public:
      * This is an internal method and should only be called from queued operations
      */
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr getConnectedLine();
+    /**
+     * Gets the SessionOwnerId for the session.
+     * This is an internal method and should only be called from queued operations
+     */
+    AsteriskSCF::SessionCommunications::PartyIdentification::V1::SessionOwnerIdPtr getSessionOwnerId();
+    /**
+     * Gets the Caller for the session.
+     * This is an internal method and should only be called from queued operations
+     */
+    AsteriskSCF::SessionCommunications::PartyIdentification::V1::CallerPtr getCaller();
 
     void getStreams_async(
         const AsteriskSCF::SessionCommunications::V1::AMD_Session_getStreamsPtr&,
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index ee2bcaf..bb35b4b 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -480,7 +480,7 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
 
             lg(Debug) << "handleRefer() calling router connectBridgedSessions(). ";
 
-            mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), false, other_session->getConnectedLine(), d);
+            mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), false, d);
             pjsip_dlg_dec_lock(other_dlg);
             return Complete;
         }

commit fa4ad6ffcb5786b086e07b5d81845be5bb2e91bd
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Dec 1 13:18:22 2011 -0600

    Remove unnecessary debug lines from the code of codes.

diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index d3c04ba..0763f35 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -947,7 +947,6 @@ void SipSession::setSelfAsCaller()
 
 void SipSession::setSessionOwnerId(const SessionOwnerIdPtr& owner)
 {
-    lg(Debug) << "!!!!!! Setting owner id on session " << mImplPriv->mEndpoint->getName();
     mImplPriv->mSessionCookies[owner->ice_id()] = owner;
     mImplPriv->cookiesUpdated();
 }
@@ -2385,8 +2384,6 @@ void SipSession::getSessionOwnerId_async(const AMD_Session_getSessionOwnerIdPtr&
 ConnectedLinePtr SipSession::getConnectedLine()
 {
 
-    lg(Debug) << "!!!!!!! Getting ConnectedLine for session " << mImplPriv->mEndpoint->getName();
-
     ConnectedLinePtr id = 0;
     AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
     cookies.push_back(new ConnectedLine());
@@ -2394,7 +2391,6 @@ ConnectedLinePtr SipSession::getConnectedLine()
 
     if (!results.empty())
     {
-        lg(Debug) << "!!!!!!!!! Found ConnectedLine";
         id = ConnectedLinePtr::dynamicCast(results.front());
     }
 

commit e9bef7f80aa63e9b09c9c63c481cbd7f7d69d271
Merge: ddf99b1 8ec91ed
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Dec 1 10:57:48 2011 -0600

    Merge branch 'master' into party-id
    
    Conflicts:
    	src/PJSipSessionModule.cpp

diff --cc src/PJSipSessionModule.cpp
index 721f9ce,5d1d207..2150d50
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@@ -26,7 -26,7 +26,8 @@@
  
  #include <IceUtil/UUID.h>
  #include <boost/lexical_cast.hpp>
 +#include <boost/algorithm/string.hpp>
+ #include <boost/numeric/conversion/cast.hpp>
  
  #include <AsteriskSCF/Core/Endpoint/EndpointIf.h>
  #include <AsteriskSCF/Core/Routing/RoutingIf.h>
@@@ -1507,9 -1171,39 +1484,39 @@@ void PJSipSessionModule::handleInviteRe
      //to add code to handle.
  
      lg(Debug) << "Queuing a HandleInviteResponseOperation";
 -    enqueueSessionWork(new HandleInviteResponseOperation(respCode, inv->state, session), inv);
 +    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.
+ void PJSipSessionModule::handleInviteRejection(pjsip_inv_session* inv,
+     pjsip_rx_data* rdata, pjsip_transaction* tsx)
+ {
+     int respCode = rdata->msg_info.msg->line.status.code;
+     PJSipSessionModInfo *session_mod_info = (PJSipSessionModInfo*)inv->mod_data[mModule.id];
+     SipSessionPtr session = session_mod_info->getSessionPtr();
+ 
+     if (respCode == 401 || respCode == 407)
+     {
+         //Aw peas, they be wanting to authenticate, boooooooooiiiiiiiiiii
+         std::vector<pjsip_cred_info> creds;
+         mAuthManager->getAuthCredentials(rdata, creds, session->getEndpoint()->getName());
+         if (creds.size() != 0)
+         {
+             pjsip_inv_uac_restart(inv, PJ_FALSE);
+             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);
+         }
+         return;
+     }
+ }
+ 
  class TransactionStateOperation : public SipQueueableOperation
  {
  public:
diff --cc src/PJSipSessionModule.h
index 3b9c3a0,59e840a..d761e1c
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@@ -144,74 -140,9 +144,76 @@@ public
  
  private:
      void handleNewInvite(pjsip_rx_data *rdata);
 +
 +    /**
 +     * Gets the value of the Privacy setting and returns true if
 +     * the value is set to "id"
 +     */
 +    bool getPrivacy(pjsip_rx_data *rdata);
 +    /**
 +     * Generic method to get Ids from a header name.
 +     * 
 +     * This can be used for any header type that does not
 +     * have specific parameters that need to be read.
 +     */
 +    void getIds(const char *headerName,
 +            pjsip_rx_data *rdata,
 +            bool privacySet,
 +            AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
 +    /**
 +     * Get the IDs in Diversion headers.
 +     *
 +     * This will also parse the reason parameters from the headers.
 +     */
 +    void getRedirectionIds(pjsip_rx_data *rdata,
 +            bool privacySet,
 +            ReasonIdSeq& ids);
 +
 +    /**
 +     * Get the IDs from Remote-Party-ID headers.
 +     *
 +     * This will also parse the privacy and screen parameters.
 +     */
 +    void getRemotePartyIds(pjsip_rx_data *rdata,
 +            bool privacySet,
 +            AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
 +
 +    /**
 +     * Generic method to get a specific parameter from a header
 +     */
 +    std::string getParam(const std::string& headerVal, const char *paramName);
 +
 +    /**
 +     * Translate a reason string into the appropriate slice enum value
 +     */
 +    AsteriskSCF::SessionCommunications::PartyIdentification::V1::Reason translateReason(const std::string& reason);
 +
 +    /**
 +     * Get caller ID
 +     *
 +     * This will first attempt to find P-Asserted-Identity headers. If none are present, it
 +     * will use the From header to find the caller ID.
 +     */
 +    AsteriskSCF::SessionCommunications::PartyIdentification::V1::CallerPtr getCallerID(pjsip_rx_data *rdata);
 +
 +    /**
 +     * Get the connected ID
 +     *
 +     * This will first attempt to find P-Asserted-Identity headers. If none are present, it
 +     * will search for Remote-Party-ID headers.
 +     */
 +    AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr getConnectedID(pjsip_rx_data *rdata);
 +
 +    /**
 +     * Get Redirections
 +     *
 +     * This will attempt to find Diversion headers.
 +     */
 +    AsteriskSCF::SessionCommunications::PartyIdentification::V1::RedirectionsPtr getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri);
 +
      void handleInviteResponse(pjsip_inv_session *inv, pjsip_rx_data *rdata, pjsip_dialog *dlg);
+     void handleInviteRejection(pjsip_inv_session *inv, pjsip_rx_data *rdata, pjsip_transaction *tsx);
+     void handleNonInviteAuthentication(pjsip_inv_session *inv, pjsip_rx_data *rdata, pjsip_dialog *dlg, pjsip_transaction *tsx);
      void handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdata);
      void handleInfo(pjsip_inv_session *inv, pjsip_rx_data *rdata);
      bool isDTMF(pjsip_rx_data *rdata);

commit ddf99b1e738d692d8b82b77006e5890180fc4d09
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Nov 9 10:35:01 2011 -0600

    I was sending incorrect information to the routing service. Oops.

diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index dfc75e4..16bc912 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -946,6 +946,7 @@ void SipSession::setSelfAsCaller()
 
 void SipSession::setSessionOwnerId(const SessionOwnerIdPtr& owner)
 {
+    lg(Debug) << "!!!!!! Setting owner id on session " << mImplPriv->mEndpoint->getName();
     mImplPriv->mSessionCookies[owner->ice_id()] = owner;
     mImplPriv->cookiesUpdated();
 }
@@ -2377,20 +2378,23 @@ void SipSession::getSessionOwnerId_async(const AMD_Session_getSessionOwnerIdPtr&
 }
 
 /**
- * Gets the SessionId party identification record for this Session.
+ * Gets the ConnectedLine party identification record for this Session.
  * This is an internal method, intended to be called from within a queued operation.
  */
-SessionOwnerIdPtr SipSession::getSessionOwnerId()
+ConnectedLinePtr SipSession::getConnectedLine()
 {
-    SessionOwnerIdPtr id = 0;
-    SessionOwnerIdPtr toFind(new SessionOwnerId());
+
+    lg(Debug) << "!!!!!!! Getting ConnectedLine for session " << mImplPriv->mEndpoint->getName();
+
+    ConnectedLinePtr id = 0;
     AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
-    cookies.push_back(toFind);
+    cookies.push_back(new ConnectedLine());
     AsteriskSCF::SessionCommunications::V1::SessionCookies results = getCookies(cookies);
 
     if (!results.empty())
     {
-        id = SessionOwnerIdPtr::dynamicCast(results.front());
+        lg(Debug) << "!!!!!!!!! Found ConnectedLine";
+        id = ConnectedLinePtr::dynamicCast(results.front());
     }
 
     return id;
diff --git a/src/SipSession.h b/src/SipSession.h
index bc9ebb6..9dfe0a3 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -230,10 +230,10 @@ public:
     void getRedirections_async(const AsteriskSCF::SessionCommunications::V1::AMD_Session_getRedirectionsPtr& cb, const Ice::Current& );
 
     /**
-     * Gets the SessionOwnerId for the session.
+     * Gets the ConnectedLine for the session.
      * This is an internal method and should only be called from queued operations
      */
-    AsteriskSCF::SessionCommunications::PartyIdentification::V1::SessionOwnerIdPtr getSessionOwnerId();
+    AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr getConnectedLine();
 
     void getStreams_async(
         const AsteriskSCF::SessionCommunications::V1::AMD_Session_getStreamsPtr&,
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 9c9b3fc..ee2bcaf 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -480,12 +480,7 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
 
             lg(Debug) << "handleRefer() calling router connectBridgedSessions(). ";
 
-            ConnectedLineSeq connectedLines;
-            SessionOwnerIdPtr sessionOwnerId = other_session->getSessionOwnerId();
-            ConnectedLinePtr connectedLine(new ConnectedLine(sessionOwnerId->ids));
-            connectedLines.push_back(connectedLine);
-
-            mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), false, connectedLines, d);
+            mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), false, other_session->getConnectedLine(), d);
             pjsip_dlg_dec_lock(other_dlg);
             return Complete;
         }

commit 60758ac259a1f15fcbb8d8293085215a808d0c51
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Nov 8 13:45:59 2011 -0600

    Provide connected line information to the routing service when doing an attended transfer.

diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index edd975a..dfc75e4 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -2376,6 +2376,26 @@ void SipSession::getSessionOwnerId_async(const AMD_Session_getSessionOwnerIdPtr&
     enqueueSessionWork(new GetCookieAmdOperation<AMD_Session_getSessionOwnerIdPtr, SessionOwnerId, SessionOwnerIdPtr>(cb, mImplPriv));
 }
 
+/**
+ * Gets the SessionId party identification record for this Session.
+ * This is an internal method, intended to be called from within a queued operation.
+ */
+SessionOwnerIdPtr SipSession::getSessionOwnerId()
+{
+    SessionOwnerIdPtr id = 0;
+    SessionOwnerIdPtr toFind(new SessionOwnerId());
+    AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
+    cookies.push_back(toFind);
+    AsteriskSCF::SessionCommunications::V1::SessionCookies results = getCookies(cookies);
+
+    if (!results.empty())
+    {
+        id = SessionOwnerIdPtr::dynamicCast(results.front());
+    }
+
+    return id;
+}
+
 /** 
  * Gets the ConnectedLine party identification record for this Session.
  */
@@ -2463,8 +2483,8 @@ public:
      */
     GetCookiesOperation(const AsteriskSCF::SessionCommunications::V1::AMD_Session_getCookiesPtr& cb,
                         const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookieTypes,
-                        const SipSessionPrivPtr& sessionPriv)
-        : mCb(cb), mCookieTypes(cookieTypes), mImplPriv(sessionPriv)
+                        const SipSessionPtr& session)
+        : mCb(cb), mCookieTypes(cookieTypes), mSession(session)
     {
     }
 
@@ -2472,23 +2492,7 @@ public:
     {
         lg(Debug) << "Executing a GetCookies operation";
 
-        AsteriskSCF::SessionCommunications::V1::SessionCookies results;
-
-        for (AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i = mCookieTypes.begin();
-	     i != mCookieTypes.end(); ++i)
-        {
-	    AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator foundItem = 
-                mImplPriv->mSessionCookies.find((*i)->ice_id());
-
-	    if (foundItem == mImplPriv->mSessionCookies.end())
-	    {
-	        continue;
-	    }
-
-	    results.push_back(foundItem->second);
-        }
-
-        mCb->ice_response(results);
+        mCb->ice_response(mSession->getCookies(mCookieTypes));
 
         return Complete;
     }
@@ -2496,7 +2500,7 @@ public:
 private:
     AsteriskSCF::SessionCommunications::V1::AMD_Session_getCookiesPtr mCb;
     AsteriskSCF::SessionCommunications::V1::SessionCookies mCookieTypes;
-    SipSessionPrivPtr mImplPriv;
+    SipSessionPtr mSession;
 };
 
 /**
@@ -2508,7 +2512,32 @@ void SipSession::getCookies_async(
     const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookieTypes, 
     const Ice::Current&)
 {
-     enqueueSessionWork(new GetCookiesOperation(cb, cookieTypes, mImplPriv));
+     enqueueSessionWork(new GetCookiesOperation(cb, cookieTypes, this));
+}
+
+/**
+ * Get specific cookie types.
+ * This is an internal function and should be called from queued operations
+ */
+AsteriskSCF::SessionCommunications::V1::SessionCookies SipSession::getCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookieTypes)
+{
+    AsteriskSCF::SessionCommunications::V1::SessionCookies results;
+
+    for (AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i = cookieTypes.begin();
+            i != cookieTypes.end(); ++i)
+    {
+        AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator foundItem = 
+                mImplPriv->mSessionCookies.find((*i)->ice_id());
+
+        if (foundItem == mImplPriv->mSessionCookies.end())
+        {
+            continue;
+        }
+
+        results.push_back(foundItem->second);
+    }
+
+    return results;
 }
 
 /**
diff --git a/src/SipSession.h b/src/SipSession.h
index 8568f7a..bc9ebb6 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -217,6 +217,7 @@ public:
         const ::AsteriskSCF::SessionCommunications::V1::AMD_Session_getCookiesPtr&, 
         const AsteriskSCF::SessionCommunications::V1::SessionCookies&, 
         const Ice::Current&);
+    AsteriskSCF::SessionCommunications::V1::SessionCookies getCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies&);
     AsteriskSCF::SessionCommunications::V1::SessionCookies getCookies();
     AsteriskSCF::SessionCommunications::V1::SessionCookieDict getAllCookies();
 
@@ -228,6 +229,12 @@ public:
     void getConnectedLine_async(const AsteriskSCF::SessionCommunications::V1::AMD_Session_getConnectedLinePtr& cb, const ::Ice::Current&);
     void getRedirections_async(const AsteriskSCF::SessionCommunications::V1::AMD_Session_getRedirectionsPtr& cb, const Ice::Current& );
 
+    /**
+     * Gets the SessionOwnerId for the session.
+     * This is an internal method and should only be called from queued operations
+     */
+    AsteriskSCF::SessionCommunications::PartyIdentification::V1::SessionOwnerIdPtr getSessionOwnerId();
+
     void getStreams_async(
         const AsteriskSCF::SessionCommunications::V1::AMD_Session_getStreamsPtr&,
         const Ice::Current&);
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 455aef5..9c9b3fc 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -23,6 +23,7 @@
 #include <AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.h>
 
 using namespace AsteriskSCF::System::Logging;
+using namespace AsteriskSCF::SessionCommunications::PartyIdentification::V1;
 
 namespace
 {
@@ -479,7 +480,12 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
 
             lg(Debug) << "handleRefer() calling router connectBridgedSessions(). ";
 
-            mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), false, d);
+            ConnectedLineSeq connectedLines;
+            SessionOwnerIdPtr sessionOwnerId = other_session->getSessionOwnerId();
+            ConnectedLinePtr connectedLine(new ConnectedLine(sessionOwnerId->ids));
+            connectedLines.push_back(connectedLine);
+
+            mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), false, connectedLines, d);
             pjsip_dlg_dec_lock(other_dlg);
             return Complete;
         }

commit cb74d1811198e4b47d128852a887bd2aef79dc67
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Oct 14 16:18:31 2011 -0500

    Add privacy header to outgoing caller and connected updates.

diff --git a/src/PJSipSessionModule.h b/src/PJSipSessionModule.h
index 56c5ed6..3b9c3a0 100644
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@ -144,22 +144,73 @@ public:
 
 private:
     void handleNewInvite(pjsip_rx_data *rdata);
+
+    /**
+     * Gets the value of the Privacy setting and returns true if
+     * the value is set to "id"
+     */
     bool getPrivacy(pjsip_rx_data *rdata);
+    /**
+     * Generic method to get Ids from a header name.
+     * 
+     * This can be used for any header type that does not
+     * have specific parameters that need to be read.
+     */
     void getIds(const char *headerName,
             pjsip_rx_data *rdata,
             bool privacySet,
             AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
+    /**
+     * Get the IDs in Diversion headers.
+     *
+     * This will also parse the reason parameters from the headers.
+     */
     void getRedirectionIds(pjsip_rx_data *rdata,
             bool privacySet,
             ReasonIdSeq& ids);
+
+    /**
+     * Get the IDs from Remote-Party-ID headers.
+     *
+     * This will also parse the privacy and screen parameters.
+     */
     void getRemotePartyIds(pjsip_rx_data *rdata,
             bool privacySet,
             AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
+
+    /**
+     * Generic method to get a specific parameter from a header
+     */
     std::string getParam(const std::string& headerVal, const char *paramName);
+
+    /**
+     * Translate a reason string into the appropriate slice enum value
+     */
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::Reason translateReason(const std::string& reason);
+
+    /**
+     * Get caller ID
+     *
+     * This will first attempt to find P-Asserted-Identity headers. If none are present, it
+     * will use the From header to find the caller ID.
+     */
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::CallerPtr getCallerID(pjsip_rx_data *rdata);
+
+    /**
+     * Get the connected ID
+     *
+     * This will first attempt to find P-Asserted-Identity headers. If none are present, it
+     * will search for Remote-Party-ID headers.
+     */
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr getConnectedID(pjsip_rx_data *rdata);
+
+    /**
+     * Get Redirections
+     *
+     * This will attempt to find Diversion headers.
+     */
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::RedirectionsPtr getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri);
+
     void handleInviteResponse(pjsip_inv_session *inv, pjsip_rx_data *rdata, pjsip_dialog *dlg);
     void handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdata);
     void handleInfo(pjsip_inv_session *inv, pjsip_rx_data *rdata);
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 2357091..edd975a 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -1564,10 +1564,17 @@ private:
         }
 
         ConnectedLinePtr caller = ConnectedLinePtr::dynamicCast(iter->second);
+        bool addPrivacy = false;
         for (IdSeq::iterator id = caller->ids.begin(); id != caller->ids.end(); ++id)
         {
             std::string connectedName = (*id)->partyName->partyName;
             std::string connectedNumber = (*id)->partyNumber->partyNumber;
+            //Logic here is that if any ID has privacy set on it, we'll add a privacy
+            //header.
+            if (!addPrivacy)
+            {
+                addPrivacy = (*id)->partyPrivacy->isPrivate;
+            }
 
             pj_str_t paiHeader;
             pj_cstr(&paiHeader, "P-Asserted-Identity");
@@ -1585,6 +1592,18 @@ private:
 
             pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
         }
+
+        if (addPrivacy)
+        {
+            pj_str_t privacyHeader;
+            pj_cstr(&privacyHeader, "Privacy");
+            pj_str_t privacyValue;
+            pj_cstr(&privacyValue, "id");
+            pjsip_generic_string_hdr *hdr =
+                pjsip_generic_string_hdr_create(packet->pool, &privacyHeader, &privacyValue);
+
+            pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
+        }
     }
 
     AsteriskSCF::SessionCommunications::V1::AMD_Session_indicatePtr mCb;
@@ -2084,10 +2103,15 @@ private:
         }
 
         CallerPtr caller = CallerPtr::dynamicCast(iter->second);
+        bool addPrivacy = false;
         for (IdSeq::iterator id = caller->ids.begin(); id != caller->ids.end(); ++id)
         {
             std::string callerName = (*id)->partyName->partyName;
             std::string callerNumber = (*id)->partyNumber->partyNumber;
+            if (!addPrivacy)
+            {
+                addPrivacy = (*id)->partyPrivacy->isPrivate;
+            }
 
             pj_str_t paiHeader;
             pj_cstr(&paiHeader, "P-Asserted-Identity");
@@ -2105,6 +2129,18 @@ private:
 
             pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
         }
+
+        if (addPrivacy)
+        {
+            pj_str_t privacyHeader;
+            pj_cstr(&privacyHeader, "Privacy");
+            pj_str_t privacyValue;
+            pj_cstr(&privacyValue, "id");
+            pjsip_generic_string_hdr *hdr =
+                pjsip_generic_string_hdr_create(packet->pool, &privacyHeader, &privacyValue);
+
+            pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
+        }
     }
 
     void addDiversion(pjsip_tx_data *packet)

commit acc52bcd5208a0f34d86da53f78194cd5b19dd31
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Oct 14 15:21:19 2011 -0500

    Add reason and privacy parsing.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index ff0ed75..721f9ce 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -26,6 +26,7 @@
 
 #include <IceUtil/UUID.h>
 #include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
 
 #include <AsteriskSCF/Core/Endpoint/EndpointIf.h>
 #include <AsteriskSCF/Core/Routing/RoutingIf.h>
@@ -630,18 +631,123 @@ CallerPtr PJSipSessionModule::getCallerID(pjsip_rx_data *rdata)
     return caller;
 }
 
+std::string PJSipSessionModule::getParam(const std::string& headerVal, const char *paramName)
+{
+    std::vector<std::string> params;
+    boost::split(params, headerVal, boost::is_any_of(";"));
+    std::string paramValue;
+    for (std::vector<std::string>::iterator paramsIter = params.begin();
+            paramsIter != params.end(); ++paramsIter)
+    {
+        if (paramsIter->substr(0, sizeof(paramName)) == paramName)
+        {
+            paramValue = paramsIter->substr(sizeof(paramName));
+        }
+    }
+    return paramValue;
+}
+
+Reason PJSipSessionModule::translateReason(const std::string& reason)
+{
+    if (reason == "unknown")
+    {
+        return Unknown;
+    }
+    else if (reason == "user-busy")
+    {
+        return UserBusy;
+    }
+    else if (reason == "no-answer")
+    {
+        return NoAnswer;
+    }
+    else if (reason == "unavailable")
+    {
+        return Unavailable;
+    }
+    else if (reason == "unconditional")
+    {
+        return Unconditional;
+    }
+    else if (reason == "time-of-day")
+    {
+        return TimeOfDay;
+    }
+    else if (reason == "do-not-disturb")
+    {
+        return DoNotDisturb;
+    }
+    else if (reason == "deflection")
+    {
+        return Deflection;
+    }
+    else if (reason == "follow-me")
+    {
+        return FollowMe;
+    }
+    else if (reason == "out-of-service")
+    {
+        return OutOfService;
+    }
+    else if (reason == "away")
+    {
+        return Away;
+    }
+    else
+    {
+        return Unknown;
+    }
+}
+
+void PJSipSessionModule::getRedirectionIds(pjsip_rx_data *rdata,
+        bool privacySet,
+        ReasonIdSeq& ids)
+{
+    pj_str_t hdrName;
+    pj_cstr(&hdrName, "Diversion");
+
+    pjsip_generic_string_hdr *hdr = (pjsip_generic_string_hdr *) &rdata->msg_info.msg->hdr;
+    while ((hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &hdrName, hdr->next)))
+    { 
+        //With diversion headers, we want to get the reason parameter.
+        std::string headerVal(pj_strbuf(&hdr->hvalue), pj_strlen(&hdr->hvalue));
+        std::string reasonStr = getParam(headerVal, "reason=");
+        Reason reason = translateReason(reasonStr);
+
+        pjsip_name_addr *idNameAddr;
+        //pjsip_parse_uri is incredibly clear that the input string must be
+        //null-terminated. The header we have grabbed is NOT null-terminated,
+        //so we need to create a null-terminated copy.
+        //
+        //Furthermore, I can't use a std::string here because std::string::c_str()
+        //returns a const char *, and pjsip_parse_uri takes a non-const char * as
+        //its second parameter.
+        pj_str_t strCopy;
+        pj_strdup_with_null(rdata->tp_info.pool, &strCopy, &hdr->hvalue);
+        idNameAddr = (pjsip_name_addr*) pjsip_parse_uri(rdata->tp_info.pool, strCopy.ptr, strCopy.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+
+        NamePtr name(new Name(std::string(pj_strbuf(&idNameAddr->display), pj_strlen(&idNameAddr->display))));
+
+        pjsip_sip_uri *idURI = (pjsip_sip_uri *) pjsip_uri_get_uri(idNameAddr);
+        NumberPtr number (new Number(std::string(pj_strbuf(&idURI->user), pj_strlen(&idURI->user))));
+
+        IdPtr id(new Id(name, number, new Privacy(privacySet)));
+        ids.push_back(std::make_pair(reason, id));
+    }
+}
+
 RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri)
 {
     RedirectionsPtr redirections(new Redirections);
-    IdSeq ids;
+    ReasonIdSeq ids;
     bool privacySet = getPrivacy(rdata);
-    getIds("Diversion", rdata, privacySet, ids);
+    getRedirectionIds(rdata, privacySet, ids);
     
     NamePtr rURIName(new Name(std::string(pj_strbuf(&ruri->user), pj_strlen(&ruri->user))));
     NumberPtr rURINumber(new Number(std::string(pj_strbuf(&ruri->user), pj_strlen(&ruri->user))));
     PrivacyPtr rURIPrivacy(new Privacy(false));
     IdPtr rURIId(new Id(rURIName, rURINumber, rURIPrivacy));
-    for (IdSeq::iterator id = ids.begin(); id != ids.end(); ++id)
+    for (ReasonIdSeq::iterator id = ids.begin(); id != ids.end(); ++id)
     {
         //Each ID we've read indicates a redirection *from* something,
         //so we'll fill in the redirecting from information based on it.
@@ -649,7 +755,7 @@ RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_
         //targets, so we will just have to fill in the to information with
         //the data from the next diversion if it is present or from the
         //RURI if we've reached the end of the list.
-        IdSeq::iterator nextId = id + 1;
+        ReasonIdSeq::iterator nextId = id + 1;
         IdPtr toId;
         if (nextId == ids.end())
         {
@@ -658,16 +764,52 @@ RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_
         }
         else
         {
-            toId = *nextId;
+            toId = nextId->second;
         }
-        //XXX TODO get the reason from the Diversion headah!
-        RedirectionReasonPtr reason(new RedirectionReason(Unknown));
-        RedirectionPtr redirect(new Redirection(*id, toId, reason));
+        RedirectionPtr redirect(new Redirection(id->second, toId, new RedirectionReason(id->first)));
         redirections->redirects.push_back(redirect);
     }
     return redirections;
 }
 
+void PJSipSessionModule::getRemotePartyIds(pjsip_rx_data *rdata, bool privacySet, IdSeq& ids)
+{
+    pj_str_t hdrName;
+    pj_cstr(&hdrName, "Remote-Party-ID");
+
+    pjsip_generic_string_hdr *hdr = (pjsip_generic_string_hdr *) &rdata->msg_info.msg->hdr;
+    while ((hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &hdrName, hdr->next)))
+    { 
+        //With Remote-Party-ID headers, we want to get the privacy and screen parameters.
+        std::string headerVal(pj_strbuf(&hdr->hvalue), pj_strlen(&hdr->hvalue));
+        std::string privacy = getParam(headerVal, "privacy=");
+        std::string screen = getParam(headerVal, "screen=");
+
+        PrivacyPtr userPrivacy = new UserNumberPrivacy(privacy == "full" || privacySet, screen == "yes");
+
+        pjsip_name_addr *idNameAddr;
+        //pjsip_parse_uri is incredibly clear that the input string must be
+        //null-terminated. The header we have grabbed is NOT null-terminated,
+        //so we need to create a null-terminated copy.
+        //
+        //Furthermore, I can't use a std::string here because std::string::c_str()
+        //returns a const char *, and pjsip_parse_uri takes a non-const char * as
+        //its second parameter.
+        pj_str_t strCopy;
+        pj_strdup_with_null(rdata->tp_info.pool, &strCopy, &hdr->hvalue);
+        idNameAddr = (pjsip_name_addr*) pjsip_parse_uri(rdata->tp_info.pool, strCopy.ptr, strCopy.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+
+        NamePtr name(new Name(std::string(pj_strbuf(&idNameAddr->display), pj_strlen(&idNameAddr->display))));
+
+        pjsip_sip_uri *idURI = (pjsip_sip_uri *) pjsip_uri_get_uri(idNameAddr);
+        NumberPtr number (new Number(std::string(pj_strbuf(&idURI->user), pj_strlen(&idURI->user))));
+
+        IdPtr id(new Id(name, number, userPrivacy));
+        ids.push_back(id);
+    }
+
+}
+
 ConnectedLinePtr PJSipSessionModule::getConnectedID(pjsip_rx_data *rdata)
 {
     ConnectedLinePtr connected(new ConnectedLine);
@@ -680,7 +822,7 @@ ConnectedLinePtr PJSipSessionModule::getConnectedID(pjsip_rx_data *rdata)
 
     //There were no P-Asserted-Identity headers present. Maybe
     //they've used Remote-Party-ID instead...
-    getIds("Remote-Party-ID", rdata, privacySet, connected->ids);
+    getRemotePartyIds(rdata, privacySet, connected->ids);
     return connected;
 }
 
diff --git a/src/PJSipSessionModule.h b/src/PJSipSessionModule.h
index cefb899..56c5ed6 100644
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@ -96,6 +96,10 @@ private:
 
 typedef IceUtil::Handle<SipSessionCreationExtensionPoint> SipSessionCreationExtensionPointPtr;
 
+typedef std::pair<AsteriskSCF::SessionCommunications::PartyIdentification::V1::Reason,
+        AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdPtr> ReasonId;
+typedef std::vector<ReasonId> ReasonIdSeq;
+
 class PJSipSessionModule : public PJSipModule
 {
 public:
@@ -145,6 +149,14 @@ private:
             pjsip_rx_data *rdata,
             bool privacySet,
             AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
+    void getRedirectionIds(pjsip_rx_data *rdata,
+            bool privacySet,
+            ReasonIdSeq& ids);
+    void getRemotePartyIds(pjsip_rx_data *rdata,
+            bool privacySet,
+            AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
+    std::string getParam(const std::string& headerVal, const char *paramName);
+    AsteriskSCF::SessionCommunications::PartyIdentification::V1::Reason translateReason(const std::string& reason);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::CallerPtr getCallerID(pjsip_rx_data *rdata);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr getConnectedID(pjsip_rx_data *rdata);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::RedirectionsPtr getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri);
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 6b3daaa..2357091 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -1576,11 +1576,9 @@ private:
                 connectedName = connectedNumber;
             }
             pj_str_t paiValue;
-            std::stringstream ss;
-
             SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
-            ss << "\"" << connectedName << "\" <" << connectedNumber << "@" << config.sessionConfig.sourceAddress << ">;party=called";
-            pj_cstr(&paiValue, ss.str().c_str());
+            std::string ss = "\"" + connectedName + "\" <" + connectedNumber + "@" + config.sessionConfig.sourceAddress + ">;party=called";
+            pj_strset(&paiValue, (char *) ss.c_str(), ss.length());
 
             pjsip_generic_string_hdr *hdr =
                 pjsip_generic_string_hdr_create(packet->pool, &paiHeader, &paiValue);
@@ -2098,10 +2096,9 @@ private:
                 callerName = callerNumber;
             }
             pj_str_t paiValue;
-            std::stringstream ss;
             SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
-            ss << "\"" << callerName << "\" <" << callerNumber << "@" << config.sessionConfig.sourceAddress << ">;party=calling";
-            pj_strset(&paiValue, (char *) ss.str().c_str(), ss.str().length());
+            std::string ss = "\"" + callerName + "\" <" + callerNumber + "@" + config.sessionConfig.sourceAddress + ">;party=calling";
+            pj_strset(&paiValue, (char *) ss.c_str(), ss.length());
 
             pjsip_generic_string_hdr *hdr =
                 pjsip_generic_string_hdr_create(packet->pool, &paiHeader, &paiValue);
@@ -2136,7 +2133,8 @@ private:
             pj_str_t diversionValue;
             std::stringstream ss;
             SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
-            ss << "\"" << fromName << "\" <" << fromNumber << "@" << config.sessionConfig.sourceAddress << ">;reason=unconditional;counter=1";
+            std::string reason = getReason(*redirects);
+            ss << "\"" << fromName << "\" <" << fromNumber << "@" << config.sessionConfig.sourceAddress << ">;reason=" << reason << ";counter=1";
             pj_strset(&diversionValue, (char *) ss.str().c_str(), ss.str().length());
 
             pjsip_generic_string_hdr *hdr =
@@ -2145,6 +2143,37 @@ private:
             pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
         }
     }
+
+    std::string getReason(const RedirectionPtr& redirection)
+    {
+        switch (redirection->reason->why)
+        {
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Unknown:
+                return "unknown";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::UserBusy:
+                return "user-busy";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::NoAnswer:
+                return "no-answer";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Unavailable:
+                return "unavailable";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Unconditional:
+                return "unconditional";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::TimeOfDay:
+                return "time-of-day";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::DoNotDisturb:
+                return "do-not-disturb";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Deflection:
+                return "deflection";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::FollowMe:
+                return "follow-me";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::OutOfService:
+                return "out-of-service";
+            case AsteriskSCF::SessionCommunications::PartyIdentification::V1::Away:
+                return "away";
+            default:
+                return "unknown";
+        }
+    }
     SipSessionPtr mSession;
     boost::shared_ptr<SipSessionPriv> mImplPriv;
 };

commit d03e55a9a03a9fd63ac7a236859552ab215af8a7
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Oct 13 18:50:15 2011 -0500

    Add privacy and reason parsing.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 65c2388..ff0ed75 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -545,7 +545,31 @@ private:
     RedirectionsPtr mRedirections;
 };
 
-void PJSipSessionModule::getIds(const char *headerName, pjsip_rx_data *rdata, IdSeq& ids)
+bool PJSipSessionModule::getPrivacy(pjsip_rx_data *rdata)
+{
+    pj_str_t privacyHdrName;
+    pj_cstr(&privacyHdrName, "Privacy");
+
+    pjsip_generic_string_hdr *privacyHdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &privacyHdrName, rdata->msg_info.msg->hdr.next);
+
+    if (!privacyHdr)
+    {
+        return false;
+    }
+
+    std::string privacyVal(pj_strbuf(&privacyHdr->hvalue), pj_strlen(&privacyHdr->hvalue));
+    if (privacyVal == "id")
+    {
+        return true;
+    }
+
+    return false;
+}
+
+void PJSipSessionModule::getIds(const char *headerName,
+        pjsip_rx_data *rdata,
+        bool privacySet,
+        IdSeq& ids)
 {
     pj_str_t hdrName;
     pj_cstr(&hdrName, headerName);
@@ -585,7 +609,7 @@ void PJSipSessionModule::getIds(const char *headerName, pjsip_rx_data *rdata, Id
         pjsip_sip_uri *idURI = (pjsip_sip_uri *) pjsip_uri_get_uri(idNameAddr);
         NumberPtr number (new Number(std::string(pj_strbuf(&idURI->user), pj_strlen(&idURI->user))));
 
-        IdPtr id(new Id(name, number));
+        IdPtr id(new Id(name, number, new Privacy(privacySet)));
         ids.push_back(id);
     }
 }
@@ -593,7 +617,8 @@ void PJSipSessionModule::getIds(const char *headerName, pjsip_rx_data *rdata, Id
 CallerPtr PJSipSessionModule::getCallerID(pjsip_rx_data *rdata)
 {
     CallerPtr caller(new Caller);
-    getIds("P-Asserted-Identity", rdata, caller->ids); 
+    bool privacySet = getPrivacy(rdata);
+    getIds("P-Asserted-Identity", rdata, privacySet, caller->ids); 
     if (!caller->ids.empty())
     {
         return caller;
@@ -601,7 +626,7 @@ CallerPtr PJSipSessionModule::getCallerID(pjsip_rx_data *rdata)
 
     //There were no P-Asserted-Identity headers present. On an incoming call, we'll get caller ID from the
     //From header instead.
-    getIds("From", rdata, caller->ids);
+    getIds("From", rdata, privacySet, caller->ids);
     return caller;
 }
 
@@ -609,11 +634,13 @@ RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_
 {
     RedirectionsPtr redirections(new Redirections);
     IdSeq ids;
-    getIds("Diversion", rdata, ids);
+    bool privacySet = getPrivacy(rdata);
+    getIds("Diversion", rdata, privacySet, ids);
     
     NamePtr rURIName(new Name(std::string(pj_strbuf(&ruri->user), pj_strlen(&ruri->user))));
     NumberPtr rURINumber(new Number(std::string(pj_strbuf(&ruri->user), pj_strlen(&ruri->user))));
-    IdPtr rURIId(new Id(rURIName, rURINumber));
+    PrivacyPtr rURIPrivacy(new Privacy(false));
+    IdPtr rURIId(new Id(rURIName, rURINumber, rURIPrivacy));
     for (IdSeq::iterator id = ids.begin(); id != ids.end(); ++id)
     {
         //Each ID we've read indicates a redirection *from* something,
@@ -633,7 +660,9 @@ RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_
         {
             toId = *nextId;
         }
-        RedirectionPtr redirect(new Redirection(*id, toId));
+        //XXX TODO get the reason from the Diversion headah!
+        RedirectionReasonPtr reason(new RedirectionReason(Unknown));
+        RedirectionPtr redirect(new Redirection(*id, toId, reason));
         redirections->redirects.push_back(redirect);
     }
     return redirections;
@@ -642,7 +671,8 @@ RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_
 ConnectedLinePtr PJSipSessionModule::getConnectedID(pjsip_rx_data *rdata)
 {
     ConnectedLinePtr connected(new ConnectedLine);
-    getIds("P-Asserted-Identity", rdata, connected->ids);
+    bool privacySet = getPrivacy(rdata);
+    getIds("P-Asserted-Identity", rdata, privacySet, connected->ids);
     if (!connected->ids.empty())
     {
         return connected;
@@ -650,7 +680,7 @@ ConnectedLinePtr PJSipSessionModule::getConnectedID(pjsip_rx_data *rdata)
 
     //There were no P-Asserted-Identity headers present. Maybe
     //they've used Remote-Party-ID instead...
-    getIds("Remote-Party-ID", rdata, connected->ids);
+    getIds("Remote-Party-ID", rdata, privacySet, connected->ids);
     return connected;
 }
 
diff --git a/src/PJSipSessionModule.h b/src/PJSipSessionModule.h
index d34fe6b..cefb899 100644
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@ -140,7 +140,11 @@ public:
 
 private:
     void handleNewInvite(pjsip_rx_data *rdata);
-    void getIds(const char *headerName, pjsip_rx_data *rdata, AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
+    bool getPrivacy(pjsip_rx_data *rdata);
+    void getIds(const char *headerName,
+            pjsip_rx_data *rdata,
+            bool privacySet,
+            AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::CallerPtr getCallerID(pjsip_rx_data *rdata);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr getConnectedID(pjsip_rx_data *rdata);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::RedirectionsPtr getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri);
diff --git a/src/SipConfiguration.cpp b/src/SipConfiguration.cpp
index 895aee0..84b3ec3 100644
--- a/src/SipConfiguration.cpp
+++ b/src/SipConfiguration.cpp
@@ -464,7 +464,8 @@ public:
 
     SessionOwnerIdPtr createSessionOwnerId(string name, string number)
     {
-        IdPtr id = new Id(new Name(name), new Number(number));
+        //XXX Should privacy be configurable?
+        IdPtr id = new Id(new Name(name), new Number(number), new Privacy(false));
         IdSeq ids;
         ids.push_back(id);
         return new SessionOwnerId(ids);
@@ -478,7 +479,7 @@ public:
             return;
         }
 
-        IdPtr id = new Id(new Name(name), new Number(number));
+        IdPtr id = new Id(new Name(name), new Number(number), new Privacy(false));
         mSessionOwnerId->ids.push_back(id);
     }
 

commit a4414ee3a8b0ee71bbf703e7c31f66995ad45005
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Oct 13 13:54:50 2011 -0500

    Adjust for change in routeSession()

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 6e86c85..65c2388 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -500,7 +500,7 @@ protected:
                 SuspendableWorkListenerPtr listener = 0;
                 SipAMICallbackPtr cb(new SipAMICallback(listener, mSession, this, false, true));
                 Ice::CallbackPtr d = Ice::newCallback(cb, &SipAMICallback::callback);
-                mSessionRouter->begin_routeSession(operationId, mSession->getSessionProxy(), mDestination, 0, mCallerID, d);
+                mSessionRouter->begin_routeSession(operationId, mSession->getSessionProxy(), mDestination, 0, mCallerID, mRedirections, d);
             }
         }
         catch (const Ice::CommunicatorDestroyedException &)

commit 79b290400e05f79f049b5b5cc087092f34813662
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Oct 13 11:46:49 2011 -0500

    Fix compiler errors and get outgoing headers set correctly.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index d233572..6e86c85 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -500,7 +500,7 @@ protected:
                 SuspendableWorkListenerPtr listener = 0;
                 SipAMICallbackPtr cb(new SipAMICallback(listener, mSession, this, false, true));
                 Ice::CallbackPtr d = Ice::newCallback(cb, &SipAMICallback::callback);
-                mSessionRouter->begin_routeSession(operationId, mSession->getSessionProxy(), mDestination, 0, d);
+                mSessionRouter->begin_routeSession(operationId, mSession->getSessionProxy(), mDestination, 0, mCallerID, d);
             }
         }
         catch (const Ice::CommunicatorDestroyedException &)
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index fefc4f7..6b3daaa 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -890,7 +890,7 @@ public:
 
     void updateCallerID(const CallerPtr& caller, const Ice::Current&)
     {
-        AsteriskSCF::SessionCommunications::V1::SEssionCookies cookies;
+        AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
         cookies.push_back(caller);
 
         mSession->enqueueSessionWork(new SetCookiesOperation(cookies, mImplPriv, true));
@@ -2066,7 +2066,7 @@ private:
         pj_str_t referredByHdrStr;
         pj_cstr(&referredByHdrStr, "Referred-By");
         pj_str_t referredByValStr;
-        pj_cstr(&referredByValStr, referredBy->value.c_str());
+        pj_strset(&referredByValStr, (char *) referredBy->value.c_str(), referredBy->value.length());
 
         pjsip_generic_string_hdr *hdr =
             pjsip_generic_string_hdr_create(packet->pool, &referredByHdrStr, &referredByValStr);
@@ -2101,7 +2101,7 @@ private:
             std::stringstream ss;
             SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
             ss << "\"" << callerName << "\" <" << callerNumber << "@" << config.sessionConfig.sourceAddress << ">;party=calling";
-            pj_cstr(&paiValue, ss.str().c_str());
+            pj_strset(&paiValue, (char *) ss.str().c_str(), ss.str().length());
 
             pjsip_generic_string_hdr *hdr =
                 pjsip_generic_string_hdr_create(packet->pool, &paiHeader, &paiValue);
@@ -2137,7 +2137,7 @@ private:
             std::stringstream ss;
             SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
             ss << "\"" << fromName << "\" <" << fromNumber << "@" << config.sessionConfig.sourceAddress << ">;reason=unconditional;counter=1";
-            pj_cstr(&diversionValue, ss.str().c_str());
+            pj_strset(&diversionValue, (char *) ss.str().c_str(), ss.str().length());
 
             pjsip_generic_string_hdr *hdr =
                 pjsip_generic_string_hdr_create(packet->pool, &diversionHeader, &diversionValue);

commit 9625afe1685db25068b894fcbbe87bd6586e749c
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Oct 12 16:40:14 2011 -0500

    Add new SessionController method.

diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index cec0879..fefc4f7 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -888,6 +888,14 @@ public:
         mSession->enqueueSessionWork(new SetCookiesOperation(cookies, mImplPriv, true));
     }
 
+    void updateCallerID(const CallerPtr& caller, const Ice::Current&)
+    {
+        AsteriskSCF::SessionCommunications::V1::SEssionCookies cookies;
+        cookies.push_back(caller);
+
+        mSession->enqueueSessionWork(new SetCookiesOperation(cookies, mImplPriv, true));
+    }
+
     /**
      * This operation provides notification that some other Session we are connected to
      * has been redirected. 

commit 74e6bddde07e381181f09c6fd9091f223fb0b615
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 11 14:44:06 2011 -0500

    Set redirections on incoming session based on Diversion headers.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 2fe4ec1..d233572 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -407,8 +407,17 @@ public:
             pjsip_tx_data *tdata,
             pjsip_dialog *replacedDialog,
             const std::string destination,
-            const CallerPtr& callerID)
-        : mSessionModule(module), mCaller(caller), mSessionRouter(router), mInv(inv), mTdata(tdata), mReplacedDialog(replacedDialog), mDestination(destination), mCallerID(callerID) { }
+            const CallerPtr& callerID,
+            const RedirectionsPtr& redirections)
+        : mSessionModule(module), 
+        mCaller(caller),
+        mSessionRouter(router),
+        mInv(inv),
+        mTdata(tdata),
+        mReplacedDialog(replacedDialog),
+        mDestination(destination),
+        mCallerID(callerID),
+        mRedirections(redirections) { }
 
 protected:
     SuspendableWorkResult initial(const SuspendableWorkListenerPtr&)
@@ -431,6 +440,7 @@ protected:
 
         mSession->setTelephonyEventSourcesAndSinks(mCaller->getConfig());
         mSession->setSessionOwnerId(mCallerID);
+        mSession->setRedirections(mRedirections);
 
         // Create an SDP offer or answer
         const pjmedia_sdp_session *remote_sdp = NULL;
@@ -532,6 +542,7 @@ private:
     const std::string mDestination;
     SipSessionPtr mSession;
     CallerPtr mCallerID;
+    RedirectionsPtr mRedirections;
 };
 
 void PJSipSessionModule::getIds(const char *headerName, pjsip_rx_data *rdata, IdSeq& ids)
@@ -552,10 +563,18 @@ void PJSipSessionModule::getIds(const char *headerName, pjsip_rx_data *rdata, Id
         }
         else
         {
-            //This sucks. P-Asserted-Identity and Remote-Party-ID are parsed
-            //as generic strings, so we have to take the string we have and
+            //This sucks. P-Asserted-Identity, Remote-Party-ID, and others are
+            //parsed as generic strings, so we have to take the string we have and
             //turn it into a name_addr.
             pjsip_generic_string_hdr *strHdr = (pjsip_generic_string_hdr *) hdr;
+
+            //pjsip_parse_uri is incredibly clear that the input string must be
+            //null-terminated. The header we have grabbed is NOT null-terminated,
+            //so we need to create a null-terminated copy.
+            //
+            //Furthermore, I can't use a std::string here because std::string::c_str()
+            //returns a const char *, and pjsip_parse_uri takes a non-const char * as
+            //its second parameter.
             pj_str_t strCopy;
             pj_strdup_with_null(rdata->tp_info.pool, &strCopy, &strHdr->hvalue);
             idNameAddr = (pjsip_name_addr*) pjsip_parse_uri(rdata->tp_info.pool, strCopy.ptr, strCopy.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
@@ -586,6 +605,40 @@ CallerPtr PJSipSessionModule::getCallerID(pjsip_rx_data *rdata)
     return caller;
 }
 
+RedirectionsPtr PJSipSessionModule::getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri)
+{
+    RedirectionsPtr redirections(new Redirections);
+    IdSeq ids;
+    getIds("Diversion", rdata, ids);
+    
+    NamePtr rURIName(new Name(std::string(pj_strbuf(&ruri->user), pj_strlen(&ruri->user))));
+    NumberPtr rURINumber(new Number(std::string(pj_strbuf(&ruri->user), pj_strlen(&ruri->user))));
+    IdPtr rURIId(new Id(rURIName, rURINumber));
+    for (IdSeq::iterator id = ids.begin(); id != ids.end(); ++id)
+    {
+        //Each ID we've read indicates a redirection *from* something,
+        //so we'll fill in the redirecting from information based on it.
+        //Unfortunately, Diversion doesn't record each of its redirection's
+        //targets, so we will just have to fill in the to information with
+        //the data from the next diversion if it is present or from the
+        //RURI if we've reached the end of the list.
+        IdSeq::iterator nextId = id + 1;
+        IdPtr toId;
+        if (nextId == ids.end())
+        {
+            //End of the list. Use RURI.
+            toId = rURIId;
+        }
+        else
+        {
+            toId = *nextId;
+        }
+        RedirectionPtr redirect(new Redirection(*id, toId));
+        redirections->redirects.push_back(redirect);
+    }
+    return redirections;
+}
+
 ConnectedLinePtr PJSipSessionModule::getConnectedID(pjsip_rx_data *rdata)
 {
     ConnectedLinePtr connected(new ConnectedLine);
@@ -750,20 +803,29 @@ void PJSipSessionModule::handleNewInvite(pjsip_rx_data *rdata)
     //We've created our calling endpoint. Now we need to look up the destination.
     pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
     std::string destination("");
+    pjsip_sip_uri *sipRuri;
     if (PJSIP_URI_SCHEME_IS_SIP(ruri) || PJSIP_URI_SCHEME_IS_SIPS(ruri))
     {
-        pjsip_sip_uri *sipRuri = (pjsip_sip_uri *)pjsip_uri_get_uri(ruri);
+        sipRuri = (pjsip_sip_uri *)pjsip_uri_get_uri(ruri);
         //For now, we only know about destination "100" so we'll
         //grab that from the URI to pass to the locator.
         destination = std::string(pj_strbuf(&sipRuri->user), pj_strlen(&sipRuri->user));
         lg(Debug) << "Call is destined for " << destination;
     }
+    else
+    {
+        //We don't support non-SIP URIs.
+        pjsip_inv_end_session(inv_session, 500, NULL, &tdata);
+        pjsip_inv_send_msg(inv_session, tdata);
+        return;
+    }
 
     //Now let's see if they've identified themselves somehow...
     CallerPtr callerID = getCallerID(rdata);
+    RedirectionsPtr redirections = getRedirections(rdata, sipRuri);
 
     lg(Debug) << "Queueing a SessionCreationOperation";
-    sessionWork->enqueueWork(new SessionCreationOperation(this, caller, mSessionRouter, inv_session, tdata, replaced_dlg, destination, callerID));
+    sessionWork->enqueueWork(new SessionCreationOperation(this, caller, mSessionRouter, inv_session, tdata, replaced_dlg, destination, callerID, redirections));
 }
 
 void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdata)
diff --git a/src/PJSipSessionModule.h b/src/PJSipSessionModule.h
index c28e055..d34fe6b 100644
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@ -143,6 +143,7 @@ private:
     void getIds(const char *headerName, pjsip_rx_data *rdata, AsteriskSCF::SessionCommunications::PartyIdentification::V1::IdSeq& ids);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::CallerPtr getCallerID(pjsip_rx_data *rdata);
     AsteriskSCF::SessionCommunications::PartyIdentification::V1::ConnectedLinePtr getConnectedID(pjsip_rx_data *rdata);
+    AsteriskSCF::SessionCommunications::PartyIdentification::V1::RedirectionsPtr getRedirections(pjsip_rx_data *rdata, pjsip_sip_uri *ruri);
     void handleInviteResponse(pjsip_inv_session *inv, pjsip_rx_data *rdata, pjsip_dialog *dlg);
     void handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdata);
     void handleInfo(pjsip_inv_session *inv, pjsip_rx_data *rdata);
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index f3fa314..cec0879 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -942,6 +942,12 @@ void SipSession::setSessionOwnerId(const SessionOwnerIdPtr& owner)
     mImplPriv->cookiesUpdated();
 }
 
+void SipSession::setRedirections(const RedirectionsPtr& redirections)
+{
+    mImplPriv->mSessionCookies[redirections->ice_id()] = redirections;
+    mImplPriv->cookiesUpdated();
+}
+
 class CheckDirectConnectionsOperation : public SuspendableWork
 {
 public:
diff --git a/src/SipSession.h b/src/SipSession.h
index 3ac4ba2..8568f7a 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -351,6 +351,8 @@ public:
     //Must be called from a queued operation
     void setSessionOwnerId(const AsteriskSCF::SessionCommunications::PartyIdentification::V1::SessionOwnerIdPtr& owner);
 
+    void setRedirections(const AsteriskSCF::SessionCommunications::PartyIdentification::V1::RedirectionsPtr& redirections);
+
 private:
     SipSession(const Ice::ObjectAdapterPtr&, const SipEndpointPtr&, const std::string&,
         const std::vector<AsteriskSCF::SessionCommunications::V1::SessionListenerPrx>&,         

commit bf350ea67b03b6acaba27ae3f3e4a2f2b88fb6f9
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Oct 10 18:15:32 2011 -0500

    Adjust algorithm for getting IDs out of a SIP message.
    
    This prevents some crashes that I saw since we were doing
    some invalid casts.
    
    I like how I say "we" like it's more than one person making
    the mistake. It's really just me. I screwed it up. Maybe I'm
    using the royal we like some pompous monarch. No, I'd never do
    something so douchey.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 9f2e038..2fe4ec1 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -539,10 +539,27 @@ void PJSipSessionModule::getIds(const char *headerName, pjsip_rx_data *rdata, Id
     pj_str_t hdrName;
     pj_cstr(&hdrName, headerName);
 
-    pjsip_fromto_hdr *hdr = (pjsip_fromto_hdr *) &rdata->msg_info.msg->hdr;
-    while ((hdr = (pjsip_fromto_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &hdrName, hdr->next)))
-    {
-        pjsip_name_addr *idNameAddr = (pjsip_name_addr*) hdr->uri;
+    pjsip_hdr *hdr = &rdata->msg_info.msg->hdr;
+    while ((hdr = (pjsip_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &hdrName, hdr->next)))
+    { 
+        pjsip_name_addr *idNameAddr;
+        if (pj_strcmp2(&hdr->name, "From") == 0)
+        {
+            //This is the easy case. The From header is parsed in a way
+            //that makes it super easy to grab a URI.
+            pjsip_fromto_hdr *fromHdr = (pjsip_fromto_hdr *) hdr;
+            idNameAddr = (pjsip_name_addr*) fromHdr->uri;
+        }
+        else
+        {
+            //This sucks. P-Asserted-Identity and Remote-Party-ID are parsed
+            //as generic strings, so we have to take the string we have and
+            //turn it into a name_addr.
+            pjsip_generic_string_hdr *strHdr = (pjsip_generic_string_hdr *) hdr;
+            pj_str_t strCopy;
+            pj_strdup_with_null(rdata->tp_info.pool, &strCopy, &strHdr->hvalue);
+            idNameAddr = (pjsip_name_addr*) pjsip_parse_uri(rdata->tp_info.pool, strCopy.ptr, strCopy.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
+        }
 
         NamePtr name(new Name(std::string(pj_strbuf(&idNameAddr->display), pj_strlen(&idNameAddr->display))));
 

commit 62c5c1710036c4212f605088b7ae150fda0be6fc
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Oct 10 11:57:41 2011 -0500

    * Add diversion header for outgoing calls.
    * Actually put a source address in P-Asserted-Identity and Diversion headers.
    * Call updateConnectedLine() where we should.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index cb70181..9f2e038 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -1212,6 +1212,7 @@ protected:
             }
         }
         mSession->setSessionOwnerId(mConnected);
+        mSession->getSessionControllerProxy()->updateConnectedLine(mConnected);
         return Complete;
     }
 
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 2c2b9e5..f3fa314 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -1549,7 +1549,7 @@ private:
             return;
         }
 
-        CallerPtr caller = CallerPtr::dynamicCast(iter->second);
+        ConnectedLinePtr caller = ConnectedLinePtr::dynamicCast(iter->second);
         for (IdSeq::iterator id = caller->ids.begin(); id != caller->ids.end(); ++id)
         {
             std::string connectedName = (*id)->partyName->partyName;
@@ -1563,7 +1563,9 @@ private:
             }
             pj_str_t paiValue;
             std::stringstream ss;
-            ss << "\"" << connectedName << "\" <" << connectedNumber << "@" << /*XXX WTF goes here? */ "..." << ">;party=called";
+
+            SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
+            ss << "\"" << connectedName << "\" <" << connectedNumber << "@" << config.sessionConfig.sourceAddress << ">;party=called";
             pj_cstr(&paiValue, ss.str().c_str());
 
             pjsip_generic_string_hdr *hdr =
@@ -2014,6 +2016,8 @@ public:
 
         addCaller(packet);
 
+        addDiversion(packet);
+
         // Boom! Houston, we have transmission.
         pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
         return Complete;
@@ -2081,7 +2085,8 @@ private:
             }
             pj_str_t paiValue;
             std::stringstream ss;
-            ss << "\"" << callerName << "\" <" << callerNumber << "@" << /*XXX WTF goes here? */ "..." << ">;party=calling";
+            SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
+            ss << "\"" << callerName << "\" <" << callerNumber << "@" << config.sessionConfig.sourceAddress << ">;party=calling";
             pj_cstr(&paiValue, ss.str().c_str());
 
             pjsip_generic_string_hdr *hdr =
@@ -2090,6 +2095,42 @@ private:
             pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
         }
     }
+
+    void addDiversion(pjsip_tx_data *packet)
+    {
+        AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator iter =
+            mImplPriv->mSessionCookies.find(Redirections::ice_staticId());
+
+        if (iter == mImplPriv->mSessionCookies.end())
+        {
+            lg(Debug) << "No Redirection cookie present";
+            return;
+        }
+
+        RedirectionsPtr redirections = RedirectionsPtr::dynamicCast(iter->second);
+        for (RedirectionSeq::iterator redirects = redirections->redirects.begin(); redirects != redirections->redirects.end(); ++redirects)
+        {
+            std::string fromName = (*redirects)->fromId->partyName->partyName;
+            std::string fromNumber = (*redirects)->fromId->partyNumber->partyNumber;
+
+            pj_str_t diversionHeader;
+            pj_cstr(&diversionHeader, "Diversion");
+            if (fromName.empty())
+            {
+                fromName = fromNumber;
+            }
+            pj_str_t diversionValue;
+            std::stringstream ss;
+            SipEndpointConfig &config = mSession->getEndpoint()->getConfig();
+            ss << "\"" << fromName << "\" <" << fromNumber << "@" << config.sessionConfig.sourceAddress << ">;reason=unconditional;counter=1";
+            pj_cstr(&diversionValue, ss.str().c_str());
+
+            pjsip_generic_string_hdr *hdr =
+                pjsip_generic_string_hdr_create(packet->pool, &diversionHeader, &diversionValue);
+
+            pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
+        }
+    }
     SipSessionPtr mSession;
     boost::shared_ptr<SipSessionPriv> mImplPriv;
 };

commit 3fff8394ae39b9151fc277e18e8249fca07b6882
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Oct 7 17:14:58 2011 -0500

    Set session owner ID based on parsed data.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 2192f88..cb70181 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -430,6 +430,7 @@ protected:
         mSession->setDialog(mInv->dlg);
 
         mSession->setTelephonyEventSourcesAndSinks(mCaller->getConfig());
+        mSession->setSessionOwnerId(mCallerID);
 
         // Create an SDP offer or answer
         const pjmedia_sdp_session *remote_sdp = NULL;
@@ -1210,6 +1211,7 @@ protected:
                 }
             }
         }
+        mSession->setSessionOwnerId(mConnected);
         return Complete;
     }
 
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 3db5ee3..2c2b9e5 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -936,6 +936,12 @@ void SipSession::setSelfAsCaller()
     mImplPriv->mSessionCookies[dialed->ice_id()] = dialed;
 }
 
+void SipSession::setSessionOwnerId(const SessionOwnerIdPtr& owner)
+{
+    mImplPriv->mSessionCookies[owner->ice_id()] = owner;
+    mImplPriv->cookiesUpdated();
+}
+
 class CheckDirectConnectionsOperation : public SuspendableWork
 {
 public:
diff --git a/src/SipSession.h b/src/SipSession.h
index 50da5f9..3ac4ba2 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -348,6 +348,9 @@ public:
 
     void setSelfAsCaller();
 
+    //Must be called from a queued operation
+    void setSessionOwnerId(const AsteriskSCF::SessionCommunications::PartyIdentification::V1::SessionOwnerIdPtr& owner);
+
 private:
     SipSession(const Ice::ObjectAdapterPtr&, const SipEndpointPtr&, const std::string&,
         const std::vector<AsteriskSCF::SessionCommunications::V1::SessionListenerPrx>&,         

commit e80f5d91f5454462a110a261eca4038112124b02
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Oct 7 16:16:08 2011 -0500

    Parse connected line data on SIP responses.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index c175836..2192f88 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -406,8 +406,9 @@ public:
             pjsip_inv_session *inv,
             pjsip_tx_data *tdata,
             pjsip_dialog *replacedDialog,
-            const std::string destination)
-        : mSessionModule(module), mCaller(caller), mSessionRouter(router), mInv(inv), mTdata(tdata), mReplacedDialog(replacedDialog), mDestination(destination) { }
+            const std::string destination,
+            const CallerPtr& callerID)
+        : mSessionModule(module), mCaller(caller), mSessionRouter(router), mInv(inv), mTdata(tdata), mReplacedDialog(replacedDialog), mDestination(destination), mCallerID(callerID) { }
 
 protected:
     SuspendableWorkResult initial(const SuspendableWorkListenerPtr&)
@@ -529,9 +530,10 @@ private:
     pjsip_dialog *mReplacedDialog;
     const std::string mDestination;
     SipSessionPtr mSession;
+    CallerPtr mCallerID;
 };
 
-void getIds(const char *headerName, pjsip_rx_data *rdata, IdSeq& ids)
... 430 lines suppressed ...


-- 
asterisk-scf/release/sip.git



More information about the asterisk-scf-commits mailing list