[asterisk-scf-commits] asterisk-scf/release/sip.git branch "master" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Mon Oct 3 17:07:58 CDT 2011
branch "master" has been updated
via bf97df459f0c054d095331534252ec3755abc1e2 (commit)
from 74d1103527d97fa8cd5887ab510a748b20ceb8ff (commit)
Summary of changes:
config/Sip.config | 5 +
config/SipConfigurator.py | 3 +
.../SipSessionManager/SipConfigurationIf.ice | 11 +
.../SipSessionManager/SipStateReplicationIf.ice | 4 +-
src/PJSipSessionModule.cpp | 4 +-
src/SipConfiguration.cpp | 10 +
src/SipEndpoint.cpp | 8 +-
src/SipEndpoint.h | 7 +-
src/SipSession.cpp | 342 ++++++++++++++++++--
src/SipSession.h | 12 +-
10 files changed, 376 insertions(+), 30 deletions(-)
- Log -----------------------------------------------------------------
commit bf97df459f0c054d095331534252ec3755abc1e2
Author: Joshua Colp <jcolp at digium.com>
Date: Mon Oct 3 19:07:36 2011 -0300
Merge direct media connection support.
diff --git a/config/Sip.config b/config/Sip.config
index 5646d97..7946dba 100644
--- a/config/Sip.config
+++ b/config/Sip.config
@@ -92,6 +92,10 @@ rtpoveripv6=no
# Allowable media formats for the endpoint. Each format is separated using , and follows the format
# <name>/<sample rate>@<frame size>;<format specific parameters>
formats=ulaw/8000,alaw/8000
+
+# Whether media should be allowed to flow directly between endpoints or not
+directmedia=no
+
#
# Simple fields for a single identity record
name='robert foo bar'
@@ -143,3 +147,4 @@ ids=bob-bar-office,bob-bar-cell
#
# baseport=[pick a number]
+
diff --git a/config/SipConfigurator.py b/config/SipConfigurator.py
index bd9a383..5505f2a 100755
--- a/config/SipConfigurator.py
+++ b/config/SipConfigurator.py
@@ -203,6 +203,9 @@ class SipSectionVisitors(Configurator.SectionVisitors):
item = AsteriskSCF.Configuration.SipSessionManager.V1.SipRTPMediaServiceItem()
mapper.map('rtpoveripv6', item, 'requireIPv6', 'mediaservice', config.getboolean, None)
+ item = AsteriskSCF.Configuration.SipSessionManager.V1.DirectMediaItem()
+ mapper.map('directmedia', item, 'enabled', 'directmedia', config.getboolean, None)
+
item = AsteriskSCF.Configuration.SipSessionManager.V1.SipCryptoCertificateItem()
mapper.map('certificateauthorityfile', item, 'certificateAuthority', 'cryptocert', config.get, None)
mapper.map('certificatefile', item, 'certificate', 'cryptocert', config.get, None)
diff --git a/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice b/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
index 119a010..c22c91b 100644
--- a/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
+++ b/slice/AsteriskSCF/Configuration/SipSessionManager/SipConfigurationIf.ice
@@ -254,6 +254,17 @@ class SRTPCryptoKey
sequence<SRTPCryptoKey> SRTPCryptoKeySeq;
/**
+ * Direct media configuration item
+ */
+class DirectMediaItem extends SipConfigurationItem
+{
+ /**
+ * Whether direct media support is enabled or not
+ */
+ bool enabled = false;
+};
+
+/**
* SRTP crypto configuration.
*/
class SRTPCryptoItem extends SipConfigurationItem
diff --git a/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice b/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
index 09e4af4..f982668 100644
--- a/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
+++ b/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
@@ -139,7 +139,7 @@ module V1
bool isClient;
};
- sequence<AsteriskSCF::Media::RTP::V1::RTPSession*> RTPMediaSessionSeq;
+ dictionary<string, AsteriskSCF::Media::RTP::V1::RTPSession*> RTPMediaSessionDict;
class SipSessionStateItem extends SipStateItem
{
@@ -152,7 +152,7 @@ module V1
AsteriskSCF::Media::V1::StreamSourceSeq sources;
AsteriskSCF::Media::V1::StreamSinkSeq sinks;
AsteriskSCF::Media::V1::StreamInformationDict streams;
- RTPMediaSessionSeq rtpMediaSessions;
+ RTPMediaSessionDict rtpMediaSessions;
AsteriskSCF::SessionCommunications::V1::SessionListenerSeq listeners;
AsteriskSCF::SessionCommunications::V1::Bridge *bridge;
AsteriskSCF::SessionCommunications::V1::SessionCookieDict cookies;
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 4a08875..3b97fd4 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -256,11 +256,11 @@ void PJSipSessionModule::replicateState(PJSipDialogModInfo *dlgInfo, PJSipTransa
lg(Debug) << "Session object identity: " << sessionInfo->mSessionState->sessionObjectId.name;
lg(Debug) << "Media session object identity: " << sessionInfo->mSessionState->mediaSessionObjectId.name;
- for (RTPMediaSessionSeq::const_iterator mediaSession = sessionInfo->mSessionState->rtpMediaSessions.begin();
+ for (RTPMediaSessionDict::const_iterator mediaSession = sessionInfo->mSessionState->rtpMediaSessions.begin();
mediaSession != sessionInfo->mSessionState->rtpMediaSessions.end();
++mediaSession)
{
- lg(Debug) << "Media session: " << (*mediaSession);
+ lg(Debug) << "Media session: " << mediaSession->second;
}
lg(Debug) << "Bridge: " << sessionInfo->mSessionState->bridge;
diff --git a/src/SipConfiguration.cpp b/src/SipConfiguration.cpp
index 5c2bca9..f4c07ef 100644
--- a/src/SipConfiguration.cpp
+++ b/src/SipConfiguration.cpp
@@ -300,6 +300,11 @@ class EndpointConfigHelper : public boost::enable_shared_from_this<EndpointConfi
mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateTarget, mConfig, target));
};
+ void visitDirectMediaItem(const DirectMediaItemPtr& direct)
+ {
+ mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateDirectMedia, mConfig, direct));
+ };
+
void visitSipRTPMediaServiceItem(const SipRTPMediaServiceItemPtr& service)
{
mUpdates.push_back(boost::bind(&EndpointConfigHelper::updateMediaService, mConfig, service));
@@ -445,6 +450,11 @@ public:
mEndpoint->setTargetAddress(target->host, target->port);
}
+ void updateDirectMedia(const DirectMediaItemPtr& direct)
+ {
+ mEndpoint->setDirectMedia(direct->enabled);
+ }
+
void updateMediaService(const SipRTPMediaServiceItemPtr& service)
{
mEndpoint->setRTPOverIPv6(service->requireIPv6);
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index 2c5bf9d..d017a06 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -337,6 +337,12 @@ void SipEndpoint::setRTPOverIPv6(bool enabled)
mImplPriv->mConfig.sessionConfig.rtpOverIPv6 = enabled;
}
+
+void SipEndpoint::setDirectMedia(bool enabled)
+{
+ mImplPriv->mConfig.sessionConfig.directMedia = enabled;
+}
+
void SipEndpoint::setMediaNATOptions(bool useICE, bool useTURN)
{
mImplPriv->mConfig.sessionConfig.rtpOverICE = useICE;
@@ -486,7 +492,7 @@ SipSessionPtr SipEndpoint::createSession
const Ice::Identity& sessionid,
const Ice::Identity& controllerid,
const Ice::Identity& mediaid,
- const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
+ const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionDict& mediasessions,
const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
const AsteriskSCF::Media::V1::StreamSinkSeq& sinks)
{
diff --git a/src/SipEndpoint.h b/src/SipEndpoint.h
index efc3a8c..0a07081 100644
--- a/src/SipEndpoint.h
+++ b/src/SipEndpoint.h
@@ -159,6 +159,8 @@ public:
// Whether we are using IPv6 for media transport
// or not.
bool rtpOverIPv6;
+ // Whether we are allowing direct media or not
+ bool directMedia;
// The method by which we will transmit
// DTMF to an endpoint
AsteriskSCF::Configuration::SipSessionManager::V1::SipDTMFOption dtmf;
@@ -318,7 +320,7 @@ public:
//
AsteriskSCF::SipSessionManager::SipSessionPtr createSession(const std::string&);
AsteriskSCF::SipSessionManager::SipSessionPtr createSession(const std::string&, const Ice::Identity&, const Ice::Identity&,
- const Ice::Identity&, const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq&,
+ const Ice::Identity&, const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionDict&,
const AsteriskSCF::Media::V1::StreamSourceSeq&, const AsteriskSCF::Media::V1::StreamSinkSeq&);
void removeSession(const AsteriskSCF::SessionCommunications::V1::SessionPtr&);
@@ -333,6 +335,7 @@ public:
void setCallDirection(enum Direction);
void setSecureTransport(enum Direction);
void setRTPOverIPv6(bool);
+ void setDirectMedia(bool);
void addFormat(const std::string& name, int sampleRate, int frameSize, const Ice::StringSeq& formatSpecific);
/**
@@ -349,9 +352,11 @@ public:
/**
* API call which returns the stream topology to be used for an SDP offer.
*/
+
void setMediaNATOptions(bool useICE, bool useTURN);
void setSRTPOptions(const SipEndpointMediaSRTPConfig& srtpConfig);
void setSignalingNATOptions(bool enable);
+
AsteriskSCF::Media::V1::StreamInformationDict getStreamTopology();
void setDTMFMethod(AsteriskSCF::Configuration::SipSessionManager::V1::SipDTMFOption dtmf);
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 106524a..dce14ab 100755
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -31,6 +31,8 @@
#include <AsteriskSCF/SessionCommunications/SessionCommunicationsIf.h>
#include <AsteriskSCF/SessionCommunications/SessionCookieIf.h>
#include <AsteriskSCF/System/ExceptionsIf.h>
+#include <AsteriskSCF/Helpers/Network.h>
+
#include <AsteriskSCF/System/WorkQueue/WorkQueueIf.h>
#include <AsteriskSCF/logger.h>
#include <AsteriskSCF/System/NAT/NATTraversalIf.h>
@@ -51,6 +53,7 @@ using namespace AsteriskSCF::Media::V1;
using namespace AsteriskSCF::Media;
using namespace AsteriskSCF::Media::SDP::V1;
using namespace AsteriskSCF::System::V1;
+using namespace AsteriskSCF::Helpers;
using namespace std;
namespace
@@ -276,9 +279,9 @@ public:
pjsip_inv_session *mInviteSession;
/**
- * A vector of RTP media sessions belonging to this endpoint.
+ * A dictionary of RTP media sessions belonging to this endpoint.
*/
- RTPMediaSessionSeq mRTPSessions;
+ RTPMediaSessionDict mRTPSessions;
/**
* A vector of media sources associated with this endpoint.
@@ -415,11 +418,11 @@ public:
AsteriskSCF::Media::V1::SessionCookies results;
// Gather the cookies from all of the Session's RTP Media Sessions.
- RTPMediaSessionSeq mediaSessions = mSession->getRTPMediaSessions();
- for(RTPMediaSessionSeq::iterator i = mediaSessions.begin();
+ RTPMediaSessionDict mediaSessions = mSession->getRTPMediaSessions();
+ for(RTPMediaSessionDict::iterator i = mediaSessions.begin();
i != mediaSessions.end(); ++i)
{
- AsteriskSCF::Media::V1::SessionCookies cookies = (*i)->getCookies(mCookieTypes);
+ AsteriskSCF::Media::V1::SessionCookies cookies = i->second->getCookies(mCookieTypes);
results.insert(results.end(), cookies.begin(), cookies.end());
}
@@ -459,11 +462,11 @@ public:
AsteriskSCF::Media::V1::SessionCookies results;
// Set the cookies on all of the Session's RTP Media Sessions.
- RTPMediaSessionSeq mediaSessions = mSession->getRTPMediaSessions();
- for(RTPMediaSessionSeq::iterator i = mediaSessions.begin();
+ RTPMediaSessionDict mediaSessions = mSession->getRTPMediaSessions();
+ for(RTPMediaSessionDict::iterator i = mediaSessions.begin();
i != mediaSessions.end(); ++i)
{
- (*i)->setCookies(mCookies);
+ i->second->setCookies(mCookies);
}
return Complete;
@@ -499,11 +502,11 @@ public:
AsteriskSCF::Media::V1::SessionCookies results;
// Set the cookies on all of the Session's RTP Media Sessions.
- RTPMediaSessionSeq mediaSessions = mSession->getRTPMediaSessions();
- for(RTPMediaSessionSeq::iterator i = mediaSessions.begin();
+ RTPMediaSessionDict mediaSessions = mSession->getRTPMediaSessions();
+ for(RTPMediaSessionDict::iterator i = mediaSessions.begin();
i != mediaSessions.end(); ++i)
{
- (*i)->removeCookies(mCookieTypes);
+ i->second->removeCookies(mCookieTypes);
}
return Complete;
@@ -895,6 +898,7 @@ private:
SipSessionPtr mSession;
};
+
/**
* Sets the party id cookies to indicate that this session's SessionOwnerId is the Caller.
*/
@@ -921,6 +925,133 @@ void SipSession::setSelfAsCaller()
mImplPriv->mSessionCookies[dialed->ice_id()] = dialed;
}
+class CheckDirectConnectionsOperation : public SuspendableWork
+{
+public:
+ CheckDirectConnectionsOperation(
+ const AsteriskSCF::Media::V1::AMD_DirectMediaConnection_checkDirectConnectionsPtr& cb,
+ const AsteriskSCF::Media::V1::DirectMediaConnectionDict& connections,
+ const SipSessionPtr& session)
+ : mCb(cb), mConnections(connections), mSession(session) { }
+
+ SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ lg(Debug) << "Executing a checkDirectConnections Operation";
+
+ mCb->ice_response(mSession->checkDirectConnections(mConnections));
+
+ return Complete;
+ }
+
+private:
+ AsteriskSCF::Media::V1::AMD_DirectMediaConnection_checkDirectConnectionsPtr mCb;
+ AsteriskSCF::Media::V1::DirectMediaConnectionDict mConnections;
+ SipSessionPtr mSession;
+};
+
+class ConnectStreamsOperation : public SuspendableWork
+{
+public:
+ ConnectStreamsOperation(
+ const AsteriskSCF::Media::V1::AMD_DirectMediaConnection_connectStreamsPtr& cb,
+ const AsteriskSCF::Media::V1::DirectMediaConnectionDict& connections,
+ const SipSessionPtr& session)
+ : mCb(cb), mConnections(connections), mSession(session) { }
+
+ SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ if (mSession->getInviteSession()->invite_tsx)
+ {
+ mSession->enqueueSessionWork(this);
+ return Complete;
+ }
+
+ pjmedia_sdp_session *sdp = mSession->modifySDPforDirectConnections(mConnections);
+ pjsip_tx_data *packet = NULL;
+
+ if ((pjsip_inv_reinvite(mSession->getInviteSession(), NULL, sdp, &packet)) == PJ_SUCCESS)
+ {
+ pjsip_inv_send_msg(mSession->getInviteSession(), packet);
+ }
+
+ mCb->ice_response();
+
+ return Complete;
+ }
+
+private:
+ AsteriskSCF::Media::V1::AMD_DirectMediaConnection_connectStreamsPtr mCb;
+ AsteriskSCF::Media::V1::DirectMediaConnectionDict mConnections;
+ const SipSessionPtr mSession;
+};
+
+class DisconnectStreamsOperation : public SuspendableWork
+{
+public:
+ DisconnectStreamsOperation(
+ const AsteriskSCF::Media::V1::AMD_DirectMediaConnection_disconnectStreamsPtr& cb,
+ const Ice::StringSeq& streams,
+ const SipSessionPtr& session)
+ : mCb(cb), mStreams(streams), mSession(session) { }
+
+ SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ pjmedia_sdp_session *sdp = mSession->modifySDP(mStreams);
+ pjsip_tx_data *packet = NULL;
+
+ if ((pjsip_inv_reinvite(mSession->getInviteSession(), NULL, sdp, &packet)) == PJ_SUCCESS)
+ {
+ pjsip_inv_send_msg(mSession->getInviteSession(), packet);
+ }
+
+ mCb->ice_response();
+
+ return Complete;
+ }
+
+private:
+ AsteriskSCF::Media::V1::AMD_DirectMediaConnection_disconnectStreamsPtr mCb;
+ Ice::StringSeq mStreams;
+ const SipSessionPtr mSession;
+};
+
+/**
+ * Implementation of a DirectMediaConnection interface for the SipSession.
+ */
+class SipDirectMediaConnection : public AsteriskSCF::Media::V1::DirectMediaConnection
+{
+public:
+ SipDirectMediaConnection(const SipSessionPtr& session) :
+ mSession(session) { }
+
+ void checkDirectConnections_async(const AsteriskSCF::Media::V1::AMD_DirectMediaConnection_checkDirectConnectionsPtr& cb,
+ const AsteriskSCF::Media::V1::DirectMediaConnectionDict& connections, const Ice::Current&)
+ {
+ lg(Debug) << "Queueing checkDirectConnections operation";
+ mSession->enqueueSessionWork(new CheckDirectConnectionsOperation(cb, connections, mSession));
+ }
+
+ void connectStreams_async(const AsteriskSCF::Media::V1::AMD_DirectMediaConnection_connectStreamsPtr& cb,
+ const AsteriskSCF::Media::V1::DirectMediaConnectionDict& connections, const Ice::Current&)
+ {
+ lg(Debug) << "Queueing connectStreams operation";
+ mSession->enqueueSessionWork(new ConnectStreamsOperation(cb, connections, mSession));
+ }
+
+ void disconnectStreams_async(const AsteriskSCF::Media::V1::AMD_DirectMediaConnection_disconnectStreamsPtr& cb,
+ const Ice::StringSeq& streams, const Ice::Current&)
+ {
+ lg(Debug) << "Queueing disconnectStreams operation";
+ mSession->enqueueSessionWork(new DisconnectStreamsOperation(cb, streams, mSession));
+ }
+
+private:
+ /**
+ * A pointer to the communications session that created us.
+ */
+ SipSessionPtr mSession;
+};
+
void SipSession::initializePJSIPStructs()
{
SipEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
@@ -1150,7 +1281,7 @@ SipSessionPtr SipSession::create(const Ice::ObjectAdapterPtr& adapter,
const Ice::Identity& sessionid,
const Ice::Identity& controllerid,
const Ice::Identity& mediaid,
- const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
+ const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionDict& mediasessions,
const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
const AsteriskSCF::Media::V1::StreamSinkSeq& sinks,
const PJSipManagerPtr& manager,
@@ -1224,6 +1355,9 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter,
mImplPriv->mOurSessionControllerProxy =
AsteriskSCF::SessionCommunications::V1::SessionControllerPrx::uncheckedCast(adapter->addWithUUID(mImplPriv->mOurSessionController));
+ DirectMediaConnectionPtr directMedia = new SipDirectMediaConnection(this);
+ adapter->addFacet(directMedia, mImplPriv->mSessionProxy->ice_getIdentity(), directMediaConnectionFacet);
+
if (isUAC)
{
lg(Debug) << "New session is UAC, so we're creating the necessary PJSIP structures";
@@ -1238,10 +1372,10 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter,
SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter,
const SipEndpointPtr& endpoint,
const std::string& destination,
- const Ice::Identity& /* sessionid */,
+ const Ice::Identity& sessionid,
const Ice::Identity& controllerid,
const Ice::Identity& mediaid,
- const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
+ const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionDict& mediasessions,
const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
const AsteriskSCF::Media::V1::StreamSinkSeq& sinks,
const PJSipManagerPtr& manager,
@@ -1263,6 +1397,9 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter,
mImplPriv->mOurSessionControllerProxy =
AsteriskSCF::SessionCommunications::V1::SessionControllerPrx::uncheckedCast(adapter->add(mImplPriv->mOurSessionController, controllerid));
+ DirectMediaConnectionPtr directMedia = new SipDirectMediaConnection(this);
+ adapter->addFacet(directMedia, sessionid, directMediaConnectionFacet);
+
mImplPriv->mRTPSessions = mediasessions;
mImplPriv->mSources = sources;
mImplPriv->mSinks = sinks;
@@ -2285,12 +2422,12 @@ public:
{
//XXX This loop may be a candidate for making AMI-ified and returning "Suspended"
// Release all the RTP sessions we are using
- for (RTPMediaSessionSeq::const_iterator i = mSessionPriv->mRTPSessions.begin();
- i != mSessionPriv->mRTPSessions.end(); ++i)
+ for (RTPMediaSessionDict::const_iterator i = mSessionPriv->mRTPSessions.begin();
+ i != mSessionPriv->mRTPSessions.end(); ++i)
{
try
{
- (*i)->release();
+ i->second->release();
}
catch (const Ice::Exception& ex)
{
@@ -2624,7 +2761,7 @@ pjmedia_sdp_session *SipSession::createSDPOffer(const AsteriskSCF::Media::V1::St
stream->second->sources.push_back(source);
// Update the SIP session with some RTP session details
- mImplPriv->mRTPSessions.push_back(session);
+ mImplPriv->mRTPSessions.insert(make_pair(boost::lexical_cast<std::string>(mImplPriv->mSDP->media_count), session));
// Add the stream to the SDP
pjmedia_sdp_media *media = allocate_from_pool<pjmedia_sdp_media>(mImplPriv->mDialog->pool);
@@ -2949,7 +3086,7 @@ pjmedia_sdp_session *SipSession::createSDPAnswer(const pjmedia_sdp_session* offe
ourStream->sources.push_back(source);
// Update the SIP session with some RTP session details
- mImplPriv->mRTPSessions.push_back(session);
+ mImplPriv->mRTPSessions.insert(make_pair(boost::lexical_cast<std::string>(stream), session));
// Just by common sense alone since we just got an RTP session for this stream we obviously
// have not added it to the answer SDP either, so do it
@@ -3083,7 +3220,7 @@ pjmedia_sdp_session *SipSession::createSDPAnswer(const pjmedia_sdp_session* offe
}
/**
- * Internal function which modifies our SDP.
+ * Internal function which modifies our SDP to contain remote destination and format details.
*/
pjmedia_sdp_session *SipSession::modifySDP(const AsteriskSCF::Media::V1::StreamInformationDict& toRemove)
{
@@ -3130,6 +3267,98 @@ pjmedia_sdp_session *SipSession::modifySDP(const AsteriskSCF::Media::V1::StreamI
}
/**
+ * Internal function which modifies our SDP to contain remote destination and format details.
+ */
+pjmedia_sdp_session *SipSession::modifySDPforDirectConnections(const AsteriskSCF::Media::V1::DirectMediaConnectionDict& connections)
+{
+ // In order to modify SDP you have to have SDP
+ if (!mImplPriv->mSDP)
+ {
+ return 0;
+ }
+
+ // Iterate through each connection request
+ for (AsteriskSCF::Media::V1::DirectMediaConnectionDict::const_iterator connection = connections.begin();
+ connection != connections.end();
+ ++connection)
+ {
+ unsigned int streamNum = boost::lexical_cast<unsigned int>(connection->first);
+
+ if (streamNum >= mImplPriv->mSDP->media_count)
+ {
+ continue;
+ }
+
+ pjmedia_sdp_media *media = mImplPriv->mSDP->media[streamNum];
+
+ // Skip unknown streams
+ if (!media)
+ {
+ continue;
+ }
+
+ StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(connection->second);
+
+ // Update connection details on the stream
+ pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr, sink->getRemoteAddress().c_str());
+ media->desc.port = (pj_uint16_t) sink->getRemotePort();
+
+ // Drop all existing formats and attributes by changing the counts to zero, this is fine since the SDP generator
+ // uses the count to determine how far to go
+ media->desc.fmt_count = 0;
+ media->attr_count = 0;
+
+ // Add formats present on the sink, this is fine to do because an SDP descriptor will only be found for ones
+ // which are naturally configured on this endpoint
+ PayloadMap payloads;
+ addFormatstoSDP(sink->getFormats(), media, payloads);
+ }
+
+ return mImplPriv->mSDP;
+}
+
+/**
+ * Internal function which modifies our SDP to contain our local destination details and formats.
+ */
+pjmedia_sdp_session *SipSession::modifySDP(const Ice::StringSeq& streams)
+{
+ // In order to modify SDP you have to have SDP
+ if (!mImplPriv->mSDP)
+ {
+ return 0;
+ }
+
+ // Iterate through each stream
+ for (Ice::StringSeq::const_iterator stream = streams.begin();
+ stream != streams.end();
+ ++stream)
+ {
+ StreamInformationDict::const_iterator ourStream = mImplPriv->mStreams.find((*stream));
+
+ // Ignore streams that we don't know about
+ if (ourStream == mImplPriv->mStreams.end())
+ {
+ continue;
+ }
+
+ // These *will* exist and be true due to implementation
+ pjmedia_sdp_media *media = mImplPriv->mSDP->media[boost::lexical_cast<int>((*stream))];
+ StreamSourceRTPPrx source = StreamSourceRTPPrx::uncheckedCast(ourStream->second->sources.front());
+
+ pj_strdup2(mImplPriv->mDialog->pool, &media->conn->addr, source->getLocalAddress().c_str());
+ media->desc.port = (pj_uint16_t) source->getLocalPort();
+
+ media->desc.fmt_count = 0;
+ media->attr_count = 0;
+
+ PayloadMap payloads;
+ addFormatstoSDP(ourStream->second->formats, media, payloads);
+ }
+
+ return mImplPriv->mSDP;
+}
+
+/**
* Internal function which sets the PJsip dialog.
*/
void SipSession::setDialog(pjsip_dialog *dialog)
@@ -3336,7 +3565,7 @@ void SipSession::setListeners(const AsteriskSCF::SessionCommunications::V1::Sess
/**
* Internal function which returns the RTP media sessions that are hidden inside the SIP session.
*/
-RTPMediaSessionSeq SipSession::getRTPMediaSessions()
+RTPMediaSessionDict SipSession::getRTPMediaSessions()
{
return mImplPriv->mRTPSessions;
}
@@ -3349,6 +3578,77 @@ void SipSession::setStreams(const AsteriskSCF::Media::V1::StreamInformationDict&
mImplPriv->mStreams = streams;
}
+/**
+ * Internal function which retrieves possible direct connections.
+ */
+Ice::StringSeq SipSession::checkDirectConnections(const AsteriskSCF::Media::V1::DirectMediaConnectionDict& connections)
+{
+ SipEndpointConfig &config = mImplPriv->mEndpoint->getConfig();
+
+ // If direct media connections are disabled or if NAT is enabled don't even bother checking
+ if (config.sessionConfig.directMedia == false || config.transportConfig.enableNAT == true)
+ {
+ return Ice::StringSeq();
+ }
+
+ Ice::StringSeq allowedStreams;
+
+ // Iterate through each requested connection checking if it is possible
+ for (AsteriskSCF::Media::V1::DirectMediaConnectionDict::const_iterator connection = connections.begin();
+ connection != connections.end();
+ ++connection)
+ {
+ // Do we have a local stream that matches this?
+ StreamInformationDict::const_iterator stream = mImplPriv->mStreams.find(connection->first);
+
+ // Uh, if they passed in a stream that we know nothing about skip it...
+ if (stream == mImplPriv->mStreams.end())
+ {
+ continue;
+ }
+
+ RTPMediaSessionDict::const_iterator session = mImplPriv->mRTPSessions.find(connection->first);
+
+ // We only support connecting streams directly that use RTP
+ if (session == mImplPriv->mRTPSessions.end())
+ {
+ continue;
+ }
+
+ // If the session is using SRTP we can not directly connect
+ SRTPSessionPrx srtp = SRTPSessionPrx::checkedCast(session->second);
+
+ if (srtp)
+ {
+ continue;
+ }
+
+ StreamSinkRTPPrx sink = StreamSinkRTPPrx::checkedCast(connection->second);
+
+ // If the provided sink is not an RTP one this connection is not possible
+ if (!sink)
+ {
+ continue;
+ }
+
+ AddressPtr theirAddress(new Address(sink->getRemoteAddress(), 0));
+
+ StreamSourceRTPPrx source = StreamSourceRTPPrx::uncheckedCast(stream->second->sources.front());
+ AddressPtr ourAddress(new Address(source->getLocalAddress(), 0));
+
+ // Ensure both are IPv4 or IPv6
+ if (theirAddress->isIPV6() != ourAddress->isIPV6())
+ {
+ continue;
+ }
+
+ // It passed! We can establish a direct external media connection
+ allowedStreams.push_back(connection->first);
+ }
+
+ return allowedStreams;
+}
+
bool SipSession::operator==(const SipSession &other) const {
return (this->mImplPriv->mInviteSession == other.mImplPriv->mInviteSession);
}
diff --git a/src/SipSession.h b/src/SipSession.h
index 895e56e..bb36ff5 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -140,7 +140,7 @@ public:
const Ice::Identity& sessionid,
const Ice::Identity& controllerid,
const Ice::Identity& mediaid,
- const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
+ const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionDict& mediasessions,
const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
const AsteriskSCF::Media::V1::StreamSinkSeq& sinks,
const PJSipManagerPtr& manager,
@@ -284,6 +284,10 @@ public:
pjmedia_sdp_session *modifySDP(const AsteriskSCF::Media::V1::StreamInformationDict&);
+ pjmedia_sdp_session *modifySDPforDirectConnections(const AsteriskSCF::Media::V1::DirectMediaConnectionDict&);
+
+ pjmedia_sdp_session *modifySDP(const Ice::StringSeq&);
+
void setDialog(pjsip_dialog *dialog);
pjsip_dialog *getDialog();
@@ -292,6 +296,8 @@ public:
pjsip_inv_session *getInviteSession();
+ Ice::StringSeq checkDirectConnections(const AsteriskSCF::Media::V1::DirectMediaConnectionDict&);
+
//
// TODO: Are these thread safe?
//
@@ -323,7 +329,7 @@ public:
void setStreams(const AsteriskSCF::Media::V1::StreamInformationDict& streams);
- AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq getRTPMediaSessions();
+ AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionDict getRTPMediaSessions();
void enqueueSessionWork(const AsteriskSCF::System::WorkQueue::V1::SuspendableWorkPtr&);
@@ -349,7 +355,7 @@ private:
bool ipv6, bool isUAC, const SipEndpointConfig& config, const NATEndpointOptions& natOptions);
SipSession(const Ice::ObjectAdapterPtr&, const SipEndpointPtr&, const std::string&, const Ice::Identity&, const Ice::Identity&,
- const Ice::Identity&, const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq&,
+ const Ice::Identity&, const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionDict&,
const AsteriskSCF::Media::V1::StreamSourceSeq&, const AsteriskSCF::Media::V1::StreamSinkSeq&,
const PJSipManagerPtr& manager, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
const SipReplicationContextPtr& replicationContext,
-----------------------------------------------------------------------
--
asterisk-scf/release/sip.git
More information about the asterisk-scf-commits
mailing list