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

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Mon Aug 1 15:26:35 CDT 2011


branch "transfer-improvements" has been updated
       via  595fbd61c6e2a05057ebcc4d80b12ae2fcc0ea8a (commit)
       via  4c99a175710c274b031593e8a21546f9b3509c24 (commit)
       via  52b7a04229bc7357904fc7696360b5216c7c168f (commit)
       via  91db4bab32da883c00fe800fabd0ca9e4751e3f7 (commit)
       via  4b4eb32a1b1920eaab3deb529270f4239f8ed7b3 (commit)
       via  11a545c5e30ed1d4b2ad4324a9608391916ed568 (commit)
       via  5b41c5a650bfccb0531f9a1fd9e006b18b8cbbed (commit)
      from  7295b9fd56b022ae4f2f3490a7b27adc8bb9d82b (commit)

Summary of changes:
 .../SipSessionManager/SipStateReplicationIf.ice    |   31 ++
 src/PJSipSessionModule.cpp                         |    2 +-
 src/SipSessionManagerApp.cpp                       |    2 +-
 src/SipStateReplicator.h                           |    8 +-
 src/SipStateReplicatorListener.cpp                 |  101 +++++-
 src/SipTransfer.cpp                                |  392 +++++++++++++-------
 src/SipTransfer.h                                  |  227 +++++++++++-
 7 files changed, 624 insertions(+), 139 deletions(-)


- Log -----------------------------------------------------------------
commit 595fbd61c6e2a05057ebcc4d80b12ae2fcc0ea8a
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Aug 1 14:58:18 2011 -0500

    Add try-catch blocks to make things all safe.

diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 9e48551..34a4523 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -166,18 +166,38 @@ SessionListenerPrx TransferListener::getProxy()
 
 void TransferListener::shutdown()
 {
-    mAdapter->remove(mListenerProxy->ice_getIdentity());
+    try
+    {
+        mAdapter->remove(mListenerProxy->ice_getIdentity());
+    }
+    catch (const Ice::Exception& ex)
+    {
+        lg(Error) << "Exception caught attempting to remove transfer session lister from object adapter: " << ex.what();
+    }
+
     removeState();
 }
 
 void TransferListener::shutdown(const SessionPrx& session)
 {
-    session->removeListener(mListenerProxy);
+    try
+    {
+        session->removeListener(mListenerProxy);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        lg(Error) << "Exception caught attempting to remove transfer session listener as a session listener: " << ex.what();
+    }
+
     shutdown();
 }
 
 void TransferListener::setState()
 {
+    if (!mReplicator)
+    {
+        return;
+    }
     std::string callId(pj_strbuf(&mDialog->call_id->id), pj_strlen(&mDialog->call_id->id));
     std::string localTag(pj_strbuf(&mDialog->local.info->tag), pj_strlen(&mDialog->local.info->tag));
     std::string remoteTag(pj_strbuf(&mDialog->remote.info->tag), pj_strlen(&mDialog->remote.info->tag));
@@ -193,14 +213,35 @@ void TransferListener::setState()
 
     SipStateItemSeq seq;
     seq.push_back(mStateItem);
-    mReplicator->setState(seq);
+
+    try
+    {
+        mReplicator->setState(seq);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        lg(Error) << "Exception caught trying to set state of transfer session listener: " << ex.what();
+    }
 }
 
 void TransferListener::removeState()
 {
+    if (!mReplicator)
+    {
+        return;
+    }
+
     SipStateItemSeq seq;
     seq.push_back(mStateItem);
-    mReplicator->removeStateForItems(seq);
+
+    try
+    {
+        mReplicator->removeStateForItems(seq);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        lg(Error) << "Exception caught trying to remove state of transfer session listener: " << ex.what();
+    }
 }
 
 TransferSessionCreationHook::TransferSessionCreationHook(
@@ -251,8 +292,10 @@ void TransferSessionCreationHook::modifySession(
     TransferListenerPtr transferListener = new TransferListener(mAdapter, mDialog, mReferCSeq, mReplicator);
     SessionListenerSeq listeners = original->listeners;
     listeners.push_back(transferListener->getProxy());
+
     AsteriskSCF::SessionCommunications::V1::SessionCookies cookies = original->cookies;
     cookies.push_back(new ReferredByCookie(mReferredBy));
+
     replacement->session = original->session;
     replacement->cookies = cookies;
     replacement->listeners = listeners;
@@ -265,12 +308,24 @@ SessionCreationHookPrx TransferSessionCreationHook::getProxy()
 
 void TransferSessionCreationHook::shutdown()
 {
-    mAdapter->remove(mProxy->ice_getIdentity());
+    try
+    {
+        mAdapter->remove(mProxy->ice_getIdentity());
+    }
+    catch (const Ice::Exception& ex)
+    {
+        lg(Error) << "Exception caught trying to remove transfer session creation hook from object adapter: " << ex.what();
+    }
+
     removeState();
 }
 
 void TransferSessionCreationHook::setState()
 {
+    if (!mReplicator)
+    {
+        return;
+    }
     std::string callId(pj_strbuf(&mDialog->call_id->id), pj_strlen(&mDialog->call_id->id));
     std::string localTag(pj_strbuf(&mDialog->local.info->tag), pj_strlen(&mDialog->local.info->tag));
     std::string remoteTag(pj_strbuf(&mDialog->remote.info->tag), pj_strlen(&mDialog->remote.info->tag));
@@ -287,14 +342,34 @@ void TransferSessionCreationHook::setState()
 
     SipStateItemSeq seq;
     seq.push_back(mStateItem);
-    mReplicator->setState(seq);
+
+    try
+    {
+        mReplicator->setState(seq);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        lg(Error) << "Exception caught attempting to set replication state for transfer session creation hook: " << ex.what();
+    }
 }
 
 void TransferSessionCreationHook::removeState()
 {
+    if (!mReplicator)
+    {
+        return;
+    }
     SipStateItemSeq seq;
     seq.push_back(mStateItem);
-    mReplicator->removeStateForItems(seq);
+
+    try
+    {
+        mReplicator->removeStateForItems(seq);
+    }
+    catch (const Ice::Exception& ex)
+    {
+        lg(Error) << "Exception caught attempting to remove replication state for transfer session creation hook: " << ex.what();
+    }
 }
 
 HandleReferOperation::HandleReferOperation(

commit 4c99a175710c274b031593e8a21546f9b3509c24
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Aug 1 14:46:54 2011 -0500

    Add documentation and change some method names to be more descriptive/less dumb.

diff --git a/src/SipStateReplicatorListener.cpp b/src/SipStateReplicatorListener.cpp
index dd50fd2..ffd4183 100644
--- a/src/SipStateReplicatorListener.cpp
+++ b/src/SipStateReplicatorListener.cpp
@@ -169,7 +169,7 @@ public:
                     continue;
                 }
 
-                hook->second->die();
+                hook->second->shutdown();
                 transferHooks.erase(hook);
             }
             else if ((transferListener = TransferSessionListenerStateItemPtr::dynamicCast(*iter)))
@@ -182,7 +182,7 @@ public:
                     continue;
                 }
 
