[asterisk-scf-commits] asterisk-scf/integration/sip.git branch "master" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Fri Sep 24 11:56:13 CDT 2010
branch "master" has been updated
via 449ef8e79aaf01d87b87ba25efba7c8f4cd8db0c (commit)
via 01550c1ac7a0cae68c96f019896f7e4d5bc41079 (commit)
from d90268b1e77a622f1b2701081393741369c9f5fc (commit)
Summary of changes:
src/PJSipSessionModule.cpp | 335 ++++++++++++++++++++-----------------------
src/PJSipSessionModule.h | 46 ++++++-
src/SipSession.cpp | 6 +-
3 files changed, 202 insertions(+), 185 deletions(-)
- Log -----------------------------------------------------------------
commit 449ef8e79aaf01d87b87ba25efba7c8f4cd8db0c
Author: Mark Michelson <mmichelson at digium.com>
Date: Fri Sep 24 11:56:45 2010 -0500
Add state replication for new outbound INVITE.
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index b6ac642..a301769 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -540,6 +540,19 @@ static void invOnStateChanged(pjsip_inv_session *inv, pjsip_event *event)
invOnTransactionStateChanged(inv, inv->invite_tsx, event);
}
}
+ if (event->type == PJSIP_EVENT_TX_MSG && inv->state == PJSIP_INV_STATE_CALLING)
+ {
+ //We have sent an INVITE out. We need to set up the transaction and dialog structures
+ //to have the appropriate mod_data and initiate some state replication here as well.
+ //The inv_session's mod_info was set up in SipSession::start() because we had the SipSession
+ //information there.
+ PJSipDialogModInfo *dlg_mod_info = new PJSipDialogModInfo(inv->dlg);
+ PJSipTransactionModInfo *tsx_mod_info = new PJSipTransactionModInfo(inv->invite_tsx);
+ PJSipSessionModInfo *session_mod_info = static_cast<PJSipSessionModInfo *>(inv->mod_data[pjsip_ua_instance()->id]);
+ inv->invite_tsx->mod_data[pjsip_ua_instance()->id] = (void *) tsx_mod_info;
+ inv->dlg->mod_data[pjsip_ua_instance()->id] = (void *) dlg_mod_info;
+ replicateState(dlg_mod_info, tsx_mod_info, session_mod_info);
+ }
}
static void invOnNewSession(pjsip_inv_session *inv, pjsip_event *event)
diff --git a/src/SipSession.cpp b/src/SipSession.cpp
index 77b634e..3ce7037 100644
--- a/src/SipSession.cpp
+++ b/src/SipSession.cpp
@@ -349,8 +349,10 @@ void SipSession::start(const Ice::Current&)
}
// Record our session within the dialog so code handling pjsip events can do STUFF
- SipSessionPtr* session = new SipSessionPtr(this);
- inviteSession->mod_data[pjsip_ua_instance()->id] = (void*)session;
+ PJSipSessionModInfo *session_mod_info = new PJSipSessionModInfo(inviteSession);
+ SipSessionPtr session = new SipSession(*this);
+ session_mod_info->setSessionPtr(session);
+ inviteSession->mod_data[pjsip_ua_instance()->id] = (void*)session_mod_info;
// Create the actual INVITE packet
pjsip_tx_data *packet;
commit 01550c1ac7a0cae68c96f019896f7e4d5bc41079
Author: Mark Michelson <mmichelson at digium.com>
Date: Fri Sep 24 11:39:45 2010 -0500
Rearrange mod_data classes so that they are declared in the .h file.
diff --git a/src/PJSipSessionModule.cpp b/src/PJSipSessionModule.cpp
index b43be02..b6ac642 100644
--- a/src/PJSipSessionModule.cpp
+++ b/src/PJSipSessionModule.cpp
@@ -38,197 +38,161 @@ using namespace AsteriskSCF::SIP::V1;
//to retrieve PJSIP URI strings.
const int URI_SIZE = 64;
+PJSipDialogModInfo::PJSipDialogModInfo(pjsip_dialog *dialog) : mDialogState(new SipDialogStateItem) , mNeedsReplication(true)
+{
+ //XXX Is there a way to tell ICE to make the default
+ //constructor for SipStateItem set key?
+ mDialogState->key = IceUtil::generateUUID();
+ updateDialogState(dialog);
+}
+
+PJSipDialogModInfo::~PJSipDialogModInfo()
+{
+ mDialogState = 0;
+}
+
/**
- * This is the data we stash in a pjsip_dialog's mod_info
- * array so we can have all the dialog info we need. This
- * is mostly used for state replication.
+ * Copies data from the pjsip_dialog structure into
+ * our state data.
*
- * XXX It may be necessary to put this class in a .h file
- * in case SipEndpoint.cpp needs to use this.
+ * XXX This could likely be optimized to only update
+ * stuff that needs updating. Important first step
+ * is to get it working.
*/
-class PJSipDialogModInfo
+void PJSipDialogModInfo::updateDialogState(pjsip_dialog *dialog)
{
-public:
- PJSipDialogModInfo(pjsip_dialog *dialog) : mDialogState(new SipDialogStateItem) , mNeedsReplication(true)
- {
- //XXX Is there a way to tell ICE to make the default
- //constructor for SipStateItem set key?
- mDialogState->key = IceUtil::generateUUID();
- updateDialogState(dialog);
- }
- ~PJSipDialogModInfo()
- {
- mDialogState = 0;
- }
- /**
- * Copies data from the pjsip_dialog structure into
- * our state data.
- *
- * XXX This could likely be optimized to only update
- * stuff that needs updating. Important first step
- * is to get it working.
- */
- void updateDialogState(pjsip_dialog *dialog)
- {
- mDialogState->mCallId = std::string(pj_strbuf(&dialog->call_id->id), pj_strlen(&dialog->call_id->id));
- mDialogState->mIsDialogEstablished = dialog->state == PJSIP_DIALOG_STATE_ESTABLISHED ? true : false;
- mDialogState->mIsSecure = dialog->secure == PJ_TRUE ? true : false;
-
- mDialogState->mLocalCSeq = dialog->local.cseq;
- mDialogState->mLocalTag = std::string(pj_strbuf(&dialog->local.info->tag), pj_strlen(&dialog->local.info->tag));
- char localUri[URI_SIZE];
- pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dialog->local.info->uri, localUri, sizeof(localUri));
- mDialogState->mLocalUri = localUri;
-
- mDialogState->mRemoteCSeq = dialog->remote.cseq;
- mDialogState->mRemoteTag = std::string(pj_strbuf(&dialog->remote.info->tag), pj_strlen(&dialog->remote.info->tag));
- char remoteUri[URI_SIZE];
- pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dialog->remote.info->uri, remoteUri, sizeof(remoteUri));
- mDialogState->mRemoteUri = remoteUri;
-
- //This is a place where the whole "only change what you need" optimization
- //will come in super-handy since we have to erase and rebuild the route set
- //every time. My recollection is that the route set can only be established
- //in the first transaction of a dialog so this is purdy wasteful.
- mDialogState->mRouteSet.erase(mDialogState->mRouteSet.begin(), mDialogState->mRouteSet.end());
- for (pjsip_route_hdr *hdr_iter = dialog->route_set.next; hdr_iter != &dialog->route_set; hdr_iter = hdr_iter->next)
- {
- char routeUri[URI_SIZE];
- pjsip_uri_print(PJSIP_URI_IN_ROUTING_HDR, hdr_iter->name_addr.uri, routeUri, sizeof(routeUri));
-
- //XXX I need to see the order in which the route set is represented
- //in a pjsip dialog. push_back could be completely incorrect here,
- //or it may only be correct depending on whether we're the UAC or UAS.
- //Also, for now we're ignoring the optional display name portion of URIs
- //in the route set. They're not strictly necessary for routing calls correctly.
- mDialogState->mRouteSet.push_back(routeUri);
- }
- //XXX I'm not 100% sure how to get the transport from a pjsip_dialog, so for now,
- //I'll just hardcode this as UDP until we start wanting to actually implement
- //other transports.
- mDialogState->mTransport = "UDP";
- mNeedsReplication = true;
- }
- /**
- * The associated dialog information. Used for state replication
- */
- SipDialogStateItemPtr mDialogState;
- /**
- * An indicator of whether there are pending updates to the dialogState.
- * This is in place so we don't send needless updates to the state replicator
- * if nothing has actually changed for the dialog.
- */
- bool mNeedsReplication;
- /**
- * An indicator of whether state needs to be removed from the state replicator.
- * This will coincide with when the corresponding PJSIP item is destroyed.
- */
- bool mNeedsRemoval;
-};
-
-class PJSipTransactionModInfo
-{
-public:
- PJSipTransactionModInfo(pjsip_transaction *transaction) : mTransactionState(new SipTransactionStateItem), mNeedsReplication(true)
+ mDialogState->mCallId = std::string(pj_strbuf(&dialog->call_id->id), pj_strlen(&dialog->call_id->id));
+ mDialogState->mIsDialogEstablished = dialog->state == PJSIP_DIALOG_STATE_ESTABLISHED ? true : false;
+ mDialogState->mIsSecure = dialog->secure == PJ_TRUE ? true : false;
+
+ mDialogState->mLocalCSeq = dialog->local.cseq;
+ mDialogState->mLocalTag = std::string(pj_strbuf(&dialog->local.info->tag), pj_strlen(&dialog->local.info->tag));
+ char localUri[URI_SIZE];
+ pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dialog->local.info->uri, localUri, sizeof(localUri));
+ mDialogState->mLocalUri = localUri;
+
+ mDialogState->mRemoteCSeq = dialog->remote.cseq;
+ mDialogState->mRemoteTag = std::string(pj_strbuf(&dialog->remote.info->tag), pj_strlen(&dialog->remote.info->tag));
+ char remoteUri[URI_SIZE];
+ pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dialog->remote.info->uri, remoteUri, sizeof(remoteUri));
+ mDialogState->mRemoteUri = remoteUri;
+
+ //This is a place where the whole "only change what you need" optimization
+ //will come in super-handy since we have to erase and rebuild the route set
+ //every time. My recollection is that the route set can only be established
+ //in the first transaction of a dialog so this is purdy wasteful.
+ mDialogState->mRouteSet.erase(mDialogState->mRouteSet.begin(), mDialogState->mRouteSet.end());
+ for (pjsip_route_hdr *hdr_iter = dialog->route_set.next; hdr_iter != &dialog->route_set; hdr_iter = hdr_iter->next)
{
- mTransactionState->key = IceUtil::generateUUID();
- updateTransactionState(transaction);
+ char routeUri[URI_SIZE];
+ pjsip_uri_print(PJSIP_URI_IN_ROUTING_HDR, hdr_iter->name_addr.uri, routeUri, sizeof(routeUri));
+
+ //XXX I need to see the order in which the route set is represented
+ //in a pjsip dialog. push_back could be completely incorrect here,
+ //or it may only be correct depending on whether we're the UAC or UAS.
+ //Also, for now we're ignoring the optional display name portion of URIs
+ //in the route set. They're not strictly necessary for routing calls correctly.
+ mDialogState->mRouteSet.push_back(routeUri);
}
- ~PJSipTransactionModInfo()
- {
- mTransactionState = 0;
- }
- void updateTransactionState(pjsip_transaction *transaction)
- {
- mTransactionState->mBranch = std::string(pj_strbuf(&transaction->branch), pj_strlen(&transaction->branch));
- mTransactionState->mIsClient = (transaction->role == PJSIP_ROLE_UAC || transaction->role == PJSIP_UAC_ROLE) ? true : false;
- mTransactionState->mCurrentState = transactionStateTranslate(transaction->state);
- mNeedsReplication = true;
- }
- SipTransactionStateItemPtr mTransactionState;
- bool mNeedsReplication;
- bool mNeedsRemoval;
-private:
- TransactionState transactionStateTranslate(pjsip_tsx_state_e state)
- {
- TransactionState retState;
- switch (state)
- {
- case PJSIP_TSX_STATE_NULL:
- retState = TransactionStateNull;
- break;
- case PJSIP_TSX_STATE_CALLING:
- retState = TransactionStateCalling;
- break;
- case PJSIP_TSX_STATE_TRYING:
- retState = TransactionStateTrying;
- break;
- case PJSIP_TSX_STATE_PROCEEDING:
- retState = TransactionStateProceeding;
- break;
- case PJSIP_TSX_STATE_COMPLETED:
- retState = TransactionStateCompleted;
- break;
- case PJSIP_TSX_STATE_CONFIRMED:
- retState = TransactionStateConfirmed;
- break;
- case PJSIP_TSX_STATE_TERMINATED:
- retState = TransactionStateTerminated;
- break;
- case PJSIP_TSX_STATE_DESTROYED:
- retState = TransactionStateDestroyed;
- break;
- default:
- std::cerr << "[ERROR] Unknown PJSIP Transaction state encountered: " << state << std::endl;
- retState = TransactionStateNull;
- break;
- }
- return retState;
- }
-};
+ //XXX I'm not 100% sure how to get the transport from a pjsip_dialog, so for now,
+ //I'll just hardcode this as UDP until we start wanting to actually implement
+ //other transports.
+ mDialogState->mTransport = "UDP";
+ mNeedsReplication = true;
+}
-class PJSipSessionModInfo
+PJSipTransactionModInfo::PJSipTransactionModInfo(pjsip_transaction *transaction) : mTransactionState(new SipTransactionStateItem), mNeedsReplication(true)
{
-public:
- PJSipSessionModInfo(pjsip_inv_session *inv_session) : mSessionState(new SipSessionStateItem), mNeedsReplication(true)
- {
- mSessionState->key = IceUtil::generateUUID();
- }
- ~PJSipSessionModInfo()
- {
- mSession->destroy();
- mSession = 0;
- }
- /* In keeping with the other ModInfo classes, there
- * is an update function. Unlike the other items, this
- * involves Asterisk SCF data and not PJSIP data, so I'm
- * leaving this a stub for the time being.
- */
- void updateSessionState()
- {
- mSessionState->mSources = mSession->getSources();
- mSessionState->mSinks = mSession->getSinks();
- //getMediaSession requires an Ice::Current reference. Since
- //it's not actually used, we can get away with passing a dummy
- //instead.
- Ice::Current dummy;
- mSessionState->mMediaSession = mSession->getMediaSession(dummy);
- }
- SipSessionPtr getSessionPtr()
- {
- return mSession;
- }
- void setSessionPtr(SipSessionPtr sessionPtr)
+ mTransactionState->key = IceUtil::generateUUID();
+ updateTransactionState(transaction);
+}
+
+PJSipTransactionModInfo::~PJSipTransactionModInfo()
+{
+ mTransactionState = 0;
+}
+
+void PJSipTransactionModInfo::updateTransactionState(pjsip_transaction *transaction)
+{
+ mTransactionState->mBranch = std::string(pj_strbuf(&transaction->branch), pj_strlen(&transaction->branch));
+ mTransactionState->mIsClient = (transaction->role == PJSIP_ROLE_UAC || transaction->role == PJSIP_UAC_ROLE) ? true : false;
+ mTransactionState->mCurrentState = transactionStateTranslate(transaction->state);
+ mNeedsReplication = true;
+}
+
+TransactionState PJSipTransactionModInfo::transactionStateTranslate(pjsip_tsx_state_e state)
+{
+ TransactionState retState;
+ switch (state)
{
- mSession = sessionPtr;
+ case PJSIP_TSX_STATE_NULL:
+ retState = TransactionStateNull;
+ break;
+ case PJSIP_TSX_STATE_CALLING:
+ retState = TransactionStateCalling;
+ break;
+ case PJSIP_TSX_STATE_TRYING:
+ retState = TransactionStateTrying;
+ break;
+ case PJSIP_TSX_STATE_PROCEEDING:
+ retState = TransactionStateProceeding;
+ break;
+ case PJSIP_TSX_STATE_COMPLETED:
+ retState = TransactionStateCompleted;
+ break;
+ case PJSIP_TSX_STATE_CONFIRMED:
+ retState = TransactionStateConfirmed;
+ break;
+ case PJSIP_TSX_STATE_TERMINATED:
+ retState = TransactionStateTerminated;
+ break;
+ case PJSIP_TSX_STATE_DESTROYED:
+ retState = TransactionStateDestroyed;
+ break;
+ default:
+ std::cerr << "[ERROR] Unknown PJSIP Transaction state encountered: " << state << std::endl;
+ retState = TransactionStateNull;
+ break;
}
- SipSessionStateItemPtr mSessionState;
- bool mNeedsReplication;
- bool mNeedsRemoval;
+ return retState;
+}
+
+PJSipSessionModInfo::PJSipSessionModInfo(pjsip_inv_session *inv_session) : mSessionState(new SipSessionStateItem), mNeedsReplication(true)
+{
+ mSessionState->key = IceUtil::generateUUID();
+}
+
+PJSipSessionModInfo::~PJSipSessionModInfo()
+{
+ mSession->destroy();
+ mSession = 0;
+}
+
+/* In keeping with the other ModInfo classes, there
+ * is an update function. Unlike the other items, this
+ * involves Asterisk SCF data and not PJSIP data, so I'm
+ * leaving this a stub for the time being.
+ */
+void PJSipSessionModInfo::updateSessionState()
+{
+ mSessionState->mSources = mSession->getSources();
+ mSessionState->mSinks = mSession->getSinks();
+ //getMediaSession requires an Ice::Current reference. Since
+ //it's not actually used, we can get away with passing a dummy
+ //instead.
+ Ice::Current dummy;
+ mSessionState->mMediaSession = mSession->getMediaSession(dummy);
+}
-private:
- SipSessionPtr mSession;
-};
+SipSessionPtr PJSipSessionModInfo::getSessionPtr()
+{
+ return mSession;
+}
+
+void PJSipSessionModInfo::setSessionPtr(SipSessionPtr sessionPtr)
+{
+ mSession = sessionPtr;
+}
static void replicateState(PJSipDialogModInfo *dlgInfo, PJSipTransactionModInfo *tsxInfo,
PJSipSessionModInfo *sessionInfo)
diff --git a/src/PJSipSessionModule.h b/src/PJSipSessionModule.h
index c2775d8..c9ca467 100644
--- a/src/PJSipSessionModule.h
+++ b/src/PJSipSessionModule.h
@@ -12,16 +12,15 @@
#include <pjsip_ua.h>
#include <pjlib.h>
+#include "SipStateReplicator.h"
+#include "SipSession.h"
+
namespace AsteriskSCF
{
namespace SipChannelService
{
-class PJSipDialogModInfo;
-class PJSipTransactionModInfo;
-class PJSipSessionModInfo;
-
class PJSipSessionModule
{
public:
@@ -34,5 +33,44 @@ private:
const std::string mName;
};
+class PJSipDialogModInfo
+{
+public:
+ PJSipDialogModInfo(pjsip_dialog *dialog);
+ ~PJSipDialogModInfo();
+ void updateDialogState(pjsip_dialog *dialog);
+ SipDialogStateItemPtr mDialogState;
+ bool mNeedsReplication;
+ bool mNeedsRemoval;
+};
+
+class PJSipTransactionModInfo
+{
+public:
+ PJSipTransactionModInfo(pjsip_transaction *transaction);
+ ~PJSipTransactionModInfo();
+ void updateTransactionState(pjsip_transaction *transaction);
+ SipTransactionStateItemPtr mTransactionState;
+ bool mNeedsReplication;
+ bool mNeedsRemoval;
+private:
+ TransactionState transactionStateTranslate(pjsip_tsx_state_e state);
+};
+
+class PJSipSessionModInfo
+{
+public:
+ PJSipSessionModInfo(pjsip_inv_session *inv_session);
+ ~PJSipSessionModInfo();
+ void updateSessionState();
+ SipSessionPtr getSessionPtr();
+ void setSessionPtr(SipSessionPtr sessionPtr);
+ SipSessionStateItemPtr mSessionState;
+ bool mNeedsReplication;
+ bool mNeedsRemoval;
+private:
+ SipSessionPtr mSession;
+};
+
}; //end namespace SipChannelService
}; //end namespace AsteriskSCF
-----------------------------------------------------------------------
--
asterisk-scf/integration/sip.git
More information about the asterisk-scf-commits
mailing list