[asterisk-scf-commits] asterisk-scf/integration/routing.git branch "transfer" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Tue Oct 12 19:26:04 CDT 2010
branch "transfer" has been updated
via a5e884534bef416a6a556b3efdff62c35b560aea (commit)
from 942efe88a38dbe7c6631ef93e7fb5aa2a7d83443 (commit)
Summary of changes:
src/SessionRouter.cpp | 99 ++++++++++++++++++++++++++++--------------------
src/SessionRouter.h | 12 +++---
test/MockBridge.cpp | 12 +++++-
test/MockBridge.h | 8 ++--
test/SharedTestData.h | 3 +-
test/TestRouting.cpp | 54 +++++++++++++++++++++++++-
6 files changed, 132 insertions(+), 56 deletions(-)
- Log -----------------------------------------------------------------
commit a5e884534bef416a6a556b3efdff62c35b560aea
Author: Ken Hunt <ken.hunt at digium.com>
Date: Tue Oct 12 19:23:41 2010 -0500
Refactoring call transfer changes based on telecon.
replaceSessionWithDestination / replaceSessionWithSession are now
connectBridgedSessionsWithDestination / connectBridgedSessions.
diff --git a/src/SessionRouter.cpp b/src/SessionRouter.cpp
index f7a8f46..7d3aed5 100644
--- a/src/SessionRouter.cpp
+++ b/src/SessionRouter.cpp
@@ -351,14 +351,14 @@ void SessionRouter::routeSession(const AsteriskSCF::SessionCommunications::V1::S
}
/**
-* Execute the routing functionality for the given session. The given session
-* will be bridged with the destination if it is successfully routed.
-* @param source The session initiating the routing event.
-* @param destination The address or id of the destination to be routed.
-*/
-void SessionRouter::replaceSessionWithDestination(const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& sessionToReplace,
- const ::std::string& destination,
- const Ice::Current& current)
+ * Replace one session in a Bridge with a new
+ * session routable by the destination param.
+ * @param source The session initiating the routing event.
+ * @param destination The address or id of the destination to be routed.
+ */
+void SessionRouter::connectBridgedSessionsWithDestination(const SessionPrx& sessionToReplace,
+ const ::std::string& destination,
+ const Ice::Current& current)
{
BridgePrx bridge(0);
try
@@ -438,7 +438,9 @@ void SessionRouter::replaceSessionWithDestination(const ::AsteriskSCF::SessionCo
// Modify the bridge
try
{
- bridge->replaceSession(destSession, sessionToReplace);
+ SessionSeq seq;
+ seq.push_back(destSession);
+ bridge->replaceSession(sessionToReplace, seq);
}
catch (const Ice::Exception &e)
{
@@ -452,27 +454,35 @@ void SessionRouter::replaceSessionWithDestination(const ::AsteriskSCF::SessionCo
mImpl->forwardStart(listener, source);
+ sessionToReplace->stop(new ResponseCode(16)); // Magic number! We need our own value mapping of isdn codes
+
// We're done with the listener.
mImpl->deleteListener(listener);
}
/**
-* Replace a session in a bridge with another session. If the newSession is already participating in a Bridge,
-* it will be removed from it's current bridge prior to be used as a replacement.
-* @param sessionToReplace The session to be replaced in a bridge. The affected Bridge interface is
-* obtained via an accessor on this interface.
-* @param newSession The session to be used as a replacement for the specified session.
-*/
-void SessionRouter::replaceSessionWithSession(const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& sessionToReplace,
- const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& newSession,
- const Ice::Current&)
+ * Replace one session in a Bridge with sessions from another bridge.
+ * No routing is actually performed. This operation exists here for consistency,
+ * since connectBridgedSessionsWithDestination(...) is implemented by this interface.
+ * @param sessionToReplace The session that is to be replaced in a
+ * bridge. The bridge obejct associated with this session will survive, and
+ * all sessions bridged to this session will be kept in the bridge.
+ * @param bridgedSession This session is assumed to be bridged to the sessions
+ * that are to be moved to another bridge. The bridgedSession itself will not
+ * be connected to the other bridge. The sessions being moved will be removed from
+ * their current bridge before being added to the bridge currenltly attached to
+ * sessionToReplace.
+ */
+void SessionRouter::connectBridgedSessions(const SessionPrx& sessionToReplace,
+ const SessionPrx& bridgedSession,
+ const Ice::Current&)
{
- // Get the bridge being modified.
- BridgePrx newBridge(0);
+ // Get the bridge being merged into.
+ BridgePrx mergeBridge(0);
try
{
- newBridge = sessionToReplace->getBridge();
+ mergeBridge = sessionToReplace->getBridge();
}
catch(const NotBridged& e)
{
@@ -480,10 +490,10 @@ void SessionRouter::replaceSessionWithSession(const ::AsteriskSCF::SessionCommun
throw e; // rethrow
}
- SessionSeq seq;
+ SessionSeq preserveSessions;
try
{
- seq = newBridge->listSessions();
+ preserveSessions = mergeBridge->listSessions();
}
catch(const Ice::Exception &e)
{
@@ -494,14 +504,14 @@ void SessionRouter::replaceSessionWithSession(const ::AsteriskSCF::SessionCommun
// Add a listener to the session not being replaced to handle early termination.
SessionListenerImplPtr listener(0);
SessionPrx source(0);
- for(SessionSeq::iterator s = seq.begin(); s !=seq.end(); ++s)
+ for(SessionSeq::iterator s = preserveSessions.begin(); s !=preserveSessions.end(); ++s)
{
if (sessionToReplace->ice_getIdentity() != (*s)->ice_getIdentity())
{
if (listener == 0)
{
source = (*s);
- listener = mImpl->createListener(source); // Only listening to the session NOT being transferred.
+ listener = mImpl->createListener(source); // Only listening to sessions NOT being replaced.
}
else
{
@@ -510,25 +520,40 @@ void SessionRouter::replaceSessionWithSession(const ::AsteriskSCF::SessionCommun
}
}
- // Get the bridge for the session being moved.
+ // Get the bridge for the sessions being moved.
BridgePrx oldBridge(0);
try
{
- oldBridge = newSession->getBridge();
+ oldBridge = bridgedSession->getBridge();
}
catch(const NotBridged&)
{
- lg(Warning) << "Unable to get bridge for the newSession in replaceSessionWithSession(). " ;
+ lg(Warning) << "Unable to get bridge for the bridgedSession in replaceSessionWithSession(). " ;
+ }
+
+ // Check for early termination by the source.
+ if (listener->isTerminated())
+ {
+ mImpl->deleteListener(listener);
+ lg(Notice) << "Source ended session before transfer in replaceSessionWithSession(). " ;
+ throw SourceTerminatedPreBridgingException(source->getEndpoint()->getId());
}
+ SessionSeq migratingSessions;
if (oldBridge != 0)
{
try
{
- // Remove the session being moved from it's old bridge.
- SessionSeq sessions;
- sessions.push_back(newSession);
- oldBridge->removeSessions(sessions);
+ // Remove the sessions being moved from their old bridge.
+ SessionSeq allSessions = oldBridge->listSessions();
+ for(SessionSeq::iterator s = allSessions.begin(); s != allSessions.end(); ++s)
+ {
+ if ((*s) != bridgedSession)
+ {
+ migratingSessions.push_back(*s);
+ }
+ }
+ oldBridge->removeSessions(migratingSessions);
}
catch(const Ice::Exception&)
{
@@ -537,20 +562,12 @@ void SessionRouter::replaceSessionWithSession(const ::AsteriskSCF::SessionCommun
}
}
- // Check for early termination by the source.
- if (listener->isTerminated())
- {
- mImpl->deleteListener(listener);
- lg(Notice) << "Source ended session before transfer in replaceSessionWithSession(). " ;
- throw SourceTerminatedPreBridgingException(source->getEndpoint()->getId());
- }
-
// Now replace the sessions.
// TBD... make order of newSession and sessionToBeReplaced consistent
// between bridge and this operation.
try
{
- newBridge->replaceSession(newSession, sessionToReplace);
+ mergeBridge->replaceSession(sessionToReplace, migratingSessions);
}
catch(const Ice::Exception& e)
{
diff --git a/src/SessionRouter.h b/src/SessionRouter.h
index f82c2a5..99f3c9e 100644
--- a/src/SessionRouter.h
+++ b/src/SessionRouter.h
@@ -51,9 +51,9 @@ public:
* obtained via an accessor on this interface.
* @param destination The address or id of a destination to be used as a replacement for the specified session.
*/
- void replaceSessionWithDestination(const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& sessionToReplace,
- const ::std::string& destination,
- const Ice::Current&);
+ void connectBridgedSessionsWithDestination(const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& sessionToReplace,
+ const ::std::string& destination,
+ const Ice::Current&);
/**
* Replace a session in a bridge with another session. If the newSession is already participating in a Bridge,
@@ -62,9 +62,9 @@ public:
* obtained via an accessor on this interface.
* @param newSession The session to be used as a replacement for the specified session.
*/
- void replaceSessionWithSession(const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& sessionToReplace,
- const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& newSession,
- const Ice::Current&);
+ void connectBridgedSessions(const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& sessionToReplace,
+ const ::AsteriskSCF::SessionCommunications::V1::SessionPrx& bridgedSession,
+ const Ice::Current&);
private:
boost::shared_ptr<SessionRouterPriv> mImpl;
diff --git a/test/MockBridge.cpp b/test/MockBridge.cpp
index 2ef893d..e804aa0 100644
--- a/test/MockBridge.cpp
+++ b/test/MockBridge.cpp
@@ -87,10 +87,20 @@ void MockBridge::addSessions(const SessionSeq& newSessions, const Ice::Current&)
mSessions.insert( mSessions.end(), newSessions.begin(), newSessions.end());
}
+void MockBridge::removeListener(const AsteriskSCF::SessionCommunications::V1::BridgeListenerPrx&, const Ice::Current& )
+{
+}
+
+void MockBridge::replaceSession(const AsteriskSCF::SessionCommunications::V1::SessionPrx& sessionToReplace,
+ const AsteriskSCF::SessionCommunications::V1::SessionSeq& newSessions,
+ const Ice::Current&)
+{
+ SharedTestData::instance.mSessionReplaced = true;
+}
void MockBridge::connected(const AsteriskSCF::SessionCommunications::V1::SessionPrx& session)
{
- SharedTestData::instance.connected = true;
+ SharedTestData::instance.mBridgeConnected = true;
}
} // RoutingTest
diff --git a/test/MockBridge.h b/test/MockBridge.h
index 17aa727..4b98987 100644
--- a/test/MockBridge.h
+++ b/test/MockBridge.h
@@ -36,11 +36,11 @@ public:
void shutdown(const Ice::Current&) {}
void addListener(const AsteriskSCF::SessionCommunications::V1::BridgeListenerPrx&, const Ice::Current& ) {}
- void removeListener(const AsteriskSCF::SessionCommunications::V1::BridgeListenerPrx&, const Ice::Current& ) {}
+ void removeListener(const AsteriskSCF::SessionCommunications::V1::BridgeListenerPrx&, const Ice::Current& );
- void replaceSession(const AsteriskSCF::SessionCommunications::V1::SessionPrx& newSession,
- const AsteriskSCF::SessionCommunications::V1::SessionPrx& oldSession,
- const Ice::Current&) {}
+ void replaceSession(const AsteriskSCF::SessionCommunications::V1::SessionPrx& sessionToReplace,
+ const AsteriskSCF::SessionCommunications::V1::SessionSeq& newSessions,
+ const Ice::Current&);
void connected(const AsteriskSCF::SessionCommunications::V1::SessionPrx& session);
diff --git a/test/SharedTestData.h b/test/SharedTestData.h
index eeecab7..2a22e1c 100644
--- a/test/SharedTestData.h
+++ b/test/SharedTestData.h
@@ -50,7 +50,8 @@ struct SharedTestData
MockBridgeManagerPtr bridgeManager;
- bool connected;
+ bool mBridgeConnected;
+ bool mSessionReplaced;
};
} // RoutingTest
diff --git a/test/TestRouting.cpp b/test/TestRouting.cpp
index cd9fa21..63b072d 100644
--- a/test/TestRouting.cpp
+++ b/test/TestRouting.cpp
@@ -203,11 +203,12 @@ struct GlobalIceFixture
SharedTestData::instance.endpointLocator->addEndpoint("101");
SharedTestData::instance.endpointLocator->addEndpoint("102");
SharedTestData::instance.endpointLocator->addEndpoint("103");
+ SharedTestData::instance.endpointLocator->addEndpoint("104");
// Initialize the regular expressions for the ids that this channel will support.
// Use two strings just for kicks.
SharedTestData::instance.regExIds.push_back("101");
- SharedTestData::instance.regExIds.push_back("10[23]"); // 102 or 103
+ SharedTestData::instance.regExIds.push_back("10[234]"); // 102, 103 or 104
}
~GlobalIceFixture()
@@ -398,12 +399,59 @@ BOOST_FIXTURE_TEST_CASE(RouteSession, PerTestFixture)
SessionPrx session = session101Endpoint->createSession("102", 0, Ice::Current());
BOOST_CHECK(session != 0);
- SharedTestData::instance.connected = false;
+ SharedTestData::instance.mBridgeConnected = false;
BOOST_TEST_MESSAGE("Routing the session...");
SharedTestData::instance.sessionRouter->routeSession(session, "102");
- BOOST_CHECK(SharedTestData::instance.connected);
+ BOOST_CHECK(SharedTestData::instance.mBridgeConnected);
+ }
+ catch(const IceUtil::Exception &ie)
+ {
+ bool IceException(false);
+ string msg = "Exception routing session:";
+ msg += ie.what();
+ BOOST_TEST_MESSAGE(msg);
+ BOOST_CHECK(IceException);
+ }
+ catch (...)
+ {
+ bool unknownException(false);
+ BOOST_TEST_MESSAGE("Exception routing session.");
+ BOOST_CHECK(unknownException);
+ }
+}
+
+/**
+ * This tests if we can support blind transfer.
+ */
+BOOST_FIXTURE_TEST_CASE(BlindTransfer, PerTestFixture)
+{
+ try
+ {
+ BOOST_TEST_MESSAGE("Local lookup of an endpoint...");
+
+ // Get our local 101 endpoint
+ MockSessionEndpointPtr session101Endpoint = SharedTestData::instance.endpointLocator->localLookup("101");
+
+ BOOST_TEST_MESSAGE("Creating a session on our test endpoint...");
+ SessionPrx session = session101Endpoint->createSession("102", 0, Ice::Current());
+ BOOST_CHECK(session != 0);
+
+ SharedTestData::instance.mBridgeConnected = false;
+ SharedTestData::instance.mSessionReplaced = false;
+
+ BOOST_TEST_MESSAGE("Routing the session...");
+ SharedTestData::instance.sessionRouter->routeSession(session, "102");
+
+ BridgePrx bridge = session->getBridge();
+ BOOST_CHECK(SharedTestData::instance.mBridgeConnected);
+
+ // Now transfer to a new extension.
+ // TBD...
+ // SharedTestData::instance.sessionRouter->connectBridgedSessionsWithDestination(session, "103");
+
+ // BOOST_CHECK(SharedTestData::instance.mSessionReplaced);
}
catch(const IceUtil::Exception &ie)
{
-----------------------------------------------------------------------
--
asterisk-scf/integration/routing.git
More information about the asterisk-scf-commits
mailing list