Commit 6f3bffff authored by Alexandre Savard's avatar Alexandre Savard

#9547: Extract all the transport layer from SIPVoIPLink to new SipTransport Class

parent 7a58f609
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "config.h" #include "config.h"
#include "../manager.h" #include "../manager.h"
#include "sip/sipvoiplink.h" #include "sip/sipvoiplink.h"
#include "sip/siptransport.h"
#include "account.h" #include "account.h"
#include "sip/sipaccount.h" #include "sip/sipaccount.h"
...@@ -411,17 +412,17 @@ std::vector<std::map<std::string, std::string> > ConfigurationManager::getHistor ...@@ -411,17 +412,17 @@ std::vector<std::map<std::string, std::string> > ConfigurationManager::getHistor
std::string std::string
ConfigurationManager::getAddrFromInterfaceName(const std::string& interface) ConfigurationManager::getAddrFromInterfaceName(const std::string& interface)
{ {
return SIPVoIPLink::getInterfaceAddrFromName(interface); return SipTransport::getInterfaceAddrFromName(interface);
} }
std::vector<std::string> ConfigurationManager::getAllIpInterface() std::vector<std::string> ConfigurationManager::getAllIpInterface()
{ {
return SIPVoIPLink::getAllIpInterface(); return SipTransport::getAllIpInterface();
} }
std::vector<std::string> ConfigurationManager::getAllIpInterfaceByName() std::vector<std::string> ConfigurationManager::getAllIpInterfaceByName()
{ {
return SIPVoIPLink::getAllIpInterfaceByName(); return SipTransport::getAllIpInterfaceByName();
} }
std::map<std::string, std::string> ConfigurationManager::getShortcuts() std::map<std::string, std::string> ConfigurationManager::getShortcuts()
......
...@@ -2563,7 +2563,7 @@ void ManagerImpl::loadDefaultAccountMap() ...@@ -2563,7 +2563,7 @@ void ManagerImpl::loadDefaultAccountMap()
{ {
// build a default IP2IP account with default parameters // build a default IP2IP account with default parameters
accountMap_[SIPAccount::IP2IP_PROFILE] = new SIPAccount(SIPAccount::IP2IP_PROFILE); accountMap_[SIPAccount::IP2IP_PROFILE] = new SIPAccount(SIPAccount::IP2IP_PROFILE);
SIPVoIPLink::instance()->createDefaultSipUdpTransport(); SIPVoIPLink::instance()->sipTransport.createDefaultSipUdpTransport();
accountMap_[SIPAccount::IP2IP_PROFILE]->registerVoIPLink(); accountMap_[SIPAccount::IP2IP_PROFILE]->registerVoIPLink();
} }
...@@ -2627,7 +2627,7 @@ void ManagerImpl::loadAccountMap(Conf::YamlParser &parser) ...@@ -2627,7 +2627,7 @@ void ManagerImpl::loadAccountMap(Conf::YamlParser &parser)
// Initialize default UDP transport according to // Initialize default UDP transport according to
// IP to IP settings (most likely using port 5060) // IP to IP settings (most likely using port 5060)
SIPVoIPLink::instance()->createDefaultSipUdpTransport(); SIPVoIPLink::instance()->sipTransport.createDefaultSipUdpTransport();
// Force IP2IP settings to be loaded to be loaded // Force IP2IP settings to be loaded to be loaded
// No registration in the sense of the REGISTER method is performed. // No registration in the sense of the REGISTER method is performed.
......
...@@ -9,12 +9,14 @@ libsiplink_la_SOURCES = \ ...@@ -9,12 +9,14 @@ libsiplink_la_SOURCES = \
sipaccount.cpp \ sipaccount.cpp \
sipcall.cpp \ sipcall.cpp \
sipvoiplink.cpp \ sipvoiplink.cpp \
siptransport.cpp \
pattern.h \ pattern.h \
sdes_negotiator.h \ sdes_negotiator.h \
sdp.h \ sdp.h \
sipaccount.h \ sipaccount.h \
sipcall.h \ sipcall.h \
sipvoiplink.h \ sipvoiplink.h \
siptransport.h \
sip_utils.cpp \ sip_utils.cpp \
sip_utils.h sip_utils.h
......
...@@ -407,7 +407,7 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details) ...@@ -407,7 +407,7 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
publishedPort_ = atoi(details[CONFIG_PUBLISHED_PORT].c_str()); publishedPort_ = atoi(details[CONFIG_PUBLISHED_PORT].c_str());
if(stunServer_ != details[CONFIG_STUN_SERVER]) { if(stunServer_ != details[CONFIG_STUN_SERVER]) {
DEBUG("Stun server changed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); DEBUG("Stun server changed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
link_->destroyStunResolver(stunServer_); link_->sipTransport.destroyStunResolver(stunServer_);
// pj_stun_sock_destroy(pj_stun_sock *stun_sock); // pj_stun_sock_destroy(pj_stun_sock *stun_sock);
} }
stunServer_ = details[CONFIG_STUN_SERVER]; stunServer_ = details[CONFIG_STUN_SERVER];
...@@ -816,7 +816,7 @@ std::string SIPAccount::getContactHeader() const ...@@ -816,7 +816,7 @@ std::string SIPAccount::getContactHeader() const
// Else we determine this infor based on transport information // Else we determine this infor based on transport information
std::string address, port; std::string address, port;
link_->findLocalAddressFromTransport(transport_, transportType, address, port); link_->sipTransport.findLocalAddressFromTransport(transport_, transportType, address, port);
// UDP does not require the transport specification // UDP does not require the transport specification
std::string scheme; std::string scheme;
......
...@@ -76,8 +76,6 @@ using namespace sfl; ...@@ -76,8 +76,6 @@ using namespace sfl;
namespace { namespace {
static pjsip_transport *localUDPTransport_ = NULL; /** The default transport (5060) */
/** A map to retreive SFLphone internal call id /** A map to retreive SFLphone internal call id
* Given a SIP call ID (usefull for transaction sucha as transfer)*/ * Given a SIP call ID (usefull for transaction sucha as transfer)*/
static std::map<std::string, std::string> transferCallID; static std::map<std::string, std::string> transferCallID;
...@@ -121,18 +119,6 @@ int SIPSessionReinvite(SIPCall *); ...@@ -121,18 +119,6 @@ int SIPSessionReinvite(SIPCall *);
*/ */
void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata); void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata);
std::string getSIPLocalIP()
{
pj_sockaddr ip_addr;
if (pj_gethostip(pj_AF_INET(), &ip_addr) == PJ_SUCCESS)
return pj_inet_ntoa(ip_addr.ipv4.sin_addr);
else {
ERROR("SIPVoIPLink: Could not get local IP");
return "";
}
}
pjsip_route_hdr *createRouteSet(const std::string &route, pj_pool_t *hdr_pool) pjsip_route_hdr *createRouteSet(const std::string &route, pj_pool_t *hdr_pool)
{ {
int port = 0; int port = 0;
...@@ -309,15 +295,15 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata) ...@@ -309,15 +295,15 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
Manager::instance().associateCallToAccount(call->getCallId(), account_id); Manager::instance().associateCallToAccount(call->getCallId(), account_id);
// May use the published address as well // May use the published address as well
std::string addrToUse = SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface()); std::string addrToUse = SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
std::string addrSdp = account->isStunEnabled() std::string addrSdp = account->isStunEnabled()
? account->getPublishedAddress() ? account->getPublishedAddress()
: addrToUse; : addrToUse;
pjsip_tpselector *tp = SIPVoIPLink::instance()->initTransportSelector(account->transport_, call->getMemoryPool()); pjsip_tpselector *tp = SIPVoIPLink::instance()->sipTransport.initTransportSelector(account->transport_, call->getMemoryPool());
if (addrToUse == "0.0.0.0") if (addrToUse == "0.0.0.0")
addrToUse = getSIPLocalIP(); addrToUse = SipTransport::getSIPLocalIP();
if (addrSdp == "0.0.0.0") if (addrSdp == "0.0.0.0")
addrSdp = addrToUse; addrSdp = addrToUse;
...@@ -427,7 +413,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata) ...@@ -427,7 +413,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
/*************************************************************************************************/ /*************************************************************************************************/
SIPVoIPLink::SIPVoIPLink() : transportMap_(), stunSocketMap_(), evThread_(new EventThread(this)) SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), evThread_(new EventThread(this))
{ {
#define TRY(ret) do { \ #define TRY(ret) do { \
if (ret != PJ_SUCCESS) \ if (ret != PJ_SUCCESS) \
...@@ -450,7 +436,11 @@ SIPVoIPLink::SIPVoIPLink() : transportMap_(), stunSocketMap_(), evThread_(new Ev ...@@ -450,7 +436,11 @@ SIPVoIPLink::SIPVoIPLink() : transportMap_(), stunSocketMap_(), evThread_(new Ev
TRY(pjsip_endpt_create(&cp_->factory, pj_gethostname()->ptr, &endpt_)); TRY(pjsip_endpt_create(&cp_->factory, pj_gethostname()->ptr, &endpt_));
if (getSIPLocalIP().empty()) sipTransport.setEndpoint(endpt_);
sipTransport.setCachingPool(cp_);
sipTransport.setPool(pool_);
if (SipTransport::getSIPLocalIP().empty())
throw VoipLinkException("UserAgent: Unable to determine network capabilities"); throw VoipLinkException("UserAgent: Unable to determine network capabilities");
TRY(pjsip_tsx_layer_init_module(endpt_)); TRY(pjsip_tsx_layer_init_module(endpt_));
...@@ -540,7 +530,7 @@ SIPVoIPLink::getEvent() ...@@ -540,7 +530,7 @@ SIPVoIPLink::getEvent()
void SIPVoIPLink::sendRegister(Account *a) void SIPVoIPLink::sendRegister(Account *a)
{ {
SIPAccount *account = dynamic_cast<SIPAccount*>(a); SIPAccount *account = dynamic_cast<SIPAccount*>(a);
createSipTransport(account); sipTransport.createSipTransport(account);
account->setRegister(true); account->setRegister(true);
account->setRegistrationState(Trying); account->setRegistrationState(Trying);
...@@ -588,7 +578,7 @@ void SIPVoIPLink::sendRegister(Account *a) ...@@ -588,7 +578,7 @@ void SIPVoIPLink::sendRegister(Account *a)
if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS) if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS)
throw VoipLinkException("Unable to initialize transaction data for account registration"); throw VoipLinkException("Unable to initialize transaction data for account registration");
if (pjsip_regc_set_transport(regc, initTransportSelector(account->transport_, pool_)) != PJ_SUCCESS) if (pjsip_regc_set_transport(regc, sipTransport.initTransportSelector(account->transport_, pool_)) != PJ_SUCCESS)
throw VoipLinkException("Unable to set transport"); throw VoipLinkException("Unable to set transport");
// decrease transport's ref count, counter incrementation is managed when acquiring transport // decrease transport's ref count, counter incrementation is managed when acquiring transport
...@@ -683,20 +673,20 @@ Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toU ...@@ -683,20 +673,20 @@ Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toU
toUri = account->getToUri(toUrl); toUri = account->getToUri(toUrl);
call->setPeerNumber(toUri); call->setPeerNumber(toUri);
std::string localAddr(getInterfaceAddrFromName(account->getLocalInterface())); std::string localAddr(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
if (localAddr == "0.0.0.0") if (localAddr == "0.0.0.0")
localAddr = getSIPLocalIP(); localAddr = SipTransport::getSIPLocalIP();
setCallMediaLocal(call, localAddr); setCallMediaLocal(call, localAddr);
// May use the published address as well // May use the published address as well
std::string addrSdp = account->isStunEnabled() ? std::string addrSdp = account->isStunEnabled() ?
account->getPublishedAddress() : account->getPublishedAddress() :
getInterfaceAddrFromName(account->getLocalInterface()); SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
if (addrSdp == "0.0.0.0") if (addrSdp == "0.0.0.0")
addrSdp = getSIPLocalIP(); addrSdp = SipTransport::getSIPLocalIP();
// Initialize the session using ULAW as default codec in case of early media // Initialize the session using ULAW as default codec in case of early media
// The session should be ready to receive media once the first INVITE is sent, before // The session should be ready to receive media once the first INVITE is sent, before
...@@ -1094,7 +1084,7 @@ SIPVoIPLink::SIPStartCall(SIPCall *call) ...@@ -1094,7 +1084,7 @@ SIPVoIPLink::SIPStartCall(SIPCall *call)
if (pjsip_inv_invite(call->inv, &tdata) != PJ_SUCCESS) if (pjsip_inv_invite(call->inv, &tdata) != PJ_SUCCESS)
return false; return false;
pjsip_tpselector *tp = initTransportSelector(account->transport_, call->inv->pool); pjsip_tpselector *tp = sipTransport.initTransportSelector(account->transport_, call->inv->pool);
if (pjsip_dlg_set_transport(dialog, tp) != PJ_SUCCESS) if (pjsip_dlg_set_transport(dialog, tp) != PJ_SUCCESS)
return false; return false;
...@@ -1164,10 +1154,10 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to) ...@@ -1164,10 +1154,10 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
call->setIPToIP(true); call->setIPToIP(true);
call->initRecFilename(to); call->initRecFilename(to);
std::string localAddress(getInterfaceAddrFromName(account->getLocalInterface())); std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
if (localAddress == "0.0.0.0") if (localAddress == "0.0.0.0")
localAddress = getSIPLocalIP(); localAddress = SipTransport::getSIPLocalIP();
setCallMediaLocal(call, localAddress); setCallMediaLocal(call, localAddress);
...@@ -1205,8 +1195,8 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to) ...@@ -1205,8 +1195,8 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
return false; return false;
} }
shutdownSipTransport(account); sipTransport.shutdownSipTransport(account);
pjsip_transport *transport = createTlsTransport(remoteAddr, account->getTlsListenerPort(), pjsip_transport *transport = sipTransport.createTlsTransport(remoteAddr, account->getTlsListenerPort(),
account->getTlsSetting()); account->getTlsSetting());
if (transport == NULL) { if (transport == NULL) {
...@@ -1231,410 +1221,6 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to) ...@@ -1231,410 +1221,6 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
// Private functions // Private functions
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
pj_bool_t
stun_sock_on_status_cb(pj_stun_sock * /*stun_sock*/, pj_stun_sock_op op,
pj_status_t status)
{
switch (op) {
case PJ_STUN_SOCK_DNS_OP:
DEBUG("UserAgent: Stun operation dns resolution");
break;
case PJ_STUN_SOCK_BINDING_OP:
DEBUG("UserAgent: Stun operation binding");
break;
case PJ_STUN_SOCK_KEEP_ALIVE_OP:
DEBUG("UserAgent: Stun operation keep alive");
break;
case PJ_STUN_SOCK_MAPPED_ADDR_CHANGE:
DEBUG("UserAgent: Stun operation address mapping change");
break;
default:
DEBUG("UserAgent: Stun unknown operation");
break;
}
if (status == PJ_SUCCESS) {
DEBUG("UserAgent: Stun operation success");
} else {
ERROR("UserAgent: Stun operation failure");
}
// Always return true so the stun transport registration retry even on failure
return true;
}
static pj_bool_t
stun_sock_on_rx_data_cb(pj_stun_sock * /*stun_sock*/, void * /*pkt*/,
unsigned /*pkt_len*/,
const pj_sockaddr_t * /*src_addr*/,
unsigned /*addr_len*/)
{
return PJ_TRUE;
}
pj_status_t SIPVoIPLink::createStunResolver(pj_str_t serverName, pj_uint16_t port)
{
pj_stun_config stunCfg;
pj_stun_config_init(&stunCfg, &cp_->factory, 0, pjsip_endpt_get_ioqueue(endpt_), pjsip_endpt_get_timer_heap(endpt_));
DEBUG("***************** Create Stun Resolver *********************");
static const pj_stun_sock_cb stun_sock_cb = {
stun_sock_on_rx_data_cb,
NULL,
stun_sock_on_status_cb
};
pj_stun_sock *stun_sock;
std::string stunResolverName(serverName.ptr, serverName.slen);
pj_status_t status = pj_stun_sock_create(&stunCfg, stunResolverName.c_str(), pj_AF_INET(), &stun_sock_cb, NULL, NULL, &stun_sock);
// store socket inside list
DEBUG(" insert %s resolver in map", stunResolverName.c_str());
stunSocketMap_.insert(std::pair<std::string, pj_stun_sock *>(stunResolverName, stun_sock));
if (status != PJ_SUCCESS) {
char errmsg[PJ_ERR_MSG_SIZE];
pj_strerror(status, errmsg, sizeof(errmsg));
ERROR("UserAgent: Error creating STUN socket for %.*s: %s", (int) serverName.slen, serverName.ptr, errmsg);
return status;
}
status = pj_stun_sock_start(stun_sock, &serverName, port, NULL);
if (status != PJ_SUCCESS) {
char errmsg[PJ_ERR_MSG_SIZE];
pj_strerror(status, errmsg, sizeof(errmsg));
DEBUG("UserAgent: Error starting STUN socket for %.*s: %s", (int) serverName.slen, serverName.ptr, errmsg);
pj_stun_sock_destroy(stun_sock);
}
return status;
}
pj_status_t SIPVoIPLink::destroyStunResolver(const std::string serverName)
{
std::map<std::string, pj_stun_sock *>::iterator it;
it = stunSocketMap_.find(serverName);
DEBUG("***************** Destroy Stun Resolver *********************");
if (it != stunSocketMap_.end()) {
DEBUG("UserAgent: Deleting stun resolver %s", it->first.c_str());
pj_stun_sock_destroy(it->second);
stunSocketMap_.erase(it);
}
return PJ_SUCCESS;
}
void SIPVoIPLink::createDefaultSipUdpTransport()
{
pj_uint16_t port = 0;
int counter = 0;
SIPAccount *account = Manager::instance().getIP2IPAccount();
pjsip_transport *transport = NULL;
static const int DEFAULT_TRANSPORT_ATTEMPTS = 5;
for (; transport == NULL and counter < DEFAULT_TRANSPORT_ATTEMPTS; ++counter) {
// if default udp transport fails to init on 5060, try other ports
// with 2 step size increment (i.e. 5062, 5064, ...)
port = account->getLocalPort() + (counter * 2);
transport = createUdpTransport(account->getLocalInterface(), port);
}
if (transport == NULL) {
ERROR("UserAgent: Create UDP transport");
return;
}
DEBUG("UserAgent: Created default sip transport on %d", port);
// set transport for this account
account->transport_ = transport;
// set local udp transport
localUDPTransport_ = account->transport_;
}
void SIPVoIPLink::createTlsListener(pj_uint16_t tlsListenerPort, pjsip_tls_setting *tlsSetting, pjsip_tpfactory **listener)
{
pj_sockaddr_in local_addr;
pj_sockaddr_in_init(&local_addr, 0, 0);
local_addr.sin_port = pj_htons(tlsListenerPort);
if (tlsSetting == NULL) {
ERROR("Error TLS settings not specified");
return;
}
if (listener == NULL) {
ERROR("Error no pointer to store new TLS listener");
return;
}
pj_str_t pjAddress;
pj_cstr(&pjAddress, PJ_INADDR_ANY);
pj_sockaddr_in_set_str_addr(&local_addr, &pjAddress);
std::string localIP(getSIPLocalIP());
pjsip_host_port a_name = {
pj_str((char*) localIP.c_str()),
local_addr.sin_port
};
pjsip_tls_transport_start(endpt_, tlsSetting, &local_addr, &a_name, 1, listener);
}
pjsip_transport *
SIPVoIPLink::createTlsTransport(const std::string &remoteAddr,
pj_uint16_t tlsListenerPort,
pjsip_tls_setting *tlsSettings)
{
pjsip_transport *transport = NULL;
pj_str_t remote;
pj_cstr(&remote, remoteAddr.c_str());
pj_sockaddr_in rem_addr;
pj_sockaddr_in_init(&rem_addr, &remote, (pj_uint16_t) DEFAULT_SIP_TLS_PORT);
// The local tls listener
static pjsip_tpfactory *localTlsListener = NULL;
if (localTlsListener == NULL)
createTlsListener(tlsListenerPort, tlsSettings, &localTlsListener);
pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr,
sizeof rem_addr, NULL, &transport);
if (transport == NULL)
ERROR("Error: Could not create new TLS transport\n");
return transport;
}
void SIPVoIPLink::createSipTransport(SIPAccount *account)
{
if (account == NULL) {
ERROR("UserAgent: Account is NULL while creating sip transport");
return;
}
shutdownSipTransport(account);
if (account->isTlsEnabled()) {
std::string remoteSipUri(account->getServerUri());
static const char SIPS_PREFIX[] = "<sips:";
size_t sips = remoteSipUri.find(SIPS_PREFIX) + (sizeof SIPS_PREFIX) - 1;
size_t trns = remoteSipUri.find(";transport");
std::string remoteAddr(remoteSipUri.substr(sips, trns-sips));
pjsip_transport *transport = createTlsTransport(remoteAddr, account->getTlsListenerPort(), account->getTlsSetting());
account->transport_ = transport;
} else if (account->isStunEnabled()) {
pjsip_transport *transport = createStunTransport(account->getStunServerName(), account->getStunPort());
account->transport_ = transport;
}
else {
pjsip_transport *transport = createUdpTransport(account->getLocalInterface(), account->getLocalPort());
account->transport_ = transport;
}
if (!account->transport_) {
// Could not create new transport, this transport may already exists
account->transport_ = transportMap_[account->getLocalPort()];
if (account->transport_)
pjsip_transport_add_ref(account->transport_);
else {
account->transport_ = localUDPTransport_;
account->setLocalPort(localUDPTransport_->local_name.port);
}
}
}
pjsip_transport *SIPVoIPLink::createUdpTransport(std::string interface, unsigned int port)
{
// init socket to bind this transport to
pj_sockaddr_in bound_addr;
pj_bzero(&bound_addr, sizeof(bound_addr));
pj_uint16_t listeningPort = (pj_uint16_t) port;
bound_addr.sin_port = pj_htons(listeningPort);
bound_addr.sin_family = PJ_AF_INET;
// determine the ip address for this transport
static const char * const DEFAULT_INTERFACE = "default";
std::string listeningAddress;
if (interface == DEFAULT_INTERFACE) {
listeningAddress = getSIPLocalIP();
bound_addr.sin_addr.s_addr = pj_htonl(PJ_INADDR_ANY);
} else {
listeningAddress = getInterfaceAddrFromName(interface);
bound_addr.sin_addr = pj_inet_addr2(listeningAddress.c_str());
}
if (listeningAddress.empty()) {
ERROR("SIP: Could not determine ip address for this transport");
return NULL;
}
if (listeningPort == 0) {
ERROR("SIP: Could not determine port for this transport");
return NULL;
}
// The published address for this transport
const pjsip_host_port a_name = {
pj_str((char*) listeningAddress.c_str()),
listeningPort
};
pjsip_transport *transport = NULL;
pj_status_t status = pjsip_udp_transport_start(endpt_, &bound_addr, &a_name, 1, &transport);
if (status != PJ_SUCCESS) {
ERROR("SIP: Could not create UDP transport for port %u", port);
return NULL;
}
// dump debug information to stdout
pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
transportMap_[listeningPort] = transport;
return transport;
}
pjsip_tpselector *SIPVoIPLink::initTransportSelector(pjsip_transport *transport, pj_pool_t *