-                listener->second->die();
+                listener->second->shutdown();
                 transferListeners.erase(listener);
             }
         }
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index e058698..9e48551 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -91,7 +91,7 @@ TransferListener::TransferListener(
     : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReplicator(replicator)
 {
     mListenerProxy = SessionListenerPrx::uncheckedCast(mAdapter->addWithUUID(this));
-    replicateState();
+    setState();
 }
 
 TransferListener::TransferListener(
@@ -121,7 +121,7 @@ void TransferListener::indicated(
         pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
         addNotifyBody(tdata, "SIP/2.0 200 OK");
         pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
-        die(source);
+        shutdown(source);
     }
     else if ((stopped = StoppedIndicationPtr::dynamicCast(event)))
     {
@@ -141,7 +141,7 @@ void TransferListener::indicated(
                 addNotifyBody(tdata, "SIP/2.0 503 Service Unavailable");
         }
         pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
-        die(source);
+        shutdown(source);
     }
     else if ((ringing = RingingIndicationPtr::dynamicCast(event)))
     {
@@ -164,22 +164,19 @@ SessionListenerPrx TransferListener::getProxy()
     return mListenerProxy;
 }
 
-void TransferListener::die()
+void TransferListener::shutdown()
 {
     mAdapter->remove(mListenerProxy->ice_getIdentity());
-
-    SipStateItemSeq seq;
-    seq.push_back(mStateItem);
-    mReplicator->removeStateForItems(seq);
+    removeState();
 }
 
-void TransferListener::die(const SessionPrx& session)
+void TransferListener::shutdown(const SessionPrx& session)
 {
     session->removeListener(mListenerProxy);
-    die();
+    shutdown();
 }
 
-void TransferListener::replicateState()
+void TransferListener::setState()
 {
     std::string callId(pj_strbuf(&mDialog->call_id->id), pj_strlen(&mDialog->call_id->id));
     std::string localTag(pj_strbuf(&mDialog->local.info->tag), pj_strlen(&mDialog->local.info->tag));
@@ -199,6 +196,13 @@ void TransferListener::replicateState()
     mReplicator->setState(seq);
 }
 
+void TransferListener::removeState()
+{
+    SipStateItemSeq seq;
+    seq.push_back(mStateItem);
+    mReplicator->removeStateForItems(seq);
+}
+
 TransferSessionCreationHook::TransferSessionCreationHook(
         const Ice::ObjectAdapterPtr& adapter,
         pjsip_dialog *dlg,
@@ -209,7 +213,7 @@ TransferSessionCreationHook::TransferSessionCreationHook(
       mReplicator(replicator)
 {
     mProxy = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(this));
-    replicateState();
+    setState();
 }
 
 TransferSessionCreationHook::TransferSessionCreationHook(
@@ -231,16 +235,16 @@ HookResult TransferSessionCreationHook::modifySession(
         const Ice::Current&)
 {
     replacementData = new SessionCreationHookData();
-    setStuff(originalData, replacementData);
+    modifySession(originalData, replacementData);
     HookResult result;
     result.status = Succeeded;
     //There's no need for this hook to exist after the sesion
     //gets modified. Go ahead and die.
-    die();
+    shutdown();
     return result;
 }
 
-void TransferSessionCreationHook::setStuff(
+void TransferSessionCreationHook::modifySession(
         const SessionCreationHookDataPtr& original,
         SessionCreationHookDataPtr& replacement)
 {
@@ -259,16 +263,13 @@ SessionCreationHookPrx TransferSessionCreationHook::getProxy()
     return mProxy;
 }
 
-void TransferSessionCreationHook::die()
+void TransferSessionCreationHook::shutdown()
 {
     mAdapter->remove(mProxy->ice_getIdentity());
-
-    SipStateItemSeq seq;
-    seq.push_back(mStateItem);
-    mReplicator->removeStateForItems(seq);
+    removeState();
 }
 
-void TransferSessionCreationHook::replicateState()
+void TransferSessionCreationHook::setState()
 {
     std::string callId(pj_strbuf(&mDialog->call_id->id), pj_strlen(&mDialog->call_id->id));
     std::string localTag(pj_strbuf(&mDialog->local.info->tag), pj_strlen(&mDialog->local.info->tag));
@@ -289,6 +290,13 @@ void TransferSessionCreationHook::replicateState()
     mReplicator->setState(seq);
 }
 
+void TransferSessionCreationHook::removeState()
+{
+    SipStateItemSeq seq;
+    seq.push_back(mStateItem);
+    mReplicator->removeStateForItems(seq);
+}
+
 HandleReferOperation::HandleReferOperation(
         pjsip_inv_session *inv,
         pjsip_transaction *tsx,
@@ -471,7 +479,7 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
         //Only blind transfers have the session creation hook to get rid of
         if (mBlindTransfer)
         {
-            mHook->die();
+            mHook->shutdown();
         }
         return Complete;
     }
@@ -484,7 +492,7 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
         //Only blind transfers have the session creation hook to get rid of
         if (mBlindTransfer)
         {
-            mHook->die();
+            mHook->shutdown();
         }
         return Complete;
     }
diff --git a/src/SipTransfer.h b/src/SipTransfer.h
index 426705c..a90f252 100644
--- a/src/SipTransfer.h
+++ b/src/SipTransfer.h
@@ -62,22 +62,63 @@ public:
             const AsteriskSCF::SessionCommunications::V1::SessionCookies&,
             const Ice::Current&);
 
-    void setProxy(const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener);
-
+    /**
+     * Get the proxy for the item.
+     */
     AsteriskSCF::SessionCommunications::V1::SessionListenerPrx getProxy();
 
-    void die();
+    /**
+     * Tell the item to shut down. Takes care of tasks like removing the item
+     * from the object adapter and removing state from the state replicator.
+     */
+    void shutdown();
     
 private:
-    void die(const AsteriskSCF::SessionCommunications::V1::SessionPrx& session);
+    /**
+     * Like the public version but also removes the item as a listener from
+     * a session.
+     */
+    void shutdown(const AsteriskSCF::SessionCommunications::V1::SessionPrx& session);
+
+    /**
+     * Notifies a state replicator of the construction of the item.
+     */
+    void setState();
 
-    void replicateState();
+    /**
+     * Remove state from the state replicator
+     */
+    void removeState();
 
+    /**
+     * The object adapter used for creating a proxy version of the object
+     */
     Ice::ObjectAdapterPtr mAdapter;
+
+    /**
+     * The REFER dialog. Necessary for transmitting sipfrag NOTIFY requests
+     */
     pjsip_dialog *mDialog;
+
+    /**
+     * The CSeq of the REFER. This is used as a header parameter for the
+     * Event header in sipfrag NOTIFY requests.
+     */
     pj_int32_t mReferCSeq;
+
+    /**
+     * The state replicator over which the object's state is replicated
+     */
     AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx> mReplicator;
+
+    /**
+     * The proxy for the object
+     */
     AsteriskSCF::SessionCommunications::V1::SessionListenerPrx mListenerProxy;
+
+    /**
+     * The item sent to the state replicator either to add or remove state
+     */
     AsteriskSCF::Replication::SipSessionManager::V1::TransferSessionListenerStateItemPtr mStateItem;
 };
 
@@ -87,6 +128,10 @@ class TransferSessionCreationHook : public AsteriskSCF::SessionCommunications::E
 {
 
 public:
+
+    /**
+     * Regular constructor.
+     */
     TransferSessionCreationHook(
             const Ice::ObjectAdapterPtr& adapter,
             pjsip_dialog *dlg,
@@ -94,6 +139,10 @@ public:
             const std::string& referredBy,
             const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx>& replicator);
     
+    /**
+     * Constructor used by state replicator.
+     * Includes the ID of the proxy to add to the object adapter
+     */
     TransferSessionCreationHook(
             const Ice::ObjectAdapterPtr& adapter,
             pjsip_dialog *dlg,
@@ -102,28 +151,88 @@ public:
             const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx>& replicator,
             const Ice::Identity& id);
 
+    /**
+     * Override of SessionCreationHook::modifySession
+     *
+     * This performs two main tasks:
+     * 1. It adds a ReferredBy cookie to the session it is modifying.
+     *    This allows for a Referred-By header to be added to an outbound
+     *    INVITE.
+     *
+     * 2. It creates a TransferListener to listen to the outbound session.
+     */
     AsteriskSCF::System::Hook::V1::HookResult modifySession(
             const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& originalData,
             AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& replacementData,
             const Ice::Current&);
 
+    /**
+     * Get the proxy for this object
+     */
     AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx getProxy();
 
-    void die();
+    /**
+     * Order shutdown of the object.
+     * This takes care of operations like removing the object from the object adapter
+     * and removing state from the state replicator.
+     */
+    void shutdown();
 
 private:
-    void setStuff(
+    /**
+     * Helper method for modifySession.
+     *
+     * This is where the "meat" of the method is.
+     */
+    void modifySession(
             const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& original,
             AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& replacement);
 
-    void replicateState();
+    /**
+     * Set state in the state replicator upon object creation.
+     */
+    void setState();
+
+    /**
+     * Remove state from the state replicator upon object destruction.
+     */
+    void removeState();
 
+    /**
+     * The adapter to which the servant is added and from which the proxy is created.
+     */
     Ice::ObjectAdapterPtr mAdapter;
+
+    /**
+     * The REFER dialog. Needed when constructing a TransferListener.
+     */
     pjsip_dialog *mDialog;
+
+    /**
+     * The CSeq of the REFER. Needed when constructing a TransferListener.
+     */
     pj_int32_t mReferCSeq;
+
+    /**
+     * The value of the Referred-By header in the REFER. Used when creating
+     * a ReferredBy cookie for a new session.
+     */
     const std::string mReferredBy;
+
+    /**
+     * The state replicator
+     */
     AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx> mReplicator;
+
+    /**
+     * The proxy for this object
+     */
     AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx mProxy;
+
+    /**
+     * The state item used for adding and removing state
+     * from the state replicator
+     */
     AsteriskSCF::Replication::SipSessionManager::V1::TransferSessionCreationHookStateItemPtr mStateItem;
 };
 

commit 52b7a04229bc7357904fc7696360b5216c7c168f
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Aug 1 14:16:39 2011 -0500

    Remove state on item destruction.

diff --git a/src/SipStateReplicatorListener.cpp b/src/SipStateReplicatorListener.cpp
index c30a2a8..dd50fd2 100644
--- a/src/SipStateReplicatorListener.cpp
+++ b/src/SipStateReplicatorListener.cpp
@@ -144,6 +144,9 @@ public:
         for (SipStateItemSeq::const_iterator iter = items.begin(); iter != items.end(); ++iter)
         {
             SipRegistrarStateItemPtr regItem;
+            TransferSessionCreationHookStateItemPtr transferHook;
+            TransferSessionListenerStateItemPtr transferListener;
+
             if ((regItem = SipRegistrarStateItemPtr::dynamicCast((*iter))))
             {
                 PJSipRegistrarModulePtr regModule;
@@ -156,6 +159,32 @@ public:
                 }
                 removeRegistrationState(regModule, regItem);
             }
+            else if ((transferHook = TransferSessionCreationHookStateItemPtr::dynamicCast(*iter)))
+            {
+                std::map<TransferSessionCreationHookStateItemPtr, TransferSessionCreationHookPtr>::iterator
+                    hook = transferHooks.find(transferHook);
+
+                if (hook == transferHooks.end())
+                {
+                    continue;
+                }
+
+                hook->second->die();
+                transferHooks.erase(hook);
+            }
+            else if ((transferListener = TransferSessionListenerStateItemPtr::dynamicCast(*iter)))
+            {
+                std::map<TransferSessionListenerStateItemPtr, TransferListenerPtr>::iterator
+                    listener = transferListeners.find(transferListener);
+
+                if (listener == transferListeners.end())
+                {
+                    continue;
+                }
+
+                listener->second->die();
+                transferListeners.erase(listener);
+            }
         }
     }
 
@@ -457,6 +486,7 @@ public:
                 }
                 
                 TransferListenerPtr listener(new TransferListener(mGlobalAdapter, referDialog, referCSeq, mStateReplicator, transferListener->objectId));
