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

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Thu Sep 15 19:38:44 CDT 2011


branch "partidextensionpoint" has been created
        at  50be13da300019e3084f6d74964e231c7bfc72af (commit)

- Log -----------------------------------------------------------------
commit 50be13da300019e3084f6d74964e231c7bfc72af
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Thu Sep 15 19:37:31 2011 -0500

     - Changed outgoing updateConnectedLine to use AMI.
     - Removed handling of updateRedirecting that was based on wrong assumption.

diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index bad71eb..866ab04 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -796,47 +796,6 @@ private:
     SipSessionPtr mSession;
 };
 
-class UpdateRedirectingOperation : public SuspendableWork
-{
-public:
-    UpdateRedirectingOperation(const RedirectingPtr& redirecting,
-                               const boost::shared_ptr<SipSessionPriv>& sessionPriv,
-                               const SipSessionPtr& session)
-        : mRedirecting(redirecting), mImplPriv(sessionPriv), mSession(session)
-    {
-    }
-
-    SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
-    {
-        lg(Debug) << "Executing an UpdateRedirecting operation";
-
-        AsteriskSCF::SessionCommunications::V1::SessionCookieDict cookies = mSession->getAllCookies();
-
-        AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(mRedirecting->ice_id());
-
-        int updatedCount = 1;
-        if (search != cookies.end())
-        {
-            RedirectingPtr found = RedirectingPtr::dynamicCast(search->second);
-            updatedCount = found->count + 1;
-        }
-
-        mRedirecting->count = updatedCount;
-
-        // Set or replace redirected info.
-        mImplPriv->mSessionCookies[mRedirecting->ice_id()] = mRedirecting;
-  
-        mImplPriv->cookiesUpdated();
-
-        return Complete;
-    }
-
-private:
-    RedirectingPtr mRedirecting;
-    boost::shared_ptr<SipSessionPriv> mImplPriv;
-    SipSessionPtr mSession;
-};
-
 class SetCookiesOperation : public SuspendableWork
 {
 public:
@@ -903,6 +862,10 @@ public:
         mSession->enqueueSessionWork(new RemoveStreamsOperation(cb, streams, mImplPriv, mSession));
     }
     
+    /**
+     * This operation allows the externally connected component (typically the bridge)
+     * to update this session's ConnectedLine information. 
+     */
     void updateConnectedLine(const ConnectedLinePtr& connected, const Ice::Current&) 
     {
         AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
@@ -911,13 +874,13 @@ public:
         mSession->enqueueSessionWork(new SetCookiesOperation(cookies, mImplPriv, true));
     }
 
-    void updateRedirecting(const RedirectingPtr& redirecting, const ::Ice::Current&) 
+    /**
+     * This operation provides notification that some other Session we are connected to
+     * has been redirected. 
+     */
+    void redirectingUpdated(const RedirectingPtr& redirecting, const ::Ice::Current&) 
     {
-        // TBD.. This merits discussion. I don't think the caller should pass in a new
-        // Redirecting record, but rather just the Id of who's being redirected to. 
-        // Counts and "from" should be maintained internally to the session that owns the record. 
-
-        mSession->enqueueSessionWork(new UpdateRedirectingOperation(redirecting, mImplPriv, mSession));
+        // TBD. 
     }
 
 private:
@@ -1628,7 +1591,7 @@ public:
                 // Set the ConnectedLine information on the other controller. 
                 SessionOwnerIdPtr owner = SessionOwnerIdPtr::dynamicCast(search->second);
                 ConnectedLinePtr connectedLine = new ConnectedLine(owner->ids);
