[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
Wed Feb 8 09:13:54 CST 2012
branch "master" has been updated
via aa883ce019d88df3a9b50f2df78370ea6c8837c1 (commit)
from 931b37bca7117716f7f6742d70ddeab0d3122f2b (commit)
Summary of changes:
config/SipConfigurator.py | 10 +++
src/PJSIPManager.cpp | 5 ++
src/PJSIPManager.h | 9 +++
src/PJSIPSessionModule.cpp | 97 +++++++++++++++++++++++++++++++-
src/PJSIPSessionModule.h | 13 ++++
src/PJSIPSessionModuleConstruction.cpp | 14 ++++-
src/SIPConfiguration.cpp | 82 ++++++++++++++++++++++++++-
src/SIPEndpoint.cpp | 15 +++++
src/SIPEndpoint.h | 21 +++++++
src/SIPSession.cpp | 28 ++++++++-
10 files changed, 282 insertions(+), 12 deletions(-)
- Log -----------------------------------------------------------------
commit aa883ce019d88df3a9b50f2df78370ea6c8837c1
Author: Brent Eagles <beagles at digium.com>
Date: Wed Feb 8 11:35:38 2012 -0330
Squashed commit of branch jira-astscf-397-sipuseragent. Integrates the
following changes:
- Added a check to make sure that the smart proxy for the session router is
only overridden if the configured and default values differ.
- Changes to incorporate user agent header setting, propagate different media
service name configurations as well as the routing service configuration
name. The latter involved adding an override in the PJSSIPSessionModule
prior to call begin_routeSession().
- Added support for configuration of the "User-Agent" general configuration item.
diff --git a/config/SipConfigurator.py b/config/SipConfigurator.py
index 4ba6cd7..f90a005 100755
--- a/config/SipConfigurator.py
+++ b/config/SipConfigurator.py
@@ -37,6 +37,14 @@ class SIPSectionVisitors(Configurator.SectionVisitors):
def visit_general(self, config, section):
group = AsteriskSCF.Configuration.SIPSessionManager.V1.SIPGeneralGroup()
group.configurationItems = { }
+ mapper = Configurator.OptionMapper()
+ item = AsteriskSCF.Configuration.SipSessionManager.V1.SipUserAgentItem()
+ mapper.map('useragent', item, 'userAgent', 'userAgent', config.get, None)
+ for option in config.options(section):
+ mapper.execute(group, section, option)
+
+ mapper.finish(group)
+
self.groups.append(group)
def visit_transport_udp(self, config, section):
@@ -298,6 +306,7 @@ class SIPSectionVisitors(Configurator.SectionVisitors):
item = AsteriskSCF.Configuration.SIPSessionManager.V1.SIPRTPMediaServiceItem()
mapper.map('rtpoveripv6', item, 'requireIPv6', 'mediaservice', config.getboolean, None)
+ mapper.map('rtpmediaservice', item, 'mediaServiceName', 'mediaservice', config.get, None)
item = AsteriskSCF.Configuration.SIPSessionManager.V1.DirectMediaItem()
mapper.map('directmedia', item, 'enabled', 'directmedia', config.getboolean, None)
@@ -306,6 +315,7 @@ class SIPSectionVisitors(Configurator.SectionVisitors):
mapper.map('udptloveripv6', item, 'requireIPv6', 'udptlmediaservice', config.getboolean, None)
mapper.map('udptloverice', item, 'enableICE', 'udptlmediaservice', config.getboolean, None)
mapper.map('udptlwithturn', item, 'enableTURN', 'udptlmediaservice', config.getboolean, None)
+ mapper.map('udptlmediaservice', item, 'mediaServiceName', 'udptlmediaservice', config.get, None);
item = AsteriskSCF.Configuration.SIPSessionManager.V1.SIPCryptoCertificateItem()
mapper.map('certificateauthorityfile', item, 'certificateAuthority', 'cryptocert', config.get, None)
diff --git a/src/PJSIPManager.cpp b/src/PJSIPManager.cpp
index b8d3f45..d706c29 100644
--- a/src/PJSIPManager.cpp
+++ b/src/PJSIPManager.cpp
@@ -251,6 +251,11 @@ void PJSIPManager::handleEvents()
pjsip_endpt_handle_events(mEndpoint, &delay);
}
+void PJSIPManager::setUserAgent(const string& userAgent)
+{
+ mSessionModule->setUserAgent(userAgent);
+}
+
pj_caching_pool* PJSIPManager::getCachingPool()
{
return &mCachingPool;
diff --git a/src/PJSIPManager.h b/src/PJSIPManager.h
index f718ae7..ca10ca6 100644
--- a/src/PJSIPManager.h
+++ b/src/PJSIPManager.h
@@ -138,6 +138,15 @@ public:
void handleEvents();
+ /**
+ * This would be better defined somewhere else, but at the moment
+ * configuration can't quite reach the PJSIPSessionModule definition
+ * While configuration could pull it in via include, it brings in a
+ * boat-load of extra build-time dependencies. The proper way to do
+ * this is to have a general configuration proxy class.
+ */
+ void setUserAgent(const std::string& userAgent);
+
private:
pjsip_endpoint *mEndpoint;
PJSIPSessionModulePtr mSessionModule;
diff --git a/src/PJSIPSessionModule.cpp b/src/PJSIPSessionModule.cpp
index 79a58a5..12a0f08 100644
--- a/src/PJSIPSessionModule.cpp
+++ b/src/PJSIPSessionModule.cpp
@@ -409,6 +409,66 @@ protected:
return Complete;
}
+ AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx> sessionRouter = mSessionRouter;
+
+ SIPEndpointConfig endpointConfig = mCaller->getConfig();
+ if (!endpointConfig.sessionConfig.routingServiceName.empty())
+ {
+ lg(Trace) << "overriding default session router";
+ try
+ {
+ AsteriskSCF::Core::Discovery::V1::ServiceLocatorParamsPtr locationParameters =
+ sessionRouter.getLocationParameters();
+ //
+ // Only change them if they are not equal.
+ //
+ if (locationParameters->service != endpointConfig.sessionConfig.routingServiceName)
+ {
+ locationParameters->service = endpointConfig.sessionConfig.routingServiceName;
+ //
+ // This should throw a 'ServiceNotFound' et al. if it is bogus.
+ //
+ sessionRouter = AsteriskSCF::Discovery::SmartProxy<SessionRouterPrx>(
+ sessionRouter.getLocator(), locationParameters, lg);
+ }
+ }
+ catch (const std::exception& ex)
+ {
+ lg(Error) << "Caught an " << ex.what() <<
+ " while trying to locate configured session routing component: "
+ << endpointConfig.sessionConfig.routingServiceName << ", responding with 500";
+ //
+ // Everything else doesn't really map so they just become internal server errors
+ //
+ if (success(pjsip_inv_end_session(mInv, 500, NULL, &mTdata)))
+ {
+ pjsip_inv_send_msg(mInv, mTdata);
+ }
+ else
+ {
+ lg(Warning) << "Unable to create 500 response for INVITE";
+ }
+ }
+ catch (...)
+ {
+ lg(Error) << "Caught an unknown exception " <<
+ " while trying to locate configured session routing component: "
+ << endpointConfig.sessionConfig.routingServiceName << ", responding with 500";
+
+ //
+ // Everything else doesn't really map so they just become internal server errors
+ //
+ if (success(pjsip_inv_end_session(mInv, 500, NULL, &mTdata)))
+ {
+ pjsip_inv_send_msg(mInv, mTdata);
+ }
+ else
+ {
+ lg(Warning) << "Unable to create 500 response for INVITE";
+ }
+ }
+ }
+
mSession->setInviteSession(mInv);
mSession->setDialog(mInv->dlg);
@@ -480,7 +540,7 @@ protected:
SuspendableWorkListenerPtr listener = 0;
SIPAMICallbackPtr cb(new SIPAMICallback(listener, mSession, this, false, true));
Ice::CallbackPtr d = Ice::newCallback(cb, &SIPAMICallback::callback);
- mSessionRouter->begin_routeSession(operationId, mSession->getSessionProxy(), mDestination, 0, mCallerID, mRedirections, d);
+ sessionRouter->begin_routeSession(operationId, mSession->getSessionProxy(), mDestination, 0, mCallerID, mRedirections, d);
}
}
catch (const Ice::CommunicatorDestroyedException &)
@@ -823,6 +883,35 @@ ConnectedLinePtr PJSIPSessionModule::getConnectedID(pjsip_rx_data *rdata)
return connected;
}
+std::string PJSIPSessionModule::getUserAgent()
+{
+ boost::shared_lock<boost::shared_mutex> lock(mUserAgentMutex);
+ return mUserAgent;
+}
+
+void PJSIPSessionModule::setUserAgent(const std::string& userAgent)
+{
+ boost::unique_lock<boost::shared_mutex> lock(mUserAgentMutex);
+ mUserAgent = userAgent;
+}
+
+void PJSIPSessionModule::addDefaultHeaders(pjsip_tx_data *tx)
+{
+ std::string userAgent = getUserAgent();
+ if (userAgent.empty() || !tx)
+ {
+ return;
+ }
+
+ pj_str_t uaHeaderField;
+ pj_cstr(&uaHeaderField, "User-Agent");
+ pj_str_t uaHeaderValue;
+ pj_strset(&uaHeaderValue, (char*)userAgent.c_str(), userAgent.length());
+ pjsip_generic_string_hdr* hdr =
+ pjsip_generic_string_hdr_create(tx->pool, &uaHeaderField, &uaHeaderValue);
+ pjsip_msg_add_hdr(tx->msg, (pjsip_hdr*)hdr);
+}
+
void PJSIPSessionModule::handleNewInvite(pjsip_rx_data *rdata)
{
//We handle most of the processing here synchronously since
@@ -1379,12 +1468,14 @@ pj_bool_t PJSIPSessionModule::on_rx_response(pjsip_rx_data*)
{
return PJ_FALSE;
}
-pj_status_t PJSIPSessionModule::on_tx_request(pjsip_tx_data*)
+pj_status_t PJSIPSessionModule::on_tx_request(pjsip_tx_data* tx)
{
+ addDefaultHeaders(tx);
return PJ_SUCCESS;
}
-pj_status_t PJSIPSessionModule::on_tx_response(pjsip_tx_data*)
+pj_status_t PJSIPSessionModule::on_tx_response(pjsip_tx_data* tx)
{
+ addDefaultHeaders(tx);
return PJ_SUCCESS;
}
void PJSIPSessionModule::on_tsx_state(pjsip_transaction*, pjsip_event*)
diff --git a/src/PJSIPSessionModule.h b/src/PJSIPSessionModule.h
index 7a6cbec..f9874ed 100644
--- a/src/PJSIPSessionModule.h
+++ b/src/PJSIPSessionModule.h
@@ -142,7 +142,13 @@ public:
AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationHookSeq getSessionCreationHooks();
+ std::string getUserAgent();
+ void setUserAgent(const std::string& userAgent);
+
private:
+
+ void addDefaultHeaders(pjsip_tx_data* tx);
+
void handleNewInvite(pjsip_rx_data *rdata);
/**
@@ -237,6 +243,13 @@ private:
AsteriskSCF::SessionCommunications::ExtensionPoints::V1::SessionCreationExtensionPointPrx mSessionCreationExtensionPointPrx;
Ice::ObjectAdapterPtr mAdapter;
AsteriskSCF::Core::Discovery::V1::ServiceManagementPrx mSessionCreationExtensionPointService;
+
+ //
+ // This is really the only thing that needs locking, so the mutex
+ // variable is named with that intent.
+ //
+ boost::shared_mutex mUserAgentMutex;
+ std::string mUserAgent;
};
typedef IceUtil::Handle<PJSIPSessionModule> PJSIPSessionModulePtr;
diff --git a/src/PJSIPSessionModuleConstruction.cpp b/src/PJSIPSessionModuleConstruction.cpp
index 002e09f..4fbfe8d 100644
--- a/src/PJSIPSessionModuleConstruction.cpp
+++ b/src/PJSIPSessionModuleConstruction.cpp
@@ -69,6 +69,16 @@ static pj_bool_t sessionOnRxRequest(pjsip_rx_data *rdata)
return sessionModule->on_rx_request(rdata);
}
+static pj_bool_t sessionOnTxRequest(pjsip_tx_data *tdata)
+{
+ return sessionModule->on_tx_request(tdata);
+}
+
+static pj_bool_t sessionOnTxResponse(pjsip_tx_data *tdata)
+{
+ return sessionModule->on_tx_response(tdata);
+}
+
static void invOnStateChanged(pjsip_inv_session *inv, pjsip_event *e)
{
sessionModule->invOnStateChanged(inv, e);
@@ -140,8 +150,8 @@ PJSIPSessionModule::PJSIPSessionModule(pjsip_endpoint *endpt,
mModule.unload = sessionUnload;
mModule.on_rx_request = sessionOnRxRequest;
mModule.on_rx_response = NULL;
- mModule.on_tx_request = NULL;
- mModule.on_tx_response = NULL;
+ mModule.on_tx_request = sessionOnTxRequest;
+ mModule.on_tx_response = sessionOnTxResponse;
mModule.on_tsx_state = NULL;
mSessionCreationExtensionPointPrx =
diff --git a/src/SIPConfiguration.cpp b/src/SIPConfiguration.cpp
index badd6b0..484d7a2 100644
--- a/src/SIPConfiguration.cpp
+++ b/src/SIPConfiguration.cpp
@@ -291,6 +291,69 @@ private:
}; // class IdentityConfig
+class GeneralGroupConfig : public ConfigBase, public boost::enable_shared_from_this<GeneralGroupConfig>
+{
+ class Visitor : public SIPConfigurationItemVisitor
+ {
+ public:
+ Visitor(const boost::shared_ptr<GeneralGroupConfig>& config) :
+ mConfig(config)
+ {
+ }
+
+ ~Visitor()
+ {
+ mConfig->finish();
+ }
+
+ void visitSIPUserAgent(const SIPUserAgentItemPtr& userAgent)
+ {
+ mConfig->setUserAgentField(userAgent);
+ }
+
+ private:
+ boost::shared_ptr<GeneralGroupConfig> mConfig;
+ };
+public:
+ GeneralGroupConfig(const PJSIPManagerPtr& manager, const SIPGeneralGroupPtr& group):
+ mManager(manager),
+ mGroup(group)
+ {
+ }
+
+ void setUserAgentField(const SIPUserAgentItemPtr& userAgent)
+ {
+ boost::unique_lock<boost::shared_mutex> lock(mLock);
+ mUserAgent = userAgent;
+ mGroup->configurationItems["user-agent"] = userAgent;
+ }
+
+ void finish()
+ {
+ boost::shared_lock<boost::shared_mutex> lock(mLock);
+ if (mUserAgent)
+ {
+ mManager->setUserAgent(mUserAgent->userAgent);
+ }
+ }
+
+ SIPGeneralGroupPtr getTypedGroup() const
+ {
+ return mGroup;
+ }
+
+ SIPConfigurationItemVisitorPtr getVisitor()
+ {
+ return new Visitor(shared_from_this());
+ }
+
+private:
+ boost::shared_mutex mLock;
+ SIPUserAgentItemPtr mUserAgent;
+ SIPGeneralGroupPtr mGroup;
+ PJSIPManagerPtr mManager;
+};
+
/**
* A helper class and visitor for propogating configuration changes to the SIPEndPoint implementation.
**/
@@ -527,11 +590,13 @@ public:
void updateMediaService(const SIPRTPMediaServiceItemPtr& service)
{
+ mEndpoint->setMediaServiceName(service->mediaServiceName);
mEndpoint->setRTPOverIPv6(service->requireIPv6);
}
void updateUDPTLMediaService(const SIPUDPTLMediaServiceItemPtr& service)
{
+ mEndpoint->setUDPTLMediaServiceName(service->mediaServiceName);
mEndpoint->setUDPTLOverIPv6(service->requireIPv6);
mEndpoint->enableUDPTLICE(service->enableICE);
mEndpoint->enableUDPTLTURN(service->enableTURN);
@@ -542,6 +607,11 @@ public:
mEndpoint->setSecureTransport(translateCallDirection(transport->secureTransport));
}
+ void updateRouting(const SIPRoutingItemPtr& item)
+ {
+ mEndpoint->setRoutingServiceName(item->routingServiceName);
+ }
+
void updateSRTP(const SRTPCryptoItemPtr& srtpOptions)
{
SIPEndpointMediaSRTPConfig srtpConfig(mEndpoint->getConfig().srtpConfig);
@@ -1139,7 +1209,7 @@ public:
return updateGroup(v);
}
- void remove(const SIPGeneralGroupPtr&)
+ void remove(const SIPGeneralGroupPtr& group)
{
boost::unique_lock<boost::shared_mutex> lock(mLock);
mGroup = 0;
@@ -1454,9 +1524,15 @@ private:
}
}
- SIPConfigurationItemVisitorPtr updateGroup(const SIPGeneralGroupPtr&)
+ SIPConfigurationItemVisitorPtr updateGroup(const SIPGeneralGroupPtr& group)
{
- return 0;
+ if (!mGroup)
+ {
+ mGroup = createGroupTemplate(group);
+ }
+
+ return boost::shared_ptr<GeneralGroupConfig>(
+ new GeneralGroupConfig(mPJSIPManager, mGroup))->getVisitor();
}
SIPConfigurationItemVisitorPtr updateGroup(const SIPEndpointGroupPtr& group)
diff --git a/src/SIPEndpoint.cpp b/src/SIPEndpoint.cpp
index 1081e9c..e630e39 100644
--- a/src/SIPEndpoint.cpp
+++ b/src/SIPEndpoint.cpp
@@ -448,6 +448,21 @@ void SIPEndpoint::enableUDPTLTURN(bool enabled)
mImplPriv->mConfig.sessionConfig.udptlWithTURN = enabled;
}
+void SIPEndpoint::setMediaServiceName(const string& serviceName)
+{
+ mImplPriv->mConfig.sessionConfig.mediaServiceName = serviceName;
+}
+
+void SIPEndpoint::setUDPTLMediaServiceName(const string& serviceName)
+{
+ mImplPriv->mConfig.sessionConfig.udptlServiceName = serviceName;
+}
+
+void SIPEndpoint::setRoutingServiceName(const string& serviceName)
+{
+ mImplPriv->mConfig.sessionConfig.routingServiceName = serviceName;
+}
+
void SIPEndpoint::setMediaNATOptions(bool useICE, bool useTURN)
{
mImplPriv->mConfig.sessionConfig.rtpOverICE = useICE;
diff --git a/src/SIPEndpoint.h b/src/SIPEndpoint.h
index cbf447f..c5fb88d 100644
--- a/src/SIPEndpoint.h
+++ b/src/SIPEndpoint.h
@@ -181,6 +181,24 @@ public:
//
bool rtpICEIncludeTURN;
+ //
+ // The service name identifier to use in locator queries for the RTP
+ // media component.
+ //
+ std::string mediaServiceName;
+
+ //
+ // The service name identifier to use in locator queries for the UDPTL
+ // component.
+ //
+ std::string udptlServiceName;
+
+ //
+ // The service name identifier to use in locator queries for the
+ // routing component.
+ //
+ std::string routingServiceName;
+
SIPEndpointSessionConfig() :
rtpOverIPv6(false),
rtpOverICE(false),
@@ -355,6 +373,9 @@ public:
void setUDPTLOverIPv6(bool);
void enableUDPTLICE(bool);
void enableUDPTLTURN(bool);
+ void setMediaServiceName(const std::string& serviceName);
+ void setUDPTLMediaServiceName(const std::string& serviceName);
+ void setRoutingServiceName(const std::string& serviceName);
void addFormat(const std::string& name, int sampleRate, int frameSize, const Ice::StringSeq& formatSpecific);
/**
diff --git a/src/SIPSession.cpp b/src/SIPSession.cpp
index a4d0849..a8d7169 100755
--- a/src/SIPSession.cpp
+++ b/src/SIPSession.cpp
@@ -2045,6 +2045,13 @@ public:
{
//lg(Debug) << "Sending new SIP INVITE to " << remote;
+ //
+ // XXX Why create a new instance of Session? A default copy is
+ // going to be a shallow copy which just copies the pointer to the
+ // internal state, ie. that data is still going to be shared. I'm
+ // not sure why thiis is necessary. Actually.. it doesn't seem to
+ // be used at all!
+ //
// Record our session within the dialog so code handling pjsip events can do STUFF
SIPSessionPtr session = new SIPSession(*mSession);
@@ -3081,10 +3088,15 @@ pjmedia_sdp_session *SIPSession::createSDPOffer(const AsteriskSCF::Media::V1::St
// If this stream contains an audio or video format the stream is transported using RTP
if ((audio = AudioFormatPtr::dynamicCast(formats.front())) || (video = VideoFormatPtr::dynamicCast(formats.front())))
{
+ SIPEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
RTPServiceLocatorParamsPtr params = new RTPServiceLocatorParams();
params->category = "rtp";
params->formats = stream->second->formats;
params->ipv6 = mImplPriv->mEndpoint->getConfig().sessionConfig.rtpOverIPv6;
+ if (!config.sessionConfig.mediaServiceName.empty())
+ {
+ params->service = config.sessionConfig.mediaServiceName;
+ }
// Try to find a factory for RTP sessions matching what we need
RTPMediaServicePrx factory = RTPMediaServicePrx::uncheckedCast(mImplPriv->mServiceLocator->locate(params));
@@ -3099,7 +3111,6 @@ pjmedia_sdp_session *SIPSession::createSDPOffer(const AsteriskSCF::Media::V1::St
RTPOptionsPtr options(new RTPOptions());
RTPAllocationOutputsPtr outputs;
- SIPEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SIPSessionManager::V1::RFC4733)
{
options->handleTelephonyEvents = true;
@@ -3201,10 +3212,15 @@ pjmedia_sdp_session *SIPSession::createSDPOffer(const AsteriskSCF::Media::V1::St
{
params = new AsteriskSCF::Media::UDPTL::V1::UDPTLServiceLocatorParams;
}
+ SIPEndpointConfig config = mImplPriv->mEndpoint->getConfig();
params->category = "udptl";
- params->ipv6 = mImplPriv->mEndpoint->getConfig().sessionConfig.udptlOverIPv6;
-
+ params->ipv6 = config.sessionConfig.udptlOverIPv6;
+ if (!config.sessionConfig.udptlServiceName.empty())
+ {
+ params->service = config.sessionConfig.udptlServiceName;
+ }
+
UDPTLMediaServicePrx factory = UDPTLMediaServicePrx::uncheckedCast(mImplPriv->mServiceLocator->locate(params));
if (factory == 0)
{
@@ -3589,11 +3605,15 @@ pjmedia_sdp_session *SIPSession::createSDPAnswer(const pjmedia_sdp_session* offe
RTPOptionsPtr options(new RTPOptions());
RTPAllocationOutputsPtr outputs;
- SIPEndpointConfig& config = mImplPriv->mEndpoint->getConfig();
+ SIPEndpointConfig config = mImplPriv->mEndpoint->getConfig();
if (config.sessionConfig.dtmf == AsteriskSCF::Configuration::SIPSessionManager::V1::RFC4733)
{
options->handleTelephonyEvents = true;
}
+ if (!config.sessionConfig.mediaServiceName.empty())
+ {
+ params->service = config.sessionConfig.mediaServiceName;
+ }
session = factory->allocate(params, options, outputs);
-----------------------------------------------------------------------
--
asterisk-scf/release/sip.git
More information about the asterisk-scf-commits
mailing list