+                transferListeners[transferListener] = listener;
             }
             else if ((transferHook = TransferSessionCreationHookStateItemPtr::dynamicCast(*item)))
             {
@@ -476,12 +506,15 @@ public:
                 }
 
                 TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mGlobalAdapter, referDialog, referCSeq, transferHook->referredBy, mStateReplicator, transferHook->objectId));
+                transferHooks[transferHook] = hook;
             }
         }
     }
     std::string mId;
     std::map<std::string, boost::shared_ptr<SipStateReplicatorItem> > mStateItems;
     boost::shared_ptr<SipEndpointFactory> mEndpointFactory;
+    std::map<TransferSessionCreationHookStateItemPtr, TransferSessionCreationHookPtr> transferHooks;
+    std::map<TransferSessionListenerStateItemPtr, TransferListenerPtr> transferListeners;
     PJSipManagerPtr mManager;
     /**
      * Note this is *not* the replication adapter.
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index fbbcf7e..e058698 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -164,10 +164,19 @@ SessionListenerPrx TransferListener::getProxy()
     return mListenerProxy;
 }
 
+void TransferListener::die()
+{
+    mAdapter->remove(mListenerProxy->ice_getIdentity());
+
+    SipStateItemSeq seq;
+    seq.push_back(mStateItem);
+    mReplicator->removeStateForItems(seq);
+}
+
 void TransferListener::die(const SessionPrx& session)
 {
     session->removeListener(mListenerProxy);
-    mAdapter->remove(mListenerProxy->ice_getIdentity());
+    die();
 }
 
 void TransferListener::replicateState()
@@ -176,12 +185,17 @@ void TransferListener::replicateState()
     std::string localTag(pj_strbuf(&mDialog->local.info->tag), pj_strlen(&mDialog->local.info->tag));
     std::string remoteTag(pj_strbuf(&mDialog->remote.info->tag), pj_strlen(&mDialog->remote.info->tag));
 
-    TransferSessionListenerStateItemPtr item(
-           new TransferSessionListenerStateItem(std::string(), std::string(), mReferCSeq, callId, localTag,
-               remoteTag, mListenerProxy->ice_getIdentity()));
+    mStateItem = new TransferSessionListenerStateItem(
+            std::string(),
+            std::string(),
+            mReferCSeq,
+            callId,
+            localTag,
+            remoteTag,
+            mListenerProxy->ice_getIdentity());
 
     SipStateItemSeq seq;
-    seq.push_back(item);
+    seq.push_back(mStateItem);
     mReplicator->setState(seq);
 }
 
@@ -248,6 +262,10 @@ SessionCreationHookPrx TransferSessionCreationHook::getProxy()
 void TransferSessionCreationHook::die()
 {
     mAdapter->remove(mProxy->ice_getIdentity());
+
+    SipStateItemSeq seq;
+    seq.push_back(mStateItem);
+    mReplicator->removeStateForItems(seq);
 }
 
 void TransferSessionCreationHook::replicateState()
@@ -256,13 +274,18 @@ void TransferSessionCreationHook::replicateState()
     std::string localTag(pj_strbuf(&mDialog->local.info->tag), pj_strlen(&mDialog->local.info->tag));
     std::string remoteTag(pj_strbuf(&mDialog->remote.info->tag), pj_strlen(&mDialog->remote.info->tag));
 
-    TransferSessionCreationHookStateItemPtr item(
-           new TransferSessionCreationHookStateItem(std::string(), std::string(),
-               mReferCSeq, mReferredBy, callId, localTag, remoteTag,
-               mProxy->ice_getIdentity()));
+    mStateItem = new TransferSessionCreationHookStateItem(
+            std::string(),
+            std::string(),
+            mReferCSeq,
+            mReferredBy,
+            callId,
+            localTag,
+            remoteTag,
+            mProxy->ice_getIdentity());
 
     SipStateItemSeq seq;
-    seq.push_back(item);
+    seq.push_back(mStateItem);
     mReplicator->setState(seq);
 }
 
diff --git a/src/SipTransfer.h b/src/SipTransfer.h
index bcfbeca..426705c 100644
--- a/src/SipTransfer.h
+++ b/src/SipTransfer.h
@@ -65,9 +65,10 @@ public:
     void setProxy(const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener);
 
     AsteriskSCF::SessionCommunications::V1::SessionListenerPrx getProxy();
+
+    void die();
     
 private:
-
     void die(const AsteriskSCF::SessionCommunications::V1::SessionPrx& session);
 
     void replicateState();
@@ -77,6 +78,7 @@ private:
     pj_int32_t mReferCSeq;
     AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx> mReplicator;
     AsteriskSCF::SessionCommunications::V1::SessionListenerPrx mListenerProxy;
+    AsteriskSCF::Replication::SipSessionManager::V1::TransferSessionListenerStateItemPtr mStateItem;
 };
 
 typedef IceUtil::Handle<TransferListener> TransferListenerPtr;
@@ -122,6 +124,7 @@ private:
     const std::string mReferredBy;
     AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx> mReplicator;
     AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx mProxy;
+    AsteriskSCF::Replication::SipSessionManager::V1::TransferSessionCreationHookStateItemPtr mStateItem;
 };
 
 typedef IceUtil::Handle<TransferSessionCreationHook> TransferSessionCreationHookPtr;

commit 91db4bab32da883c00fe800fabd0ca9e4751e3f7
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Aug 1 13:49:02 2011 -0500

    Replicate state on construction of objects.

diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 0337f7a..fbbcf7e 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -172,6 +172,17 @@ void TransferListener::die(const SessionPrx& session)
 
 void TransferListener::replicateState()
 {
+    std::string callId(pj_strbuf(&mDialog->call_id->id), pj_strlen(&mDialog->call_id->id));
+    std::string localTag(pj_strbuf(&mDialog->local.info->tag), pj_strlen(&mDialog->local.info->tag));
+    std::string remoteTag(pj_strbuf(&mDialog->remote.info->tag), pj_strlen(&mDialog->remote.info->tag));
+
+    TransferSessionListenerStateItemPtr item(
+           new TransferSessionListenerStateItem(std::string(), std::string(), mReferCSeq, callId, localTag,
+               remoteTag, mListenerProxy->ice_getIdentity()));
+
+    SipStateItemSeq seq;
+    seq.push_back(item);
+    mReplicator->setState(seq);
 }
 
 TransferSessionCreationHook::TransferSessionCreationHook(
@@ -184,6 +195,7 @@ TransferSessionCreationHook::TransferSessionCreationHook(
       mReplicator(replicator)
 {
     mProxy = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(this));
+    replicateState();
 }
 
 TransferSessionCreationHook::TransferSessionCreationHook(
@@ -238,6 +250,22 @@ void TransferSessionCreationHook::die()
     mAdapter->remove(mProxy->ice_getIdentity());
 }
 
+void TransferSessionCreationHook::replicateState()
+{
+    std::string callId(pj_strbuf(&mDialog->call_id->id), pj_strlen(&mDialog->call_id->id));
+    std::string localTag(pj_strbuf(&mDialog->local.info->tag), pj_strlen(&mDialog->local.info->tag));
+    std::string remoteTag(pj_strbuf(&mDialog->remote.info->tag), pj_strlen(&mDialog->remote.info->tag));
+
+    TransferSessionCreationHookStateItemPtr item(
+           new TransferSessionCreationHookStateItem(std::string(), std::string(),
+               mReferCSeq, mReferredBy, callId, localTag, remoteTag,
+               mProxy->ice_getIdentity()));
+
+    SipStateItemSeq seq;
+    seq.push_back(item);
+    mReplicator->setState(seq);
+}
+
 HandleReferOperation::HandleReferOperation(
         pjsip_inv_session *inv,
         pjsip_transaction *tsx,
diff --git a/src/SipTransfer.h b/src/SipTransfer.h
index f78484c..bcfbeca 100644
--- a/src/SipTransfer.h
+++ b/src/SipTransfer.h
@@ -114,6 +114,8 @@ private:
             const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& original,
             AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& replacement);
 
+    void replicateState();
+
     Ice::ObjectAdapterPtr mAdapter;
     pjsip_dialog *mDialog;
     pj_int32_t mReferCSeq;

commit 4b4eb32a1b1920eaab3deb529270f4239f8ed7b3
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Aug 1 13:00:31 2011 -0500

    Get a state replicator to the transfer hook and listener.

diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 258239b..9f9a839 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -810,7 +810,7 @@ void PJSipSessionModule::handleRefer(pjsip_inv_session *inv, pjsip_rx_data *rdat
     }
 
     lg(Debug) << "Queuing a HandleReferOperation";
-    enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, referredByVal, target, session, mSessionRouter, mAdapter, mModule.id), inv);
+    enqueueSessionWork(new HandleReferOperation(inv, tsx, tdata, replaces_param, to_tag_param, from_tag_param, referredByVal, target, session, mSessionRouter, mAdapter, mStateReplicator, mModule.id), inv);
 }
 
 pj_bool_t PJSipSessionModule::on_rx_request(pjsip_rx_data *rdata)
diff --git a/src/SipSessionManagerApp.cpp b/src/SipSessionManagerApp.cpp
index 1390c38..39f9b74 100644
--- a/src/SipSessionManagerApp.cpp
+++ b/src/SipSessionManagerApp.cpp
@@ -625,7 +625,7 @@ void SipSessionManager::initialize(const string& appName, const Ice::Communicato
         lg(Debug) << "Added Auth extension point to object adapter";
 
         // Create and publish our state replicator listener interface.
-        mReplicatorListener = new SipStateReplicatorListenerI(mEndpointFactory, mPJSipManager, mGlobalAdapter);
+        mReplicatorListener = new SipStateReplicatorListenerI(mEndpointFactory, mPJSipManager, mGlobalAdapter, mStateReplicator);
         mReplicatorListenerProxy =
             SipStateReplicatorListenerPrx::uncheckedCast(mLocalAdapter->addWithUUID(mReplicatorListener));
         lg(Debug) << "Got proxy to SIP state replicator";
diff --git a/src/SipStateReplicator.h b/src/SipStateReplicator.h
index 0b68f51..8341b19 100644
--- a/src/SipStateReplicator.h
+++ b/src/SipStateReplicator.h
@@ -19,6 +19,8 @@
 #include "SipEndpointFactory.h"
 #include <Ice/Ice.h>
 #include <AsteriskSCF/Replication/StateReplicator.h>
+#include <AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.h>
+#include <AsteriskSCF/Discovery/SmartProxy.h>
 #include <SipStateReplicationIf.h>
 
 #include <boost/shared_ptr.hpp>
@@ -45,7 +47,8 @@ public:
     SipStateReplicatorListenerI(
             const boost::shared_ptr<SipEndpointFactory>& factory,
             const PJSipManagerPtr& manager,
-            const Ice::ObjectAdapterPtr& globalAdapter);
+            const Ice::ObjectAdapterPtr& globalAdapter,
+            const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx>& replicator);
     void stateRemoved(const Ice::StringSeq&, const Ice::Current&);
     void stateRemovedForItems(const AsteriskSCF::Replication::SipSessionManager::V1::SipStateItemSeq&, const Ice::Current&);
     void stateSet(const AsteriskSCF::Replication::SipSessionManager::V1::SipStateItemSeq&, const Ice::Current&);
diff --git a/src/SipStateReplicatorListener.cpp b/src/SipStateReplicatorListener.cpp
index 80d48e6..c30a2a8 100644
--- a/src/SipStateReplicatorListener.cpp
+++ b/src/SipStateReplicatorListener.cpp
@@ -66,8 +66,11 @@ public:
     SipStateReplicatorListenerImpl(
             const boost::shared_ptr<SipEndpointFactory>& factory,
             const PJSipManagerPtr& manager,
-            const Ice::ObjectAdapterPtr& globalAdapter)
-        : mId(IceUtil::generateUUID()), mEndpointFactory(factory), mManager(manager), mGlobalAdapter(globalAdapter) {}
+            const Ice::ObjectAdapterPtr& globalAdapter,
+            const AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx>& replicator)
+        : mId(IceUtil::generateUUID()), mEndpointFactory(factory),
+          mManager(manager), mGlobalAdapter(globalAdapter),
+          mStateReplicator(replicator) {}
     
     void removeStateNoticeImpl(const Ice::StringSeq& itemKeys)
     {
@@ -453,7 +456,7 @@ public:
                     continue;
                 }
                 
-                TransferListenerPtr listener(new TransferListener(mGlobalAdapter, referDialog, referCSeq, transferListener->objectId));
+                TransferListenerPtr listener(new TransferListener(mGlobalAdapter, referDialog, referCSeq, mStateReplicator, transferListener->objectId));
             }
             else if ((transferHook = TransferSessionCreationHookStateItemPtr::dynamicCast(*item)))
             {
@@ -472,7 +475,7 @@ public:
                     continue;
                 }
 
-                TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mGlobalAdapter, referDialog, referCSeq, transferHook->referredBy, transferHook->objectId));
+                TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mGlobalAdapter, referDialog, referCSeq, transferHook->referredBy, mStateReplicator, transferHook->objectId));
             }
         }
     }
@@ -487,13 +490,15 @@ public:
      * order to be constructed.
      */
     Ice::ObjectAdapterPtr mGlobalAdapter;
