[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
Thu Jul 28 16:46:34 CDT 2011
branch "transfer-improvements" has been updated
via 6dc4fb170b7ce46665a7b5bda8b51a0d16839ede (commit)
via 1f8f20c806b604bb903f24bd1b88e4502d337f6d (commit)
via 0107322adb94249b436546340bd17a760c321540 (commit)
via 000e0a031874c76c9cc0430a9ffe7809dd7acc60 (commit)
via 33626a959dc3d70e4e477a522c9ffffb4270a7b4 (commit)
from 8606dbf96a428332539b91df02e0bd0c342ecf52 (commit)
Summary of changes:
.../SipSessionManager/SipSessionCookiesIf.ice | 50 +++++
src/CMakeLists.txt | 1 +
src/SipSession.cpp | 91 +++++++--
src/SipSession.h | 9 +
src/SipTransfer.cpp | 198 ++++++++++++--------
src/SipTransfer.h | 19 ++-
6 files changed, 261 insertions(+), 107 deletions(-)
create mode 100644 slice/AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.ice
- Log -----------------------------------------------------------------
commit 6dc4fb170b7ce46665a7b5bda8b51a0d16839ede
Author: Mark Michelson <mmichelson at digium.com>
Date: Thu Jul 28 16:46:50 2011 -0500
Do some cleanup.
Next up is state replication. I am not looking forward to it even a little bit.
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 713b7fd..5a0dec0 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -193,9 +193,9 @@ public:
return result;
}
- void setProxyID(const Ice::Identity& id)
+ void setProxy(const SessionCreationHookPrx& proxy)
{
- mProxyID = id;
+ mProxy = proxy;
}
private:
@@ -217,14 +217,14 @@ private:
void die()
{
- mAdapter->remove(mProxyID);
+ mAdapter->remove(mProxy->ice_getIdentity());
}
Ice::ObjectAdapterPtr mAdapter;
pjsip_dialog *mDialog;
pj_int32_t mReferCSeq;
const std::string mReferredBy;
- Ice::Identity mProxyID;
+ SessionCreationHookPrx mProxy;
};
typedef IceUtil::Handle<TransferSessionCreationHook> TransferSessionCreationHookPtr;
@@ -273,47 +273,7 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
}
else
{
- // It is possible for the to and from tag value to be present within the Replaces parameter value, so try to
- // parse it out
- std::string replaces_value_tmp = std::string(pj_strbuf(&mReplacesParam->value),
- pj_strlen(&mReplacesParam->value));
- std::vector<std::string> params;
-
- boost::split(params, replaces_value_tmp, boost::is_any_of(";"));
-
- //The first value will be the actual replaces value.
- std::string replaces = params.front();
-
- std::string to;
- std::string from;
- std::string fromTagParamName("from-tag=");
- std::string toTagParamName("to-tag=");
- for(std::vector<std::string>::iterator iter = params.begin();
- iter != params.end(); ++iter)
- {
- if (iter->compare(0, toTagParamName.size(), toTagParamName) == 0)
- {
- to = iter->substr(toTagParamName.size());
- }
- if (iter->compare(0, fromTagParamName.size(), fromTagParamName) == 0)
- {
- from = iter->substr(fromTagParamName.size());
- }
- }
-
- if (from.empty() || to.empty())
- {
- lg(Debug) << "handleRefer() sending 400 due to From or To missing. ";
- pjsip_dlg_modify_response(mInv->dlg, mTdata, 400, NULL);
- pjsip_dlg_send_response(mInv->dlg, mTsx, mTdata);
- return Complete;
- }
-
- pj_str_t to_tag_str = pj_str((char*)to.c_str());
- pj_str_t from_tag_str = pj_str((char*)from.c_str());
- pj_str_t replaces_tag_str = pj_str((char*)replaces.c_str());
-
- other_dlg = pjsip_ua_find_dialog(&replaces_tag_str, &to_tag_str, &from_tag_str, PJ_TRUE);
+ other_dlg = findDialogFromReplaces();
}
if (!other_dlg)
@@ -369,16 +329,11 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
lg(Debug) << "handleRefer() calling router connectBridgedSessions(). ";
- TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy));
- SessionCreationHookPrx hookPrx = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(hook));
- hook->setProxyID(hookPrx->ice_getIdentity());
- mHookPrxID = hookPrx->ice_getIdentity();
-
mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), d);
pjsip_dlg_dec_lock(other_dlg);
return Complete;
}
- catch (const Ice::CommunicatorDestroyedException &)
+ catch (const Ice::CommunicatorDestroyedException&)
{
lg(Debug) << "handleRefer() sending 503 due to communicator destruction";
pjsip_dlg_modify_response(mInv->dlg, mTdata, 503, NULL);
@@ -392,7 +347,6 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
//Go ahead and send a 202 for the REFER. We can send a NOTIFY later to indicate if something
//on the outbound leg went awry.
pjsip_dlg_send_response(mInv->dlg, mTsx, mTdata);
-
// Now that we have the target user we can pass this into routing and go on our marry way
try
{
@@ -406,18 +360,15 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
lg(Debug) << "Session to replace is with endpoint " << session->getEndpoint()->getName();
lg(Debug) << "Destination is " << mTarget;
mWasWithDestination = true;
-
- TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy));
- SessionCreationHookPrx hookPrx = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(hook));
- hook->setProxyID(hookPrx->ice_getIdentity());
- mHookPrxID = hookPrx->ice_getIdentity();
-
+
+ createTransferSessionCreationHook();
+
//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, hookPrx, d);
+ mSessionRouter->begin_connectBridgedSessionsWithDestination(operationId, session->getSessionProxy(), mTarget, mHookPrx, d);
return Complete;
}
catch (const Ice::CommunicatorDestroyedException &)
@@ -451,7 +402,7 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, false);
addNotifyBody(tdata, "SIP/2.0 404 Not Found");
pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
- mAdapter->remove(mHookPrxID);
+ mAdapter->remove(mHookPrx->ice_getIdentity());
return Complete;
}
catch (const std::exception& e)
@@ -460,12 +411,60 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, false);
addNotifyBody(tdata, "SIP/2.0 400 Bad Request");
pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
- mAdapter->remove(mHookPrxID);
+ mAdapter->remove(mHookPrx->ice_getIdentity());
return Complete;
}
-
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
+ // parse it out
+ std::string replaces_value_tmp = std::string(pj_strbuf(&mReplacesParam->value),
+ pj_strlen(&mReplacesParam->value));
+ std::vector<std::string> params;
+
+ boost::split(params, replaces_value_tmp, boost::is_any_of(";"));
+
+ //The first value will be the actual replaces value.
+ std::string replaces = params.front();
+
+ std::string to;
+ std::string from;
+ std::string fromTagParamName("from-tag=");
+ std::string toTagParamName("to-tag=");
+ for(std::vector<std::string>::iterator iter = params.begin();
+ iter != params.end(); ++iter)
+ {
+ if (iter->compare(0, toTagParamName.size(), toTagParamName) == 0)
+ {
+ to = iter->substr(toTagParamName.size());
+ }
+ if (iter->compare(0, fromTagParamName.size(), fromTagParamName) == 0)
+ {
+ from = iter->substr(fromTagParamName.size());
+ }
+ }
+
+ if (from.empty() || to.empty())
+ {
+ return NULL;
+ }
+
+ pj_str_t to_tag_str = pj_str((char*)to.c_str());
+ pj_str_t from_tag_str = pj_str((char*)from.c_str());
+ pj_str_t replaces_tag_str = pj_str((char*)replaces.c_str());
+
+ return pjsip_ua_find_dialog(&replaces_tag_str, &to_tag_str, &from_tag_str, PJ_TRUE);
+}
+
}; //end namespace SipSessionManager
}; //end namespace AsteriskSCF
diff --git a/src/SipTransfer.h b/src/SipTransfer.h
index bb2ba1d..37ac51f 100644
--- a/src/SipTransfer.h
+++ b/src/SipTransfer.h
@@ -66,6 +66,16 @@ 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.
+ */
+ pjsip_dialog* findDialogFromReplaces();
+ /**
* The INVITE session, which contains the dialog on which the
* REFER was received.
*/
@@ -130,9 +140,11 @@ private:
*/
bool mWasWithDestination;
/**
- * The identity of the session creation hook we create.
+ * The proxy of the session creation hook we create.
+ * We have to hold onto this in case our AMI call to create the outbound
+ * session fails.
*/
- Ice::Identity mHookPrxID;
+ AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookPrx mHookPrx;
};
}; //end namespace SipSessionManager
commit 1f8f20c806b604bb903f24bd1b88e4502d337f6d
Author: Mark Michelson <mmichelson at digium.com>
Date: Thu Jul 28 14:34:15 2011 -0500
Set up session creation hook on attended transfers.
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 9b9059b..713b7fd 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -368,6 +368,12 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
Ice::CallbackPtr d = Ice::newCallback(cb, &SipAMICallback::callback);
lg(Debug) << "handleRefer() calling router connectBridgedSessions(). ";
+
+ TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy));
+ SessionCreationHookPrx hookPrx = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(hook));
+ hook->setProxyID(hookPrx->ice_getIdentity());
+ mHookPrxID = hookPrx->ice_getIdentity();
+
mSessionRouter->begin_connectBridgedSessions(operationId, mSession->getSessionProxy(), other_session->getSessionProxy(), d);
pjsip_dlg_dec_lock(other_dlg);
return Complete;
commit 0107322adb94249b436546340bd17a760c321540
Author: Mark Michelson <mmichelson at digium.com>
Date: Thu Jul 28 13:49:53 2011 -0500
Add some more sipfrag messages.
* 100 Trying immediately
* 486 on busy user
* 503 on other failures of the outbound call
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 324c325..9b9059b 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -113,7 +113,19 @@ public:
{
lg(Debug) << "Got the stopped indication. Should send some sort of final response sipfrag NOTIFY";
pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, false);
- addNotifyBody(tdata, "SIP/2.0 200 OK");
+ //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);
}
@@ -388,10 +400,17 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
lg(Debug) << "Session to replace is with endpoint " << session->getEndpoint()->getName();
lg(Debug) << "Destination is " << mTarget;
mWasWithDestination = true;
+
TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy));
SessionCreationHookPrx hookPrx = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(hook));
hook->setProxyID(hookPrx->ice_getIdentity());
mHookPrxID = hookPrx->ice_getIdentity();
+
+ //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, hookPrx, d);
return Complete;
}
@@ -409,9 +428,6 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
{
SessionRouterPrx router = SessionRouterPrx::uncheckedCast(asyncResult->getProxy());
- // We need to send a NOTIFY to indicate how things went on the other leg.
- // XXX Once we have a subscription module written, we can actually use it.
-
try
{
if (mWasWithDestination)
commit 000e0a031874c76c9cc0430a9ffe7809dd7acc60
Author: Mark Michelson <mmichelson at digium.com>
Date: Thu Jul 28 13:09:39 2011 -0500
Add support for a ReferredBy cookie.
Now when a transfer occurs, and a REFER has a Referred-By header,
we will duplicate this on our outbound INVITE to the transfer target.
diff --git a/slice/AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.ice b/slice/AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.ice
new file mode 100644
index 0000000..e3263e6
--- /dev/null
+++ b/slice/AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.ice
@@ -0,0 +1,50 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.ice>
+
+module AsteriskSCF
+{
+
+module SessionCookies
+{
+
+module SipSessionManager
+{
+
+["suppress"]
+module V1
+{
+
+/**
+ * When creating an outbound session, if this cookie is present,
+ * then this value should be included in a Referred-By header
+ * on the outbound INVITE.
+ */
+unsliceable class ReferredByCookie extends AsteriskSCF::SessionCommunications::V1::SessionCookie
+{
+ /**
+ * The value of the Referred-By header from a REFER
+ */
+ string value;
+};
+
+}; //end module V1
+}; //end module SipSessionManager
+}; //end module SessionCookies
+}; //end module AsteriskSCF
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 81f2bec..71cfbd9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -63,6 +63,7 @@ astscf_component_add_files(SipSessionManager SipRegistrarListener.h)
astscf_component_add_slices(SipSessionManager PROJECT SipIf.ice)
astscf_component_add_slices(SipSessionManager PROJECT AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice)
astscf_component_add_slices(SipSessionManager PROJECT AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice)
+astscf_component_add_slices(SipSessionManager PROJECT AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.ice)
astscf_component_add_ice_libraries(SipSessionManager IceStorm)
astscf_component_add_boost_libraries(SipSessionManager core)
astscf_component_add_slice_collection_libraries(SipSessionManager ASTSCF)
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index d8d0a76..47fad2e 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -30,6 +30,7 @@
#include <AsteriskSCF/logger.h>
#include <AsteriskSCF/System/NAT/NATTraversalIf.h>
#include <AsteriskSCF/Media/SDP/MediaSDPIf.h>
+#include <AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.h>
#include "NATOptions.h"
using namespace AsteriskSCF::System::Logging;
@@ -422,7 +423,8 @@ void SipSession::initializePJSIPStructs()
void SipSession::activateIceObjects(const AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookSeq& hooks)
{
- AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr initial(new AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookData(mImplPriv->mSessionProxy, mImplPriv->mListeners));
+ AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr initial(
+ new AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookData(mImplPriv->mSessionProxy, mImplPriv->mListeners, getCookies()));
AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookDataPtr in = initial;
@@ -448,6 +450,11 @@ void SipSession::activateIceObjects(const AsteriskSCF::SessionCommunications::Ex
mImplPriv->mPublicSessionProxy = out->session;
mImplPriv->mListeners.clear();
mImplPriv->mListeners = out->listeners;
+ // Note this is the setCookies method
+ // typically called from a queued operation.
+ // It's safe to do here since the session is
+ // in the process of being created.
+ setCookies(out->cookies);
in = out;
}
}
@@ -953,12 +960,49 @@ public:
return Complete;
}
+ addReferredBy(packet);
+
// Boom! Houston, we have transmission.
pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
return Complete;
}
private:
+ /**
+ * If this session is being started as the result of
+ * a transfer, there may be a Referred-By header to
+ * include.
+ */
+ void addReferredBy(pjsip_tx_data *packet)
+ {
+ AsteriskSCF::SessionCommunications::V1::SessionCookieDict::const_iterator iter =
+ mImplPriv->mSessionCookies.find(AsteriskSCF::SessionCookies::SipSessionManager::V1::ReferredByCookie::ice_staticId());
+
+ if (iter == mImplPriv->mSessionCookies.end())
+ {
+ lg(Debug) << "No ReferredBy cookie present";
+ return;
+ }
+
+ AsteriskSCF::SessionCookies::SipSessionManager::V1::ReferredByCookiePtr referredBy =
+ AsteriskSCF::SessionCookies::SipSessionManager::V1::ReferredByCookiePtr::dynamicCast(iter->second);
+
+ if (referredBy->value.empty())
+ {
+ lg(Debug) << "Referred-By is empty.";
+ return;
+ }
+
+ pj_str_t referredByHdrStr;
+ pj_cstr(&referredByHdrStr, "Referred-By");
+ pj_str_t referredByValStr;
+ pj_cstr(&referredByValStr, referredBy->value.c_str());
+
+ pjsip_generic_string_hdr *hdr =
+ pjsip_generic_string_hdr_create(packet->pool, &referredByHdrStr, &referredByValStr);
+
+ pjsip_msg_add_hdr(packet->msg, (pjsip_hdr*) hdr);
+ }
SipSessionPtr mSession;
boost::shared_ptr<SipSessionPriv> mImplPriv;
};
@@ -1023,32 +1067,18 @@ class SetCookiesOperation : public SuspendableWork
{
public:
SetCookiesOperation(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies,
- const boost::shared_ptr<SipSessionPriv>& sessionPriv)
- : mCookies(cookies), mImplPriv(sessionPriv) { }
+ const SipSessionPtr& session)
+ : mCookies(cookies), mSession(session) { }
SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
{
- for (AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i = mCookies.begin();
- i != mCookies.end();
- ++i)
- {
- mImplPriv->mSessionCookies.erase((*i)->ice_id());
- mImplPriv->mSessionCookies.insert(make_pair((*i)->ice_id(), (*i)));
- }
-
- if (mImplPriv->mInviteSession)
- {
- PJSipSessionModInfo *session_mod_info = static_cast<PJSipSessionModInfo*>(mImplPriv->mInviteSession->mod_data[mImplPriv->mManager->getSessionModule()->getModule().id]);
- session_mod_info->updateSessionState(mImplPriv->mInviteSession);
- mImplPriv->mManager->getSessionModule()->replicateState(NULL, NULL, session_mod_info);
- }
-
+ mSession->setCookies(mCookies);
return Complete;
}
private:
AsteriskSCF::SessionCommunications::V1::SessionCookies mCookies;
- boost::shared_ptr<SipSessionPriv> mImplPriv;
+ SipSessionPtr mSession;
};
/**
@@ -1058,7 +1088,28 @@ private:
void SipSession::setCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies, const Ice::Current&)
{
lg(Debug) << "queuing a setCookies operation";
- enqueueSessionWork(new SetCookiesOperation(cookies, mImplPriv));
+ enqueueSessionWork(new SetCookiesOperation(cookies, this));
+}
+
+/**
+ * Typically called from queued operations
+ */
+void SipSession::setCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies& cookies)
+{
+ for (AsteriskSCF::SessionCommunications::V1::SessionCookies::const_iterator i = cookies.begin();
+ i != cookies.end();
+ ++i)
+ {
+ mImplPriv->mSessionCookies.erase((*i)->ice_id());
+ mImplPriv->mSessionCookies.insert(make_pair((*i)->ice_id(), (*i)));
+ }
+
+ if (mImplPriv->mInviteSession)
+ {
+ PJSipSessionModInfo *session_mod_info = static_cast<PJSipSessionModInfo*>(mImplPriv->mInviteSession->mod_data[mImplPriv->mManager->getSessionModule()->getModule().id]);
+ session_mod_info->updateSessionState(mImplPriv->mInviteSession);
+ mImplPriv->mManager->getSessionModule()->replicateState(NULL, NULL, session_mod_info);
+ }
}
/**
diff --git a/src/SipSession.h b/src/SipSession.h
index ad50231..2d6c3e9 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -178,6 +178,15 @@ public:
void stop(const AsteriskSCF::SessionCommunications::V1::ResponseCodePtr&, const Ice::Current&);
void unhold(const Ice::Current&);
void setCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies&, const Ice::Current&);
+ /**
+ * Typically called from queued operations to set cookies.
+ * Also used during session creation when modifications hooks have changed
+ * the cookies
+ */
+ void setCookies(const AsteriskSCF::SessionCommunications::V1::SessionCookies&);
+ /**
+ * 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&);
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 002f338..324c325 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -21,6 +21,7 @@
#include <AsteriskSCF/logger.h>
#include <AsteriskSCF/SessionCommunications/SessionCommunicationsExtensionPointsIf.h>
+#include <AsteriskSCF/SessionCookies/SipSessionManager/SipSessionCookiesIf.h>
using namespace AsteriskSCF::System::Logging;
@@ -28,7 +29,7 @@ namespace
{
Logger lg = getLoggerFactory().getLogger("AsteriskSCF.SipSessionManager");
-pjsip_tx_data* createNotify(pjsip_dialog *dlg, pj_int32_t cseq)
+pjsip_tx_data* createNotify(pjsip_dialog *dlg, pj_int32_t cseq, bool active)
{
pjsip_tx_data *tdata;
pjsip_dlg_create_request(dlg, pjsip_get_notify_method(), -1, &tdata);
@@ -41,8 +42,15 @@ pjsip_tx_data* createNotify(pjsip_dialog *dlg, pj_int32_t cseq)
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) event);
pjsip_sub_state_hdr *subState = pjsip_sub_state_hdr_create(tdata->pool);
- pj_strdup2(tdata->pool, &subState->sub_state, "terminated");
- pj_strdup2(tdata->pool, &subState->reason_param, "noresource");
+ if (active)
+ {
+ pj_strdup2(tdata->pool, &subState->sub_state, "active");
+ }
+ else
+ {
+ pj_strdup2(tdata->pool, &subState->sub_state, "terminated");
+ pj_strdup2(tdata->pool, &subState->reason_param, "noresource");
+ }
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) subState);
return tdata;
@@ -73,6 +81,7 @@ using namespace AsteriskSCF::SessionCommunications::V1;
using namespace AsteriskSCF::SessionCommunications::ExtensionPoints::V1;
using namespace AsteriskSCF::System::WorkQueue::V1;
using namespace AsteriskSCF::System::Hook::V1;
+using namespace AsteriskSCF::SessionCookies::SipSessionManager::V1;
class TransferListener : public SessionListener
{
@@ -85,7 +94,7 @@ public:
void indicated(
const SessionPrx& source,
const IndicationPtr& event,
- const SessionCookies&,
+ const AsteriskSCF::SessionCommunications::V1::SessionCookies&,
const Ice::Current&)
{
ConnectedIndicationPtr connected;
@@ -95,7 +104,7 @@ public:
if ((connected = ConnectedIndicationPtr::dynamicCast(event)))
{
lg(Debug) << "Got the connected indication. Should send a 200 sipfrag NOTIFY";
- pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq);
+ 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);
@@ -103,7 +112,7 @@ public:
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);
+ 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);
@@ -111,14 +120,14 @@ public:
else if ((ringing = RingingIndicationPtr::dynamicCast(event)))
{
lg(Debug) << "Got a ringing indication. Should send a 180 sipfrag NOTIFY";
- pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq);
+ 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);
+ pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq, true);
addNotifyBody(tdata, "SIP/2.0 183 Session Progress");
pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
}
@@ -151,8 +160,9 @@ public:
TransferSessionCreationHook(
const Ice::ObjectAdapterPtr& adapter,
pjsip_dialog *dlg,
- pj_int32_t referCSeq)
- : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq)
+ pj_int32_t referCSeq,
+ const std::string& referredBy)
+ : mAdapter(adapter), mDialog(dlg), mReferCSeq(referCSeq), mReferredBy(referredBy)
{
}
@@ -186,7 +196,10 @@ private:
transferListener->setProxy(transferListenerPrx);
SessionListenerSeq listeners = original->listeners;
listeners.push_back(transferListenerPrx);
+ AsteriskSCF::SessionCommunications::V1::SessionCookies cookies = original->cookies;
+ cookies.push_back(new ReferredByCookie(mReferredBy));
replacement->session = original->session;
+ replacement->cookies = cookies;
replacement->listeners = listeners;
}
@@ -198,6 +211,7 @@ private:
Ice::ObjectAdapterPtr mAdapter;
pjsip_dialog *mDialog;
pj_int32_t mReferCSeq;
+ const std::string mReferredBy;
Ice::Identity mProxyID;
};
@@ -374,7 +388,7 @@ SuspendableWorkResult HandleReferOperation::initial(const SuspendableWorkListene
lg(Debug) << "Session to replace is with endpoint " << session->getEndpoint()->getName();
lg(Debug) << "Destination is " << mTarget;
mWasWithDestination = true;
- TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq));
+ TransferSessionCreationHookPtr hook(new TransferSessionCreationHook(mAdapter, mInv->dlg, mReferCSeq, mReferredBy));
SessionCreationHookPrx hookPrx = SessionCreationHookPrx::uncheckedCast(mAdapter->addWithUUID(hook));
hook->setProxyID(hookPrx->ice_getIdentity());
mHookPrxID = hookPrx->ice_getIdentity();
@@ -398,8 +412,6 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
// We need to send a NOTIFY to indicate how things went on the other leg.
// XXX Once we have a subscription module written, we can actually use it.
- pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq);
-
try
{
if (mWasWithDestination)
@@ -414,7 +426,7 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
catch (const AsteriskSCF::Core::Routing::V1::DestinationNotFoundException&)
{
lg(Debug) << "ConnectBridgedSessionsWithDestination sending 404 due to destination not found.";
-
+ pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, false);
addNotifyBody(tdata, "SIP/2.0 404 Not Found");
pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
mAdapter->remove(mHookPrxID);
@@ -423,7 +435,7 @@ SuspendableWorkResult HandleReferOperation::calledBack(const Ice::AsyncResultPtr
catch (const std::exception& e)
{
lg(Debug) << "ConnectBridgedSessionsCallback sending 400 due to exception: " << e.what();
-
+ pjsip_tx_data *tdata = createNotify(mInv->dlg, mReferCSeq, false);
addNotifyBody(tdata, "SIP/2.0 400 Bad Request");
pjsip_dlg_send_request(mInv->dlg, tdata, -1, NULL);
mAdapter->remove(mHookPrxID);
diff --git a/src/SipTransfer.h b/src/SipTransfer.h
index f607429..bb2ba1d 100644
--- a/src/SipTransfer.h
+++ b/src/SipTransfer.h
@@ -96,9 +96,6 @@ private:
pjsip_param *mFromTagParam;
/**
* The content from the Referred-By header, if one existed.
- * XXX We currently have this handy, but we don't actually do
- * anything with it. This is because we don't have a way to place
- * this information in the outgoing INVITE.
*/
const std::string mReferredBy;
/**
commit 33626a959dc3d70e4e477a522c9ffffb4270a7b4
Author: Mark Michelson <mmichelson at digium.com>
Date: Thu Jul 28 10:33:33 2011 -0500
Be sure to remove the session listener once we're done with it.
diff --git a/src/SipTransfer.cpp b/src/SipTransfer.cpp
index 1a6e63b..002f338 100644
--- a/src/SipTransfer.cpp
+++ b/src/SipTransfer.cpp
@@ -83,7 +83,7 @@ public:
}
void indicated(
- const SessionPrx&,
+ const SessionPrx& source,
const IndicationPtr& event,
const SessionCookies&,
const Ice::Current&)
@@ -98,7 +98,7 @@ public:
pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq);
addNotifyBody(tdata, "SIP/2.0 200 OK");
pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
- die();
+ die(source);
}
else if ((stopped = StoppedIndicationPtr::dynamicCast(event)))
{
@@ -106,7 +106,7 @@ public:
pjsip_tx_data *tdata = createNotify(mDialog, mReferCSeq);
addNotifyBody(tdata, "SIP/2.0 200 OK");
pjsip_dlg_send_request(mDialog, tdata, -1, NULL);
- die();
+ die(source);
}
else if ((ringing = RingingIndicationPtr::dynamicCast(event)))
{
@@ -124,21 +124,22 @@ public:
}
}
- void setProxyID(const Ice::Identity& id)
+ void setProxy(const SessionListenerPrx& listener)
{
- mProxyID = id;
+ mListenerProxy = listener;
}
private:
- void die()
+ void die(const SessionPrx& session)
{
- mAdapter->remove(mProxyID);
+ session->removeListener(mListenerProxy);
+ mAdapter->remove(mListenerProxy->ice_getIdentity());
}
Ice::ObjectAdapterPtr mAdapter;
pjsip_dialog *mDialog;
pj_int32_t mReferCSeq;
- Ice::Identity mProxyID;
+ SessionListenerPrx mListenerProxy;
};
typedef IceUtil::Handle<TransferListener> TransferListenerPtr;
@@ -182,7 +183,7 @@ private:
{
TransferListenerPtr transferListener = new TransferListener(mAdapter, mDialog, mReferCSeq);
SessionListenerPrx transferListenerPrx = SessionListenerPrx::uncheckedCast(mAdapter->addWithUUID(transferListener));
- transferListener->setProxyID(transferListenerPrx->ice_getIdentity());
+ transferListener->setProxy(transferListenerPrx);
SessionListenerSeq listeners = original->listeners;
listeners.push_back(transferListenerPrx);
replacement->session = original->session;
-----------------------------------------------------------------------
--
asterisk-scf/integration/sip.git
More information about the asterisk-scf-commits
mailing list