-                mController->updateConnectedLine(connectedLine); // Need to be AMI?
+                mController->begin_updateConnectedLine(connectedLine); 
             }
             else
             {

commit ec01c62e89fc764c104d4552891d366db52ad9b9
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Sun Sep 11 22:52:07 2011 -0500

    Support changes to API made for Media Session cookie support.

diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index dfaebf8..effd1f4 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -48,7 +48,7 @@ namespace AsteriskSCF
 namespace SipSessionManager
 {
 
-string cookieKey(string &endpointName, const SessionCookiePtr& cookie)
+string cookieKey(string &endpointName, const AsteriskSCF::SessionCommunications::V1::SessionCookiePtr& cookie)
 {
     string key = endpointName + "::" + cookie->ice_id();
     return key;
@@ -185,7 +185,7 @@ public:
         mName(name), mAdapter(adapter), mEndpointFactory(factory), mManager(manager), mServiceLocator(serviceLocator),
         mReplicationContext(replicationContext),
         mDefaultListeners(new AsteriskSCF::Collections::ProxySet<SessionListenerPrx>(adapter, lg, "Default Session Listeners")),
-        mDefaultSessionCookies(new AsteriskSCF::Collections::HandleSet<SessionCookiePtr>(lg, "Default Cookies"))
+        mDefaultSessionCookies(new AsteriskSCF::Collections::HandleSet<AsteriskSCF::SessionCommunications::V1::SessionCookiePtr>(lg, "Default Cookies"))
     {
     };
     
@@ -238,7 +238,7 @@ public:
     AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx mServiceLocator;
     SipReplicationContextPtr mReplicationContext;
     AsteriskSCF::Collections::ProxySet<SessionListenerPrx>::SetPtr mDefaultListeners;
-    AsteriskSCF::Collections::HandleSet<SessionCookiePtr>::SetPtr mDefaultSessionCookies;
+    AsteriskSCF::Collections::HandleSet<AsteriskSCF::SessionCommunications::V1::SessionCookiePtr>::SetPtr mDefaultSessionCookies;
 };
 
 SipEndpoint::SipEndpoint(const Ice::ObjectAdapterPtr& adapter, 
@@ -402,7 +402,7 @@ AsteriskSCF::SessionCommunications::V1::SessionPrx SipEndpoint::createSession(
         listeners.push_back(listener);
     }
 
-    SessionCookies defaultCookies = mImplPriv->mDefaultSessionCookies->getAll();
+    AsteriskSCF::SessionCommunications::V1::SessionCookies defaultCookies = mImplPriv->mDefaultSessionCookies->getAll();
 
     SipSessionPtr session = SipSession::create(
             mImplPriv->mAdapter, 
@@ -430,7 +430,7 @@ AsteriskSCF::SessionCommunications::V1::SessionPrx SipEndpoint::createSession(
 AsteriskSCF::SipSessionManager::SipSessionPtr SipEndpoint::createSession(const std::string& destination)
 {
     vector<SessionListenerPrx> defaultListeners = mImplPriv->mDefaultListeners->getAll();
-    SessionCookies defaultCookies = mImplPriv->mDefaultSessionCookies->getAll();
+    AsteriskSCF::SessionCommunications::V1::SessionCookies defaultCookies = mImplPriv->mDefaultSessionCookies->getAll();
 
     SipSessionPtr session = SipSession::create(
              mImplPriv->mAdapter, 
@@ -575,13 +575,14 @@ void SipEndpoint::removeDefaultSessionListener(const SessionListenerPrx& listene
 /** 
  * Copies the input cookies minus the read-only cookies. 
  */
-SessionCookies filterReadOnlyCookies(const SessionCookies& cookiesIn, const std::string& logMessage)
+AsteriskSCF::SessionCommunications::V1::SessionCookies 
+    filterReadOnlyCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookiesIn, const std::string& logMessage)
 {
-    SessionCookies cookiesOut;
+    AsteriskSCF::SessionCommunications::V1::SessionCookies cookiesOut;
 
     // Filter out any read-only cookies passed in. They must be set through specific API calls, 
     // not via generic cookie API. 
-    for(SessionCookies::const_iterator i=cookiesIn.begin(); i != cookiesIn.end(); ++i)
+    for(AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i=cookiesIn.begin(); i != cookiesIn.end(); ++i)
     {
         if (SipSession::isSessionCookieReadOnly(*i))
         {
@@ -598,9 +599,9 @@ SessionCookies filterReadOnlyCookies(const SessionCookies& cookiesIn, const std:
  * @param cookies A sequence of cookies to be removed. 
  * @param privileged Indicates if the calling operation has privilege to alter read-only cookies. 
  */
-void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, bool privileged)
+void SipEndpoint::addDefaultSessionCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies, bool privileged)
 {
-    SessionCookies modCookies;
+    AsteriskSCF::SessionCommunications::V1::SessionCookies modCookies;
 
     if (privileged)
     {
@@ -621,7 +622,7 @@ void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, bool p
 
     // Replicate this change. 
     SipStateItemSeq items;
-    for(SessionCookies::const_iterator i=modCookies.begin(); i != modCookies.end(); ++i)
+    for(AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i=modCookies.begin(); i != modCookies.end(); ++i)
     {
         items.push_back(new DefaultSessionCookieItem(cookieKey(mImplPriv->mName,  *i),
                 "", 
@@ -632,8 +633,7 @@ void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, bool p
     mImplPriv->mReplicationContext->getReplicator().tryOneWay()->setState(items);
 }
 
-
-void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, const Ice::Current&)
+void SipEndpoint::addDefaultSessionCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies, const Ice::Current&)
 {
     addDefaultSessionCookies(cookies, false);
 }
@@ -643,9 +643,9 @@ void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, const
  * @param cookies A sequence of cookies to be removed. 
  * @param privileged Indicates if the calling operation has privilege to alter read-only cookies. 
  */
-void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, bool privileged)
+void SipEndpoint::removeDefaultSessionCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies, bool privileged)
 {
-    SessionCookies modCookies;
+    AsteriskSCF::SessionCommunications::V1::SessionCookies modCookies;
 
     if (privileged)
     {
@@ -666,7 +666,7 @@ void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, boo
 
     // Replicate this change. 
     SipStateItemSeq items;
-    for(SessionCookies::const_iterator i=modCookies.begin(); i != modCookies.end(); ++i)
+    for(AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i=modCookies.begin(); i != modCookies.end(); ++i)
     {
         items.push_back(new DefaultSessionCookieItem(cookieKey(mImplPriv->mName,  *i),
                 "", 
@@ -677,21 +677,21 @@ void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, boo
     mImplPriv->mReplicationContext->getReplicator().tryOneWay()->removeStateForItems(items);
 }
 
-void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, const Ice::Current&)
+void SipEndpoint::removeDefaultSessionCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies, const Ice::Current&)
 {
     removeDefaultSessionCookies(cookies, false);
 }
 
-void SipEndpoint::addDefaultSessionCookie(const SessionCookiePtr& cookie)
+void SipEndpoint::addDefaultSessionCookie(const AsteriskSCF::SessionCommunications::V1::SessionCookiePtr& cookie)
 {
-    SessionCookies cookies;
+    AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
     cookies.push_back(cookie);
     addDefaultSessionCookies(cookies, true);
 }
 
-void SipEndpoint::removeDefaultSessionCookie(const SessionCookiePtr& cookie)
+void SipEndpoint::removeDefaultSessionCookie(const AsteriskSCF::SessionCommunications::V1::SessionCookiePtr& cookie)
 {
-    SessionCookies cookies;
+    AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
     cookies.push_back(cookie);
     removeDefaultSessionCookies(cookies, true);
 }
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index b06a154..bad71eb 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -39,6 +39,7 @@
 #include <AsteriskSCF/Media/SDP/MediaSDPIf.h>
 #include <AsteriskSCF/Media/RTP/MediaRTCPIf.h>
 #include <AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.h>
+#include <AsteriskSCF/Collections/HandleSet.h>
 #include "NATOptions.h"
 
 using namespace AsteriskSCF::System::Logging;
@@ -64,38 +65,6 @@ namespace SipSessionManager
 
 using namespace AsteriskSCF::System::WorkQueue::V1;
 
-class SipMediaSession : public Media::V1::Session
-{
-public:
-    SipMediaSession(const SipSessionPtr& session) : mId(IceUtil::generateUUID()), mSession(session) { };
-
-    AsteriskSCF::Media::V1::StreamSourceSeq getSources(const Ice::Current&)
-    {
-        return mSession->getMediaSources();
-    }
-
-    AsteriskSCF::Media::V1::StreamSinkSeq getSinks(const Ice::Current&)
-    {
-        return mSession->getMediaSinks();
-    }
-
-    virtual std::string getId(const Ice::Current&)
-    {
-        return mId;
-    }
-
-private:
-    /**
-     * Unique identifier for the media session.
-     */
-    std::string mId;
-
-    /**
-     * A pointer to the communications session that created us.
-     */
-    SipSessionPtr mSession;
-};
-
 /**
  * A class that identifies a set of read-only cookie types.
  * The types in this set will be protected from being altered
@@ -408,7 +377,6 @@ private:
 }; // class SipSessionPriv
 typedef boost::shared_ptr<SipSessionPriv> SipSessionPrivPtr;
 
-
 ReadOnlyCookieTypes SipSessionPriv::mReadOnlyCookieTypes;
 
 /**
@@ -420,6 +388,192 @@ bool SipSession::isSessionCookieReadOnly(const AsteriskSCF::SessionCommunication
 }
 
 /**
+ * Get the specified cookies from the media sessions and pass it to 
+ * the given AMD callback handle. 
+ */
+class GetMediaSessionCookiesOperation : public SuspendableWork
+{
+public:
+    /**
+     * ctor()
+     * @param cb The AMD callback reference.
+     * @param cookieTypes The cookies to get. 
+     * @param sessionPriv The session for whom the information is requested from.
+     */
+    GetMediaSessionCookiesOperation(
+        const AsteriskSCF::Media::V1::AMD_Session_getCookiesPtr& cb,
+        const AsteriskSCF::Media::V1::SessionCookies& cookieTypes, 
+        const SipSessionPtr& session)
+         : mCb(cb), mCookieTypes(cookieTypes), mSession(session)
+    {
+    }
+
+    SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+    {
+        lg(Debug) << "Executing a GetMediaSessionCookiesOperation operation";
+
+        AsteriskSCF::Media::V1::SessionCookies results;
+
+        // Gather the cookies from all of the Session's RTP Media Sessions. 
+        RTPMediaSessionSeq mediaSessions = mSession->getRTPMediaSessions();
+        for(RTPMediaSessionSeq::iterator i = mediaSessions.begin(); 
+            i != mediaSessions.end(); ++i)
+        {
+            AsteriskSCF::Media::V1::SessionCookies cookies = (*i)->getCookies(mCookieTypes);
+            results.insert(results.end(), cookies.begin(), cookies.end());
+        }
+
+        mCb->ice_response(results);
+
+        return Complete;
+    }
+
+private:
+    AsteriskSCF::Media::V1::AMD_Session_getCookiesPtr mCb;
+    AsteriskSCF::Media::V1::SessionCookies mCookieTypes;
+    SipSessionPtr mSession;
+};
+
+/**
+ * Set the specified cookies on the media sessions. 
+ */
+class SetMediaSessionCookiesOperation : public SuspendableWork
+{
+public:
+    /**
+     * ctor()
+     * @param cookieTypes The cookies to get. 
+     * @param sessionPriv The session for whom the information is requested from.
+     */
+    SetMediaSessionCookiesOperation(
+        const AsteriskSCF::Media::V1::SessionCookies& cookies, 
+        const SipSessionPtr& session)
+         : mCookies(cookies), mSession(session)
+    {
+    }
+
+    SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+    {
+        lg(Debug) << "Executing a SetMediaSessionCookiesOperation operation";
+
+        AsteriskSCF::Media::V1::SessionCookies results;
+
+        // Set the cookies on all of the Session's RTP Media Sessions. 
+        RTPMediaSessionSeq mediaSessions = mSession->getRTPMediaSessions();
+        for(RTPMediaSessionSeq::iterator i = mediaSessions.begin(); 
+            i != mediaSessions.end(); ++i)
+        {
+            (*i)->setCookies(mCookies);
+        }
+
+        return Complete;
+    }
+
+private:
+    AsteriskSCF::Media::V1::SessionCookies mCookies;
+    SipSessionPtr mSession;
+};
+
+/**
+ * Remove the specified cookies from the media sessions. 
+ */
+class RemoveMediaSessionCookiesOperation : public SuspendableWork
+{
+public:
+    /**
+     * ctor()
+     * @param cookieTypes The cookies to get. 
+     * @param sessionPriv The session for whom the information is requested from.
+     */
+    RemoveMediaSessionCookiesOperation(
+        const AsteriskSCF::Media::V1::SessionCookies& cookieTypes, 
+        const SipSessionPtr& session)
+         : mCookieTypes(cookieTypes), mSession(session)
+    {
+    }
+
+    SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+    {
+        lg(Debug) << "Executing a RemoveMediaSessionCookiesOperation operation";
+
+        AsteriskSCF::Media::V1::SessionCookies results;
+
+        // Set the cookies on all of the Session's RTP Media Sessions. 
+        RTPMediaSessionSeq mediaSessions = mSession->getRTPMediaSessions();
+        for(RTPMediaSessionSeq::iterator i = mediaSessions.begin(); 
+            i != mediaSessions.end(); ++i)
+        {
+            (*i)->removeCookies(mCookieTypes);
+        }
+
+        return Complete;
+    }
+
+private:
+    AsteriskSCF::Media::V1::SessionCookies mCookieTypes;
+    SipSessionPtr mSession;
+};
+
+/** 
+ * Servant for the Sessions's media Session interface.
+ */
+class SipMediaSession : public Media::V1::Session
+{
+public:
+    SipMediaSession(const SipSessionPtr& session) 
+        : mId(IceUtil::generateUUID()), 
+          mSession(session)
+    {
+    }
+
+    AsteriskSCF::Media::V1::StreamSourceSeq getSources(const Ice::Current&)
+    {
+        return mSession->getMediaSources();
+    }
+
+    AsteriskSCF::Media::V1::StreamSinkSeq getSinks(const Ice::Current&)
+    {
+        return mSession->getMediaSinks();
+    }
+
+    virtual std::string getId(const Ice::Current&)
+    {
+        return mId;
+    }
+
+    void setCookies(const AsteriskSCF::Media::V1::SessionCookies& cookies, 
+                    const Ice::Current&)
+    {
+        mSession->enqueueSessionWork(new SetMediaSessionCookiesOperation(cookies, mSession));
+    }
+
+    void getCookies_async(
+          const ::AsteriskSCF::Media::V1::AMD_Session_getCookiesPtr& cb,
+          const AsteriskSCF::Media::V1::SessionCookies& cookiesToGet, 
+          const Ice::Current&)
+    {
+        mSession->enqueueSessionWork(new GetMediaSessionCookiesOperation(cb, cookiesToGet, mSession));
+    }
+
+    void removeCookies(const AsteriskSCF::Media::V1::SessionCookies& cookies, 
+                    const Ice::Current&)
+    {
+        mSession->enqueueSessionWork(new RemoveMediaSessionCookiesOperation(cookies, mSession));
+    }
+
+private:
+    /**
+     * Unique identifier for the media session.
+     */
+    std::string mId;
+
+    /**
+     * A pointer to the communications session that created us.
+     */
+    SipSessionPtr mSession;
+};
+
+/**
  * Template for allocating from a pool.
  */
 template<typename T>
@@ -656,9 +810,9 @@ public:
     {
         lg(Debug) << "Executing an UpdateRedirecting operation";
 
-        SessionCookieDict cookies = mSession->getAllCookies();
+        AsteriskSCF::SessionCommunications::V1::SessionCookieDict cookies = mSession->getAllCookies();
 
-        SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(mRedirecting->ice_id());
+        AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(mRedirecting->ice_id());
 
         int updatedCount = 1;
         if (search != cookies.end())
@@ -785,7 +939,7 @@ void SipSession::setSelfAsCaller()
 {
     // Note: The SessionOwnerId is set via a default cookie added to the Endpoint. 
     SessionOwnerIdPtr test = new SessionOwnerId();
-    SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(test->ice_id());
+    AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(test->ice_id());
 
     if (search == mImplPriv->mSessionCookies.end())
     {
@@ -1468,7 +1622,7 @@ public:
 
             // Update the party identification. 
             SessionOwnerIdPtr test = new SessionOwnerId();
-            SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(test->ice_id());
+            AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(test->ice_id());
             if (search != mImplPriv->mSessionCookies.end())
             {
                 // Set the ConnectedLine information on the other controller. 
@@ -1840,7 +1994,7 @@ public:
         lg(Debug) << "Executing a GetCookie operation";
 
         CookiePtr test = new CookieType();
-        SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(test->ice_id());
+        AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(test->ice_id());
 
         if (search == mImplPriv->mSessionCookies.end())
         {
@@ -1979,28 +2133,68 @@ void SipSession::removeCookies(const AsteriskSCF::SessionCommunications::V1::Ses
 }
 
 /**
- * An implementation of the getCookies method as defined in SessionCommunications.ice which gets specific cookies
- * from the session.
+ * Get the specified cookies from the session and pass it to 
+ * the given AMD callback handle. 
+ *
+ * @param cb The AMD callback reference.
+ * @param cookieTypes The cookies to get. 
+ * @param sessionPriv The session for whom the information is requested from.
  */
-AsteriskSCF::SessionCommunications::V1::SessionCookies SipSession::getCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookieTypes, const Ice::Current&)
+class GetCookiesOperation : public SuspendableWork
 {
-    AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
-
-    for (AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i = cookieTypes.begin();
-     i != cookieTypes.end();
-     ++i)
+public:
+    /**
+     * @param cb The callback handle for the AMD operation that requested the information.
+     * @param session The session for whom the information is requested from.
+     */
+    GetCookiesOperation(const AsteriskSCF::SessionCommunications::V1::AMD_Session_getCookiesPtr& cb,
+                        const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookieTypes,
+                        const SipSessionPrivPtr& sessionPriv)
+        : mCb(cb), mCookieTypes(cookieTypes), mImplPriv(sessionPriv)
     {
-    AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator cookie = mImplPriv->mSessionCookies.find((*i)->ice_id());
+    }
 
-    if (cookie == mImplPriv->mSessionCookies.end())
+    SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
     {
-        continue;
-    }
+        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());
 
-    cookies.push_back(cookie->second);
+	    if (foundItem == mImplPriv->mSessionCookies.end())
+	    {
+	        continue;
+	    }
+
+	    results.push_back(foundItem->second);
+        }
+
+        mCb->ice_response(results);
+
+        return Complete;
     }
 
-    return cookies;
+private:
+    AsteriskSCF::SessionCommunications::V1::AMD_Session_getCookiesPtr mCb;
+    AsteriskSCF::SessionCommunications::V1::SessionCookies mCookieTypes;
+    SipSessionPrivPtr mImplPriv;
+};
+
+/**
+ * An implementation of the getCookies method as defined in SessionCommunications.ice which gets specific cookies
+ * from the session.
+ */
+void SipSession::getCookies_async(
+    const ::AsteriskSCF::SessionCommunications::V1::AMD_Session_getCookiesPtr&cb,
+    const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookieTypes, 
+    const Ice::Current&)
+{
+     enqueueSessionWork(new GetCookiesOperation(cb, cookieTypes, mImplPriv));
 }
 
 /**
diff --git a/src/SipSession.h b/src/SipSession.h
index cb501f1..788e736 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -211,8 +211,11 @@ public:
      * Used during replication
      */
     void setCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookieDict&);
-    void removeCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies&, const Ice::Current& );
-    AsteriskSCF::SessionCommunications::V1::SessionCookies getCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies&, const Ice::Current&);
+    void removeCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies&, const Ice::Current&);
+    void getCookies_async(
+        const ::AsteriskSCF::SessionCommunications::V1::AMD_Session_getCookiesPtr&, 
+        const AsteriskSCF::SessionCommunications::V1::SessionCookies&, 
+        const Ice::Current&);
     AsteriskSCF::SessionCommunications::V1::SessionCookies getCookies();
     AsteriskSCF::SessionCommunications::V1::SessionCookieDict getAllCookies();
 

commit 1c329a070da3354941507edd495c84d1cd0535ca
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Sun Sep 11 21:40:59 2011 -0500

    Support for Party Identification in Sessions.

diff --git a/config/Sip.config b/config/Sip.config
index ac8e349..6843989 100644
--- a/config/Sip.config
+++ b/config/Sip.config
@@ -19,6 +19,16 @@ type=transport-udp
 host=::1
 port=5061
 
+[bob-bar-office]
+type=identity
+name='robert bar (office)'
+number=100
+ 
+[bob-bar-cell]
+type=identity
+name='robert bar (cell)'
+number=200
+
 # Example of a TCP transport binding to IPv4 localhost
 [localhost-tcp]
 # A type of transport-tcp specifies transport using TCP
@@ -82,3 +92,12 @@ rtpoveripv6=no
 # Allowable media formats for the endpoint. Each format is separated using , and follows the format
 # <name>/<sample rate>@<frame size>;<format specific parameters>
 formats=ulaw/8000,alaw/8000
+#
+# Simple fields for a single identity record
+name='robert foo bar'
+number=123
+#
+# Or, a reference to a list of individual identity items
+ids=bob-bar-office,bob-bar-cell
+
+
diff --git a/config/SipConfigurator.py b/config/SipConfigurator.py
index 88639a8..bd9a383 100755
--- a/config/SipConfigurator.py
+++ b/config/SipConfigurator.py
@@ -19,10 +19,10 @@
 # Sip configurator
 
 # Bring in the common configuration infrastructure
-import Ice, Configurator, sys, os, traceback
+import ConfigParser, Ice, Configurator, sys, os, traceback
 
 # Load our component specific configuration definitions
-Ice.loadSlice("--underscore -I" + os.environ["ASTSCF_HOME"] + " -I" + Ice.getSliceDir() + " --all ../slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice")
+Ice.loadSlice("--underscore -I\"" + os.environ["ASTSCF_HOME"] + "\" -I" + Ice.getSliceDir() + " --all ../sip/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice")
 import AsteriskSCF.Configuration.SipSessionManager.V1
 
 
@@ -102,6 +102,25 @@ class SipSectionVisitors(Configurator.SectionVisitors):
 
         self.groups.append(group)
 
+    def visit_identity(self, config, section):
+        group = AsteriskSCF.Configuration.SipSessionManager.V1.IdentityGroup()
+        group.name = section
+        group.configurationItems = { }
+
+        mapper = Configurator.OptionMapper()
+
+        item =  AsteriskSCF.Configuration.SipSessionManager.V1.IdentityItem()
+	#      map(option, object, item, item_name, method, default)
+        mapper.map('name', item, 'name', 'id', config.get, None)
+        mapper.map('number', item, 'number', 'id', config.get, None)
+
+        for option in config.options(section):
+            mapper.execute(group, section, option)
+
+        mapper.finish(group)
+
+        self.groups.append(group)
+
     def visit_endpoint(self, config, section):
         group = AsteriskSCF.Configuration.SipSessionManager.V1.SipEndpointGroup()
         group.name = section
@@ -111,6 +130,22 @@ class SipSectionVisitors(Configurator.SectionVisitors):
 
         mapper.map('routing', AsteriskSCF.Configuration.SipSessionManager.V1.SipRoutingItem(), 'routingServiceName', 'routingService', config.get, None)
 
+	item = AsteriskSCF.Configuration.SipSessionManager.V1.IdentityItem()
+	mapper.map('name', item, 'name', 'identity', config.get, None)
+        mapper.map('number', item, 'number', 'identity', config.get, None)
+
+        # Alternate form of setting id is a list of references to IdentityGroup objects.
+	try:
+            ids = config.get(section, 'ids')
+            idList = ids.split(',')
+            for id in idList:
+                item = AsteriskSCF.Configuration.SipSessionManager.V1.IdentityGroupRef()
+                item.identityGroupName = id
+                group.configurationItems[id] = item
+	except ConfigParser.NoOptionError:
+	    # It's legit to omit the ids option from this section.
+	    pass
+
         item = AsteriskSCF.Configuration.SipSessionManager.V1.SipSourceTransportAddressItem()
         mapper.map('sourcehost', item, 'host', 'sourceaddress', config.get, None)
         mapper.map('sourceport', item, 'port', 'sourceaddress', config.getint, 5060)
@@ -254,6 +289,8 @@ class SipSectionVisitors(Configurator.SectionVisitors):
             self.visit_transport_tls(config, section)
         elif config.get(section, 'type') == 'endpoint':
             self.visit_endpoint(config, section)
+        elif config.get(section, 'type') == 'identity':
+            self.visit_identity(config, section)
 
 # In order to do service locator based lookup we need to pass in a params object
 serviceLocatorParams = AsteriskSCF.Core.Discovery.V1.ServiceLocatorParams()
diff --git a/config/test_sip.conf b/config/test_sip.conf
index 3b5b45c..ad26db5 100644
--- a/config/test_sip.conf
+++ b/config/test_sip.conf
@@ -39,7 +39,6 @@ Sip.StateReplicatorListener=no
 # Endpoints that we know about
 Sip.Endpoints=cisco 18005558355
 
-Sip.Standalone=true
 
 # This is Josh's phone
 Sip.Endpoint.cisco.Session.CallDirection=Both
@@ -50,3 +49,6 @@ Sip.Endpoint.18005558355.Transport.Address=172.16.1.10
 
 IceBox.InheritProperties = 1
 IceBox.Service.SipSessionManager=SipSessionManager:create
+
+SipSessionManager.Standalone=true
+
diff --git a/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice b/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
index 6bddae5..119a010 100644
--- a/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
+++ b/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
@@ -19,6 +19,7 @@
 #include <Ice/BuiltinSequences.ice>
 #include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.ice>
 #include <AsteriskSCF/System/Component/ConfigurationIf.ice>
+#include <AsteriskSCF/SessionCommunications/PartyIdentificationIf.ice>
 
 module AsteriskSCF
 {
@@ -270,6 +271,30 @@ class SRTPCryptoItem extends SipConfigurationItem
     SRTPCryptoKeySeq cryptoKeys;
 };
 
+class IdentityItem extends SipConfigurationItem
+{
+    string name;
+    string number;
+};
+
+class IdentityGroup extends SipConfigurationGroup
+{
+    /** 
+     * Identifier for this IdentityGroup. IdentityGroup
+     * allows identities to be defined outside the body of 
+     * an endpoint, and refrenced by name from the endpoint. 
+     */ 
+    string name;
+};
+
+class IdentityGroupRef extends SipConfigurationItem
+{
+    /**
+     * Name of an identity group. 
+     */
+     string identityGroupName;
+};
+
 /**
  * Routing service configuration item
  */
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 61aada4..40ef11f 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -479,6 +479,10 @@ protected:
             {
                 // If this is not an attended transfer we can just route the session as normally
                 std::string operationId = ::IceUtil::generateUUID();
+
+                // Update the Party Id information on the session.
+                mSession->setSelfAsCaller();
+
                 SuspendableWorkListenerPtr listener = 0;
                 SipAMICallbackPtr cb(new SipAMICallback(listener, mSession, this, false, true));
                 Ice::CallbackPtr d = Ice::newCallback(cb, &SipAMICallback::callback);
diff --git a/src/SipConfiguration.cpp b/src/SipConfiguration.cpp
index d6a342a..5c2bca9 100644
--- a/src/SipConfiguration.cpp
+++ b/src/SipConfiguration.cpp
@@ -40,6 +40,7 @@
 
 using namespace AsteriskSCF::System::Configuration::V1;
 using namespace AsteriskSCF::Configuration::SipSessionManager::V1;
+using namespace AsteriskSCF::SessionCommunications::PartyIdentification::V1;
 using namespace AsteriskSCF::Core::Routing::V1;
 using namespace std;
 
@@ -137,6 +138,101 @@ static void performSerialCheck(const ConfigurationItemDict& changedItems, const
 typedef boost::function<void()> UpdateCommand;
 typedef vector<UpdateCommand> UpdateCommandList;
 
+class ConfigBase
+{
+public:
+    virtual ~ConfigBase() {}
+
+    virtual SipConfigurationItemVisitorPtr getVisitor() { return 0; }
+};
+typedef boost::shared_ptr<ConfigBase> ConfigBasePtr;
+
+class IdentityConfig;
+typedef boost::shared_ptr<IdentityConfig> IdentityConfigPtr;
+typedef std::map<std::string, IdentityConfigPtr> IdentityConfigMap;
+
+/**
+ * Configured Identity groups. This has to be accessible to 
+ * the EndpointConfigHelper. 
+ */
+IdentityConfigMap mIdentityConfigMap;
+
+/** 
+ * Identity groups allow identity to be defined separately from endpoints, 
+ * and for endpoints to have multiple identities. 
+ */
+class IdentityConfig : public ConfigBase, public boost::enable_shared_from_this<IdentityConfig>
+{
+    class Visitor : public SipConfigurationItemVisitor
+    {
+    public:
+        Visitor(const boost::shared_ptr<IdentityConfig>& config) :
+            mConfig(config)
+        {
+        }
+
+        void visitIdentityItem(const IdentityItemPtr& identityItem)
+        {
+            mConfig->update(identityItem);
+        }
+
+    private:
+
+        UpdateCommandList mUpdates;
+
+        boost::shared_ptr<IdentityConfig> mConfig;
+    };
+    
+public:
+    /**
+     * Constructor implementation for this
+     */
+    IdentityConfig(const IdentityGroupPtr& group) :
+        mGroup(group)
+    {
+    };
+
+    /**
+     * Destructor implementation that shuts down the transport gracefully if we go away
+     */
+    ~IdentityConfig()
+    {
+    };
+    
+    SipConfigurationItemVisitorPtr getVisitor()
+    {
+        return new Visitor(shared_from_this());
+    }
+
+    void update(const IdentityItemPtr& identityItem)
+    {
+         boost::unique_lock<boost::shared_mutex> lock(mLock);
+         mIdentityItem = identityItem;
+    }
+
+    IdentityGroupPtr getTypedGroup() const
+    {
+        return mGroup;
+    }
+
+    IdentityItemPtr getIdentityItem()
+    {
+        return mIdentityItem;
+    }
+
+private:
+    boost::shared_mutex mLock;
+    
+    IdentityItemPtr mIdentityItem;
+
+    /**
+     * Configuration group itself.
+     */
+    mutable IdentityGroupPtr mGroup;
+
+}; // class IdentityConfig
+
+
 /**
  * A helper class and visitor for propogating configuration changes to the SIPEndPoint implementation.
  **/
@@ -160,7 +256,6 @@ class EndpointConfigHelper : public boost::enable_shared_from_this<EndpointConfi
         {
             try
             {
-                //
                 // Don't forget to tell the helper that all of the updates have been performed
                 // and it can perform final processing.
                 //
@@ -229,9 +324,19 @@ class EndpointConfigHelper : public boost::enable_shared_from_this<EndpointConfi
             mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateDTMF, mConfig, dtmf));
         };
 
+        void visitIdentityItem(const IdentityItemPtr& identity)
+        {
+            mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateIdentity, mConfig, identity));
+        };
+
+        void visitIdentityGroupRef(const IdentityGroupRefPtr& identityGroupRef)
+        {
+            mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateIdentityGroupRef, mConfig, identityGroupRef));
+        };
+
     private:
 
-        UpdateCommandList mUpdates;;
+        UpdateCommandList mUpdates;
         //
         // We keep a reference to the parent as the helper itself isn't held by the configuration
         // object or client.
@@ -283,6 +388,48 @@ public:
         mEndpoint->setCallDirection(translateCallDirection(direction->callDirection));
     }
 
+    SessionOwnerIdPtr createSessionOwnerId(string name, string number)
+    {
+        IdPtr id = new Id(new Name(name), new Number(number));
+        IdSeq ids;
+        ids.push_back(id);
+        return new SessionOwnerId(ids);
+    }
+
+    void updateSessionOwnerId(string name, string number)
+    {
+        if (mSessionOwnerId == 0)
+        {
+            mSessionOwnerId = createSessionOwnerId(name, number);
+            return;
+        }
+
+        IdPtr id = new Id(new Name(name), new Number(number));
+        mSessionOwnerId->ids.push_back(id);
+    }
+
+    void updateIdentity(const IdentityItemPtr& identity)
+    {
+         updateSessionOwnerId(identity->name, identity->number);
+    }
+
+    void updateIdentityGroupRef(const IdentityGroupRefPtr& identityGroupRef)
+    {
+        IdentityConfigMap::const_iterator mapEntry = mIdentityConfigMap.find(identityGroupRef->identityGroupName);
+        if (mapEntry == mIdentityConfigMap.end())
+        {
+            return;
+        }
+
+        if (mapEntry->second->getIdentityItem() == 0)
+        {
+            return;
+        }
+
+        updateSessionOwnerId(mapEntry->second->getIdentityItem()->name, 
+                             mapEntry->second->getIdentityItem()->number);
+    }
+
     void addFormat(const SipMediaFormatItemPtr& format)
     {
 	mEndpoint->addFormat(format->name, format->sampleRate, format->frameSize, format->formatSpecific);
@@ -356,6 +503,10 @@ public:
                 UpdateCommand command = *op;
                 command();
             }
+            if (mSessionOwnerId != 0)
+            {
+                mEndpoint->addDefaultSessionCookie(mSessionOwnerId);
+            }
             if (updateSystem)
             {
                 mFactory->generateRoutingDestinations(destinations);
@@ -373,17 +524,9 @@ private:
     boost::shared_ptr<SipEndpointFactory> mFactory;
     LocatorRegistrySmartPrx mRegistry;
     string mRoutingId;
+    SessionOwnerIdPtr mSessionOwnerId;
 };
 
-class ConfigBase
-{
-public:
-    virtual ~ConfigBase() {}
-
-    virtual SipConfigurationItemVisitorPtr getVisitor() { return 0; }
-};
-typedef boost::shared_ptr<ConfigBase> ConfigBasePtr;
-
 /**
  * The Transport specializations take care of any transport specific configuration and
  * initialization. The UDP and TCP transports are so similar that they could probably
@@ -808,6 +951,7 @@ public:
         mRoutingId(routingId), 
         mRoutingServiceLocatorRegistry(registry) 
     {
+        mIdentityConfigMap.clear();
     }
 
     /**
@@ -940,6 +1084,24 @@ public:
         }
     }
 
+    void remove(const IdentityGroupPtr& group)
+    {
+        //
+        // It's a good idea to hold a reference to this until after we release the lock on the config item. That way any
+        // code that might happen as a result of its destruction cannot come back and cause deadlocks on this object.
+        //
+        IdentityConfigPtr config;
+        {
+            boost::unique_lock<boost::shared_mutex> lock(mLock);
+            IdentityConfigMap::iterator i = mIdentityConfigMap.find(group->name);
+            if (i != mIdentityConfigMap.end())
+            {
+                config = i->second;
+                mIdentityConfigMap.erase(i);
+            }
+        }
+    }
+
     void remove(const SipSTUNTransportGroupPtr& group)
     {
         STUNTransportConfigPtr config;
@@ -1035,6 +1197,26 @@ public:
         return 0;
     }
 
+    const IdentityGroupPtr getGroupFor(const IdentityGroupPtr& group)
+    {
+        IdentityConfigMap::const_iterator i;
+        if (getItem(mIdentityConfigMap, i, group->name))
+        {
+            return i->second->getTypedGroup();
+        }
+        return 0;
+    }
+
+    const IdentityGroupPtr getGroupByName(const std::string& groupName)
+    {
+        IdentityConfigMap::const_iterator i;
+        if (getItem(mIdentityConfigMap, i, groupName))
+        {
+            return i->second->getTypedGroup();
+        }
+        return 0;
+    }
+
 private:
 
     boost::shared_mutex mLock;
@@ -1043,7 +1225,7 @@ private:
      * Configured SIP domains
      */
     DomainMap mDomains;
-    
+
     /**
      * Configured UDP SIP transports
      */
@@ -1217,6 +1399,22 @@ private:
         return transport->getVisitor();
     }
 
+    SipConfigurationItemVisitorPtr updateGroup(const IdentityGroupPtr& group)
+    {
+        IdentityConfigMap::const_iterator i;
+        IdentityConfigPtr identityConfig;
+        if (!getItem(mIdentityConfigMap, i, group->name))
+        {
+            identityConfig.reset(new IdentityConfig(group));
+            mIdentityConfigMap.insert(make_pair(group->name, identityConfig));
+        }
+        else
+        {
+            identityConfig = i->second;
+        }
+        return identityConfig->getVisitor();
+    }
+
     template <class T>
     void copyTemplates(ConfigurationGroupSeq& groups, const T& items)
     {
@@ -1355,6 +1553,11 @@ ConfigurationGroupSeq ConfigurationServiceImpl::getConfiguration(
             getGeneric<SipEndpointGroupPtr>(mImpl->getData(), group, mGroups);
 	};
 
+        void visitIdentityGroup(const IdentityGroupPtr& group)
+        {
+            getGeneric<IdentityGroupPtr>(mImpl->getData(), group, mGroups);
+        }
+
 	ConfigurationServiceImplPtr mImpl;
 	ConfigurationGroupSeq& mGroups;
     };
@@ -1428,6 +1631,11 @@ ConfigurationGroupSeq ConfigurationServiceImpl::getConfigurationAll(
             genericGetAll<SipEndpointGroupPtr>(mImpl->getData(), group, mGroups);
 	};
 
+        void visitIdentityGroup(const IdentityGroupPtr& group)
+        {
+            genericGetAll<IdentityGroupPtr>(mImpl->getData(), group, mGroups);
+        }
+
 	ConfigurationServiceImplPtr mImpl;
 	ConfigurationGroupSeq& mGroups;
     };
@@ -1513,6 +1721,11 @@ void ConfigurationServiceImpl::setConfiguration(const AsteriskSCF::System::Confi
         {
             genericSet<SipEndpointGroupPtr>(mImpl->getData(), group);
         };
+
+        void visitIdentityGroup(const IdentityGroupPtr& group)
+        {
+            genericSet<IdentityGroupPtr>(mImpl->getData(), group);
+        }
 	
 	ConfigurationServiceImplPtr mImpl;
     };
@@ -1570,6 +1783,12 @@ void ConfigurationServiceImpl::removeConfigurationItems(
         {
             mImpl->getData()->removeFromGroup(group);
         };
+
+        void visitIdentityGroup(const IdentityGroupPtr& group)
+        {
+            mImpl->getData()->removeFromGroup(group);
+        }
+
     private:
 	ConfigurationServiceImplPtr mImpl;
     };
@@ -1626,6 +1845,11 @@ void ConfigurationServiceImpl::removeConfigurationGroups(
             mImpl->getData()->remove(group);
         };
 
+        void visitIdentityGroup(const IdentityGroupPtr& group)
+        {
+            mImpl->getData()->remove(group);
+        }
+
 	ConfigurationServiceImplPtr mImpl;
     };
     
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index f88691b..dfaebf8 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -16,6 +16,7 @@
 #include "PJSipManager.h"
 #include "SipEndpointFactory.h"
 #include "SipSession.h"
+
 #include <Ice/Ice.h>
 #include <IceUtil/UUID.h>
 
@@ -403,24 +404,25 @@ AsteriskSCF::SessionCommunications::V1::SessionPrx SipEndpoint::createSession(
 
     SessionCookies defaultCookies = mImplPriv->mDefaultSessionCookies->getAll();
 
-    SipSessionPtr session = new SipSession(
-            mImplPriv->mAdapter,
-            this,
-            destination,
-            listeners,
-            defaultCookies,
-            mImplPriv->mManager,
-            mImplPriv->mServiceLocator,
-            mImplPriv->mReplicationContext,
+    SipSessionPtr session = SipSession::create(
+            mImplPriv->mAdapter, 
+	    this, 
+	    destination, 
+	    listeners, 
+            defaultCookies, 
+	    mImplPriv->mManager, 
+	    mImplPriv->mServiceLocator, 
+	    mImplPriv->mReplicationContext, 
             oneShotHook,
-            mImplPriv->mConfig.sessionConfig.rtpOverIPv6,
-            true,
-            mImplPriv->mConfig,
+            mImplPriv->mConfig.sessionConfig.rtpOverIPv6, 
+	    true, 
+	    mImplPriv->mConfig, 
             NATEndpointOptions(mImplPriv->mConfig.sessionConfig.rtpOverICE, 
-                mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
-                mImplPriv->mConfig.transportConfig.enableNAT));
+                 mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
+                 mImplPriv->mConfig.transportConfig.enableNAT));
 
     mImplPriv->mSessions.push_back(session);
+
     std::cout << "And now we're returing a session proxy..." << std::endl;
     return session->getSessionProxy();
 }