+    AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx> mStateReplicator;
 };
 
 SipStateReplicatorListenerI::SipStateReplicatorListenerI(
         const boost::shared_ptr<SipEndpointFactory>& factory,
         const PJSipManagerPtr& manager,
-        const Ice::ObjectAdapterPtr& globalAdapter)
-    : mImpl(new SipStateReplicatorListenerImpl(factory, manager, globalAdapter)) 
+        const Ice::ObjectAdapterPtr& globalAdapter,
+        const AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx>& replicator)
+    : mImpl(new SipStateReplicatorListenerImpl(factory, manager, globalAdapter, replicator)) 
 {
 }
 
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 543cc94..0337f7a 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -81,21 +81,26 @@ using namespace AsteriskSCF::SessionCommunications::ExtensionPoints::V1;
 using namespace AsteriskSCF::System::WorkQueue::V1;
 using namespace AsteriskSCF::System::Hook::V1;
 using namespace AsteriskSCF::SessionCookies::SipSessionManager::V1;
+using namespace AsteriskSCF::Replication::SipSessionManager::V1;
 
 TransferListener::TransferListener(
         const Ice::ObjectAdapterPtr& adapter,
         pjsip_dialog *dlg,
-        pj_int32_t referCSeq)
-    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq)
+        pj_int32_t referCSeq,
+        const AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx>& replicator)
+    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReplicator(replicator)
 {
     mListenerProxy = SessionListenerPrx::uncheckedCast(mAdapter->addWithUUID(this));
+    replicateState();
 }
