[asterisk-scf-commits] asterisk-scf/integration/sip.git branch "sessioncontroller" created.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Tue Jun 28 18:43:48 CDT 2011
branch "sessioncontroller" has been created
at a47266522a86a264400f6cfa47bc603f115ade3b (commit)
- Log -----------------------------------------------------------------
commit a47266522a86a264400f6cfa47bc603f115ade3b
Author: Joshua Colp <jcolp at digium.com>
Date: Tue Jun 28 20:41:19 2011 -0300
Add an implementation of removeStreams for SIP.
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index f5ce9e4..7e05ef3 100644
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -310,101 +310,168 @@ public:
: mStreams(streams), mImplPriv(sessionPriv) { }
SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ lg(Debug) << "Executing a changeStreamStates Operation";
+
+ // This boolean is set to true if at least one stream is actually changed. This is to prevent
+ // needless reinvites.
+ bool changed = false;
+
+ // We iterate through each stream making sure we have one that matches it
+ for (AsteriskSCF::Media::V1::StreamStateDict::const_iterator stream = mStreams.begin();
+ stream != mStreams.end();
+ ++stream)
{
- lg(Debug) << "Executing a changeStreamStates Operation";
+ AsteriskSCF::Media::V1::StreamInformationDict::iterator ourStream = mImplPriv->mStreams.find(stream->first);
+
+ // If we don't have a stream stored locally then they gave us a stream that we really know nothing about it
+ if (ourStream == mImplPriv->mStreams.end())
+ {
+ continue;
+ }
- // This boolean is set to true if at least one stream is actually changed. This is to prevent
- // needless reinvites.
- bool changed = false;
+ // If this doesn't actually alter the state of the stream do nothing, since it would just be silly
+ if (ourStream->second->state == stream->second)
+ {
+ continue;
+ }
- // We iterate through each stream making sure we have one that matches it
- for (AsteriskSCF::Media::V1::StreamStateDict::const_iterator stream = mStreams.begin();
- stream != mStreams.end();
- ++stream)
+ // The implementation of how we store streams and SDP are linked together, if we can find a stream
+ // in our dictionary of streams than it also exists in the SDP
+ pjmedia_sdp_media *media = mImplPriv->mSDP->media[boost::lexical_cast<int>(stream->first)];
+
+ // Depending on the current state go ahead and remove the current attribute
+ if (ourStream->second->state == SendAndReceive)
+ {
+ pjmedia_sdp_media_remove_all_attr(media, "sendrecv");
+ }
+ else if (ourStream->second->state == SendOnly)
{
- AsteriskSCF::Media::V1::StreamInformationDict::iterator ourStream = mImplPriv->mStreams.find(stream->first);
+ pjmedia_sdp_media_remove_all_attr(media, "sendonly");
+ }
+ else if (ourStream->second->state == ReceiveOnly)
+ {
+ pjmedia_sdp_media_remove_all_attr(media, "recvonly");
+ }
+ else if (ourStream->second->state == Inactive)
+ {
+ pjmedia_sdp_media_remove_all_attr(media, "inactive");
+ }
+
+ // Now that the old attribute is removed we can go ahead and update our state
+ ourStream->second->state = stream->second;
+
+ // Now we can go ahead and add in the corret attribute
+ pjmedia_sdp_attr *attr = NULL;
- // If we don't have a stream stored locally then they gave us a stream that we really know nothing about it
- if (ourStream == mImplPriv->mStreams.end())
- {
- continue;
- }
+ if (ourStream->second->state == SendAndReceive)
+ {
+ attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "sendrecv", NULL);
+ }
+ else if (ourStream->second->state == SendOnly)
+ {
+ attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "sendonly", NULL);
+ }
+ else if (ourStream->second->state == ReceiveOnly)
+ {
+ attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "recvonly", NULL);
+ }
+ else if (ourStream->second->state == Inactive)
+ {
+ attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "inactive", NULL);
+ }
- // If this doesn't actually alter the state of the stream do nothing, since it would just be silly
- if (ourStream->second->state == stream->second)
- {
- continue;
- }
+ if (attr)
+ {
+ pjmedia_sdp_media_add_attr(media, attr);
+ changed = true;
+ }
+ }
- // The implementation of how we store streams and SDP are linked together, if we can find a stream
- // in our dictionary of streams than it also exists in the SDP
- pjmedia_sdp_media *media = mImplPriv->mSDP->media[boost::lexical_cast<int>(stream->first)];
+ // If any streams were actually updated trigger a reinvite if need be
+ if (changed == true)
+ {
+ // TODO: Add code here to determine if we really do need to send the reinvite, if we haven't actually answered yet
+ // what we really want to do is just update our answer SDP
+ pjsip_tx_data *packet = NULL;
- // Depending on the current state go ahead and remove the current attribute
- if (ourStream->second->state == SendAndReceive)
- {
- pjmedia_sdp_media_remove_all_attr(media, "sendrecv");
- }
- else if (ourStream->second->state == SendOnly)
- {
- pjmedia_sdp_media_remove_all_attr(media, "sendonly");
- }
- else if (ourStream->second->state == ReceiveOnly)
- {
- pjmedia_sdp_media_remove_all_attr(media, "recvonly");
- }
- else if (ourStream->second->state == Inactive)
- {
- pjmedia_sdp_media_remove_all_attr(media, "inactive");
- }
+ if ((pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, mImplPriv->mSDP, &packet)) == PJ_SUCCESS)
+ {
+ pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
+ }
+ }
+
+ return Complete;
+ }
+
+private:
+ AsteriskSCF::Media::V1::StreamStateDict mStreams;
+ boost::shared_ptr<SipSessionPriv> mImplPriv;
+};
- // Now that the old attribute is removed we can go ahead and update our state
- ourStream->second->state = stream->second;
+class RemoveStreamsOperation : public SuspendableWork
+{
+public:
+ RemoveStreamsOperation(
+ const AsteriskSCF::Media::V1::StreamInformationDict& streams,
+ const boost::shared_ptr<SipSessionPriv>& sessionPriv)
+ : mStreams(streams), mImplPriv(sessionPriv) { }
- // Now we can go ahead and add in the corret attribute
- pjmedia_sdp_attr *attr = NULL;
-
- if (ourStream->second->state == SendAndReceive)
- {
- attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "sendrecv", NULL);
- }
- else if (ourStream->second->state == SendOnly)
- {
- attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "sendonly", NULL);
- }
- else if (ourStream->second->state == ReceiveOnly)
- {
- attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "recvonly", NULL);
- }
- else if (ourStream->second->state == Inactive)
- {
- attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "inactive", NULL);
- }
+ SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ lg(Debug) << "Executing a removeStreams Operation";
- if (attr)
- {
- pjmedia_sdp_media_add_attr(media, attr);
- changed = true;
- }
+ // This gets set to true if at least one stream was actually removed
+ bool removed = false;
+
+ // We iterate through each stream making sure we have one that matches it
+ for (AsteriskSCF::Media::V1::StreamInformationDict::const_iterator stream = mStreams.begin();
+ stream != mStreams.end();
+ ++stream)
+ {
+ AsteriskSCF::Media::V1::StreamInformationDict::iterator ourStream = mImplPriv->mStreams.find(stream->first);
+
+ // If we don't have a stream stored locally then they gave us a stream that we really know nothing about it
+ if (ourStream == mImplPriv->mStreams.end())
+ {
+ continue;
}
- // If any streams were actually updated trigger a reinvite if need be
- if (changed == true)
+ // If the stream has already been removed doing it again is silllly
+ if (ourStream->second->state == Removed)
{
- // TODO: Add code here to determine if we really do need to send the reinvite
- pjsip_tx_data *packet = NULL;
+ continue;
+ }
- if ((pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, mImplPriv->mSDP, &packet)) == PJ_SUCCESS)
- {
- pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
- }
+ ourStream->second->state = Removed;
+
+ pjmedia_sdp_media *media = mImplPriv->mSDP->media[boost::lexical_cast<int>(stream->first)];
+
+ // Per the RFC removing the stream is accomplished by setting the port to 0
+ media->desc.port = 0;
+ media->desc.port_count = 0;
+
+ // The RFC states that an implementation MAY choose to remove all formats but one and all attributes
+ // but at this point in time we choose not to do this
+ }
+
+ if (removed == true)
+ {
+ // TODO: Add code here to determine if we really do need to send the reinvite, if we haven't actually answered yet
+ // what we really want to do is just update our answer SDP
+ pjsip_tx_data *packet = NULL;
+
+ if ((pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, mImplPriv->mSDP, &packet)) == PJ_SUCCESS)
+ {
+ pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
}
-
- return Complete;
}
-
+
+ return Complete;
+ }
+
private:
- AsteriskSCF::Media::V1::StreamStateDict mStreams;
+ AsteriskSCF::Media::V1::StreamInformationDict mStreams;
boost::shared_ptr<SipSessionPriv> mImplPriv;
};
@@ -417,18 +484,20 @@ public:
SipSessionController(boost::shared_ptr<SipSessionPriv> implPriv, const SipSessionPtr& session) :
mImplPriv(implPriv), mSession(session) { }
- void changeStreamStates(const AsteriskSCF::Media::V1::StreamStateDict& streams, const Ice::Current&)
+ void changeStreamStates(const AsteriskSCF::Media::V1::StreamStateDict& states, const Ice::Current&)
{
lg(Debug) << "Queueing changeStreamStates operation";
- mSession->enqueueSessionWork(new ChangeStreamStatesOperation(streams, mImplPriv));
+ mSession->enqueueSessionWork(new ChangeStreamStatesOperation(states, mImplPriv));
}
AsteriskSCF::Media::V1::StreamInformationDict addStreams(const AsteriskSCF::Media::V1::StreamInformationDict&, const Ice::Current&)
{
}
- void removeStreams(const AsteriskSCF::Media::V1::StreamInformationDict&, const Ice::Current&)
+ void removeStreams(const AsteriskSCF::Media::V1::StreamInformationDict& streams, const Ice::Current&)
{
+ lg(Debug) << "Queueing removeStreams operation";
+ mSession->enqueueSessionWork(new RemoveStreamsOperation(streams, mImplPriv));
}
private:
commit 891c3ae35b077eba1a5cef8ff131d6fdf8c9ac8a
Author: Joshua Colp <jcolp at digium.com>
Date: Tue Jun 28 20:18:42 2011 -0300
Add an implementation of changeStreamStates for SIP.
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index d54fe8b..f5ce9e4 100644
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -82,39 +82,6 @@ private:
};
/**
- * Implementation of a SessionController interface for the SipSession.
- */
-class SipSessionController : public AsteriskSCF::SessionCommunications::V1::SessionController
-{
-public:
- SipSessionController(boost::shared_ptr<SipSessionPriv> implPriv, const SipSessionPtr& session) :
- mImplPriv(implPriv), mSession(session) { }
-
- void changeStreamStates(const AsteriskSCF::Media::V1::StreamStateDict&, const Ice::Current&)
- {
- }
-
- AsteriskSCF::Media::V1::StreamInformationDict addStreams(const AsteriskSCF::Media::V1::StreamInformationDict&, const Ice::Current&)
- {
- }
-
- void removeStreams(const AsteriskSCF::Media::V1::StreamInformationDict&, const Ice::Current&)
- {
- }
-
-private:
- /**
- * Private implementation details for SipSession.
- */
- boost::shared_ptr<SipSessionPriv> mImplPriv;
-
- /**
- * A pointer to the communications session that created us.
- */
- SipSessionPtr mSession;
-};
-
-/**
* Private implementation details for SipSession.
*/
class SipSessionPriv
@@ -334,6 +301,148 @@ inline T *allocate_from_pool(pj_pool_t *pool)
return static_cast<T*>(pj_pool_zalloc(pool, sizeof(T)));
}
+class ChangeStreamStatesOperation : public SuspendableWork
+{
+public:
+ ChangeStreamStatesOperation(
+ const AsteriskSCF::Media::V1::StreamStateDict& streams,
+ const boost::shared_ptr<SipSessionPriv>& sessionPriv)
+ : mStreams(streams), mImplPriv(sessionPriv) { }
+
+ SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ lg(Debug) << "Executing a changeStreamStates Operation";
+
+ // This boolean is set to true if at least one stream is actually changed. This is to prevent
+ // needless reinvites.
+ bool changed = false;
+
+ // We iterate through each stream making sure we have one that matches it
+ for (AsteriskSCF::Media::V1::StreamStateDict::const_iterator stream = mStreams.begin();
+ stream != mStreams.end();
+ ++stream)
+ {
+ AsteriskSCF::Media::V1::StreamInformationDict::iterator ourStream = mImplPriv->mStreams.find(stream->first);
+
+ // If we don't have a stream stored locally then they gave us a stream that we really know nothing about it
+ if (ourStream == mImplPriv->mStreams.end())
+ {
+ continue;
+ }
+
+ // If this doesn't actually alter the state of the stream do nothing, since it would just be silly
+ if (ourStream->second->state == stream->second)
+ {
+ continue;
+ }
+
+ // The implementation of how we store streams and SDP are linked together, if we can find a stream
+ // in our dictionary of streams than it also exists in the SDP
+ pjmedia_sdp_media *media = mImplPriv->mSDP->media[boost::lexical_cast<int>(stream->first)];
+
+ // Depending on the current state go ahead and remove the current attribute
+ if (ourStream->second->state == SendAndReceive)
+ {
+ pjmedia_sdp_media_remove_all_attr(media, "sendrecv");
+ }
+ else if (ourStream->second->state == SendOnly)
+ {
+ pjmedia_sdp_media_remove_all_attr(media, "sendonly");
+ }
+ else if (ourStream->second->state == ReceiveOnly)
+ {
+ pjmedia_sdp_media_remove_all_attr(media, "recvonly");
+ }
+ else if (ourStream->second->state == Inactive)
+ {
+ pjmedia_sdp_media_remove_all_attr(media, "inactive");
+ }
+
+ // Now that the old attribute is removed we can go ahead and update our state
+ ourStream->second->state = stream->second;
+
+ // Now we can go ahead and add in the corret attribute
+ pjmedia_sdp_attr *attr = NULL;
+
+ if (ourStream->second->state == SendAndReceive)
+ {
+ attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "sendrecv", NULL);
+ }
+ else if (ourStream->second->state == SendOnly)
+ {
+ attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "sendonly", NULL);
+ }
+ else if (ourStream->second->state == ReceiveOnly)
+ {
+ attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "recvonly", NULL);
+ }
+ else if (ourStream->second->state == Inactive)
+ {
+ attr = pjmedia_sdp_attr_create(mImplPriv->mDialog->pool, "inactive", NULL);
+ }
+
+ if (attr)
+ {
+ pjmedia_sdp_media_add_attr(media, attr);
+ changed = true;
+ }
+ }
+
+ // If any streams were actually updated trigger a reinvite if need be
+ if (changed == true)
+ {
+ // TODO: Add code here to determine if we really do need to send the reinvite
+ pjsip_tx_data *packet = NULL;
+
+ if ((pjsip_inv_reinvite(mImplPriv->mInviteSession, NULL, mImplPriv->mSDP, &packet)) == PJ_SUCCESS)
+ {
+ pjsip_inv_send_msg(mImplPriv->mInviteSession, packet);
+ }
+ }
+
+ return Complete;
+ }
+
+private:
+ AsteriskSCF::Media::V1::StreamStateDict mStreams;
+ boost::shared_ptr<SipSessionPriv> mImplPriv;
+};
+
+/**
+ * Implementation of a SessionController interface for the SipSession.
+ */
+class SipSessionController : public AsteriskSCF::SessionCommunications::V1::SessionController
+{
+public:
+ SipSessionController(boost::shared_ptr<SipSessionPriv> implPriv, const SipSessionPtr& session) :
+ mImplPriv(implPriv), mSession(session) { }
+
+ void changeStreamStates(const AsteriskSCF::Media::V1::StreamStateDict& streams, const Ice::Current&)
+ {
+ lg(Debug) << "Queueing changeStreamStates operation";
+ mSession->enqueueSessionWork(new ChangeStreamStatesOperation(streams, mImplPriv));
+ }
+
+ AsteriskSCF::Media::V1::StreamInformationDict addStreams(const AsteriskSCF::Media::V1::StreamInformationDict&, const Ice::Current&)
+ {
+ }
+
+ void removeStreams(const AsteriskSCF::Media::V1::StreamInformationDict&, const Ice::Current&)
+ {
+ }
+
+private:
+ /**
+ * Private implementation details for SipSession.
+ */
+ boost::shared_ptr<SipSessionPriv> mImplPriv;
+
+ /**
+ * A pointer to the communications session that created us.
+ */
+ SipSessionPtr mSession;
+};
+
void SipSession::initializePJSIPStructs()
{
pj_str_t local_uri, remote_uri;
commit d6a4f1e97ddde4de20071c6e28fdbaa802097fd3
Author: Joshua Colp <jcolp at digium.com>
Date: Tue Jun 28 19:51:55 2011 -0300
Add support for storing stream information, making it available, and replicating it. Additionally add a blank SessionController and replicate the object ID of it.
diff --git a/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice b/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
index 605b249..db8dd79 100644
--- a/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
+++ b/slice/AsteriskSCF/Replication/SipSessionManager/SipStateReplicationIf.ice
@@ -152,8 +152,10 @@ module V1
string mEndpointName;
Ice::Identity mSessionObjectId;
Ice::Identity mMediaSessionObjectId;
+ Ice::Identity mSessionControllerObjectId;
AsteriskSCF::Media::V1::StreamSourceSeq mSources;
AsteriskSCF::Media::V1::StreamSinkSeq mSinks;
+ AsteriskSCF::Media::V1::StreamInformationDict mStreams;
RTPMediaSessionSeq mRTPMediaSessions;
SessionListenerSeq mListeners;
AsteriskSCF::SessionCommunications::V1::Bridge *mBridge;
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index 7128453..48b2bba 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -96,10 +96,12 @@ void PJSipSessionModInfo::updateSessionState(pjsip_inv_session *inv_session)
mSessionState->mEndpointName = mSession->getEndpoint()->getName();
mSessionState->mSessionObjectId = mSession->getSessionProxy()->ice_getIdentity();
mSessionState->mMediaSessionObjectId = mSession->getMediaSessionProxy()->ice_getIdentity();
+ mSessionState->mSessionControllerObjectId = mSession->getOurSessionControllerProxy()->ice_getIdentity();
mSessionState->mSources = mSession->getSources();
mSessionState->mSinks = mSession->getSinks();
mSessionState->mRTPMediaSessions = mSession->getRTPMediaSessions();
mSessionState->mListeners = mSession->getListeners();
+ mSessionState->mStreams = mSession->getStreams();
try
{
mSessionState->mBridge = mSession->getBridge();
diff --git a/src/SipEndpoint.cpp b/src/SipEndpoint.cpp
index ac3518a..0d44513 100644
--- a/src/SipEndpoint.cpp
+++ b/src/SipEndpoint.cpp
@@ -343,12 +343,13 @@ AsteriskSCF::SipSessionManager::SipSessionPtr SipEndpoint::createSession(const s
}
AsteriskSCF::SipSessionManager::SipSessionPtr SipEndpoint::createSession(const std::string& destination,
- const Ice::Identity& sessionid, const Ice::Identity& mediaid,
+ const Ice::Identity& sessionid, const Ice::Identity& controllerid,
+ const Ice::Identity& mediaid,
const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
const AsteriskSCF::Media::V1::StreamSourceSeq& sources,
const AsteriskSCF::Media::V1::StreamSinkSeq& sinks)
{
- SipSessionPtr session = new SipSession(mImplPriv->mAdapter, this, destination, sessionid, mediaid, mediasessions,
+ SipSessionPtr session = new SipSession(mImplPriv->mAdapter, this, destination, sessionid, controllerid, mediaid, mediasessions,
sources, sinks, mImplPriv->mManager, mImplPriv->mServiceLocator, mImplPriv->mReplica, false);
mImplPriv->mSessions.push_back(session);
return session;
diff --git a/src/SipEndpoint.h b/src/SipEndpoint.h
index ebf4d87..b5b7e02 100644
--- a/src/SipEndpoint.h
+++ b/src/SipEndpoint.h
@@ -245,7 +245,7 @@ public:
// dependency insanity
//
AsteriskSCF::SipSessionManager::SipSessionPtr createSession(const std::string&);
- AsteriskSCF::SipSessionManager::SipSessionPtr createSession(const std::string&, const Ice::Identity&,
+ AsteriskSCF::SipSessionManager::SipSessionPtr createSession(const std::string&, const Ice::Identity&, const Ice::Identity&,
const Ice::Identity&, const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq&,
const AsteriskSCF::Media::V1::StreamSourceSeq&, const AsteriskSCF::Media::V1::StreamSinkSeq&);
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 6210963..d54fe8b 100644
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -82,6 +82,39 @@ private:
};
/**
+ * Implementation of a SessionController interface for the SipSession.
+ */
+class SipSessionController : public AsteriskSCF::SessionCommunications::V1::SessionController
+{
+public:
+ SipSessionController(boost::shared_ptr<SipSessionPriv> implPriv, const SipSessionPtr& session) :
+ mImplPriv(implPriv), mSession(session) { }
+
+ void changeStreamStates(const AsteriskSCF::Media::V1::StreamStateDict&, const Ice::Current&)
+ {
+ }
+
+ AsteriskSCF::Media::V1::StreamInformationDict addStreams(const AsteriskSCF::Media::V1::StreamInformationDict&, const Ice::Current&)
+ {
+ }
+
+ void removeStreams(const AsteriskSCF::Media::V1::StreamInformationDict&, const Ice::Current&)
+ {
+ }
+
+private:
+ /**
+ * Private implementation details for SipSession.
+ */
+ boost::shared_ptr<SipSessionPriv> mImplPriv;
+
+ /**
+ * A pointer to the communications session that created us.
+ */
+ SipSessionPtr mSession;
+};
+
+/**
* Private implementation details for SipSession.
*/
class SipSessionPriv
@@ -191,6 +224,16 @@ public:
AsteriskSCF::Media::V1::SessionPrx mMediaSessionProxy;
/**
+ * An instance of a session controller.
+ */
+ AsteriskSCF::SessionCommunications::V1::SessionControllerPtr mOurSessionController;
+
+ /**
+ * A proxy to our own session controller.
+ */
+ AsteriskSCF::SessionCommunications::V1::SessionControllerPrx mOurSessionControllerProxy;
+
+ /**
* A proxy to this communications session.
*/
AsteriskSCF::SessionCommunications::V1::SessionPrx mSessionProxy;
@@ -270,6 +313,16 @@ public:
* Whether the SDP has been finalized or not.
*/
bool mSDPFinalized;
+
+ /**
+ * Streams present on the session.
+ */
+ StreamInformationDict mStreams;
+
+ /**
+ * A proxy to the SessionController we are controlling.
+ */
+ AsteriskSCF::SessionCommunications::V1::SessionControllerPrx mSessionController;
};
/**
@@ -364,6 +417,10 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter, const SipEndpointPt
mImplPriv->mMediaSessionProxy =
AsteriskSCF::Media::V1::SessionPrx::uncheckedCast(adapter->addWithUUID(mImplPriv->mMediaSession));
+ mImplPriv->mOurSessionController = new SipSessionController(mImplPriv, this);
+ mImplPriv->mOurSessionControllerProxy =
+ AsteriskSCF::SessionCommunications::V1::SessionControllerPrx::uncheckedCast(adapter->addWithUUID(mImplPriv->mOurSessionController));
+
if (isUAC)
{
lg(Debug) << "New session is UAC, so we're creating the necessary PJSIP structures";
@@ -376,6 +433,7 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter, const SipEndpointPt
*/
SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter, const SipEndpointPtr& endpoint,
const std::string& destination, const Ice::Identity& sessionid,
+ const Ice::Identity& controllerid,
const Ice::Identity& mediaid, const AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq& mediasessions,
const AsteriskSCF::Media::V1::StreamSourceSeq& sources, const AsteriskSCF::Media::V1::StreamSinkSeq& sinks,
PJSipManager *manager, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
@@ -389,6 +447,10 @@ SipSession::SipSession(const Ice::ObjectAdapterPtr& adapter, const SipEndpointPt
mImplPriv->mMediaSessionProxy =
AsteriskSCF::Media::V1::SessionPrx::uncheckedCast(adapter->add(mImplPriv->mMediaSession, mediaid));
+ mImplPriv->mOurSessionController = new SipSessionController(mImplPriv, this);
+ mImplPriv->mOurSessionControllerProxy =
+ AsteriskSCF::SessionCommunications::V1::SessionControllerPrx::uncheckedCast(adapter->add(mImplPriv->mOurSessionController, controllerid));
+
mImplPriv->mRTPSessions = mediasessions;
mImplPriv->mSources = sources;
mImplPriv->mSinks = sinks;
@@ -658,6 +720,115 @@ void SipSession::getBridge_async(
enqueueSessionWork(new GetBridgeOperation(cb, mImplPriv));
}
+class GetStreamsOperation : public SuspendableWork
+{
+public:
+ GetStreamsOperation(const AsteriskSCF::SessionCommunications::V1::AMD_Session_getStreamsPtr& cb,
+ const boost::shared_ptr<SipSessionPriv>& sessionPriv)
+ : mCb(cb), mImplPriv(sessionPriv) { }
+
+ SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ lg(Debug) << "Executing a GetStreams operation";
+ mCb->ice_response(mImplPriv->mStreams);
+ return Complete;
+ }
+
+private:
+ AsteriskSCF::SessionCommunications::V1::AMD_Session_getStreamsPtr mCb;
+ boost::shared_ptr<SipSessionPriv> mImplPriv;
+};
+
+/**
+ * An implementation of the getStreams method as defined in SessionCommunications.ice
+ */
+void SipSession::getStreams_async(
+ const AsteriskSCF::SessionCommunications::V1::AMD_Session_getStreamsPtr& cb,
+ const Ice::Current&)
+{
+ lg(Debug) << "queuing a getStreams operation";
+ enqueueSessionWork(new GetStreamsOperation(cb, mImplPriv));
+}
+
+class SetAndGetSessionControllerOperation : public SuspendableWork
+{
+public:
+ SetAndGetSessionControllerOperation(const AsteriskSCF::SessionCommunications::V1::AMD_Session_setAndGetSessionControllerPtr& cb,
+ const AsteriskSCF::SessionCommunications::V1::SessionControllerPrx& controller,
+ const boost::shared_ptr<SipSessionPriv>& sessionPriv)
+ : mCb(cb), mController(controller), mImplPriv(sessionPriv) { }
+
+ SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ lg(Debug) << "Executing a SetAndGetSessionController operation";
+
+ if (mImplPriv->mSessionController)
+ {
+ mCb->ice_response(0);
+ }
+
+ mImplPriv->mSessionController = mController;
+ mCb->ice_response(mImplPriv->mOurSessionControllerProxy);
+ return Complete;
+ }
+
+private:
+ AsteriskSCF::SessionCommunications::V1::AMD_Session_setAndGetSessionControllerPtr mCb;
+ AsteriskSCF::SessionCommunications::V1::SessionControllerPrx mController;
+ boost::shared_ptr<SipSessionPriv> mImplPriv;
+};
+
+/**
+ * An implementation of the setAndGetSessionController method as defined in SessionCommunications.ice
+ */
+void SipSession::setAndGetSessionController_async(
+ const AsteriskSCF::SessionCommunications::V1::AMD_Session_setAndGetSessionControllerPtr& cb,
+ const AsteriskSCF::SessionCommunications::V1::SessionControllerPrx& controller,
+ const Ice::Current&)
+{
+ lg(Debug) << "queueing a setAndGetSessionController operation";
+ enqueueSessionWork(new SetAndGetSessionControllerOperation(cb, controller, mImplPriv));
+}
+
+class RemoveSessionControllerOperation : public SuspendableWork
+{
+public:
+ RemoveSessionControllerOperation(const AsteriskSCF::SessionCommunications::V1::AMD_Session_removeSessionControllerPtr& cb,
+ const AsteriskSCF::SessionCommunications::V1::SessionControllerPrx& controller,
+ const boost::shared_ptr<SipSessionPriv>& sessionPriv)
+ : mCb(cb), mController(controller), mImplPriv(sessionPriv) { }
+
+ SuspendableWorkResult execute(const SuspendableWorkListenerPtr&)
+ {
+ lg(Debug) << "Executing a RemoveSessionController operation";
+
+ if (mImplPriv->mSessionController == mController)
+ {
+ mImplPriv->mSessionController = 0;
+ }
+
+ mCb->ice_response();
+ return Complete;
+ }
+
+private:
+ AsteriskSCF::SessionCommunications::V1::AMD_Session_removeSessionControllerPtr mCb;
+ AsteriskSCF::SessionCommunications::V1::SessionControllerPrx mController;
+ boost::shared_ptr<SipSessionPriv> mImplPriv;
+};
+
+
+/**
+ * An implementation of the removeSessionController method as defined in SessionCommunications.ice
+ */
+void SipSession::removeSessionController_async(const AsteriskSCF::SessionCommunications::V1::AMD_Session_removeSessionControllerPtr& cb,
+ const AsteriskSCF::SessionCommunications::V1::SessionControllerPrx& controller,
+ const Ice::Current&)
+{
+ lg(Debug) << "queueing a removeSessionController operation";
+ enqueueSessionWork(new RemoveSessionControllerOperation(cb, controller, mImplPriv));
+}
+
class SetBridgeOperation : public SuspendableWork
{
public:
@@ -1203,6 +1374,8 @@ pjmedia_sdp_session *SipSession::createSDPOffer()
mImplPriv->mSDP = createSDP();
}
+ int streamNum = 0;
+
// Iterate through each stream present in the topology
for (StreamTopologyMap::const_iterator stream = streams.begin();
stream != streams.end();
@@ -1231,14 +1404,25 @@ pjmedia_sdp_session *SipSession::createSDPOffer()
continue;
}
+ // Instantiate a stream information class to contain details about this stream
+ StreamInformationPtr ourStream = new StreamInformation();
+
+ // Formats we already have so just copy them
+ ourStream->formats = stream->second;
+
+ // You might notice we do not set the state of the stream, this is because by default it is already
+ // set to be send and receive.
+
// RTP sessions should only provide a single sink, so grab it and update the connection details with that
// of the remote party
StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(session->getSinks().front());
mImplPriv->mSinks.push_back(sink);
+ ourStream->sinks.push_back(sink);
// Ditto goes for source
StreamSourceRTPPrx source = StreamSourceRTPPrx::uncheckedCast(session->getSources().front());
mImplPriv->mSources.push_back(source);
+ ourStream->sources.push_back(source);
// Update the SIP session with some RTP session details
mImplPriv->mRTPSessions.push_back(session);
@@ -1285,6 +1469,9 @@ pjmedia_sdp_session *SipSession::createSDPOffer()
// The SDP has been finalized enough
mImplPriv->mSDPFinalized = true;
+
+ // Now that all is done we can add this stream in
+ mImplPriv->mStreams.insert(make_pair(boost::lexical_cast<std::string>(streamNum++), ourStream));
}
return mImplPriv->mSDPFinalized == true ? mImplPriv->mSDP : 0;
@@ -1446,15 +1633,40 @@ pjmedia_sdp_session *SipSession::createSDPAnswer(const pjmedia_sdp_session* offe
continue;
}
+ // Instantiate a stream information class so we can keep track of this stream
+ StreamInformationPtr ourStream = new StreamInformation();
+
+ // Formats actually accepted by us were determined above so we can just copy them
+ ourStream->formats = formats;
+
+ // Determine the state of the stream
+ if (pjmedia_sdp_media_find_attr2(offer->media[stream], "sendonly", NULL))
+ {
+ ourStream->state = SendOnly;
+ }
+ else if (pjmedia_sdp_media_find_attr2(offer->media[stream], "recvonly", NULL))
+ {
+ ourStream->state = ReceiveOnly;
+ }
+ else if (pjmedia_sdp_media_find_attr2(offer->media[stream], "inactive", NULL))
+ {
+ ourStream->state = Inactive;
+ }
+
+ // We don't explicitly look for sendrecv since the default state of a newly created StreamInformation
+ // is SendAndReceive, which is also implied if none of the above are found in the SDP
+
// RTP sessions should only provide a single sink, so grab it and update the connection details with that
// of the remote party
StreamSinkRTPPrx sink = StreamSinkRTPPrx::uncheckedCast(session->getSinks().front());
sink->setRemoteDetails(connection, offer->media[stream]->desc.port);
mImplPriv->mSinks.push_back(sink);
+ ourStream->sinks.push_back(sink);
// Ditto goes for source
StreamSourceRTPPrx source = StreamSourceRTPPrx::uncheckedCast(session->getSources().front());
mImplPriv->mSources.push_back(source);
+ ourStream->sources.push_back(source);
// Update the SIP session with some RTP session details
mImplPriv->mRTPSessions.push_back(session);
@@ -1492,6 +1704,9 @@ pjmedia_sdp_session *SipSession::createSDPAnswer(const pjmedia_sdp_session* offe
// The SDP has been finalized enough
mImplPriv->mSDPFinalized = true;
+
+ // Add this as a stream to ourselves, yay!
+ mImplPriv->mStreams.insert(make_pair(boost::lexical_cast<std::string>(stream), ourStream));
}
return mImplPriv->mSDPFinalized == true ? mImplPriv->mSDP : 0;
@@ -1568,6 +1783,14 @@ std::vector<AsteriskSCF::SessionCommunications::V1::SessionListenerPrx> SipSessi
}
/**
+ * Internal function which gets the streams on this session.
+ */
+AsteriskSCF::Media::V1::StreamInformationDict& SipSession::getStreams()
+{
+ return mImplPriv->mStreams;
+}
+
+/**
* Internal function which gets the endpoint associated with the session.
*/
SipEndpointPtr SipSession::getEndpoint()
@@ -1592,6 +1815,14 @@ AsteriskSCF::Media::V1::SessionPrx& SipSession::getMediaSessionProxy()
}
/**
+ * Internal function which gets the proxy to our session controller.
+ */
+AsteriskSCF::SessionCommunications::V1::SessionControllerPrx& SipSession::getOurSessionControllerProxy()
+{
+ return mImplPriv->mOurSessionControllerProxy;
+}
+
+/**
* Internal function which sets the listeners explicitly.
*/
void SipSession::setListeners(const SessionListenerSeq& listeners)
@@ -1607,6 +1838,14 @@ RTPMediaSessionSeq SipSession::getRTPMediaSessions()
return mImplPriv->mRTPSessions;
}
+/**
+ * Internal function which sets the streams explicitly.
+ */
+void SipSession::setStreams(const AsteriskSCF::Media::V1::StreamInformationDict& streams)
+{
+ mImplPriv->mStreams = streams;
+}
+
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 ce5dd43..1ad2a41 100644
--- a/src/SipSession.h
+++ b/src/SipSession.h
@@ -101,6 +101,7 @@ public:
bool isUAC);
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 AsteriskSCF::Media::V1::StreamSourceSeq&, const AsteriskSCF::Media::V1::StreamSinkSeq&,
PJSipManager *manager, const AsteriskSCF::Core::Discovery::V1::ServiceLocatorPrx& serviceLocator,
@@ -169,6 +170,19 @@ public:
AsteriskSCF::SessionCommunications::V1::SessionCookies getCookies();
AsteriskSCF::SessionCommunications::V1::SessionCookieDict getAllCookies();
+ void getStreams_async(
+ const AsteriskSCF::SessionCommunications::V1::AMD_Session_getStreamsPtr&,
+ const Ice::Current&);
+
+ void setAndGetSessionController_async(
+ const AsteriskSCF::SessionCommunications::V1::AMD_Session_setAndGetSessionControllerPtr&,
+ const AsteriskSCF::SessionCommunications::V1::SessionControllerPrx&,
+ const Ice::Current&);
+
+ void removeSessionController_async(const AsteriskSCF::SessionCommunications::V1::AMD_Session_removeSessionControllerPtr&,
+ const AsteriskSCF::SessionCommunications::V1::SessionControllerPrx&,
+ const Ice::Current&);
+
/**
* Implementation specific functions.
*/
@@ -195,14 +209,20 @@ public:
std::vector<AsteriskSCF::SessionCommunications::V1::SessionListenerPrx> getListeners();
+ AsteriskSCF::Media::V1::StreamInformationDict& getStreams();
+
SipEndpointPtr getEndpoint();
AsteriskSCF::SessionCommunications::V1::SessionPrx& getSessionProxy();
AsteriskSCF::Media::V1::SessionPrx& getMediaSessionProxy();
+ AsteriskSCF::SessionCommunications::V1::SessionControllerPrx& getOurSessionControllerProxy();
+
void setListeners(const AsteriskSCF::Replication::SipSessionManager::V1::SessionListenerSeq&);
+ void setStreams(const AsteriskSCF::Media::V1::StreamInformationDict& streams);
+
AsteriskSCF::Replication::SipSessionManager::V1::RTPMediaSessionSeq getRTPMediaSessions();
void enqueueSessionWork(const AsteriskSCF::System::WorkQueue::V1::SuspendableWorkPtr&);
diff --git a/src/SipStateReplicatorListener.cpp b/src/SipStateReplicatorListener.cpp
index c80d019..fad4ece 100644
--- a/src/SipStateReplicatorListener.cpp
+++ b/src/SipStateReplicatorListener.cpp
@@ -102,6 +102,7 @@ public:
// Now that all is well we can create an actual session
SipSessionPtr localSession = endpoint->createSession("", session->mSessionObjectId,
+ session->mSessionControllerObjectId,
session->mMediaSessionObjectId, session->mRTPMediaSessions, session->mSources, session->mSinks);
localitem->setSession(localSession);
}
@@ -113,6 +114,7 @@ public:
localitem->getSession()->setListeners(session->mListeners);
localitem->getSession()->setBridge(session->mBridge);
localitem->getSession()->setCookies(session->mCookies);
+ localitem->getSession()->setStreams(session->mStreams);
}
else if ((dialog = SipDialogStateItemPtr::dynamicCast((*item))))
{
-----------------------------------------------------------------------
--
asterisk-scf/integration/sip.git
More information about the asterisk-scf-commits
mailing list