@@ -430,23 +432,23 @@ AsteriskSCF::SipSessionManager::SipSessionPtr SipEndpoint::createSession(const s
     vector<SessionListenerPrx> defaultListeners = mImplPriv->mDefaultListeners->getAll();
     SessionCookies defaultCookies = mImplPriv->mDefaultSessionCookies->getAll();
 
-    SipSessionPtr session = new SipSession(
-            mImplPriv->mAdapter,
-            this,
-            destination,
-            defaultListeners,
-            defaultCookies,
-            mImplPriv->mManager,
-            mImplPriv->mServiceLocator,
-            mImplPriv->mReplicationContext,
-            0,
-            mImplPriv->mConfig.sessionConfig.rtpOverIPv6,
-            false,
-            mImplPriv->mConfig, 
-            NATEndpointOptions(mImplPriv->mConfig.sessionConfig.rtpOverICE, 
-                mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
-                mImplPriv->mConfig.transportConfig.enableNAT)
-        );
+    SipSessionPtr session = SipSession::create(
+             mImplPriv->mAdapter, 
+	     this, 
+	     destination, 
+	     defaultListeners, 
+             defaultCookies, 
+	     mImplPriv->mManager, 
+	     mImplPriv->mServiceLocator, 
+	     mImplPriv->mReplicationContext, 
+	     0,
+             mImplPriv->mConfig.sessionConfig.rtpOverIPv6, 
+	     false, 
+	     mImplPriv->mConfig, 
+             NATEndpointOptions(mImplPriv->mConfig.sessionConfig.rtpOverICE, 
+                                mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
+                                mImplPriv->mConfig.transportConfig.enableNAT)
+	     );
 
     mImplPriv->mSessions.push_back(session);
     return session;
@@ -457,36 +459,44 @@ AsteriskSCF::SipSessionManager::SipSessionPtr SipEndpoint::createSession(const s
  * Note: Default session cookies and listeners are part of the replicated state, so none are added
  * here. 
  */
-AsteriskSCF::SipSessionManager::SipSessionPtr SipEndpoint::createSession(const std::string& destination,
-                                                                         const Ice::Identity& sessionid, const Ice::Identity& controllerid,
-                                                                         const Ice::Identity& mediaid,
-                                                                         const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
-                                                                         const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
-                                                                         const AsteriskSCF::Media::V1::StreamSinkSeq& sinks)
-{
-    SipSessionPtr session = new SipSession(
-            mImplPriv->mAdapter,
-            this,
-            destination,
-            sessionid,
-            controllerid,
-            mediaid,
-            mediasessions,
-            sources,
-            sinks,
-            mImplPriv->mManager,
-            mImplPriv->mServiceLocator,
-            mImplPriv->mReplicationContext,
-            0,
-            false,
-            mImplPriv->mConfig,
-            NATEndpointOptions(mImplPriv->mConfig.sessionConfig.rtpOverICE,
-                mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
-                mImplPriv->mConfig.transportConfig.enableNAT));
+SipSessionPtr SipEndpoint::createSession
+               (const std::string& destination,
+                const Ice::Identity& sessionid, 
+		const Ice::Identity& controllerid,
+                const Ice::Identity& mediaid,
+                const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
+                const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
+                const AsteriskSCF::Media::V1::StreamSinkSeq& sinks)
+{
+    SipSessionPtr session = SipSession::create
+	    (mImplPriv->mAdapter, 
+	     this, 
+	     destination, 
+	     sessionid, 
+             controllerid, 
+	     mediaid, 
+	     mediasessions, 
+	     sources, 
+	     sinks, 
+	     mImplPriv->mManager, 
+             mImplPriv->mServiceLocator, 
+	     mImplPriv->mReplicationContext, 
+	     0,
+	     false, 
+	     mImplPriv->mConfig,
+             NATEndpointOptions(mImplPriv->mConfig.sessionConfig.rtpOverICE, 
+                                mImplPriv->mConfig.sessionConfig.rtpICEIncludeTURN,
+                                mImplPriv->mConfig.transportConfig.enableNAT));
+
     mImplPriv->mSessions.push_back(session);
     return session;
 }
 
+/** 
+ * Remove the Session from our set of active sessions. 
+ * Note: The Session actually calls this method, and is responsible for removing
+ * itself from the object adapter. 
+ */
 void SipEndpoint::removeSession(const AsteriskSCF::SessionCommunications::V1::SessionPtr& session)
 {
     SipSessionPtr sipsession = SipSessionPtr::dynamicCast(session);
@@ -562,9 +572,47 @@ void SipEndpoint::removeDefaultSessionListener(const SessionListenerPrx& listene
     mImplPriv->mReplicationContext->getReplicator().tryOneWay()->removeStateForItems(items);
 }
 
-void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, const Ice::Current&)
+/** 
+ * Copies the input cookies minus the read-only cookies. 
+ */
+SessionCookies filterReadOnlyCookies(const SessionCookies& cookiesIn, const std::string& logMessage)
 {
-    mImplPriv->mDefaultSessionCookies->add(cookies);
+    SessionCookies cookiesOut;
+
+    // Filter out any read-only cookies passed in. They must be set through specific API calls, 
+    // not via generic cookie API. 
+    for(SessionCookies::const_iterator i=cookiesIn.begin(); i != cookiesIn.end(); ++i)
+    {
+        if (SipSession::isSessionCookieReadOnly(*i))
+        {
+            lg(Debug) << BOOST_CURRENT_FUNCTION << " " << logMessage << " of type " <<  (*i)->ice_id();
+            continue;
+        }
+        cookiesOut.push_back(*i);
+    }
+    return cookiesOut;
+}
+
+/**
+ * Adds to the endpoint's default session cookies. 
+ * @param cookies A sequence of cookies to be removed. 
+ * @param privileged Indicates if the calling operation has privilege to alter read-only cookies. 
+ */
+void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, bool privileged)
+{
+    SessionCookies modCookies;
+
+    if (privileged)
+    {
+        // Use the cookies passed in as-is. 
+        modCookies = cookies;
+    }
+    else
+    {
+        modCookies = filterReadOnlyCookies(cookies, "attempted to add read-only default Session Cookie");
+    }
+
+    mImplPriv->mDefaultSessionCookies->add(modCookies);
 
     if (mImplPriv->mReplicationContext->isReplicating() == false)
     {
@@ -573,20 +621,43 @@ void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, const
 
     // Replicate this change. 
     SipStateItemSeq items;
-    for(SessionCookies::const_iterator i=cookies.begin(); i != cookies.end(); ++i)
+    for(SessionCookies::const_iterator i=modCookies.begin(); i != modCookies.end(); ++i)
     {
         items.push_back(new DefaultSessionCookieItem(cookieKey(mImplPriv->mName,  *i),
                 "", 
-                    mImplPriv->mName, 
+                mImplPriv->mName, 
                 (*i)));
     }
 
     mImplPriv->mReplicationContext->getReplicator().tryOneWay()->setState(items);
 }
 
-void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, const Ice::Current&)
+
+void SipEndpoint::addDefaultSessionCookies(const SessionCookies& cookies, const Ice::Current&)
+{
+    addDefaultSessionCookies(cookies, false);
+}
+
+/**
+ * Alters the endpoint's default session cookies. 
+ * @param cookies A sequence of cookies to be removed. 
+ * @param privileged Indicates if the calling operation has privilege to alter read-only cookies. 
+ */
+void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, bool privileged)
 {
-    mImplPriv->mDefaultSessionCookies->remove(cookies);
+    SessionCookies modCookies;
+
+    if (privileged)
+    {
+        // Use the cookies passed in as-is. 
+        modCookies = cookies;
+    }
+    else
+    {
+         modCookies = filterReadOnlyCookies(cookies,  "attempted to remove read-only default Session Cookie");
+    }
+
+    mImplPriv->mDefaultSessionCookies->remove(modCookies);
 
     if (mImplPriv->mReplicationContext->isReplicating() == false)
     {
@@ -595,7 +666,7 @@ void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, con
 
     // Replicate this change. 
     SipStateItemSeq items;
-    for(SessionCookies::const_iterator i=cookies.begin(); i != cookies.end(); ++i)
+    for(SessionCookies::const_iterator i=modCookies.begin(); i != modCookies.end(); ++i)
     {
         items.push_back(new DefaultSessionCookieItem(cookieKey(mImplPriv->mName,  *i),
                 "", 
@@ -606,18 +677,23 @@ void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, con
     mImplPriv->mReplicationContext->getReplicator().tryOneWay()->removeStateForItems(items);
 }
 
+void SipEndpoint::removeDefaultSessionCookies(const SessionCookies& cookies, const Ice::Current&)
+{
+    removeDefaultSessionCookies(cookies, false);
+}
+
 void SipEndpoint::addDefaultSessionCookie(const SessionCookiePtr& cookie)
 {
     SessionCookies cookies;
     cookies.push_back(cookie);
-    addDefaultSessionCookies(cookies);
+    addDefaultSessionCookies(cookies, true);
 }
 
 void SipEndpoint::removeDefaultSessionCookie(const SessionCookiePtr& cookie)
 {
     SessionCookies cookies;
     cookies.push_back(cookie);
-    removeDefaultSessionCookies(cookies);
+    removeDefaultSessionCookies(cookies, true);
 }
 
 SDPDescriptorServicePrx SipEndpoint::getDescriptorService(const SDPDescriptorPtr& descriptor)
diff --git a/src/SipEndpoint.h b/src/SipEndpoint.h
index 80b9e2e..efc3a8c 100644
--- a/src/SipEndpoint.h
+++ b/src/SipEndpoint.h
@@ -362,6 +362,11 @@ public:
         const AsteriskSCF::SessionCommunications::V1::SessionCookiePtr& cookie);
 
 private:
+    void addDefaultSessionCookies(
+        const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookiesInput, bool privileged);
+    void removeDefaultSessionCookies(
+        const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookiesInput, bool privileged);
+
     /**
      * Private implementation details.
      */
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index f550ce9..b06a154 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -28,6 +28,9 @@
 #include <boost/thread/shared_mutex.hpp>
 #include <boost/lexical_cast.hpp>
 
+#include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
+#include <AsteriskSCF/SessionCommunications/SessionCookieIf.h>
+#include <AsteriskSCF/System/ExceptionsIf.h>
 #include <AsteriskSCF/System/WorkQueue/WorkQueueIf.h>
 #include <AsteriskSCF/logger.h>
 #include <AsteriskSCF/System/NAT/NATTraversalIf.h>
@@ -41,10 +44,12 @@
 using namespace AsteriskSCF::System::Logging;
 using namespace AsteriskSCF::System::NAT::V1;
 using namespace AsteriskSCF::SessionCommunications::V1;
+using namespace AsteriskSCF::SessionCommunications::PartyIdentification::V1;
 using namespace AsteriskSCF::Media::RTP::V1;
 using namespace AsteriskSCF::Media::V1;
 using namespace AsteriskSCF::Media;
 using namespace AsteriskSCF::Media::SDP::V1;
+using namespace AsteriskSCF::System::V1;
 using namespace std;
 
 namespace
@@ -92,6 +97,47 @@ private:
 };
 
 /**
+ * A class that identifies a set of read-only cookie types.
+ * The types in this set will be protected from being altered
+ * by the general-purpose setCookies() operation. (Such types 
+ * may, however, be altered via some other API that has the 
+ * privilege to to do so.)
+ * Note: immutable class. 
+ */
+class ReadOnlyCookieTypes
+{
+public:
+    ReadOnlyCookieTypes()
+    {
+        registerType(Dialed::ice_staticId());
+
+        registerType(Caller::ice_staticId());
+
+        registerType(SessionOwnerId::ice_staticId());
+
+        registerType(ConnectedLine::ice_staticId());
+
+        registerType(Redirecting::ice_staticId());
+    }
+
+    bool contains(const std::string& cookieTypeId) const 
+    {
+        // If we have an entry registered for cookieTypeId, it's read-only.
+        return (mRegisteredTypes.find(cookieTypeId) != mRegisteredTypes.end());
+    }
+
+private:
+
+    void registerType(const std::string& type)
+    {
+         mRegisteredTypes.insert(type);
+    }
+
+    std::set<std::string> mRegisteredTypes;
+};
+
+
+/**
  * Private implementation details for SipSession.
  */
 class SipSessionPriv
@@ -107,8 +153,9 @@ public:
         const NATEndpointOptions& natOptions)
         : mAdapter(adapter), mDialog(0), mInviteSession(0), mEndpoint(endpoint), mDestination(destination),
           mManager(manager), mServiceLocator(serviceLocator), mReplicationContext(replicationContext), 
-	  mNatOptions(natOptions), mSDP(0)
+      mNatOptions(natOptions), mSDP(0)
     { 
+
     }
 
     AsteriskSCF::SessionCommunications::V1::SessionInfoPtr getInfo()
@@ -194,6 +241,24 @@ public:
         return mBridge;
     }
 
+    /** 
+     * Replicate a change in cookie state if needed.
+     */
+    void cookiesUpdated()
+    {
+        if (mInviteSession)
+        {
+            PJSipSessionModInfo *session_mod_info = static_cast<PJSipSessionModInfo*>(mInviteSession->mod_data[mManager->getSessionModule()->getModule().id]);
+            session_mod_info->updateSessionState(mInviteSession);
+            mManager->getSessionModule()->replicateState(NULL, NULL, session_mod_info);
+        }
+    }
+
+    static bool isCookieReadOnly(const std::string& typeId)
+    {
+        return mReadOnlyCookieTypes.contains(typeId);
+    }
+
     /**
      * An instance of a media session.
      */
@@ -336,7 +401,23 @@ public:
     AsteriskSCF::SessionCommunications::V1::TelephonyEventSourcePrx mEventSourcePrx;
 
     AsteriskSCF::SessionCommunications::V1::TelephonyEventSourceSeq mExternalEventSources;
-};
+
+private:
+    static ReadOnlyCookieTypes mReadOnlyCookieTypes;
+
+}; // class SipSessionPriv
+typedef boost::shared_ptr<SipSessionPriv> SipSessionPrivPtr;
+
+
+ReadOnlyCookieTypes SipSessionPriv::mReadOnlyCookieTypes;
+
+/**
+ * Static operation to allow other classes to test for read-only cookies. 
+ */
+bool SipSession::isSessionCookieReadOnly(const AsteriskSCF::SessionCommunications::V1::SessionCookiePtr &cookie)
+{
+    return SipSessionPriv::isCookieReadOnly(cookie->ice_id());
+}
 
 /**
  * Template for allocating from a pool.
@@ -561,6 +642,83 @@ private:
     SipSessionPtr mSession;
 };
 
+class UpdateRedirectingOperation : public SuspendableWork
+{
+public:
+    UpdateRedirectingOperation(const RedirectingPtr& redirecting,
+                               const boost::shared_ptr<SipSessionPriv>& sessionPriv,
+                               const SipSessionPtr& session)
+        : mRedirecting(redirecting), mImplPriv(sessionPriv), mSession(session)
+    {
+    }
+
+    SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+    {
+        lg(Debug) << "Executing an UpdateRedirecting operation";
+
+        SessionCookieDict cookies = mSession->getAllCookies();
+
+        SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(mRedirecting->ice_id());
+
+        int updatedCount = 1;
+        if (search != cookies.end())
+        {
+            RedirectingPtr found = RedirectingPtr::dynamicCast(search->second);
+            updatedCount = found->count + 1;
+        }
+
+        mRedirecting->count = updatedCount;
+
+        // Set or replace redirected info.
+        mImplPriv->mSessionCookies[mRedirecting->ice_id()] = mRedirecting;
+  
+        mImplPriv->cookiesUpdated();
+
+        return Complete;
+    }
+
+private:
+    RedirectingPtr mRedirecting;
+    boost::shared_ptr<SipSessionPriv> mImplPriv;
+    SipSessionPtr mSession;
+};
+
+class SetCookiesOperation : public SuspendableWork
+{
+public:
+    SetCookiesOperation(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies,
+                        const boost::shared_ptr<SipSessionPriv>& sessionPriv, 
+                        bool privileged = false)
+        : mCookies(cookies), mImplPriv(sessionPriv), mPrivileged(privileged) { }
+
+    SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+    {
+        for (AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i = mCookies.begin();
+             i != mCookies.end();
+             ++i)
+        {
+            string cookieType = (*i)->ice_id();
+            if ((mPrivileged == false) && mImplPriv->isCookieReadOnly(cookieType))
+            {
+                lg(Debug) << "setCookies attempted to set read-only cookie of type " << cookieType;
+                continue;
+            }
+
+            mImplPriv->mSessionCookies.erase(cookieType);
+            mImplPriv->mSessionCookies.insert(make_pair(cookieType, (*i)));
+        }
+
+        mImplPriv->cookiesUpdated();
+
+        return Complete;
+    }
+
+private:
+    AsteriskSCF::SessionCommunications::V1::SessionCookies mCookies;
+    boost::shared_ptr<SipSessionPriv> mImplPriv;
+    bool mPrivileged;
+};
+
 /**
  * Implementation of a SessionController interface for the SipSession.
  */