+
 TransferListener::TransferListener(
         const Ice::ObjectAdapterPtr& adapter,
         pjsip_dialog *dlg,
         pj_int32_t referCSeq,
+        const AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx>& replicator,
         const Ice::Identity& id)
-    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq)
+    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReplicator(replicator)
 {
     mListenerProxy = SessionListenerPrx::uncheckedCast(mAdapter->add(this, id));
 }
@@ -165,12 +170,18 @@ void TransferListener::die(const SessionPrx& session)
     mAdapter->remove(mListenerProxy->ice_getIdentity());
 }
 
+void TransferListener::replicateState()
+{
+}
+
 TransferSessionCreationHook::TransferSessionCreationHook(
         const Ice::ObjectAdapterPtr& adapter,
         pjsip_dialog *dlg,
         pj_int32_t referCSeq,
-        const std::string& referredBy)
-    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReferredBy(referredBy)
+        const std::string& referredBy, 
+        const AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx>& replicator)
+    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReferredBy(referredBy),
+      mReplicator(replicator)
 {
     mProxy = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(this));
 }
@@ -180,8 +191,10 @@ TransferSessionCreationHook::TransferSessionCreationHook(
         pjsip_dialog *dlg,
         pj_int32_t referCSeq,
         const std::string& referredBy,
+        const AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx>& replicator,
         const Ice::Identity& id)
-    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReferredBy(referredBy)
+    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReferredBy(referredBy),
+      mReplicator(replicator)
 {
     mProxy = SessionCreationHookPrx::uncheckedCast(mAdapter->add(this, id));
 }
@@ -205,7 +218,7 @@ void TransferSessionCreationHook::setStuff(
         const SessionCreationHookDataPtr& original,
         SessionCreationHookDataPtr& replacement)
 {
-    TransferListenerPtr transferListener = new TransferListener(mAdapter, mDialog, mReferCSeq);
+    TransferListenerPtr transferListener = new TransferListener(mAdapter, mDialog, mReferCSeq, mReplicator);
     SessionListenerSeq listeners = original->listeners;
     listeners.push_back(transferListener->getProxy());
     AsteriskSCF::SessionCommunications::V1::SessionCookies cookies = original->cookies;
@@ -237,6 +250,7 @@ HandleReferOperation::HandleReferOperation(
         const SipSessionPtr& session,
         const AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx>& sessionRouter,
         const Ice::ObjectAdapterPtr& adapter,
+        const AsteriskSCF::Discovery::SmartProxy<SipStateReplicatorPrx>& replicator,
         const int moduleId)
     : mInv(inv), mTsx(tsx), mTdata(tdata), 
     mReplacesParam(replaces_param ? new pjsip_param(*replaces_param) : NULL), 
@@ -244,8 +258,13 @@ HandleReferOperation::HandleReferOperation(
     mFromTagParam(from_tag_param ? new pjsip_param(*from_tag_param) : NULL),
     mReferredBy(referredBy),
     mTarget(target),
-    mSession(session), mSessionRouter(sessionRouter), mAdapter(adapter),
-    mModuleId(moduleId), mReferCSeq(tsx->cseq), mBlindTransfer(false) {}
+    mSession(session), 
+    mSessionRouter(sessionRouter),
+    mAdapter(adapter),
+    mReplicator(replicator),
+    mModuleId(moduleId),
+    mReferCSeq(tsx->cseq),
+    mBlindTransfer(false) {}
 
 HandleReferOperation::~HandleReferOperation()
 {
@@ -357,7 +376,7 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
             lg(Debug) << "Destination is " << mTarget;
             mBlindTransfer = true;
             
-            mHook = new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy);
+            mHook = new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy, mReplicator);
             
             //Go ahead and send the 100 Trying sipfrag
             pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, true);
diff --git a/src/SipTransfer.h b/src/SipTransfer.h
index 44ffcc7..f78484c 100644
--- a/src/SipTransfer.h
+++ b/src/SipTransfer.h
@@ -18,6 +18,8 @@
 
 #include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
 #include <AsteriskSCF/SessionCommunications/SessionCommunicationsExtensionPointsIf.h>
+#include <AsteriskSCF/Discovery/SmartProxy.h>
+#include <AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.h>
 #include <AsteriskSCF/System/Hook/HookIf.h>
 
 namespace AsteriskSCF
@@ -35,7 +37,8 @@ public:
     TransferListener(
             const Ice::ObjectAdapterPtr& adapter,
             pjsip_dialog *dlg,
-            pj_int32_t referCSeq);
+            pj_int32_t referCSeq,
+            const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx>& replicator);
 
     /**
      * Replica constructor. Provides the Identity to use when adding to the object adapter
@@ -44,6 +47,7 @@ public:
             const Ice::ObjectAdapterPtr& adapter,
             pjsip_dialog *dlg,
             pj_int32_t referCSeq,
+            const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx>& replicator,
             const Ice::Identity& id);
 
     /**
@@ -66,9 +70,12 @@ private:
 
     void die(const AsteriskSCF::SessionCommunications::V1::SessionPrx& session);
 
+    void replicateState();
+
     Ice::ObjectAdapterPtr mAdapter;
     pjsip_dialog *mDialog;
     pj_int32_t mReferCSeq;
+    AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx> mReplicator;
     AsteriskSCF::SessionCommunications::V1::SessionListenerPrx mListenerProxy;
 };
 
@@ -82,13 +89,15 @@ public:
             const Ice::ObjectAdapterPtr& adapter,
             pjsip_dialog *dlg,
             pj_int32_t referCSeq,
-            const std::string& referredBy);
+            const std::string& referredBy,
+            const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx>& replicator);
     
     TransferSessionCreationHook(
             const Ice::ObjectAdapterPtr& adapter,
             pjsip_dialog *dlg,
             pj_int32_t referCSeq,
             const std::string& referredBy,
+            const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx>& replicator,
             const Ice::Identity& id);
 
     AsteriskSCF::System::Hook::V1::HookResult modifySession(
@@ -109,6 +118,7 @@ private:
     pjsip_dialog *mDialog;
     pj_int32_t mReferCSeq;
     const std::string mReferredBy;
+    AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx> mReplicator;
     AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx mProxy;
 };
 
@@ -129,6 +139,7 @@ public:
             const SipSessionPtr& session,
             const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::SessionCommunications::V1::SessionRouterPrx>& sessionRouter,
             const Ice::ObjectAdapterPtr& adapter,
+            const AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx>& replicator,
             const int moduleId);
 
     ~HandleReferOperation();
@@ -156,10 +167,6 @@ protected:
 
 private:
     /**
-     * Create the transfer session creation hook
-     */
-    void createTransferSessionCreationHook();
-    /**
      * Find matching dialog from the replaces header.
      * This mostly exists just so there isn't a huge
      * block of code in the middle of processing.
@@ -216,6 +223,10 @@ private:
      */
     Ice::ObjectAdapterPtr mAdapter;
     /**
+     * The state replicator
+     */
+    AsteriskSCF::Discovery::SmartProxy<AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorPrx> mReplicator;
+    /**
      * The identifier of the PJSipSessionModule. Used for retrieving module data from mInv
      */
     const int mModuleId;

commit 11a545c5e30ed1d4b2ad4324a9608391916ed568
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Jul 29 14:01:55 2011 -0500

    Get state replication of the session creation hook for transfers.

diff --git a/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice b/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
index 4d90992..ccc8dfd 100644
--- a/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
+++ b/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
@@ -188,6 +188,7 @@ module V1
         string callId;
         string localTag;
         string remoteTag;
