mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
Merge branch 'master' into merge-upstream
Conflicts: daemon/src/audio/codecs/audiocodec.h daemon/src/audio/codecs/audiocodecfactory.cpp daemon/src/dbus/callmanager.cpp daemon/src/dbus/callmanager.h daemon/src/managerimpl.cpp daemon/src/sip/sipvoiplink.cpp
This commit is contained in:
@ -62,8 +62,10 @@ Sdp::Sdp(pj_pool_t *pool)
|
||||
, sessionVideoMedia_()
|
||||
, localIpAddr_()
|
||||
, remoteIpAddr_()
|
||||
, localAudioPort_(0)
|
||||
, localVideoPort_(0)
|
||||
, localAudioDataPort_(0)
|
||||
, localAudioControlPort_(0)
|
||||
, localVideoDataPort_(0)
|
||||
, localVideoControlPort_(0)
|
||||
, remoteAudioPort_(0)
|
||||
, remoteVideoPort_(0)
|
||||
, zrtpHelloHash_()
|
||||
@ -205,7 +207,7 @@ Sdp::setMediaDescriptorLines(bool audio)
|
||||
|
||||
med->desc.media = audio ? pj_str((char*) "audio") : pj_str((char*) "video");
|
||||
med->desc.port_count = 1;
|
||||
med->desc.port = audio ? localAudioPort_ : localVideoPort_;
|
||||
med->desc.port = audio ? localAudioDataPort_ : localVideoDataPort_;
|
||||
// in case of sdes, media are tagged as "RTP/SAVP", RTP/AVP elsewhere
|
||||
med->desc.transport = pj_str(srtpCrypto_.empty() ? (char*) "RTP/AVP" : (char*) "RTP/SAVP");
|
||||
|
||||
@ -283,10 +285,8 @@ Sdp::setMediaDescriptorLines(bool audio)
|
||||
|
||||
void Sdp::addRTCPAttribute(pjmedia_sdp_media *med)
|
||||
{
|
||||
// FIXME: get this from CCRTP directly, don't just assume that the RTCP port is
|
||||
// RTP + 1
|
||||
std::ostringstream os;
|
||||
os << localIpAddr_ << ":" << (localAudioPort_ + 1);
|
||||
os << localIpAddr_ << ":" << localAudioControlPort_;
|
||||
const std::string str(os.str());
|
||||
pj_str_t input_str = pj_str((char*) str.c_str());
|
||||
pj_sockaddr outputAddr;
|
||||
@ -300,6 +300,15 @@ void Sdp::addRTCPAttribute(pjmedia_sdp_media *med)
|
||||
pjmedia_sdp_attr_add(&med->attr_count, med->attr, attr);
|
||||
}
|
||||
|
||||
void
|
||||
Sdp::updatePorts(const std::vector<pj_sockaddr_in> &sockets)
|
||||
{
|
||||
localAudioDataPort_ = pj_ntohs(sockets[0].sin_port);
|
||||
localAudioControlPort_ = pj_ntohs(sockets[1].sin_port);
|
||||
localVideoDataPort_ = pj_ntohs(sockets[2].sin_port);
|
||||
localVideoControlPort_ = pj_ntohs(sockets[3].sin_port);
|
||||
}
|
||||
|
||||
|
||||
void Sdp::setTelephoneEventRtpmap(pjmedia_sdp_media *med)
|
||||
{
|
||||
|
@ -163,13 +163,17 @@ class Sdp {
|
||||
}
|
||||
|
||||
void setLocalPublishedAudioPort(int port) {
|
||||
localAudioPort_ = port;
|
||||
localAudioDataPort_ = port;
|
||||
localAudioControlPort_ = port + 1;
|
||||
}
|
||||
|
||||
void setLocalPublishedVideoPort (int port) {
|
||||
localVideoPort_ = port;
|
||||
localVideoDataPort_ = port;
|
||||
localVideoControlPort_ = port + 1;
|
||||
}
|
||||
|
||||
void updatePorts(const std::vector<pj_sockaddr_in> &sockets);
|
||||
|
||||
/**
|
||||
* Return IP of destination
|
||||
* @return const std:string The remote IP address
|
||||
@ -202,6 +206,10 @@ class Sdp {
|
||||
return remoteVideoPort_;
|
||||
}
|
||||
|
||||
unsigned int getLocalVideoPort() const {
|
||||
return localVideoDataPort_;
|
||||
}
|
||||
|
||||
void addAttributeToLocalAudioMedia(const char *attr);
|
||||
void removeAttributeFromLocalAudioMedia(const char *attr);
|
||||
void addAttributeToLocalVideoMedia(const char *attr);
|
||||
@ -304,8 +312,10 @@ class Sdp {
|
||||
std::string localIpAddr_;
|
||||
std::string remoteIpAddr_;
|
||||
|
||||
int localAudioPort_;
|
||||
int localVideoPort_;
|
||||
int localAudioDataPort_;
|
||||
int localAudioControlPort_;
|
||||
int localVideoDataPort_;
|
||||
int localVideoControlPort_;
|
||||
unsigned int remoteAudioPort_;
|
||||
unsigned int remoteVideoPort_;
|
||||
|
||||
|
@ -126,12 +126,21 @@ sip_utils::stripSipUriPrefix(std::string& sipUri)
|
||||
size_t found = sipUri.find(SIP_PREFIX);
|
||||
|
||||
if (found != std::string::npos)
|
||||
sipUri.erase(found, found + (sizeof SIP_PREFIX) - 1);
|
||||
sipUri.erase(found, (sizeof SIP_PREFIX) - 1);
|
||||
|
||||
// URI may or may not be between brackets
|
||||
found = sipUri.find("<");
|
||||
if (found != std::string::npos)
|
||||
sipUri.erase(found, 1);
|
||||
|
||||
found = sipUri.find("@");
|
||||
|
||||
if (found != std::string::npos)
|
||||
sipUri.erase(found);
|
||||
|
||||
found = sipUri.find(">");
|
||||
if (found != std::string::npos)
|
||||
sipUri.erase(found, 1);
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
#include <pjsip/sip_msg.h>
|
||||
|
||||
class pjsip_msg;
|
||||
struct pjsip_msg;
|
||||
|
||||
namespace sip_utils {
|
||||
/**
|
||||
|
@ -318,7 +318,7 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
|
||||
if (not isIP2IP()) mapNode.getValue(MAILBOX_KEY, &mailBox_);
|
||||
mapNode.getValue(AUDIO_CODECS_KEY, &audioCodecStr_);
|
||||
// Update codec list which one is used for SDP offer
|
||||
setActiveAudioCodecs(ManagerImpl::split_string(audioCodecStr_));
|
||||
setActiveAudioCodecs(split_string(audioCodecStr_));
|
||||
#ifdef SFL_VIDEO
|
||||
YamlNode *videoCodecsNode(mapNode.getValue(VIDEO_CODECS_KEY));
|
||||
|
||||
|
@ -316,9 +316,6 @@ class SIPAccount : public Account {
|
||||
pj_uint16_t getStunPort() const {
|
||||
return stunPort_;
|
||||
}
|
||||
void setStunPort(pj_uint16_t port) {
|
||||
stunPort_ = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool Tells if current transport for that
|
||||
@ -442,6 +439,11 @@ class SIPAccount : public Account {
|
||||
return publishedIpAddress_;
|
||||
}
|
||||
|
||||
void setPublishedAddress(const std::string &ip_addr) {
|
||||
publishedIpAddress_ = ip_addr;
|
||||
}
|
||||
|
||||
|
||||
std::string getServiceRoute() const {
|
||||
return serviceRoute_;
|
||||
}
|
||||
|
@ -45,7 +45,8 @@ namespace {
|
||||
}
|
||||
|
||||
SIPCall::SIPCall(const std::string& id, Call::CallType type,
|
||||
pj_caching_pool *caching_pool) : Call(id, type)
|
||||
pj_caching_pool *caching_pool, const std::string &account_id) :
|
||||
Call(id, type, account_id)
|
||||
, inv(NULL)
|
||||
, audiortp_(this)
|
||||
#ifdef SFL_VIDEO
|
||||
|
@ -44,10 +44,10 @@
|
||||
|
||||
#include "noncopyable.h"
|
||||
|
||||
class pjsip_evsub;
|
||||
class pj_caching_pool;
|
||||
class pj_pool_t;
|
||||
class pjsip_inv_session;
|
||||
struct pjsip_evsub;
|
||||
struct pj_caching_pool;
|
||||
struct pj_pool_t;
|
||||
struct pjsip_inv_session;
|
||||
class Sdp;
|
||||
|
||||
/**
|
||||
@ -63,7 +63,8 @@ class SIPCall : public Call {
|
||||
* @param type The type of the call. Could be Incoming
|
||||
* Outgoing
|
||||
*/
|
||||
SIPCall(const std::string& id, Call::CallType type, pj_caching_pool *caching_pool);
|
||||
SIPCall(const std::string& id, Call::CallType type,
|
||||
pj_caching_pool *caching_pool, const std::string &account_id);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
|
@ -465,6 +465,27 @@ pjsip_tpselector *SipTransport::createTransportSelector(pjsip_transport *transpo
|
||||
return tp;
|
||||
}
|
||||
|
||||
std::vector<pj_sockaddr_in>
|
||||
SipTransport::getSTUNAddresses(const SIPAccount &account,
|
||||
std::vector<long> &socketDescriptors) const
|
||||
{
|
||||
const pj_str_t serverName = account.getStunServerName();
|
||||
const pj_uint16_t port = account.getStunPort();
|
||||
|
||||
std::vector<pj_sockaddr_in> result(socketDescriptors.size());
|
||||
|
||||
if (pjstun_get_mapped_addr(&cp_->factory, socketDescriptors.size(), &socketDescriptors[0],
|
||||
&serverName, port, &serverName, port, &result[0]) != PJ_SUCCESS)
|
||||
throw std::runtime_error("Can't contact STUN server");
|
||||
|
||||
for (std::vector<pj_sockaddr_in>::const_iterator it = result.begin();
|
||||
it != result.end(); ++it)
|
||||
WARN("STUN PORTS: %ld", pj_ntohs(it->sin_port));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
pjsip_transport *SipTransport::createStunTransport(SIPAccount &account)
|
||||
{
|
||||
#if HAVE_DBUS
|
||||
@ -480,7 +501,6 @@ pjsip_transport *SipTransport::createStunTransport(SIPAccount &account)
|
||||
pj_str_t serverName = account.getStunServerName();
|
||||
pj_uint16_t port = account.getStunPort();
|
||||
|
||||
DEBUG("Create STUN transport server name: %s, port: %d", serverName, port);
|
||||
RETURN_IF_STUN_FAIL(createStunResolver(serverName, port) == PJ_SUCCESS, "Can't resolve STUN server");
|
||||
|
||||
pj_sock_t sock = PJ_INVALID_SOCKET;
|
||||
|
@ -112,6 +112,13 @@ class SipTransport {
|
||||
*/
|
||||
void shutdownSTUNResolver(SIPAccount &account);
|
||||
|
||||
/**
|
||||
* This function returns a list of STUN mapped sockets for
|
||||
* a given set of socket file descriptors */
|
||||
std::vector<pj_sockaddr_in>
|
||||
getSTUNAddresses(const SIPAccount &account,
|
||||
std::vector<long> &socks) const;
|
||||
|
||||
/**
|
||||
* This function unset the transport for a given account.
|
||||
*/
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "sipvoiplink.h"
|
||||
#include "array_size.h"
|
||||
#include "manager.h"
|
||||
#include "map_utils.h"
|
||||
#include "logger.h"
|
||||
#include "scoped_lock.h"
|
||||
|
||||
@ -218,6 +219,23 @@ void showLog(int level, const char *data, int len)
|
||||
}
|
||||
#endif
|
||||
|
||||
void updateSDPFromSTUN(SIPCall &call, SIPAccount &account, const SipTransport &transport)
|
||||
{
|
||||
std::vector<long> socketDescriptors(call.getAudioRtp().getSocketDescriptors());
|
||||
|
||||
try {
|
||||
std::vector<pj_sockaddr_in> stunPorts(transport.getSTUNAddresses(account, socketDescriptors));
|
||||
|
||||
// FIXME: get video sockets
|
||||
stunPorts.resize(4);
|
||||
|
||||
account.setPublishedAddress(pj_inet_ntoa(stunPorts[0].sin_addr));
|
||||
call.getLocalSDP()->updatePorts(stunPorts);
|
||||
} catch (const std::runtime_error &e) {
|
||||
ERROR("%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
|
||||
{
|
||||
|
||||
@ -302,8 +320,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
|
||||
|
||||
Manager::instance().hookPreference.runHook(rdata->msg_info.msg);
|
||||
|
||||
SIPCall* call = new SIPCall(Manager::instance().getNewCallID(), Call::INCOMING, cp_);
|
||||
Manager::instance().associateCallToAccount(call->getCallId(), account_id);
|
||||
SIPCall* call = new SIPCall(Manager::instance().getNewCallID(), Call::INCOMING, cp_, account_id);
|
||||
|
||||
// May use the published address as well
|
||||
std::string addrToUse = SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
|
||||
@ -318,11 +335,10 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
|
||||
std::string peerNumber(tmp, std::min(length, sizeof tmp));
|
||||
sip_utils::stripSipUriPrefix(peerNumber);
|
||||
|
||||
std::string remote_user(sip_from_uri->user.ptr, sip_from_uri->user.slen);
|
||||
std::string remove_hostname(sip_from_uri->host.ptr, sip_from_uri->host.slen);
|
||||
if (remote_user.size() > 0 && remove_hostname.size() > 0) {
|
||||
peerNumber = remote_user + "@" + remove_hostname;
|
||||
}
|
||||
const std::string remote_user(sip_from_uri->user.ptr, sip_from_uri->user.slen);
|
||||
const std::string remote_hostname(sip_from_uri->host.ptr, sip_from_uri->host.slen);
|
||||
if (not remote_user.empty() and not remote_hostname.empty())
|
||||
peerNumber = remote_user + "@" + remote_hostname;
|
||||
|
||||
call->setConnectionState(Call::PROGRESSING);
|
||||
call->setPeerNumber(peerNumber);
|
||||
@ -342,6 +358,9 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
|
||||
return PJ_FALSE;
|
||||
}
|
||||
|
||||
if (account->isStunEnabled())
|
||||
updateSDPFromSTUN(*call, *account, SIPVoIPLink::instance()->sipTransport);
|
||||
|
||||
if (body and body->len > 0 and call->getAudioRtp().isSdesEnabled()) {
|
||||
std::string sdpOffer(static_cast<const char*>(body->data), body->len);
|
||||
size_t start = sdpOffer.find("a=crypto:");
|
||||
@ -722,14 +741,24 @@ void SIPVoIPLink::sendRegister(Account *a)
|
||||
std::string contact = account->getContactHeader();
|
||||
pj_str_t pjContact = pj_str((char*) contact.c_str());
|
||||
|
||||
|
||||
#ifndef __ANDROID__
|
||||
#warning update pj_sip
|
||||
if (not received.empty() and received != account->getPublishedAddress()) {
|
||||
|
||||
if (account->isStunEnabled()) {
|
||||
DEBUG("Setting VIA sent-by to %s:%u", account->transport_->local_name.host.ptr, account->transport_->local_name.port);
|
||||
if (pjsip_regc_set_via_sent_by(regc, &account->transport_->local_name, account->transport_) != PJ_SUCCESS)
|
||||
throw VoipLinkException("Unable to set the \"sent-by\" field");
|
||||
} else if (not received.empty() and received != account->getPublishedAddress()) {
|
||||
|
||||
DEBUG("Setting VIA sent-by to %s:%d", received.c_str(), account->getRPort());
|
||||
if (pjsip_regc_set_via_sent_by(regc, account->getViaAddr(), account->transport_) != PJ_SUCCESS)
|
||||
throw VoipLinkException("Unable to set the \"sent-by\" field");
|
||||
}
|
||||
|
||||
#else
|
||||
#warning update pj_sip
|
||||
#endif
|
||||
|
||||
if (pjsip_regc_init(regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, account->getRegistrationExpire()) != PJ_SUCCESS)
|
||||
throw VoipLinkException("Unable to initialize account registration structure");
|
||||
|
||||
@ -852,7 +881,7 @@ bool isValidIpAddress(const std::string &address)
|
||||
}
|
||||
|
||||
|
||||
Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toUrl)
|
||||
Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toUrl, const std::string &account_id)
|
||||
{
|
||||
DEBUG("New outgoing call to %s", toUrl.c_str());
|
||||
std::string toCpy = toUrl;
|
||||
@ -863,10 +892,9 @@ Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toU
|
||||
Manager::instance().setIPToIPForCall(id, IPToIP);
|
||||
|
||||
if (IPToIP) {
|
||||
Manager::instance().associateCallToAccount(id, SIPAccount::IP2IP_PROFILE);
|
||||
return SIPNewIpToIpCall(id, toUrl);
|
||||
return SIPNewIpToIpCall(id, toCpy);
|
||||
} else {
|
||||
return newRegisteredAccountCall(id, toUrl);
|
||||
return newRegisteredAccountCall(id, toUrl, account_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -879,7 +907,7 @@ Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to
|
||||
if (!account)
|
||||
throw VoipLinkException("Could not retrieve default account for IP2IP call");
|
||||
|
||||
SIPCall *call = new SIPCall(id, Call::OUTGOING, cp_);
|
||||
SIPCall *call = new SIPCall(id, Call::OUTGOING, cp_, SIPAccount::IP2IP_PROFILE);
|
||||
|
||||
call->setIPToIP(true);
|
||||
call->initRecFilename(to);
|
||||
@ -920,16 +948,16 @@ Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to
|
||||
return call;
|
||||
}
|
||||
|
||||
Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::string& toUrl)
|
||||
Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::string& toUrl, const std::string &account_id)
|
||||
{
|
||||
DEBUG("UserAgent: New registered account call to %s", toUrl.c_str());
|
||||
|
||||
SIPAccount *account = Manager::instance().getSipAccount(Manager::instance().getAccountFromCall(id));
|
||||
SIPAccount *account = Manager::instance().getSipAccount(account_id);
|
||||
|
||||
if (account == NULL) // TODO: We should investigate how we could get rid of this error and create a IP2IP call instead
|
||||
throw VoipLinkException("Could not get account for this call");
|
||||
|
||||
SIPCall* call = new SIPCall(id, Call::OUTGOING, cp_);
|
||||
SIPCall* call = new SIPCall(id, Call::OUTGOING, cp_, account->getAccountID());
|
||||
|
||||
// If toUri is not a well formatted sip URI, use account information to process it
|
||||
std::string toUri;
|
||||
@ -964,6 +992,10 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st
|
||||
try {
|
||||
call->getAudioRtp().initConfig();
|
||||
call->getAudioRtp().initSession();
|
||||
|
||||
if (account->isStunEnabled())
|
||||
updateSDPFromSTUN(*call, *account, SIPVoIPLink::instance()->sipTransport);
|
||||
|
||||
call->getAudioRtp().initLocalCryptoInfo();
|
||||
call->getAudioRtp().start(audioCodecs);
|
||||
} catch (...) {
|
||||
@ -1020,7 +1052,7 @@ SIPVoIPLink::hangup(const std::string& id, int reason)
|
||||
if (!call)
|
||||
return;
|
||||
|
||||
std::string account_id(Manager::instance().getAccountFromCall(id));
|
||||
std::string account_id(call->getAccountId());
|
||||
SIPAccount *account = Manager::instance().getSipAccount(account_id);
|
||||
|
||||
if (account == NULL)
|
||||
@ -1164,6 +1196,13 @@ SIPVoIPLink::offhold(const std::string& id)
|
||||
|
||||
call->getAudioRtp().initConfig();
|
||||
call->getAudioRtp().initSession();
|
||||
|
||||
const std::string account_id(call->getAccountId());
|
||||
SIPAccount *account = Manager::instance().getSipAccount(account_id);
|
||||
|
||||
if (account and account->isStunEnabled())
|
||||
updateSDPFromSTUN(*call, *account, SIPVoIPLink::instance()->sipTransport);
|
||||
|
||||
call->getAudioRtp().restoreLocalContext();
|
||||
call->getAudioRtp().initLocalCryptoInfoOnOffHold();
|
||||
call->getAudioRtp().start(audioCodecs);
|
||||
@ -1218,6 +1257,17 @@ SIPVoIPLink::clearSipCallMap()
|
||||
sipCallMap_.clear();
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string>
|
||||
SIPVoIPLink::getCallIDs()
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
sfl::ScopedLock m(sipCallMapMutex_);
|
||||
|
||||
map_utils::vectorFromMapKeys(sipCallMap_, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
void SIPVoIPLink::addSipCall(SIPCall* call)
|
||||
{
|
||||
if (!call)
|
||||
@ -1323,7 +1373,7 @@ SIPVoIPLink::transfer(const std::string& id, const std::string& to)
|
||||
|
||||
call->stopRecording();
|
||||
|
||||
std::string account_id(Manager::instance().getAccountFromCall(id));
|
||||
std::string account_id(call->getAccountId());
|
||||
SIPAccount *account = Manager::instance().getSipAccount(account_id);
|
||||
|
||||
if (account == NULL)
|
||||
@ -1515,14 +1565,15 @@ SIPVoIPLink::requestKeyframe(const std::string &callID)
|
||||
void
|
||||
SIPVoIPLink::carryingDTMFdigits(const std::string& id, char code)
|
||||
{
|
||||
std::string accountID(Manager::instance().getAccountFromCall(id));
|
||||
SIPCall *call = getSipCall(id);
|
||||
if (!call)
|
||||
return;
|
||||
|
||||
const std::string accountID(call->getAccountId());
|
||||
SIPAccount *account = Manager::instance().getSipAccount(accountID);
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
SIPCall *call = getSipCall(id);
|
||||
if (!call)
|
||||
return;
|
||||
dtmfSend(*call, code, account->getDtmfType());
|
||||
}
|
||||
|
||||
@ -1530,8 +1581,8 @@ SIPVoIPLink::carryingDTMFdigits(const std::string& id, char code)
|
||||
bool
|
||||
SIPVoIPLink::SIPStartCall(SIPCall *call)
|
||||
{
|
||||
std::string id(Manager::instance().getAccountFromCall(call->getCallId()));
|
||||
SIPAccount *account = Manager::instance().getSipAccount(id);
|
||||
std::string account_id(call->getAccountId());
|
||||
SIPAccount *account = Manager::instance().getSipAccount(account_id);
|
||||
|
||||
if (account == NULL) {
|
||||
ERROR("Account is NULL in SIPStartCall");
|
||||
@ -1682,7 +1733,7 @@ void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *ev)
|
||||
// After we sent or received a ACK - The connection is established
|
||||
link->SIPCallAnswered(call, ev->body.tsx_state.src.rdata);
|
||||
} else if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
|
||||
std::string accId(Manager::instance().getAccountFromCall(call->getCallId()));
|
||||
std::string accId(call->getAccountId());
|
||||
|
||||
switch (inv->cause) {
|
||||
// The call terminates normally - BYE / CANCEL
|
||||
@ -1719,7 +1770,7 @@ void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *off
|
||||
if (!call)
|
||||
return;
|
||||
|
||||
std::string accId(Manager::instance().getAccountFromCall(call->getCallId()));
|
||||
std::string accId(call->getAccountId());
|
||||
SIPAccount *account = Manager::instance().getSipAccount(accId);
|
||||
if (!account)
|
||||
return;
|
||||
@ -1737,7 +1788,7 @@ void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
|
||||
SIPCall *call = static_cast<SIPCall*>(inv->mod_data[mod_ua_.id]);
|
||||
if (!call)
|
||||
return;
|
||||
std::string accountid(Manager::instance().getAccountFromCall(call->getCallId()));
|
||||
std::string accountid(call->getAccountId());
|
||||
|
||||
SIPAccount *account = Manager::instance().getSipAccount(accountid);
|
||||
if (!account)
|
||||
@ -1840,7 +1891,7 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
|
||||
Manager::instance().getVideoControls()->stopPreview();
|
||||
call->getVideoRtp().updateSDP(*call->getLocalSDP());
|
||||
call->getVideoRtp().updateDestination(call->getLocalSDP()->getRemoteIP(), call->getLocalSDP()->getRemoteVideoPort());
|
||||
call->getVideoRtp().start();
|
||||
call->getVideoRtp().start(call->getLocalSDP()->getLocalVideoPort());
|
||||
#endif
|
||||
|
||||
// Get the crypto attribute containing srtp's cryptographic context (keys, cipher)
|
||||
@ -1881,11 +1932,15 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
|
||||
call->getAudioRtp().stop();
|
||||
call->getAudioRtp().setSrtpEnabled(false);
|
||||
|
||||
std::string accountID = Manager::instance().getAccountFromCall(call->getCallId());
|
||||
const std::string accountID = call->getAccountId();
|
||||
|
||||
SIPAccount *sipaccount = Manager::instance().getSipAccount(accountID);
|
||||
if (sipaccount and sipaccount->getSrtpFallback())
|
||||
if (sipaccount and sipaccount->getSrtpFallback()) {
|
||||
call->getAudioRtp().initSession();
|
||||
|
||||
if (sipaccount->isStunEnabled())
|
||||
updateSDPFromSTUN(*call, *sipaccount, SIPVoIPLink::instance()->sipTransport);
|
||||
}
|
||||
}
|
||||
#endif // HAVE_SDES
|
||||
|
||||
@ -2215,7 +2270,8 @@ void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata)
|
||||
}
|
||||
|
||||
try {
|
||||
SIPVoIPLink::instance()->newOutgoingCall(Manager::instance().getNewCallID(), std::string(refer_to->hvalue.ptr, refer_to->hvalue.slen));
|
||||
SIPVoIPLink::instance()->newOutgoingCall(Manager::instance().getNewCallID(),
|
||||
std::string(refer_to->hvalue.ptr, refer_to->hvalue.slen), currentCall->getAccountId());
|
||||
Manager::instance().hangupCall(currentCall->getCallId());
|
||||
} catch (const VoipLinkException &e) {
|
||||
ERROR("%s", e.what());
|
||||
@ -2295,30 +2351,28 @@ void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event)
|
||||
}
|
||||
|
||||
namespace {
|
||||
// returns port in range [10500, 64998]
|
||||
unsigned int getRandomPort()
|
||||
// returns even number in range [lower, upper]
|
||||
unsigned int getRandomEvenNumber(int lower, int upper)
|
||||
{
|
||||
return ((rand() % 27250) + 5250) * 2;
|
||||
const unsigned halfUpper = upper * 0.5;
|
||||
const unsigned halfLower = lower * 0.5;
|
||||
return 2 * (halfLower + rand() % (halfUpper - halfLower + 1));
|
||||
}
|
||||
}
|
||||
|
||||
void setCallMediaLocal(SIPCall* call, const std::string &localIP)
|
||||
{
|
||||
std::string account_id(Manager::instance().getAccountFromCall(call->getCallId()));
|
||||
std::string account_id(call->getAccountId());
|
||||
SIPAccount *account = Manager::instance().getSipAccount(account_id);
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
// Reference: http://www.cs.columbia.edu/~hgs/rtp/faq.html#ports
|
||||
// We only want to set ports to new values if they haven't been set
|
||||
if (call->getLocalAudioPort() == 0) {
|
||||
const unsigned int callLocalAudioPort = getRandomPort();
|
||||
|
||||
const unsigned int callLocalExternAudioPort = account->isStunEnabled()
|
||||
? account->getStunPort()
|
||||
: callLocalAudioPort;
|
||||
|
||||
const unsigned callLocalAudioPort = getRandomEvenNumber(16384, 32766);
|
||||
call->setLocalAudioPort(callLocalAudioPort);
|
||||
call->getLocalSDP()->setLocalPublishedAudioPort(callLocalExternAudioPort);
|
||||
call->getLocalSDP()->setLocalPublishedAudioPort(callLocalAudioPort);
|
||||
}
|
||||
|
||||
call->setLocalIp(localIP);
|
||||
@ -2326,10 +2380,9 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP)
|
||||
#ifdef SFL_VIDEO
|
||||
if (call->getLocalVideoPort() == 0) {
|
||||
// https://projects.savoirfairelinux.com/issues/17498
|
||||
const unsigned int MAX_VIDEO_PORT = 20001;
|
||||
unsigned int callLocalVideoPort = 0;
|
||||
unsigned int callLocalVideoPort;
|
||||
do
|
||||
callLocalVideoPort = getRandomPort() % MAX_VIDEO_PORT;
|
||||
callLocalVideoPort = getRandomEvenNumber(49152, 65534);
|
||||
while (call->getLocalAudioPort() == callLocalVideoPort);
|
||||
|
||||
call->setLocalVideoPort(callLocalVideoPort);
|
||||
|
@ -100,6 +100,10 @@ class SIPVoIPLink : public VoIPLink {
|
||||
*/
|
||||
virtual bool getEvent();
|
||||
|
||||
/* Returns a list of all callIDs */
|
||||
std::vector<std::string>
|
||||
getCallIDs();
|
||||
|
||||
/**
|
||||
* Return the internal account map for this VOIP link
|
||||
*/
|
||||
@ -132,7 +136,7 @@ class SIPVoIPLink : public VoIPLink {
|
||||
* @param toUrl The Sip address of the recipient of the call
|
||||
* @return Call* The current call
|
||||
*/
|
||||
virtual Call* newOutgoingCall(const std::string& id, const std::string& toUrl);
|
||||
virtual Call* newOutgoingCall(const std::string& id, const std::string& toUrl, const std::string &account_id);
|
||||
|
||||
/**
|
||||
* Start a new SIP call using the IP2IP profile
|
||||
@ -146,7 +150,7 @@ class SIPVoIPLink : public VoIPLink {
|
||||
* @param The call id
|
||||
* @param The target sip uri
|
||||
*/
|
||||
Call *newRegisteredAccountCall(const std::string& id, const std::string& toUrl);
|
||||
Call *newRegisteredAccountCall(const std::string& id, const std::string& toUrl, const std::string &account_id);
|
||||
|
||||
/**
|
||||
* Answer the call
|
||||
@ -272,6 +276,7 @@ class SIPVoIPLink : public VoIPLink {
|
||||
#endif
|
||||
void clearSipCallMap();
|
||||
void addSipCall(SIPCall* call);
|
||||
|
||||
SIPCall* getSipCall(const std::string& id);
|
||||
SIPCall* tryGetSipCall(const std::string& id);
|
||||
void removeSipCall(const std::string &id);
|
||||
|
Reference in New Issue
Block a user