@@ -591,6 +749,23 @@ public:
         mSession->enqueueSessionWork(new RemoveStreamsOperation(cb, streams, mImplPriv, mSession));
     }
     
+    void updateConnectedLine(const ConnectedLinePtr& connected, const Ice::Current&) 
+    {
+        AsteriskSCF::SessionCommunications::V1::SessionCookies cookies;
+        cookies.push_back(connected);
+
+        mSession->enqueueSessionWork(new SetCookiesOperation(cookies, mImplPriv, true));
+    }
+
+    void updateRedirecting(const RedirectingPtr& redirecting, const ::Ice::Current&) 
+    {
+        // TBD.. This merits discussion. I don't think the caller should pass in a new
+        // Redirecting record, but rather just the Id of who's being redirected to. 
+        // Counts and "from" should be maintained internally to the session that owns the record. 
+
+        mSession->enqueueSessionWork(new UpdateRedirectingOperation(redirecting, mImplPriv, mSession));
+    }
+
 private:
     /**
      * Private implementation details for SipSession.
@@ -603,6 +778,32 @@ private:
     SipSessionPtr mSession;
 };
 
+/**
+ * Sets the party id cookies to indicate that this session's SessionOwnerId is the Caller. 
+ */
+void SipSession::setSelfAsCaller()
+{
+    // Note: The SessionOwnerId is set via a default cookie added to the Endpoint. 
+    SessionOwnerIdPtr test = new SessionOwnerId();
+    SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(test->ice_id());
+
+    if (search == mImplPriv->mSessionCookies.end())
+    {
+        lg(Info) << "Party Id information not configured. " << BOOST_CURRENT_FUNCTION << 
+             "Can't update session Caller info. Endpoint" << mImplPriv->mEndpoint->getName();
+        return;
+    } 
+
+    SessionOwnerIdPtr owner = SessionOwnerIdPtr::dynamicCast(search->second);
+    CallerPtr caller = new Caller(owner->ids);
+    mImplPriv->mSessionCookies[caller->ice_id()] = caller;
+
+    // Since we're the caller, we know the Dialed info as well. 
+    NumberPtr number = new Number(mImplPriv->mDestination);
+    DialedPtr dialed = new Dialed(number);
+    mImplPriv->mSessionCookies[dialed->ice_id()] = dialed;
+}
+
 void SipSession::initializePJSIPStructs()
 {
     SipEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
@@ -766,6 +967,7 @@ void SipSession::activateIceObjects(const AsteriskSCF::SessionCommunications::Ex
         }
     }
 }