+        Ice::Identity objectId;
    };
 
    /**
diff --git a/src/SipStateReplicatorListener.cpp b/src/SipStateReplicatorListener.cpp
index 3034ac8..80d48e6 100644
--- a/src/SipStateReplicatorListener.cpp
+++ b/src/SipStateReplicatorListener.cpp
@@ -472,7 +472,7 @@ public:
                     continue;
                 }
 
-                //Now to create the hook...
+                TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mGlobalAdapter, referDialog, referCSeq, transferHook->referredBy, transferHook->objectId));
             }
         }
     }
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index cdf4f74..543cc94 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -20,7 +20,6 @@
 #include <IceUtil/UUID.h>
 
 #include <AsteriskSCF/logger.h>
-#include <AsteriskSCF/SessionCommunications/SessionCommunicationsExtensionPointsIf.h>
 #include <AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.h>
 
 using namespace AsteriskSCF::System::Logging;
@@ -166,67 +165,65 @@ void TransferListener::die(const SessionPrx& session)
     mAdapter->remove(mListenerProxy->ice_getIdentity());
 }
 
-class TransferSessionCreationHook : public SessionCreationHook
+TransferSessionCreationHook::TransferSessionCreationHook(
+        const Ice::ObjectAdapterPtr& adapter,
+        pjsip_dialog *dlg,
+        pj_int32_t referCSeq,
+        const std::string& referredBy)
+    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReferredBy(referredBy)
 {
+    mProxy = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(this));
+}
 
-public:
-    TransferSessionCreationHook(
-            const Ice::ObjectAdapterPtr& adapter,
-            pjsip_dialog *dlg,
-            pj_int32_t referCSeq,
-            const std::string& referredBy)
-        : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReferredBy(referredBy)
-    {
-    }
-
-    HookResult modifySession(
-            const SessionCreationHookDataPtr& originalData,
-            SessionCreationHookDataPtr& replacementData,
-            const Ice::Current&)
-    {
-        replacementData = new SessionCreationHookData();
-        setStuff(originalData, replacementData);
-        HookResult result;
-        result.status = Succeeded;
-        //There's no need for this hook to exist after the sesion
-        //gets modified. Go ahead and die.
-        die();
-        return result;
-    }
-
-    void setProxy(const SessionCreationHookPrx& proxy)
-    {
-        mProxy = proxy;
-    }
+TransferSessionCreationHook::TransferSessionCreationHook(
+        const Ice::ObjectAdapterPtr& adapter,
+        pjsip_dialog *dlg,
+        pj_int32_t referCSeq,
+        const std::string& referredBy,
+        const Ice::Identity& id)
+    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReferredBy(referredBy)
+{
+    mProxy = SessionCreationHookPrx::uncheckedCast(mAdapter->add(this, id));
+}
 
-private:
-    void setStuff(
-            const SessionCreationHookDataPtr& original,
-            SessionCreationHookDataPtr& replacement)
-    {
-        TransferListenerPtr transferListener = new TransferListener(mAdapter, mDialog, mReferCSeq);
-        SessionListenerSeq listeners = original->listeners;
-        listeners.push_back(transferListener->getProxy());
-        AsteriskSCF::SessionCommunications::V1::SessionCookies cookies = original->cookies;
-        cookies.push_back(new ReferredByCookie(mReferredBy));
-        replacement->session = original->session;
-        replacement->cookies = cookies;
-        replacement->listeners = listeners;
-    }
+HookResult TransferSessionCreationHook::modifySession(
+        const SessionCreationHookDataPtr& originalData,
+        SessionCreationHookDataPtr& replacementData,
+        const Ice::Current&)
+{
+    replacementData = new SessionCreationHookData();
+    setStuff(originalData, replacementData);
+    HookResult result;
+    result.status = Succeeded;
+    //There's no need for this hook to exist after the sesion
+    //gets modified. Go ahead and die.
+    die();
+    return result;
+}
 
-    void die()
-    {
-        mAdapter->remove(mProxy->ice_getIdentity());
-    }
+void TransferSessionCreationHook::setStuff(
+        const SessionCreationHookDataPtr& original,
+        SessionCreationHookDataPtr& replacement)
+{
+    TransferListenerPtr transferListener = new TransferListener(mAdapter, mDialog, mReferCSeq);
+    SessionListenerSeq listeners = original->listeners;
+    listeners.push_back(transferListener->getProxy());
+    AsteriskSCF::SessionCommunications::V1::SessionCookies cookies = original->cookies;
+    cookies.push_back(new ReferredByCookie(mReferredBy));
+    replacement->session = original->session;
+    replacement->cookies = cookies;
+    replacement->listeners = listeners;
+}
 
-    Ice::ObjectAdapterPtr mAdapter;
-    pjsip_dialog *mDialog;
-    pj_int32_t mReferCSeq;
-    const std::string mReferredBy;
-    SessionCreationHookPrx mProxy;
-};
+SessionCreationHookPrx TransferSessionCreationHook::getProxy()
+{
+    return mProxy;
+}
 
-typedef IceUtil::Handle<TransferSessionCreationHook> TransferSessionCreationHookPtr;
+void TransferSessionCreationHook::die()
+{
+    mAdapter->remove(mProxy->ice_getIdentity());
+}
 
 HandleReferOperation::HandleReferOperation(
         pjsip_inv_session *inv,
@@ -360,14 +357,14 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
             lg(Debug) << "Destination is " << mTarget;
             mBlindTransfer = true;
             
-            createTransferSessionCreationHook();
+            mHook = new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy);
             
             //Go ahead and send the 100 Trying sipfrag
             pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, true);
             addNotifyBody(tdata, "SIP/2.0 100 Trying");
             pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
 
-            mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, mHookPrx, d);
+            mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, mHook->getProxy(), d);
             return Complete;
         }
         catch (const Ice::CommunicatorDestroyedException &)
@@ -404,7 +401,7 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
         //Only blind transfers have the session creation hook to get rid of
         if (mBlindTransfer)
         {
-            mAdapter->remove(mHookPrx->ice_getIdentity());
+            mHook->die();
         }
         return Complete;
     }
@@ -417,7 +414,7 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
         //Only blind transfers have the session creation hook to get rid of
         if (mBlindTransfer)
         {
-            mAdapter->remove(mHookPrx->ice_getIdentity());
+            mHook->die();
         }
         return Complete;
     }
@@ -435,13 +432,6 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
     return Complete;
 }
 
-void HandleReferOperation::createTransferSessionCreationHook()
-{
-    TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy));
-    mHookPrx = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(hook));
-    hook->setProxy(mHookPrx);
-}
-
 pjsip_dialog* HandleReferOperation::findDialogFromReplaces()
 {
     // It is possible for the to and from tag value to be present within the Replaces parameter value, so try to
diff --git a/src/SipTransfer.h b/src/SipTransfer.h
index aa2c5e3..44ffcc7 100644
--- a/src/SipTransfer.h
+++ b/src/SipTransfer.h
@@ -17,6 +17,8 @@
 #include "PJSipSessionModule.h"
 
 #include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
+#include <AsteriskSCF/SessionCommunications/SessionCommunicationsExtensionPointsIf.h>
+#include <AsteriskSCF/System/Hook/HookIf.h>
 
 namespace AsteriskSCF
 {
@@ -72,6 +74,46 @@ private:
 
 typedef IceUtil::Handle<TransferListener> TransferListenerPtr;
 
+class TransferSessionCreationHook : public AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHook
+{
+
+public:
+    TransferSessionCreationHook(
+            const Ice::ObjectAdapterPtr& adapter,
+            pjsip_dialog *dlg,
+            pj_int32_t referCSeq,
+            const std::string& referredBy);
+    
+    TransferSessionCreationHook(
+            const Ice::ObjectAdapterPtr& adapter,
+            pjsip_dialog *dlg,
+            pj_int32_t referCSeq,
+            const std::string& referredBy,
+            const Ice::Identity& id);
+
+    AsteriskSCF::System::Hook::V1::HookResult modifySession(
+            const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& originalData,
+            AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& replacementData,
+            const Ice::Current&);
+
+    AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx getProxy();
+
+    void die();
+
+private:
+    void setStuff(
+            const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& original,
+            AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr& replacement);
+
+    Ice::ObjectAdapterPtr mAdapter;
+    pjsip_dialog *mDialog;
+    pj_int32_t mReferCSeq;
+    const std::string mReferredBy;
+    AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx mProxy;
+};
+
+typedef IceUtil::Handle<TransferSessionCreationHook> TransferSessionCreationHookPtr;
+
 class HandleReferOperation : public SipQueueableOperation 
 {
 public:
@@ -187,11 +229,11 @@ private:
      */
     bool mBlindTransfer;
     /**
-     * The proxy of the session creation hook we create.
+     * The session creation hook we create.
      * We have to hold onto this in case our AMI call to create the outbound
      * session fails.
      */
-    AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx mHookPrx;
+    TransferSessionCreationHookPtr mHook;
 };
 
 }; //end namespace SipSessionManager

commit 5b41c5a650bfccb0531f9a1fd9e006b18b8cbbed
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Jul 29 11:19:55 2011 -0500

    Implement replication of Transfer session listener.

diff --git a/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice b/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
index 4a48474..4d90992 100644
--- a/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
+++ b/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
@@ -175,6 +175,36 @@ module V1
       bool newBindings;
    };
 
+   /**
+    * The only real state we replicate here is the existence or
+    * nonexistence of this item. So we need to have enough
+    * information to be able to construct this item.
+    */
+   class TransferSessionCreationHookStateItem extends SipStateItem
+   {
+        int referCSeq;
+        string referredBy;
+        //We need enough information to find the REFER dialog.
+        string callId;
+        string localTag;
+        string remoteTag;
+   };
+
+   /**
+    * The state we replicate here is the existence or nonexistence
+    * of the item. We need enough information to be able to construct
+    * the item.
+    */
+    class TransferSessionListenerStateItem extends SipStateItem
+    {
+        int referCSeq;
+        //We need enough information to find the REFER dialog.
+        string callId;
+        string localTag;
+        string remoteTag;
+        Ice::Identity objectId;
+    };
+
 }; /* module V1 */
 
 }; /* module SipSessionManager */
diff --git a/src/SipSessionManagerApp.cpp b/src/SipSessionManagerApp.cpp
index 5722809..1390c38 100644
--- a/src/SipSessionManagerApp.cpp
+++ b/src/SipSessionManagerApp.cpp
@@ -625,7 +625,7 @@ void SipSessionManager::initialize(const string& appName, const Ice::Communicato
         lg(Debug) << "Added Auth extension point to object adapter";
 
         // Create and publish our state replicator listener interface.
-        mReplicatorListener = new SipStateReplicatorListenerI(mEndpointFactory, mPJSipManager);
+        mReplicatorListener = new SipStateReplicatorListenerI(mEndpointFactory, mPJSipManager, mGlobalAdapter);
         mReplicatorListenerProxy =
             SipStateReplicatorListenerPrx::uncheckedCast(mLocalAdapter->addWithUUID(mReplicatorListener));
         lg(Debug) << "Got proxy to SIP state replicator";
diff --git a/src/SipStateReplicator.h b/src/SipStateReplicator.h
index d53bc81..0b68f51 100644
--- a/src/SipStateReplicator.h
+++ b/src/SipStateReplicator.h
@@ -42,7 +42,10 @@ struct SipStateReplicatorListenerImpl;
 class SipStateReplicatorListenerI : public AsteriskSCF::Replication::SipSessionManager::V1::SipStateReplicatorListener
 {
 public:
-    SipStateReplicatorListenerI(const boost::shared_ptr<SipEndpointFactory>& factory, const PJSipManagerPtr& manager);
+    SipStateReplicatorListenerI(
+            const boost::shared_ptr<SipEndpointFactory>& factory,
+            const PJSipManagerPtr& manager,
+            const Ice::ObjectAdapterPtr& globalAdapter);
     void stateRemoved(const Ice::StringSeq&, const Ice::Current&);
     void stateRemovedForItems(const AsteriskSCF::Replication::SipSessionManager::V1::SipStateItemSeq&, const Ice::Current&);
     void stateSet(const AsteriskSCF::Replication::SipSessionManager::V1::SipStateItemSeq&, const Ice::Current&);
diff --git a/src/SipStateReplicatorListener.cpp b/src/SipStateReplicatorListener.cpp
index ed9fd83..3034ac8 100644
--- a/src/SipStateReplicatorListener.cpp
+++ b/src/SipStateReplicatorListener.cpp
@@ -20,6 +20,7 @@
 #include "SipEndpointFactory.h"
 #include "SipSession.h"
 #include "PJSipManager.h"
+#include "SipTransfer.h"
 #include <pjlib.h>
 
 #include <IceUtil/UUID.h>
@@ -62,8 +63,11 @@ private:
 struct SipStateReplicatorListenerImpl
 {
 public:
-    SipStateReplicatorListenerImpl(const boost::shared_ptr<SipEndpointFactory>& factory, const PJSipManagerPtr& manager)
-        : mId(IceUtil::generateUUID()), mEndpointFactory(factory), mManager(manager) {}
+    SipStateReplicatorListenerImpl(
+            const boost::shared_ptr<SipEndpointFactory>& factory,
+            const PJSipManagerPtr& manager,
+            const Ice::ObjectAdapterPtr& globalAdapter)
+        : mId(IceUtil::generateUUID()), mEndpointFactory(factory), mManager(manager), mGlobalAdapter(globalAdapter) {}
     
     void removeStateNoticeImpl(const Ice::StringSeq& itemKeys)
     {
@@ -238,6 +242,8 @@ public:
             SipInviteSessionStateItemPtr invitesession;
             SipTransactionStateItemPtr transaction;
             SipRegistrarStateItemPtr regItem;
+            TransferSessionCreationHookStateItemPtr transferHook;
+            TransferSessionListenerStateItemPtr transferListener;
             boost::shared_ptr<SipStateReplicatorItem> localitem;
 
             // Depending on the type of state item we apply it differently
@@ -430,17 +436,64 @@ public:
                 }
                 setRegistrationState(regModule, regItem);
             }
+            else if ((transferListener = TransferSessionListenerStateItemPtr::dynamicCast(*item)))
+            {
+                pj_int32_t referCSeq = transferListener->referCSeq;
+                pj_str_t callId;
+                pj_cstr(&callId, transferListener->callId.c_str());
+                pj_str_t localTag;
+                pj_cstr(&localTag, transferListener->localTag.c_str());
+                pj_str_t remoteTag;
+                pj_cstr(&remoteTag, transferListener->remoteTag.c_str());
+
+                pjsip_dialog *referDialog = pjsip_ua_find_dialog(&callId, &localTag, &remoteTag, PJ_TRUE);
+
+                if (!referDialog)
+                {
+                    continue;
+                }
+                
+                TransferListenerPtr listener(new TransferListener(mGlobalAdapter, referDialog, referCSeq, transferListener->objectId));
+            }
+            else if ((transferHook = TransferSessionCreationHookStateItemPtr::dynamicCast(*item)))
+            {
+                pj_int32_t referCSeq = transferHook->referCSeq;
+                pj_str_t callId;
+                pj_cstr(&callId, transferHook->callId.c_str());
+                pj_str_t localTag;
+                pj_cstr(&localTag, transferHook->localTag.c_str());
+                pj_str_t remoteTag;
+                pj_cstr(&remoteTag, transferHook->remoteTag.c_str());
+
+                pjsip_dialog *referDialog = pjsip_ua_find_dialog(&callId, &localTag, &remoteTag, PJ_TRUE);
+
+                if (!referDialog)
+                {
+                    continue;
+                }
+
+                //Now to create the hook...
+            }
         }
     }
     std::string mId;
     std::map<std::string, boost::shared_ptr<SipStateReplicatorItem> > mStateItems;
     boost::shared_ptr<SipEndpointFactory> mEndpointFactory;
     PJSipManagerPtr mManager;
+    /**
+     * Note this is *not* the replication adapter.
+     * This is the "global" adapter that sessions and other
+     * items are added to. Some replicated items need this in
+     * order to be constructed.
+     */
+    Ice::ObjectAdapterPtr mGlobalAdapter;
 };
 
-SipStateReplicatorListenerI::SipStateReplicatorListenerI(const boost::shared_ptr<SipEndpointFactory>& factory,
-        const PJSipManagerPtr& manager)
-    : mImpl(new SipStateReplicatorListenerImpl(factory, manager)) 
+SipStateReplicatorListenerI::SipStateReplicatorListenerI(
+        const boost::shared_ptr<SipEndpointFactory>& factory,
+        const PJSipManagerPtr& manager,
+        const Ice::ObjectAdapterPtr& globalAdapter)
+    : mImpl(new SipStateReplicatorListenerImpl(factory, manager, globalAdapter)) 
 {
 }
 
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 39da03d..cdf4f74 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -83,87 +83,88 @@ using namespace AsteriskSCF::System::WorkQueue::V1;
 using namespace AsteriskSCF::System::Hook::V1;
 using namespace AsteriskSCF::SessionCookies::SipSessionManager::V1;
 