+
 void SipSession::setTelephonyEventSourcesAndSinks(const SipEndpointConfig& config)
 {
     if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SipSessionManager::V1::INFO)
@@ -781,6 +983,96 @@ void SipSession::setTelephonyEventSourcesAndSinks(const SipEndpointConfig& confi
 }
 
 /**
+ * Standard factory method used by an active component to create SipSession objects.
+ */
+SipSessionPtr SipSession::create(const Ice::ObjectAdapterPtr& adapter, 
+        const SipEndpointPtr& endpoint,
+        const std::string& destination, 
+        const vector<SessionListenerPrx>& listeners,
+        const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies,
+        const PJSipManagerPtr& manager, 
+        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
+        const SipReplicationContextPtr& replicationContext, 
+        const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx& oneShotHook,
+        bool doIpV6, 
+        bool isUAC, 
+        const SipEndpointConfig &config,
+        const NATEndpointOptions& natOptions)
+{
+    SipSessionPtr newSession = new SipSession(adapter, 
+       endpoint,
+       destination, 
+       listeners,
+       cookies,
+       manager, 
+       serviceLocator,
+       replicationContext, 
+       doIpV6, 
+       isUAC, 
+       config,
+       natOptions);
+
+    AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookSeq hooks = 
+        newSession->mImplPriv->mManager->getSessionModule()->getSessionCreationHooks();
+
+    if (oneShotHook)
+    {
+        hooks.push_back(oneShotHook);
+    }
+    newSession->activateIceObjects(hooks);
+
+    return newSession;
+}
+
+/**
+ * Factory used by a standby component to create replicas. 
+ */
+SipSessionPtr SipSession::create(const Ice::ObjectAdapterPtr& adapter, 
+                       const SipEndpointPtr& endpoint,
+                       const std::string& destination, 
+                       const Ice::Identity& sessionid,
+                       const Ice::Identity& controllerid,
+                       const Ice::Identity& mediaid, 
+                       const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
+                       const AsteriskSCF::Media::V1::StreamSourceSeq& sources, 
+                       const AsteriskSCF::Media::V1::StreamSinkSeq& sinks,
+                       const PJSipManagerPtr& manager, 
+                       const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
+                       const SipReplicationContextPtr& replicationContext, 
+                       const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx& oneShotHook,
+                       bool isUAC, 
+                       const SipEndpointConfig &config,
+                       const NATEndpointOptions& natOptions)
+{
+    SipSessionPtr newSession = new SipSession(adapter, 
+                       endpoint,
+                       destination, 
+                       sessionid,
+                       controllerid,
+                       mediaid, 
+                       mediasessions,
+                       sources, 
+                       sinks,
+                       manager, 
+                       serviceLocator,
+                       replicationContext, 
+                       isUAC, 
+                       config,
+                       natOptions);
+
+    AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookSeq hooks =
+        newSession->mImplPriv->mManager->getSessionModule()->getSessionCreationHooks();
+
+    if (oneShotHook)
+    {
+        hooks.push_back(oneShotHook);
+    }
+    newSession->activateIceObjects(hooks);
+
+    return newSession;
+}
+
+/**
  * Standard constructor for use by an active component.
  */
 SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter, 
@@ -791,7 +1083,6 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter,
         const PJSipManagerPtr& manager, 
         const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
         const SipReplicationContextPtr& replicationContext, 
-        const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx& oneShotHook,
         bool /* ipv6 */, 
         bool isUAC, 
         const SipEndpointConfig &config,
@@ -822,14 +1113,6 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter,
         initializePJSIPStructs();
         setTelephonyEventSourcesAndSinks(config);
     }
-
-    AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookSeq hooks =
-        mImplPriv->mManager->getSessionModule()->getSessionCreationHooks();
-    if (oneShotHook)
-    {
-        hooks.push_back(oneShotHook);
-    }
-    activateIceObjects(hooks);
 }
 
 /**
@@ -847,7 +1130,6 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter,
                        const PJSipManagerPtr& manager,
                        const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
                        const SipReplicationContextPtr& replicationContext,
-                       const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx& oneShotHook,
                        bool isUAC,
                        const SipEndpointConfig &config,
                        const NATEndpointOptions& natOptions)
@@ -874,13 +1156,6 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter,
         setTelephonyEventSourcesAndSinks(config);
     }
 
-    AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookSeq hooks =
-        mImplPriv->mManager->getSessionModule()->getSessionCreationHooks();
-    if (oneShotHook)
-    {
-        hooks.push_back(oneShotHook);
-    }
-    activateIceObjects(hooks);
 }
 
 class AddListenerOperation : public SuspendableWork
@@ -1190,6 +1465,22 @@ public:
             }
 
             mImplPriv->mSessionController = mController;
+
+            // Update the party identification. 
+            SessionOwnerIdPtr test = new SessionOwnerId();
+            SessionCookieDict::const_iterator search = mImplPriv->mSessionCookies.find(test->ice_id());
+            if (search != mImplPriv->mSessionCookies.end())
+            {
+                // Set the ConnectedLine information on the other controller. 
+                SessionOwnerIdPtr owner = SessionOwnerIdPtr::dynamicCast(search->second);
+                ConnectedLinePtr connectedLine = new ConnectedLine(owner->ids);
+                mController->updateConnectedLine(connectedLine); // Need to be AMI?
+            }
+            else
+            {
+                lg(Info) << "Unable to set ConnectedLine party info. No Id configured for endpoint " << mImplPriv->mEndpoint->getName(); 
+            }
+
             mCb->ice_response(mImplPriv->mOurSessionControllerProxy);
             return Complete;
         }
@@ -1229,6 +1520,10 @@ public:
                 mImplPriv->mSessionController = 0;
             }
 
+            // Update the connected controller's ConnectedLine information.  
+            SessionOwnerIdPtr test;
+            mImplPriv->mSessionCookies.erase(test->ice_id());
+
             mCb->ice_response();
             return Complete;
         }
@@ -1507,35 +1802,68 @@ void SipSession::stop(const AsteriskSCF::SessionCommunications::V1::ResponseCode
     enqueueSessionWork(new StopOperation(response, mImplPriv->mInviteSession));
 }
 
-class SetCookiesOperation : public SuspendableWork
+/**
+ * An implementation of the setCookies method as defined in SessionCommunicationsIf.ice which sets cookies
+ * on the session. The task is enqueued for thread-safe access to the Session state information.
+ */
+void SipSession::setCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies, const Ice::Current&)
+{
... 497 lines suppressed ...


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list