-class TransferListener : public SessionListener
+TransferListener::TransferListener(
+        const Ice::ObjectAdapterPtr& adapter,
+        pjsip_dialog *dlg,
+        pj_int32_t referCSeq)
+    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq)
 {
-public:
-    TransferListener(const Ice::ObjectAdapterPtr& adapter, pjsip_dialog *dlg, pj_int32_t referCSeq)
-        : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq)
+    mListenerProxy = SessionListenerPrx::uncheckedCast(mAdapter->addWithUUID(this));
+}
+TransferListener::TransferListener(
+        const Ice::ObjectAdapterPtr& adapter,
+        pjsip_dialog *dlg,
+        pj_int32_t referCSeq,
+        const Ice::Identity& id)
+    : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq)
+{
+    mListenerProxy = SessionListenerPrx::uncheckedCast(mAdapter->add(this, id));
+}
+
+void TransferListener::indicated(
+        const SessionPrx& source,
+        const IndicationPtr& event,
+        const AsteriskSCF::SessionCommunications::V1::SessionCookies&,
+        const Ice::Current&)
+{
+    ConnectedIndicationPtr connected;
+    StoppedIndicationPtr stopped;
+    RingingIndicationPtr ringing;
+    ProgressingIndicationPtr progressing;
+    if ((connected = ConnectedIndicationPtr::dynamicCast(event)))
     {
+        lg(Debug) << "Got the connected indication. Should send a 200 sipfrag NOTIFY";
+        pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
+        addNotifyBody(tdata, "SIP/2.0 200 OK");
+        pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+        die(source);
     }
-
-    void indicated(
-            const SessionPrx& source,
-            const IndicationPtr& event,
-            const AsteriskSCF::SessionCommunications::V1::SessionCookies&,
-            const Ice::Current&)
+    else if ((stopped = StoppedIndicationPtr::dynamicCast(event)))
     {
-        ConnectedIndicationPtr connected;
-        StoppedIndicationPtr stopped;
-        RingingIndicationPtr ringing;
-        ProgressingIndicationPtr progressing;
-        if ((connected = ConnectedIndicationPtr::dynamicCast(event)))
-        {
-            lg(Debug) << "Got the connected indication. Should send a 200 sipfrag NOTIFY";
-            pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
-            addNotifyBody(tdata, "SIP/2.0 200 OK");
-            pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
-            die(source);
-        }
-        else if ((stopped = StoppedIndicationPtr::dynamicCast(event)))
-        {
-            lg(Debug) << "Got the stopped indication. Should send some sort of final response sipfrag NOTIFY";
-            pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
-            //XXX We could stand to add more possible responses here, but for now
-            //just getting things working is my top priority, and we conform to
-            //RFC 3515.
-            switch (stopped->response->isdnCode)
-            {
-                //Busy
-                case 17:
-                    addNotifyBody(tdata, "SIP/2.0 486 Busy Here");
-                //RFC 3515 section 2.4.5 says that we can send a 503 for any reference
-                //that fails.
-                default:
-                    addNotifyBody(tdata, "SIP/2.0 503 Service Unavailable");
-            }
-            pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
-            die(source);
-        }
-        else if ((ringing = RingingIndicationPtr::dynamicCast(event)))
+        lg(Debug) << "Got the stopped indication. Should send some sort of final response sipfrag NOTIFY";
+        pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
+        //XXX We could stand to add more possible responses here, but for now
+        //just getting things working is my top priority, and we conform to
+        //RFC 3515.
+        switch (stopped->response->isdnCode)
         {
-            lg(Debug) << "Got a ringing indication. Should send a 180 sipfrag NOTIFY";
-            pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, true);
-            addNotifyBody(tdata, "SIP/2.0 180 Ringing");
-            pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
-        }
-        else if ((progressing = ProgressingIndicationPtr::dynamicCast(event)))
-        {
-            lg(Debug) << "Got a progressing indication. Should send a 183 sipfrag NOTIFY";
-            pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, true);
-            addNotifyBody(tdata, "SIP/2.0 183 Session Progress");
-            pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+            //Busy
+            case 17:
+                addNotifyBody(tdata, "SIP/2.0 486 Busy Here");
+            //RFC 3515 section 2.4.5 says that we can send a 503 for any reference
+            //that fails.
+            default:
+                addNotifyBody(tdata, "SIP/2.0 503 Service Unavailable");
         }
+        pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
+        die(source);
     }
-
-    void setProxy(const SessionListenerPrx& listener)
+    else if ((ringing = RingingIndicationPtr::dynamicCast(event)))
     {
-        mListenerProxy = listener;
+        lg(Debug) << "Got a ringing indication. Should send a 180 sipfrag NOTIFY";
+        pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, true);
+        addNotifyBody(tdata, "SIP/2.0 180 Ringing");
+        pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
     }
-private:
-
-    void die(const SessionPrx& session)
+    else if ((progressing = ProgressingIndicationPtr::dynamicCast(event)))
     {
-        session->removeListener(mListenerProxy);
-        mAdapter->remove(mListenerProxy->ice_getIdentity());
+        lg(Debug) << "Got a progressing indication. Should send a 183 sipfrag NOTIFY";
+        pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, true);
+        addNotifyBody(tdata, "SIP/2.0 183 Session Progress");
+        pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
     }
+}
 
-    Ice::ObjectAdapterPtr mAdapter;
-    pjsip_dialog *mDialog;
-    pj_int32_t mReferCSeq;
-    SessionListenerPrx mListenerProxy;
-};
+SessionListenerPrx TransferListener::getProxy()
+{
+    return mListenerProxy;
+}
 
-typedef IceUtil::Handle<TransferListener> TransferListenerPtr;
+void TransferListener::die(const SessionPrx& session)
+{
+    session->removeListener(mListenerProxy);
+    mAdapter->remove(mListenerProxy->ice_getIdentity());
+}
 
 class TransferSessionCreationHook : public SessionCreationHook
 {
@@ -204,10 +205,8 @@ private:
             SessionCreationHookDataPtr& replacement)
     {
         TransferListenerPtr transferListener = new TransferListener(mAdapter, mDialog, mReferCSeq);
-        SessionListenerPrx transferListenerPrx = SessionListenerPrx::uncheckedCast(mAdapter->addWithUUID(transferListener));
-        transferListener->setProxy(transferListenerPrx);
         SessionListenerSeq listeners = original->listeners;
-        listeners.push_back(transferListenerPrx);
+        listeners.push_back(transferListener->getProxy());
         AsteriskSCF::SessionCommunications::V1::SessionCookies cookies = original->cookies;
         cookies.push_back(new ReferredByCookie(mReferredBy));
         replacement->session = original->session;
diff --git a/src/SipTransfer.h b/src/SipTransfer.h
index b00195e..aa2c5e3 100644
--- a/src/SipTransfer.h
+++ b/src/SipTransfer.h
@@ -24,6 +24,54 @@ namespace AsteriskSCF
 namespace SipSessionManager
 {
 
+class TransferListener : public AsteriskSCF::SessionCommunications::V1::SessionListener
+{
+public:
+    /**
+     * Regular constructor
+     */
+    TransferListener(
+            const Ice::ObjectAdapterPtr& adapter,
+            pjsip_dialog *dlg,
+            pj_int32_t referCSeq);
+
+    /**
+     * Replica constructor. Provides the Identity to use when adding to the object adapter
+     */
+    TransferListener(
+            const Ice::ObjectAdapterPtr& adapter,
+            pjsip_dialog *dlg,
+            pj_int32_t referCSeq,
+            const Ice::Identity& id);
+
+    /**
+     * Overload of SessionListener's indicated() method.
+     *
+     * Provides the referer with information about how the outbound
+     * call is progressing
+     */
+    void indicated(
+            const AsteriskSCF::SessionCommunications::V1::SessionPrx& source,
+            const AsteriskSCF::SessionCommunications::V1::IndicationPtr& event,
+            const AsteriskSCF::SessionCommunications::V1::SessionCookies&,
+            const Ice::Current&);
+
+    void setProxy(const AsteriskSCF::SessionCommunications::V1::SessionListenerPrx& listener);
+
+    AsteriskSCF::SessionCommunications::V1::SessionListenerPrx getProxy();
+    
+private:
+
+    void die(const AsteriskSCF::SessionCommunications::V1::SessionPrx& session);
+
+    Ice::ObjectAdapterPtr mAdapter;
+    pjsip_dialog *mDialog;
+    pj_int32_t mReferCSeq;
+    AsteriskSCF::SessionCommunications::V1::SessionListenerPrx mListenerProxy;
+};
+
+typedef IceUtil::Handle<TransferListener> TransferListenerPtr;
+
 class HandleReferOperation : public SipQueueableOperation 
 {
 public:

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


-- 
asterisk-scf/integration/sip.git



More information about the asterisk-scf-commits mailing list