- clang format + naming improved
This commit is contained in:
@@ -15,49 +15,46 @@
|
||||
#define CONFIG(X) mConfig->at(X)
|
||||
#define CONFIG_EXISTS(X) mConfig->exists(X)
|
||||
|
||||
//#define MODIFY_VIA_BEHIND_NAT
|
||||
// #define MODIFY_VIA_BEHIND_NAT
|
||||
|
||||
// NAT decorator
|
||||
class NATDecorator: public resip::MessageDecorator
|
||||
class NATDecorator : public resip::MessageDecorator
|
||||
{
|
||||
protected:
|
||||
UserAgent& mUserAgent;
|
||||
UserAgent& mUserAgent;
|
||||
resip::SipMessage mMessage;
|
||||
|
||||
resip::Data mViaHost;
|
||||
unsigned short mViaPort;
|
||||
resip::Data mViaHost;
|
||||
unsigned short mViaPort;
|
||||
|
||||
resip::Data mContactsHost;
|
||||
resip::Data mContactsScheme;
|
||||
unsigned short mContactsPort;
|
||||
resip::Data mContactsHost;
|
||||
resip::Data mContactsScheme;
|
||||
unsigned short mContactsPort;
|
||||
|
||||
public:
|
||||
NATDecorator(UserAgent& endpoint);
|
||||
virtual ~NATDecorator();
|
||||
|
||||
virtual void decorateMessage(resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data& sigcompId);
|
||||
virtual void rollbackMessage(resip::SipMessage& msg);
|
||||
virtual void decorateMessage(resip::SipMessage& msg, const resip::Tuple& source, const resip::Tuple& destination,
|
||||
const resip::Data& sigcompId);
|
||||
virtual void rollbackMessage(resip::SipMessage& msg);
|
||||
virtual MessageDecorator* clone() const;
|
||||
};
|
||||
|
||||
|
||||
NATDecorator::NATDecorator(UserAgent& ua)
|
||||
:mUserAgent(ua), mViaPort(0), mContactsPort(0)
|
||||
{
|
||||
}
|
||||
NATDecorator::NATDecorator(UserAgent& ua) : mUserAgent(ua), mViaPort(0), mContactsPort(0) {}
|
||||
|
||||
NATDecorator::~NATDecorator()
|
||||
{
|
||||
}
|
||||
NATDecorator::~NATDecorator() {}
|
||||
|
||||
void NATDecorator::decorateMessage(resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data& sigcompId)
|
||||
void NATDecorator::decorateMessage(resip::SipMessage& msg, const resip::Tuple& source, const resip::Tuple& destination,
|
||||
const resip::Data& sigcompId)
|
||||
{
|
||||
// Make a copy to allow rollback
|
||||
mMessage = msg;
|
||||
|
||||
std::stringstream dump;
|
||||
mMessage.encode(dump);
|
||||
//ICELogDebug(<< "Decorating message: \n" << dump.str());
|
||||
// ICELogDebug(<< "Decorating message: \n" << dump.str());
|
||||
|
||||
// Check From: header and find the account
|
||||
resip::NameAddr from;
|
||||
@@ -101,11 +98,11 @@ void NATDecorator::decorateMessage(resip::SipMessage &msg, const resip::Tuple &s
|
||||
uri.port() = account->mExternalAddress.port();
|
||||
if (account->mConfig->at(CONFIG_SIPS).asBool())
|
||||
{
|
||||
//uri.scheme() = "sips";
|
||||
//uri.param(resip::p_transport) = "tls";
|
||||
// uri.scheme() = "sips";
|
||||
// uri.param(resip::p_transport) = "tls";
|
||||
}
|
||||
|
||||
//uri.scheme() = account->mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip";
|
||||
// uri.scheme() = account->mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,7 +111,7 @@ void NATDecorator::rollbackMessage(resip::SipMessage& msg)
|
||||
{
|
||||
// Check From: header and find the account
|
||||
resip::NameAddr from = msg.header(resip::h_From);
|
||||
PAccount account = mUserAgent.getAccount(from);
|
||||
PAccount account = mUserAgent.getAccount(from);
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
@@ -141,7 +138,7 @@ void NATDecorator::rollbackMessage(resip::SipMessage& msg)
|
||||
{
|
||||
uri.host() = mContactsHost;
|
||||
uri.port() = mContactsPort;
|
||||
//uri.scheme() = mContactsScheme;
|
||||
// uri.scheme() = mContactsScheme;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,19 +150,16 @@ resip::MessageDecorator* NATDecorator::clone() const
|
||||
}
|
||||
|
||||
Account::Account(PVariantMap config, UserAgent& agent)
|
||||
:mAgent(agent), mId(0), mConfig(config), mRegistrationState(RegistrationState::None),
|
||||
mRegistration(NULL)
|
||||
: mAgent(agent), mId(0), mConfig(config), mRegistrationState(RegistrationState::None), mRegistration(NULL)
|
||||
{
|
||||
mProfile = std::make_shared<resip::UserProfile>(agent.mProfile);
|
||||
mId = Account::generateId();
|
||||
setup(*config);
|
||||
}
|
||||
|
||||
Account::~Account()
|
||||
{
|
||||
}
|
||||
Account::~Account() {}
|
||||
|
||||
void Account::setup(VariantMap &config)
|
||||
void Account::setup(VariantMap& config)
|
||||
{
|
||||
// Credentials
|
||||
|
||||
@@ -176,8 +170,8 @@ void Account::setup(VariantMap &config)
|
||||
mProfile->setDigestCredential(resip::Data(config[CONFIG_DOMAIN].asStdString()),
|
||||
resip::Data(config[CONFIG_USERNAME].asStdString()),
|
||||
resip::Data(config[CONFIG_PASSWORD].asStdString()));
|
||||
ICELogInfo( << "Credentials are set to domain " << config[CONFIG_DOMAIN].asStdString() <<
|
||||
", username to " << config[CONFIG_USERNAME].asStdString());
|
||||
ICELogInfo(<< "Credentials are set to domain " << config[CONFIG_DOMAIN].asStdString() << ", username to "
|
||||
<< config[CONFIG_USERNAME].asStdString());
|
||||
|
||||
// Proxy
|
||||
mProfile->unsetOutboundProxy();
|
||||
@@ -234,7 +228,7 @@ void Account::setup(VariantMap &config)
|
||||
if (config[CONFIG_DOMAINPORT].asInt() != 0)
|
||||
from.uri().port() = config[CONFIG_DOMAINPORT].asInt();
|
||||
else
|
||||
from.uri().port();// = 5060;
|
||||
from.uri().port(); // = 5060;
|
||||
|
||||
from.uri().user() = resip::Data(config[CONFIG_USERNAME].asStdString());
|
||||
from.uri().host() = resip::Data(config[CONFIG_DOMAIN].asStdString());
|
||||
@@ -266,10 +260,12 @@ void Account::start()
|
||||
|
||||
// Create registration
|
||||
mRegistration = new ResipSession(*mAgent.mDum);
|
||||
auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, mConfig->at(CONFIG_REGISTERDURATION).asInt(), mRegistration);
|
||||
auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile,
|
||||
mConfig->at(CONFIG_REGISTERDURATION).asInt(), mRegistration);
|
||||
|
||||
for (UserInfo::const_iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++)
|
||||
regmessage->header(resip::ExtensionHeader(iter->first.c_str())).push_back(resip::StringCategory(iter->second.c_str()));
|
||||
regmessage->header(resip::ExtensionHeader(iter->first.c_str()))
|
||||
.push_back(resip::StringCategory(iter->second.c_str()));
|
||||
|
||||
mRegistrationState = RegistrationState::Registering;
|
||||
|
||||
@@ -278,10 +274,10 @@ void Account::start()
|
||||
|
||||
// Check if STUN IP is required
|
||||
bool noStunServerIp = !CONFIG_EXISTS(CONFIG_STUNSERVER_IP);
|
||||
//bool hasStunServerName = !CONFIG(CONFIG_STUNSERVER_NAME).asStdString().empty();
|
||||
// bool hasStunServerName = !CONFIG(CONFIG_STUNSERVER_NAME).asStdString().empty();
|
||||
if (noStunServerIp)
|
||||
{
|
||||
ICELogInfo(<<"No STUN server name or IP is not specified. Has to resolve/discover STUN server IP.");
|
||||
ICELogInfo(<< "No STUN server name or IP is not specified. Has to resolve/discover STUN server IP.");
|
||||
mRefreshStunServerIpTimer.start(CONFIG(CONFIG_DNS_CACHE_TIME).asInt() * 1000);
|
||||
mRefreshStunServerIpTimer.isTimeToSend();
|
||||
queryStunServerIp();
|
||||
@@ -305,11 +301,10 @@ void Account::stop()
|
||||
mRegistrationHandle->removeAll();
|
||||
mRegistrationHandle = resip::ClientRegistrationHandle();
|
||||
}
|
||||
else
|
||||
if (mRegistration)
|
||||
{
|
||||
mRegistration->end();
|
||||
}
|
||||
else if (mRegistration)
|
||||
{
|
||||
mRegistration->end();
|
||||
}
|
||||
mRegistration = NULL;
|
||||
mRegistrationState = RegistrationState::None;
|
||||
}
|
||||
@@ -361,7 +356,8 @@ void Account::publishPresence(bool online, const std::string& content, int secon
|
||||
if (mPublication.isValid())
|
||||
mPublication->update(&p);
|
||||
else
|
||||
mAgent.mDum->send(mAgent.mDum->makePublication(contact(SecureScheme::TlsOnly), mProfile, p, resip::Symbols::Presence, seconds));
|
||||
mAgent.mDum->send(mAgent.mDum->makePublication(contact(SecureScheme::TlsOnly), mProfile, p,
|
||||
resip::Symbols::Presence, seconds));
|
||||
}
|
||||
|
||||
void Account::stopPublish()
|
||||
@@ -381,14 +377,14 @@ PClientObserver Account::observe(const std::string& target, const std::string& p
|
||||
observer->mPeer = target;
|
||||
|
||||
std::shared_ptr<resip::SipMessage> msg;
|
||||
int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME;
|
||||
int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME;
|
||||
if (mConfig->exists(CONFIG_SUBSCRIPTION_TIME))
|
||||
expires = CONFIG(CONFIG_SUBSCRIPTION_TIME).asInt();
|
||||
if (mConfig->exists(CONFIG_SUBSCRIPTION_REFRESHTIME))
|
||||
refresh = CONFIG(CONFIG_SUBSCRIPTION_REFRESHTIME).asInt();
|
||||
|
||||
msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(target)), mProfile,
|
||||
resip::Data(package), expires, refresh, observer->mSession);
|
||||
msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(target)), mProfile, resip::Data(package), expires,
|
||||
refresh, observer->mSession);
|
||||
msg->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY);
|
||||
|
||||
mAgent.mClientObserverMap[observer->mSessionId] = observer;
|
||||
@@ -406,15 +402,17 @@ int Account::sendMsg(const std::string& peer, const void* ptr, unsigned length,
|
||||
s->setRemoteAddress(peer);
|
||||
|
||||
// Find MIME type
|
||||
resip::Mime type;
|
||||
resip::Mime type;
|
||||
std::string::size_type p = mime.find('/');
|
||||
if (p != std::string::npos)
|
||||
type = resip::Mime(resip::Data(mime.substr(0, p)), resip::Data(mime.substr(p+1)));
|
||||
type = resip::Mime(resip::Data(mime.substr(0, p)), resip::Data(mime.substr(p + 1)));
|
||||
else
|
||||
type = resip::Mime(resip::Data(mime), resip::Data());
|
||||
|
||||
resip::ClientPagerMessageHandle msgHandle = mAgent.mDum->makePagerMessage(resip::NameAddr(resip::Data(peer)), mProfile, s);
|
||||
unique_ptr<resip::Contents> contentPtr(new resip::PlainContents(resip::Data(std::string((const char*)ptr, length)),type));
|
||||
resip::ClientPagerMessageHandle msgHandle =
|
||||
mAgent.mDum->makePagerMessage(resip::NameAddr(resip::Data(peer)), mProfile, s);
|
||||
unique_ptr<resip::Contents> contentPtr(
|
||||
new resip::PlainContents(resip::Data(std::string((const char*)ptr, length)), type));
|
||||
int result = s->sessionId();
|
||||
msgHandle->page(std::move(contentPtr));
|
||||
|
||||
@@ -451,12 +449,13 @@ resip::NameAddr Account::contact(SecureScheme ss)
|
||||
|
||||
void Account::queryStunServerIp()
|
||||
{
|
||||
ICELogInfo(<<"Looking for STUN/TURN server IP");
|
||||
ICELogInfo(<< "Looking for STUN/TURN server IP");
|
||||
|
||||
if (!mConfig->exists(CONFIG_STUNSERVER_NAME))
|
||||
{
|
||||
// Send request to find STUN or TURN service
|
||||
std::string target = std::string(mConfig->at(CONFIG_RELAY).asBool() ? "_turn" : "_stun") + "._udp." + mConfig->at(CONFIG_DOMAIN).asStdString();
|
||||
std::string target = std::string(mConfig->at(CONFIG_RELAY).asBool() ? "_turn" : "_stun") + "._udp." +
|
||||
mConfig->at(CONFIG_DOMAIN).asStdString();
|
||||
|
||||
// Start lookup
|
||||
mAgent.mStack->getDnsStub().lookup<resip::RR_SRV>(resip::Data(target), this);
|
||||
@@ -475,9 +474,9 @@ void Account::queryStunServerIp()
|
||||
}
|
||||
}
|
||||
|
||||
void Account::prepareIceStack(Session *session, ice::AgentRole icerole)
|
||||
void Account::prepareIceStack(Session* session, ice::AgentRole icerole)
|
||||
{
|
||||
ice::ServerConfig config;
|
||||
ice::ServerConfig config;
|
||||
ice::NetworkAddress addr;
|
||||
addr.setIp(mConfig->at(CONFIG_STUNSERVER_IP).asStdString());
|
||||
if (mConfig->at(CONFIG_STUNSERVER_PORT).asInt())
|
||||
@@ -495,8 +494,8 @@ void Account::prepareIceStack(Session *session, ice::AgentRole icerole)
|
||||
|
||||
config.mUseIPv4 = mAgent.config()[CONFIG_IPV4].asBool();
|
||||
config.mUseIPv6 = mAgent.config()[CONFIG_IPV6].asBool();
|
||||
//config.mDetectNetworkChange = true;
|
||||
//config.mNetworkCheckInterval = 5000;
|
||||
// config.mDetectNetworkChange = true;
|
||||
// config.mNetworkCheckInterval = 5000;
|
||||
|
||||
session->mIceStack = std::shared_ptr<ice::Stack>(ice::Stack::makeICEBox(config));
|
||||
session->mIceStack->setEventHandler(session, this);
|
||||
@@ -509,7 +508,7 @@ void Account::process()
|
||||
queryStunServerIp();
|
||||
}
|
||||
|
||||
void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage &response)
|
||||
void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response)
|
||||
{
|
||||
// Save registration handle
|
||||
mRegistrationHandle = h;
|
||||
@@ -519,16 +518,16 @@ void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessa
|
||||
mRegistrationHandle->setCustomHeader(resip::Data(iter->first.c_str()), resip::Data(iter->second.c_str()));
|
||||
|
||||
// Get the Via
|
||||
const resip::Via& via = response.header(resip::h_Vias).front();
|
||||
const resip::Via& via = response.header(resip::h_Vias).front();
|
||||
|
||||
// Get the sent host
|
||||
const resip::Data& sentHost = via.sentHost();//response.header(h_Contacts).front().uri().host();
|
||||
const resip::Data& sentHost = via.sentHost(); // response.header(h_Contacts).front().uri().host();
|
||||
|
||||
// Get the sentPort
|
||||
int sentPort = via.sentPort();
|
||||
int sentPort = via.sentPort();
|
||||
|
||||
const resip::Data& sourceHost = response.getSource().toData(resip::UDP);
|
||||
int rport = 0;
|
||||
int rport = 0;
|
||||
if (via.exists(resip::p_rport))
|
||||
rport = via.param(resip::p_rport).port();
|
||||
|
||||
@@ -553,13 +552,14 @@ void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessa
|
||||
}
|
||||
|
||||
mUsedTransport = response.getReceivedTransportTuple().getType();
|
||||
//bool streamTransport = mUsedTransport == resip::TCP || mUsedTransport == resip::TLS;
|
||||
// bool streamTransport = mUsedTransport == resip::TCP || mUsedTransport == resip::TLS;
|
||||
|
||||
// Retry registration for stream based transport too
|
||||
if ( (hostChanged || portChanged) && mRegistrationState == RegistrationState::Registering /*&& !streamTransport*/ && mConfig->at(CONFIG_EXTERNALIP).asBool())
|
||||
if ((hostChanged || portChanged) && mRegistrationState == RegistrationState::Registering /*&& !streamTransport*/ &&
|
||||
mConfig->at(CONFIG_EXTERNALIP).asBool())
|
||||
{
|
||||
//mRegistrationHandle->requestRefresh();
|
||||
// Unregister at first
|
||||
// mRegistrationHandle->requestRefresh();
|
||||
// Unregister at first
|
||||
mRegistrationHandle->removeAll();
|
||||
mRegistrationState = RegistrationState::Reregistering;
|
||||
return;
|
||||
@@ -570,12 +570,12 @@ void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessa
|
||||
mAgent.onAccountStart(mAgent.getAccount(this));
|
||||
}
|
||||
|
||||
void Account::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage &response)
|
||||
void Account::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response)
|
||||
{
|
||||
// Check if this unregistering is a part of rport pr
|
||||
if (mRegistrationState == RegistrationState::Reregistering)
|
||||
{
|
||||
//if (/*this->mUseExternalIP && */response.getSource().getType() == resip::UDP)
|
||||
// if (/*this->mUseExternalIP && */response.getSource().getType() == resip::UDP)
|
||||
{
|
||||
resip::Uri hostport(contact(SecureScheme::TlsOnly).uri());
|
||||
hostport.host() = resip::Data(mExternalAddress.ip());
|
||||
@@ -585,19 +585,24 @@ void Account::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessa
|
||||
const char* transportName = nullptr;
|
||||
switch (mUsedTransport)
|
||||
{
|
||||
case resip::TCP: transportName = "tcp"; break;
|
||||
case resip::TLS: transportName = "tls"; break;
|
||||
case resip::TCP:
|
||||
transportName = "tcp";
|
||||
break;
|
||||
case resip::TLS:
|
||||
transportName = "tls";
|
||||
break;
|
||||
}
|
||||
|
||||
hostport.param(resip::p_transport) = resip::Data(transportName);
|
||||
}
|
||||
mProfile->setOverrideHostAndPort(hostport);
|
||||
//mProfile->setDefaultFrom(from);
|
||||
// mProfile->setDefaultFrom(from);
|
||||
}
|
||||
mProfile->setRegId(mConfig->at(CONFIG_REGID).asInt());
|
||||
auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, UA_REGISTRATION_TIME);
|
||||
for (UserInfo::const_iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++)
|
||||
regmessage->header(resip::ExtensionHeader(iter->first.c_str())).push_back(resip::StringCategory(iter->second.c_str()));
|
||||
regmessage->header(resip::ExtensionHeader(iter->first.c_str()))
|
||||
.push_back(resip::StringCategory(iter->second.c_str()));
|
||||
|
||||
mAgent.mDum->send(regmessage);
|
||||
return;
|
||||
@@ -625,16 +630,17 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsHostRecord>& result)
|
||||
if (result.status == 0)
|
||||
{
|
||||
resip::Data foundAddress = result.records.front().host();
|
||||
ICELogInfo( << "Success to resolve STUN/TURN address to " << foundAddress.c_str());
|
||||
ICELogInfo(<< "Success to resolve STUN/TURN address to " << foundAddress.c_str());
|
||||
mConfig->at(CONFIG_STUNSERVER_IP) = std::string(foundAddress.c_str());
|
||||
|
||||
// Here the IP address of STUN/TURN server is found. If account is registered already - it means account is ready.
|
||||
// Here the IP address of STUN/TURN server is found. If account is registered already - it means account is
|
||||
// ready.
|
||||
if (mRegistrationState == RegistrationState::Registered)
|
||||
mAgent.onAccountStart(mAgent.getAccount(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
ICELogError( << "Failed to resolve STUN or TURN server IP address.");
|
||||
ICELogError(<< "Failed to resolve STUN or TURN server IP address.");
|
||||
if (mRegistrationState == RegistrationState::Registered)
|
||||
{
|
||||
int startCode = mConfig->at(CONFIG_STUNSERVER_NAME).asStdString().empty() ? 0 : 503;
|
||||
@@ -643,10 +649,7 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsHostRecord>& result)
|
||||
}
|
||||
}
|
||||
|
||||
void Account::onDnsResult(const resip::DNSResult<resip::DnsAAAARecord>&)
|
||||
{
|
||||
|
||||
}
|
||||
void Account::onDnsResult(const resip::DNSResult<resip::DnsAAAARecord>&) {}
|
||||
|
||||
void Account::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
|
||||
{
|
||||
@@ -654,14 +657,14 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
|
||||
{
|
||||
// Find lowest priority
|
||||
int priority = 0x7FFFFFFF;
|
||||
for (size_t i=0; i<result.records.size(); i++)
|
||||
for (size_t i = 0; i < result.records.size(); i++)
|
||||
if (result.records[i].priority() < priority)
|
||||
priority = result.records[i].priority();
|
||||
|
||||
size_t index = 0;
|
||||
int weight = 0;
|
||||
int weight = 0;
|
||||
|
||||
for (size_t i=0; i<result.records.size(); i++)
|
||||
for (size_t i = 0; i < result.records.size(); i++)
|
||||
{
|
||||
if (result.records[i].priority() == priority && result.records[i].weight() >= weight)
|
||||
{
|
||||
@@ -674,15 +677,15 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
|
||||
|
||||
const char* host = result.records[index].target().c_str();
|
||||
|
||||
ICELogInfo( << "Success to find STUN/TURN server on " << result.records[index].target().c_str() <<
|
||||
":" << (int)result.records[index].port());
|
||||
ICELogInfo(<< "Success to find STUN/TURN server on " << result.records[index].target().c_str() << ":"
|
||||
<< (int)result.records[index].port());
|
||||
|
||||
|
||||
if (inet_addr(host) == INADDR_NONE)
|
||||
{
|
||||
// Try to resolve domain name now
|
||||
mAgent.mStack->getDnsStub().lookup<resip::RR_A>(result.records[index].target(), this);
|
||||
//mStack->getDnsStub().lookup<resip::RR_AAAA>(result.records[index].target(), this);
|
||||
// mStack->getDnsStub().lookup<resip::RR_AAAA>(result.records[index].target(), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -691,27 +694,20 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
|
||||
}
|
||||
else
|
||||
{
|
||||
ICELogError( << "Failed to find STUN or TURN service for specified domain.");
|
||||
//mAgent::shutdown();
|
||||
ICELogError(<< "Failed to find STUN or TURN service for specified domain.");
|
||||
// mAgent::shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Account::onDnsResult(const resip::DNSResult<resip::DnsNaptrRecord>&)
|
||||
{
|
||||
void Account::onDnsResult(const resip::DNSResult<resip::DnsNaptrRecord>&) {}
|
||||
|
||||
}
|
||||
void Account::onDnsResult(const resip::DNSResult<resip::DnsCnameRecord>&) {}
|
||||
|
||||
void Account::onDnsResult(const resip::DNSResult<resip::DnsCnameRecord>&)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Account::isResponsibleFor(const resip::NameAddr &addr)
|
||||
bool Account::isResponsibleFor(const resip::NameAddr& addr)
|
||||
{
|
||||
std::string user = addr.uri().user().c_str();
|
||||
std::string domain = addr.uri().host().c_str();
|
||||
int p = addr.uri().port();
|
||||
int p = addr.uri().port();
|
||||
if (mConfig->at(CONFIG_USERNAME).asStdString() == user && mConfig->at(CONFIG_DOMAIN).asStdString() == domain)
|
||||
{
|
||||
// Check if ports are the same or port is not specified at all
|
||||
@@ -724,7 +720,7 @@ bool Account::isResponsibleFor(const resip::NameAddr &addr)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Account::setUserInfo(const UserInfo &info)
|
||||
void Account::setUserInfo(const UserInfo& info)
|
||||
{
|
||||
mUserInfo = info;
|
||||
if (mRegistrationHandle.isValid())
|
||||
@@ -740,7 +736,7 @@ Account::UserInfo Account::getUserInfo() const
|
||||
}
|
||||
|
||||
std::atomic_int Account::IdGenerator;
|
||||
int Account::generateId()
|
||||
int Account::generateId()
|
||||
{
|
||||
return ++IdGenerator;
|
||||
}
|
||||
|
||||
@@ -22,10 +22,11 @@
|
||||
class UserAgent;
|
||||
class Session;
|
||||
|
||||
class Account: public resip::DnsResultSink
|
||||
class Account : public resip::DnsResultSink
|
||||
{
|
||||
friend class UserAgent;
|
||||
friend class NATDecorator;
|
||||
|
||||
public:
|
||||
Account(PVariantMap config, UserAgent& agent);
|
||||
~Account();
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
void stop();
|
||||
void refresh();
|
||||
bool active();
|
||||
int id() const;
|
||||
int id() const;
|
||||
|
||||
enum class RegistrationState
|
||||
{
|
||||
@@ -47,69 +48,69 @@ public:
|
||||
RegistrationState registrationState();
|
||||
|
||||
/* Publishes new presence information */
|
||||
void publishPresence(bool online, const std::string& content, int seconds = 600);
|
||||
void publishPresence(bool online, const std::string& content, int seconds = 600);
|
||||
|
||||
/* Stops publishing of presence */
|
||||
void stopPublish();
|
||||
void stopPublish();
|
||||
|
||||
/* Starts observing on specified target / package */
|
||||
PClientObserver observe(const std::string& target, const std::string& package, void* tag);
|
||||
PClientObserver observe(const std::string& target, const std::string& package, void* tag);
|
||||
|
||||
/* Queues message to peer with specified mime type. Returns ID of message. */
|
||||
int sendMsg(const std::string& peer, const void* ptr, unsigned length, const std::string& mime, void* tag);
|
||||
int sendMsg(const std::string& peer, const void* ptr, unsigned length, const std::string& mime, void* tag);
|
||||
|
||||
/* Returns name of account - <sip:user@domain> */
|
||||
std::string name();
|
||||
|
||||
/* Updates account with configuration */
|
||||
void setup(VariantMap& config);
|
||||
void setup(VariantMap& config);
|
||||
|
||||
/* Returns corresponding resiprocate profile */
|
||||
std::shared_ptr<resip::UserProfile> getUserProfile() const { return mProfile; }
|
||||
std::shared_ptr<resip::UserProfile> getUserProfile() const { return mProfile; }
|
||||
|
||||
typedef std::map<std::string, std::string> UserInfo;
|
||||
void setUserInfo(const UserInfo& info);
|
||||
UserInfo getUserInfo() const;
|
||||
void setUserInfo(const UserInfo& info);
|
||||
UserInfo getUserInfo() const;
|
||||
|
||||
protected:
|
||||
PVariantMap mConfig;
|
||||
PVariantMap mConfig;
|
||||
|
||||
// Registration
|
||||
ResipSession* mRegistration;
|
||||
resip::ClientRegistrationHandle mRegistrationHandle;
|
||||
resip::ClientPublicationHandle mPublication;
|
||||
resip::TransportType mUsedTransport;
|
||||
ResipSession* mRegistration;
|
||||
resip::ClientRegistrationHandle mRegistrationHandle;
|
||||
resip::ClientPublicationHandle mPublication;
|
||||
resip::TransportType mUsedTransport;
|
||||
|
||||
RegistrationState mRegistrationState;
|
||||
RegistrationState mRegistrationState;
|
||||
|
||||
ice::NetworkAddress mExternalAddress;
|
||||
ice::NetworkAddress mExternalAddress;
|
||||
std::shared_ptr<resip::UserProfile> mProfile;
|
||||
UserAgent& mAgent;
|
||||
bool mPresenceOnline;
|
||||
std::string mPresenceContent;
|
||||
UserAgent& mAgent;
|
||||
bool mPresenceOnline;
|
||||
std::string mPresenceContent;
|
||||
|
||||
// Timer to refresh STUN server IP
|
||||
ice::ICEScheduleTimer mRefreshStunServerIpTimer;
|
||||
ice::ICEScheduleTimer mRefreshStunServerIpTimer;
|
||||
|
||||
// Cached auth
|
||||
resip::Auth mCachedAuth;
|
||||
resip::Auth mCachedAuth;
|
||||
|
||||
// Id of account
|
||||
int mId;
|
||||
int mId;
|
||||
|
||||
// User info about current state
|
||||
UserInfo mUserInfo;
|
||||
UserInfo mUserInfo;
|
||||
|
||||
// List of client subscriptions sent from this account
|
||||
typedef std::set<PClientObserver> ClientObserverSet;
|
||||
ClientObserverSet mClientObserverSet;
|
||||
typedef std::set<PClientObserver> ClientObserverSet;
|
||||
ClientObserverSet mClientObserverSet;
|
||||
|
||||
|
||||
void process();
|
||||
void process();
|
||||
// Method queries new stun server ip from dns (if stun server is specified as dns name)
|
||||
void queryStunServerIp();
|
||||
void queryStunServerIp();
|
||||
|
||||
bool isResponsibleFor(const resip::NameAddr& addr);
|
||||
bool isResponsibleFor(const resip::NameAddr& addr);
|
||||
enum class SecureScheme
|
||||
{
|
||||
SipsAndTls,
|
||||
@@ -121,10 +122,10 @@ protected:
|
||||
resip::NameAddr contact(SecureScheme ss = SecureScheme::SipsOnly);
|
||||
|
||||
// This method prepares configuration, creates ice stack and sets ownership to session
|
||||
void prepareIceStack(Session* session, ice::AgentRole role);
|
||||
void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response);
|
||||
void prepareIceStack(Session* session, ice::AgentRole role);
|
||||
void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response);
|
||||
|
||||
#pragma region DnsResultSink implementation
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsHostRecord>&);
|
||||
@@ -134,7 +135,7 @@ protected:
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsCnameRecord>&);
|
||||
#pragma endregion
|
||||
|
||||
static int generateId();
|
||||
static int generateId();
|
||||
static std::atomic_int IdGenerator;
|
||||
};
|
||||
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
#define LOG_SUBSYSTEM "engine"
|
||||
|
||||
AudioProvider::AudioProvider(UserAgent& agent, MT::Terminal& terminal)
|
||||
:mUserAgent(agent), mTerminal(terminal), mState(0),
|
||||
mRemoteTelephoneCodec(0), mRemoteNoSdp(false)
|
||||
: mUserAgent(agent), mTerminal(terminal), mState(0), mRemoteTelephoneCodec(0), mRemoteNoSdp(false)
|
||||
{
|
||||
mActive = mfActive;
|
||||
mRemoteState = msSendRecv;
|
||||
@@ -26,12 +25,11 @@ AudioProvider::AudioProvider(UserAgent& agent, MT::Terminal& terminal)
|
||||
if (mUserAgent.config().exists(CONFIG_CODEC_PRIORITY))
|
||||
mCodecPriority.setupFrom(mUserAgent.config()[CONFIG_CODEC_PRIORITY].asVMap());
|
||||
mSrtpSuite = SRTP_NONE;
|
||||
setStateImpl((int)StreamState::SipRecv | (int)StreamState::SipSend | (int)StreamState::Receiving | (int)StreamState::Sending);
|
||||
setStateImpl((int)StreamState::SipRecv | (int)StreamState::SipSend | (int)StreamState::Receiving |
|
||||
(int)StreamState::Sending);
|
||||
}
|
||||
|
||||
AudioProvider::~AudioProvider()
|
||||
{
|
||||
}
|
||||
AudioProvider::~AudioProvider() {}
|
||||
|
||||
std::string AudioProvider::streamName()
|
||||
{
|
||||
@@ -47,7 +45,7 @@ std::string AudioProvider::streamProfile()
|
||||
}
|
||||
|
||||
// Sets destination IP address
|
||||
void AudioProvider::setDestinationAddress(const RtpPair<InternetAddress>& addr)
|
||||
void AudioProvider::setDestinationAddress(const RtpPair<InternetAddress>& addr)
|
||||
{
|
||||
if (!mActiveStream)
|
||||
return;
|
||||
@@ -55,7 +53,7 @@ void AudioProvider::setDestinationAddress(const RtpPair<InternetAddress>& addr)
|
||||
mActiveStream->setDestination(addr);
|
||||
}
|
||||
|
||||
void AudioProvider::configureMediaObserver(MT::Stream::MediaObserver *observer, void* userTag)
|
||||
void AudioProvider::configureMediaObserver(MT::Stream::MediaObserver* observer, void* userTag)
|
||||
{
|
||||
mMediaObserver = observer;
|
||||
mMediaObserverTag = userTag;
|
||||
@@ -64,20 +62,21 @@ void AudioProvider::configureMediaObserver(MT::Stream::MediaObserver *observer,
|
||||
}
|
||||
|
||||
// Processes incoming data
|
||||
void AudioProvider::processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& source)
|
||||
void AudioProvider::processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& source)
|
||||
{
|
||||
if (!mActiveStream)
|
||||
return;
|
||||
|
||||
if (RtpHelper::isRtpOrRtcp(dataBuffer, dataSize))
|
||||
{
|
||||
ICELogMedia(<<"Adding new data to stream processing");
|
||||
ICELogMedia(<< "Adding new data to stream processing");
|
||||
mActiveStream->dataArrived(s, dataBuffer, dataSize, source);
|
||||
}
|
||||
}
|
||||
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
void AudioProvider::sendData(const PDatagramSocket& s, InternetAddress& destination, const void* buffer, unsigned int size)
|
||||
void AudioProvider::sendData(const PDatagramSocket& s, InternetAddress& destination, const void* buffer,
|
||||
unsigned int size)
|
||||
{
|
||||
s->sendDatagram(destination, buffer, size);
|
||||
}
|
||||
@@ -105,7 +104,7 @@ void AudioProvider::updateSdpOffer(resip::SdpContents::Session::Medium& sdp, Sdp
|
||||
// Use CodecListPriority mCodecPriority adapter to work with codec priorities
|
||||
if (mAvailableCodecs.empty())
|
||||
{
|
||||
for (int i=0; i<mCodecPriority.count(mTerminal.codeclist()); i++)
|
||||
for (int i = 0; i < mCodecPriority.count(mTerminal.codeclist()); i++)
|
||||
mCodecPriority.codecAt(mTerminal.codeclist(), i).updateSdp(sdp.codecs(), direction);
|
||||
sdp.addCodec(resip::SdpContents::Session::Codec::TelephoneEvent);
|
||||
}
|
||||
@@ -122,22 +121,35 @@ void AudioProvider::updateSdpOffer(resip::SdpContents::Session::Medium& sdp, Sdp
|
||||
switch (mActive)
|
||||
{
|
||||
case mfActive:
|
||||
switch(mRemoteState)
|
||||
switch (mRemoteState)
|
||||
{
|
||||
case msSendonly: attr = "recvonly"; break;
|
||||
case msInactive: attr = "recvonly"; break;
|
||||
case msSendonly:
|
||||
attr = "recvonly";
|
||||
break;
|
||||
case msInactive:
|
||||
attr = "recvonly";
|
||||
break;
|
||||
case msRecvonly:
|
||||
case msSendRecv: break; // Do nothing here
|
||||
case msSendRecv:
|
||||
break; // Do nothing here
|
||||
}
|
||||
break;
|
||||
|
||||
case mfPaused:
|
||||
switch (mRemoteState)
|
||||
{
|
||||
case msRecvonly: attr = "sendonly"; break;
|
||||
case msSendonly: attr = "inactive"; break;
|
||||
case msInactive: attr = "inactive"; break;
|
||||
case msSendRecv: attr = "sendonly"; break;
|
||||
case msRecvonly:
|
||||
attr = "sendonly";
|
||||
break;
|
||||
case msSendonly:
|
||||
attr = "inactive";
|
||||
break;
|
||||
case msInactive:
|
||||
attr = "inactive";
|
||||
break;
|
||||
case msSendRecv:
|
||||
attr = "sendonly";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -227,7 +239,7 @@ bool AudioProvider::processSdpOffer(const resip::SdpContents::Session::Medium& m
|
||||
|
||||
// Use CodecListPriority mCodecPriority to work with codec priorities
|
||||
int pt;
|
||||
for (int localIndex=0; localIndex<mCodecPriority.count(mTerminal.codeclist()); localIndex++)
|
||||
for (int localIndex = 0; localIndex < mCodecPriority.count(mTerminal.codeclist()); localIndex++)
|
||||
{
|
||||
MT::Codec::Factory& factory = mCodecPriority.codecAt(mTerminal.codeclist(), localIndex);
|
||||
if ((pt = factory.processSdp(media.codecs(), sdpDirection)) != -1)
|
||||
@@ -242,14 +254,14 @@ bool AudioProvider::processSdpOffer(const resip::SdpContents::Session::Medium& m
|
||||
{
|
||||
// Find the most strong crypt suite
|
||||
const std::list<resip::Data>& vl = media.getValues("crypto");
|
||||
SrtpSuite ss = SRTP_NONE;
|
||||
ByteBuffer key;
|
||||
SrtpSuite ss = SRTP_NONE;
|
||||
ByteBuffer key;
|
||||
for (std::list<resip::Data>::const_iterator attrIter = vl.begin(); attrIter != vl.end(); attrIter++)
|
||||
{
|
||||
const resip::Data& attr = *attrIter;
|
||||
ByteBuffer tempkey;
|
||||
int tag = 1;
|
||||
SrtpSuite suite = processCryptoAttribute(attr, tempkey, &tag);
|
||||
ByteBuffer tempkey;
|
||||
int tag = 1;
|
||||
SrtpSuite suite = processCryptoAttribute(attr, tempkey, &tag);
|
||||
if (srtpSuiteStrength(suite) > srtpSuiteStrength(ss))
|
||||
{
|
||||
ss = suite;
|
||||
@@ -316,9 +328,9 @@ std::string AudioProvider::createCryptoAttribute(SrtpSuite suite, int tag)
|
||||
|
||||
SrtpSuite AudioProvider::processCryptoAttribute(const resip::Data& value, ByteBuffer& key, int* tag)
|
||||
{
|
||||
int srtpTag = 0;
|
||||
int srtpTag = 0;
|
||||
char suite[64], keyChunk[256];
|
||||
int components = sscanf(value.c_str(), "%d %63s inline: %255s", &srtpTag, suite, keyChunk);
|
||||
int components = sscanf(value.c_str(), "%d %63s inline: %255s", &srtpTag, suite, keyChunk);
|
||||
if (components != 3)
|
||||
return SRTP_NONE;
|
||||
if (tag)
|
||||
@@ -343,7 +355,7 @@ void AudioProvider::findRfc2833(const resip::SdpContents::Session::Medium::Codec
|
||||
for (codecIter = codecs.begin(); codecIter != codecs.end(); codecIter++)
|
||||
{
|
||||
if (strcmp("TELEPHONE-EVENT", codecIter->getName().c_str()) == 0 ||
|
||||
strcmp("telephone-event", codecIter->getName().c_str()) == 0)
|
||||
strcmp("telephone-event", codecIter->getName().c_str()) == 0)
|
||||
mRemoteTelephoneCodec = codecIter->payloadType();
|
||||
}
|
||||
}
|
||||
@@ -367,9 +379,9 @@ void AudioProvider::setupMirror(bool enable)
|
||||
mActiveStream->setupMirror(enable);
|
||||
}
|
||||
|
||||
void AudioProvider::setStateImpl(unsigned int state) {
|
||||
void AudioProvider::setStateImpl(unsigned int state)
|
||||
{
|
||||
mState = state;
|
||||
if (mActiveStream)
|
||||
mActiveStream->setState(state);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,104 +18,103 @@
|
||||
|
||||
class UserAgent;
|
||||
|
||||
class AudioProvider: public DataProvider
|
||||
class AudioProvider : public DataProvider
|
||||
{
|
||||
public:
|
||||
AudioProvider(UserAgent& agent, MT::Terminal& terminal);
|
||||
virtual ~AudioProvider();
|
||||
|
||||
AudioProvider(UserAgent& agent, MT::Terminal& terminal);
|
||||
virtual ~AudioProvider();
|
||||
|
||||
// Returns provider RTP name
|
||||
std::string streamName() override;
|
||||
|
||||
// Returns provider RTP profile name
|
||||
std::string streamProfile() override;
|
||||
|
||||
// Sets destination IP address
|
||||
void setDestinationAddress(const RtpPair<InternetAddress>& addr) override;
|
||||
// Returns provider RTP name
|
||||
std::string streamName() override;
|
||||
|
||||
// Processes incoming data
|
||||
void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& source) override;
|
||||
// Returns provider RTP profile name
|
||||
std::string streamProfile() override;
|
||||
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize) override;
|
||||
// Sets destination IP address
|
||||
void setDestinationAddress(const RtpPair<InternetAddress>& addr) override;
|
||||
|
||||
// Updates SDP offer
|
||||
void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) override;
|
||||
// Processes incoming data
|
||||
void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& source) override;
|
||||
|
||||
// Called by user agent when session is deleted.
|
||||
void sessionDeleted() override;
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer,
|
||||
unsigned int datasize) override;
|
||||
|
||||
// Called by user agent when session is terminated.
|
||||
void sessionTerminated() override;
|
||||
// Updates SDP offer
|
||||
void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) override;
|
||||
|
||||
// Called by user agent when session is started.
|
||||
void sessionEstablished(int conntype) override;
|
||||
// Called by user agent when session is deleted.
|
||||
void sessionDeleted() override;
|
||||
|
||||
// Called by user agent to save media socket for this provider
|
||||
void setSocket(const RtpPair<PDatagramSocket>& p4, const RtpPair<PDatagramSocket>& p6) override;
|
||||
|
||||
// Called by user agent to get media socket for this provider
|
||||
RtpPair<PDatagramSocket>& socket(int family) override;
|
||||
// Called by user agent when session is terminated.
|
||||
void sessionTerminated() override;
|
||||
|
||||
// Called by user agent to process media stream description from remote peer.
|
||||
// Returns true if description is processed succesfully. Otherwise method returns false.
|
||||
// myAnswer sets if the answer will be sent after.
|
||||
bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) override;
|
||||
// Called by user agent when session is started.
|
||||
void sessionEstablished(int conntype) override;
|
||||
|
||||
// Called by user agent to save media socket for this provider
|
||||
void setSocket(const RtpPair<PDatagramSocket>& p4, const RtpPair<PDatagramSocket>& p6) override;
|
||||
|
||||
// Called by user agent to get media socket for this provider
|
||||
RtpPair<PDatagramSocket>& socket(int family) override;
|
||||
|
||||
// Called by user agent to process media stream description from remote peer.
|
||||
// Returns true if description is processed succesfully. Otherwise method returns false.
|
||||
// myAnswer sets if the answer will be sent after.
|
||||
bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) override;
|
||||
|
||||
|
||||
void setState(unsigned state) override;
|
||||
unsigned state() override;
|
||||
MT::Statistics getStatistics() override;
|
||||
MT::PStream activeStream();
|
||||
void setState(unsigned state) override;
|
||||
unsigned state() override;
|
||||
MT::Statistics getStatistics() override;
|
||||
MT::PStream activeStream();
|
||||
|
||||
void readFile(const Audio::PWavFileReader& stream, MT::Stream::MediaDirection direction);
|
||||
void writeFile(const Audio::PWavFileWriter& stream, MT::Stream::MediaDirection direction);
|
||||
void setupMirror(bool enable);
|
||||
void readFile(const Audio::PWavFileReader& stream, MT::Stream::MediaDirection direction);
|
||||
void writeFile(const Audio::PWavFileWriter& stream, MT::Stream::MediaDirection direction);
|
||||
void setupMirror(bool enable);
|
||||
|
||||
void configureMediaObserver(MT::Stream::MediaObserver* observer, void* userTag);
|
||||
static SrtpSuite processCryptoAttribute(const resip::Data& value, ByteBuffer& key, int* tag = nullptr);
|
||||
void configureMediaObserver(MT::Stream::MediaObserver* observer, void* userTag);
|
||||
static SrtpSuite processCryptoAttribute(const resip::Data& value, ByteBuffer& key, int* tag = nullptr);
|
||||
|
||||
protected:
|
||||
// SDP's stream name
|
||||
std::string mStreamName;
|
||||
|
||||
// Socket handles to operate
|
||||
RtpPair<PDatagramSocket> mSocket4, mSocket6;
|
||||
// SDP's stream name
|
||||
std::string mStreamName;
|
||||
|
||||
// Destination IP4/6 address
|
||||
RtpPair<InternetAddress> mDestination;
|
||||
|
||||
MT::PStream mActiveStream;
|
||||
UserAgent& mUserAgent;
|
||||
MT::Terminal& mTerminal;
|
||||
MT::Statistics mBackupStats;
|
||||
// Socket handles to operate
|
||||
RtpPair<PDatagramSocket> mSocket4, mSocket6;
|
||||
|
||||
unsigned mState;
|
||||
SrtpSuite mSrtpSuite;
|
||||
int mSrtpTag = 1; // RFC 4568 tag of the negotiated crypto attribute
|
||||
struct RemoteCodec
|
||||
{
|
||||
RemoteCodec(MT::Codec::Factory* factory, int payloadType)
|
||||
:mFactory(factory), mRemotePayloadType(payloadType)
|
||||
{ }
|
||||
// Destination IP4/6 address
|
||||
RtpPair<InternetAddress> mDestination;
|
||||
|
||||
MT::Codec::Factory* mFactory;
|
||||
int mRemotePayloadType;
|
||||
};
|
||||
std::vector<RemoteCodec> mAvailableCodecs;
|
||||
int mRemoteTelephoneCodec; // Payload type of remote rfc2833 codec
|
||||
bool mRemoteNoSdp; // Marks if we got no-sdp offer
|
||||
MT::CodecListPriority mCodecPriority;
|
||||
MT::Stream::MediaObserver* mMediaObserver = nullptr;
|
||||
void* mMediaObserverTag = nullptr;
|
||||
MT::PStream mActiveStream;
|
||||
UserAgent& mUserAgent;
|
||||
MT::Terminal& mTerminal;
|
||||
MT::Statistics mBackupStats;
|
||||
|
||||
std::string createCryptoAttribute(SrtpSuite suite, int tag);
|
||||
void findRfc2833(const resip::SdpContents::Session::Medium::CodecContainer& codecs);
|
||||
unsigned mState;
|
||||
SrtpSuite mSrtpSuite;
|
||||
int mSrtpTag = 1; // RFC 4568 tag of the negotiated crypto attribute
|
||||
struct RemoteCodec
|
||||
{
|
||||
RemoteCodec(MT::Codec::Factory* factory, int payloadType) : mFactory(factory), mRemotePayloadType(payloadType)
|
||||
{
|
||||
}
|
||||
|
||||
// Implements setState() logic. This allows to be called from constructor (it is not virtual function)
|
||||
void setStateImpl(unsigned state);
|
||||
MT::Codec::Factory* mFactory;
|
||||
int mRemotePayloadType;
|
||||
};
|
||||
std::vector<RemoteCodec> mAvailableCodecs;
|
||||
int mRemoteTelephoneCodec; // Payload type of remote rfc2833 codec
|
||||
bool mRemoteNoSdp; // Marks if we got no-sdp offer
|
||||
MT::CodecListPriority mCodecPriority;
|
||||
MT::Stream::MediaObserver* mMediaObserver = nullptr;
|
||||
void* mMediaObserverTag = nullptr;
|
||||
|
||||
std::string createCryptoAttribute(SrtpSuite suite, int tag);
|
||||
void findRfc2833(const resip::SdpContents::Session::Medium::CodecContainer& codecs);
|
||||
|
||||
// Implements setState() logic. This allows to be called from constructor (it is not virtual function)
|
||||
void setStateImpl(unsigned state);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@ bool DataProvider::isSupported(const char* name)
|
||||
{
|
||||
return !strcmp(name, "audio");
|
||||
|
||||
//return (!strcmp(name, "screen") || !strcmp(name, "data") || !strcmp(name, "audio") || !strcmp(name, "video"));
|
||||
// return (!strcmp(name, "screen") || !strcmp(name, "data") || !strcmp(name, "audio") || !strcmp(name, "video"));
|
||||
}
|
||||
|
||||
void DataProvider::pause()
|
||||
@@ -20,7 +20,7 @@ void DataProvider::pause()
|
||||
|
||||
// Stop receive RTP stream
|
||||
if (state() & (int)StreamState::Receiving)
|
||||
setState( state() & ~(int)StreamState::Receiving );
|
||||
setState(state() & ~(int)StreamState::Receiving);
|
||||
|
||||
mActive = mfPaused;
|
||||
}
|
||||
@@ -28,10 +28,10 @@ void DataProvider::pause()
|
||||
void DataProvider::resume()
|
||||
{
|
||||
// Tell remote peer about resumed receiving in SDP
|
||||
//setState( state() | STATE_SIPRECV );
|
||||
// setState( state() | STATE_SIPRECV );
|
||||
|
||||
// Start receive RTP stream
|
||||
setState( state() | (int)StreamState::Receiving );
|
||||
setState(state() | (int)StreamState::Receiving);
|
||||
|
||||
mActive = mfActive;
|
||||
}
|
||||
@@ -44,31 +44,29 @@ bool DataProvider::processSdpOffer(const resip::SdpContents::Session::Medium& me
|
||||
mRemoteState = msSendonly;
|
||||
setState(state() & ~(int)StreamState::Sending);
|
||||
}
|
||||
else if (media.exists("recvonly"))
|
||||
{
|
||||
mRemoteState = msRecvonly;
|
||||
setState(state() & ~(int)StreamState::Receiving);
|
||||
}
|
||||
else if (media.exists("inactive"))
|
||||
{
|
||||
mRemoteState = msInactive;
|
||||
setState(state() & ~((int)StreamState::Sending | (int)StreamState::Receiving));
|
||||
}
|
||||
else
|
||||
if (media.exists("recvonly"))
|
||||
{
|
||||
mRemoteState = msSendRecv;
|
||||
switch (mActive)
|
||||
{
|
||||
mRemoteState = msRecvonly;
|
||||
setState(state() & ~(int)StreamState::Receiving);
|
||||
}
|
||||
else
|
||||
if (media.exists("inactive"))
|
||||
{
|
||||
mRemoteState = msInactive;
|
||||
setState(state() & ~((int)StreamState::Sending | (int)StreamState::Receiving) );
|
||||
}
|
||||
else
|
||||
{
|
||||
mRemoteState = msSendRecv;
|
||||
switch (mActive)
|
||||
{
|
||||
case mfActive:
|
||||
setState(state() | (int)StreamState::Sending | (int)StreamState::Receiving);
|
||||
break;
|
||||
case mfActive:
|
||||
setState(state() | (int)StreamState::Sending | (int)StreamState::Receiving);
|
||||
break;
|
||||
|
||||
case mfPaused:
|
||||
setState(state() | (int)StreamState::Sending );
|
||||
break;
|
||||
}
|
||||
}
|
||||
case mfPaused:
|
||||
setState(state() | (int)StreamState::Sending);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -33,59 +33,61 @@ public:
|
||||
msInactive
|
||||
};
|
||||
|
||||
static bool isSupported(const char* name);
|
||||
static bool isSupported(const char* name);
|
||||
|
||||
// Returns provider RTP name
|
||||
virtual std::string streamName() = 0;
|
||||
virtual std::string streamName() = 0;
|
||||
|
||||
// Returns provider RTP profile name
|
||||
virtual std::string streamProfile() = 0;
|
||||
virtual std::string streamProfile() = 0;
|
||||
|
||||
// Sets destination IP address
|
||||
virtual void setDestinationAddress(const RtpPair<InternetAddress>& addr) = 0;
|
||||
virtual void setDestinationAddress(const RtpPair<InternetAddress>& addr) = 0;
|
||||
|
||||
// Processes incoming data
|
||||
virtual void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& address) = 0;
|
||||
virtual void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize,
|
||||
InternetAddress& address) = 0;
|
||||
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
virtual void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize) = 0;
|
||||
virtual void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer,
|
||||
unsigned int datasize) = 0;
|
||||
|
||||
// Updates SDP offer
|
||||
virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) = 0;
|
||||
virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) = 0;
|
||||
|
||||
// Called by user agent when session is deleted. Comes after sessionTerminated().
|
||||
virtual void sessionDeleted() = 0;
|
||||
virtual void sessionDeleted() = 0;
|
||||
|
||||
// Called by user agent when session is terminated.
|
||||
virtual void sessionTerminated() = 0;
|
||||
virtual void sessionTerminated() = 0;
|
||||
|
||||
// Called by user agent when session is started.
|
||||
virtual void sessionEstablished(int conntype) = 0;
|
||||
virtual void sessionEstablished(int conntype) = 0;
|
||||
|
||||
// Called by user agent to save media socket for this provider
|
||||
virtual void setSocket(const RtpPair<PDatagramSocket>& p4, const RtpPair<PDatagramSocket>& p6) = 0;
|
||||
virtual void setSocket(const RtpPair<PDatagramSocket>& p4, const RtpPair<PDatagramSocket>& p6) = 0;
|
||||
|
||||
// Called by user agent to get media socket for this provider
|
||||
virtual RtpPair<PDatagramSocket>& socket(int family) = 0;
|
||||
|
||||
// Called by user agent to process media stream description from remote peer.
|
||||
// Returns true if description is processed succesfully. Otherwise method returns false.
|
||||
virtual bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) = 0;
|
||||
virtual bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) = 0;
|
||||
|
||||
virtual unsigned state() = 0;
|
||||
virtual void setState(unsigned state) = 0;
|
||||
virtual unsigned state() = 0;
|
||||
virtual void setState(unsigned state) = 0;
|
||||
|
||||
virtual void pause();
|
||||
virtual void resume();
|
||||
virtual void pause();
|
||||
virtual void resume();
|
||||
|
||||
virtual MT::Statistics getStatistics() = 0;
|
||||
virtual MT::Statistics getStatistics() = 0;
|
||||
|
||||
protected:
|
||||
MediaFlow mActive;
|
||||
MediaState mRemoteState;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<DataProvider> PDataProvider;
|
||||
typedef std::shared_ptr<DataProvider> PDataProvider;
|
||||
typedef std::vector<PDataProvider> DataProviderVector;
|
||||
|
||||
#endif
|
||||
|
||||
+290
-317
File diff suppressed because it is too large
Load Diff
+142
-133
@@ -70,45 +70,47 @@ enum
|
||||
|
||||
enum
|
||||
{
|
||||
CONFIG_IPV4 = 0, // Use IP4
|
||||
CONFIG_IPV6, // Use IP6.
|
||||
CONFIG_USERNAME, // Username. String value.
|
||||
CONFIG_DOMAIN, // Domain. String value.
|
||||
CONFIG_PASSWORD, // Password. String value.
|
||||
CONFIG_RINSTANCE, // Determines if SIP rinstance field has to be used during registration. Boolean value.
|
||||
CONFIG_INSTANCE_ID, // Instance id. It is alternative option to rinstance.
|
||||
CONFIG_DISPLAYNAME, // Optional user display name. String value.
|
||||
CONFIG_DOMAINPORT, // Optional domain port number. Integer value.
|
||||
CONFIG_REGISTERDURATION, // Wanted duration for registration. Integer value. It is MANDATORY value.
|
||||
CONFIG_RPORT, // Use SIP rport field. Recommended to set it to true. Boolean value.
|
||||
CONFIG_KEEPALIVETIME, // Interval between UDP keep-alive messages. Boolean value.
|
||||
CONFIG_RELAY, // Sets if TURN server must be used instead of STUN. Boolean value.
|
||||
CONFIG_ICETIMEOUT, // Optional timeout for ICE connectivity checks and candidate gathering. Integer value.
|
||||
CONFIG_ICEUSERNAME, // Optional username for TURN server. String value.
|
||||
CONFIG_ICEPASSWORD, // Optional password for TURN server. String value.
|
||||
CONFIG_SIPS, // Marks if account credentials are sips: scheme. Boolean value.
|
||||
CONFIG_STUNSERVER_IP, // Optional IP address of STUN/TURN server. String value. It is better to use CONFIG_STUNSERVER_NAME.
|
||||
CONFIG_STUNSERVER_NAME, // Host name of STUN/TURN server. stun.xten.com for example. String value.
|
||||
CONFIG_STUNSERVER_PORT, // Port number of STUN/TURN server. Integer value.
|
||||
CONFIG_USERAGENT, // Name of user agent in SIP headers. String value.
|
||||
CONFIG_ICEREQUIRED, // ICE MUST be present in remote peer offers and answers. Boolean value.
|
||||
CONFIG_TRANSPORT, // 0 - all transports, 1 - UDP, 2 - TCP, 3 - TLS,
|
||||
CONFIG_SUBSCRIPTION_TIME, // Subscription time (in seconds)
|
||||
CONFIG_IPV4 = 0, // Use IP4
|
||||
CONFIG_IPV6, // Use IP6.
|
||||
CONFIG_USERNAME, // Username. String value.
|
||||
CONFIG_DOMAIN, // Domain. String value.
|
||||
CONFIG_PASSWORD, // Password. String value.
|
||||
CONFIG_RINSTANCE, // Determines if SIP rinstance field has to be used during registration. Boolean value.
|
||||
CONFIG_INSTANCE_ID, // Instance id. It is alternative option to rinstance.
|
||||
CONFIG_DISPLAYNAME, // Optional user display name. String value.
|
||||
CONFIG_DOMAINPORT, // Optional domain port number. Integer value.
|
||||
CONFIG_REGISTERDURATION, // Wanted duration for registration. Integer value. It is MANDATORY value.
|
||||
CONFIG_RPORT, // Use SIP rport field. Recommended to set it to true. Boolean value.
|
||||
CONFIG_KEEPALIVETIME, // Interval between UDP keep-alive messages. Boolean value.
|
||||
CONFIG_RELAY, // Sets if TURN server must be used instead of STUN. Boolean value.
|
||||
CONFIG_ICETIMEOUT, // Optional timeout for ICE connectivity checks and candidate gathering. Integer value.
|
||||
CONFIG_ICEUSERNAME, // Optional username for TURN server. String value.
|
||||
CONFIG_ICEPASSWORD, // Optional password for TURN server. String value.
|
||||
CONFIG_SIPS, // Marks if account credentials are sips: scheme. Boolean value.
|
||||
CONFIG_STUNSERVER_IP, // Optional IP address of STUN/TURN server. String value. It is better to use
|
||||
// CONFIG_STUNSERVER_NAME.
|
||||
CONFIG_STUNSERVER_NAME, // Host name of STUN/TURN server. stun.xten.com for example. String value.
|
||||
CONFIG_STUNSERVER_PORT, // Port number of STUN/TURN server. Integer value.
|
||||
CONFIG_USERAGENT, // Name of user agent in SIP headers. String value.
|
||||
CONFIG_ICEREQUIRED, // ICE MUST be present in remote peer offers and answers. Boolean value.
|
||||
CONFIG_TRANSPORT, // 0 - all transports, 1 - UDP, 2 - TCP, 3 - TLS,
|
||||
CONFIG_SUBSCRIPTION_TIME, // Subscription time (in seconds)
|
||||
CONFIG_SUBSCRIPTION_REFRESHTIME, // Refresh interval for subscriptions
|
||||
CONFIG_DNS_CACHE_TIME, // DNS cache time; default is 86400 seconds
|
||||
CONFIG_PRESENCE_ID, // Tuple ID used in presence publishing; determines source device
|
||||
CONFIG_ROOTCERT, // Additional root cert in PEM format; string.
|
||||
CONFIG_CACHECREDENTIALS, // Attempt to cache credentials that comes in response from PBX. Use them when possible to reduce number of steps of SIP transaction
|
||||
CONFIG_RTCP_ATTR, // Use "rtcp" attribute in sdp. Default value is true.
|
||||
CONFIG_MULTIPLEXING, // Do rtp/rtcp multiplexing
|
||||
CONFIG_DEFERRELAYED, // Defer relayed media path
|
||||
CONFIG_PROXY, // Proxy host name or IP address
|
||||
CONFIG_PROXYPORT, // Proxy port number
|
||||
CONFIG_CODEC_PRIORITY, // Another VariantMap with codec priorities,
|
||||
CONFIG_ACCOUNT, // VariantMap with account configuration
|
||||
CONFIG_EXTERNALIP, // Use external/public IP in outgoing requests
|
||||
CONFIG_OWN_DNS, // Use predefined DNS servers
|
||||
CONFIG_REGID // reg-id value from RFC5626,
|
||||
CONFIG_DNS_CACHE_TIME, // DNS cache time; default is 86400 seconds
|
||||
CONFIG_PRESENCE_ID, // Tuple ID used in presence publishing; determines source device
|
||||
CONFIG_ROOTCERT, // Additional root cert in PEM format; string.
|
||||
CONFIG_CACHECREDENTIALS, // Attempt to cache credentials that comes in response from PBX. Use them when possible to
|
||||
// reduce number of steps of SIP transaction
|
||||
CONFIG_RTCP_ATTR, // Use "rtcp" attribute in sdp. Default value is true.
|
||||
CONFIG_MULTIPLEXING, // Do rtp/rtcp multiplexing
|
||||
CONFIG_DEFERRELAYED, // Defer relayed media path
|
||||
CONFIG_PROXY, // Proxy host name or IP address
|
||||
CONFIG_PROXYPORT, // Proxy port number
|
||||
CONFIG_CODEC_PRIORITY, // Another VariantMap with codec priorities,
|
||||
CONFIG_ACCOUNT, // VariantMap with account configuration
|
||||
CONFIG_EXTERNALIP, // Use external/public IP in outgoing requests
|
||||
CONFIG_OWN_DNS, // Use predefined DNS servers
|
||||
CONFIG_REGID // reg-id value from RFC5626,
|
||||
};
|
||||
|
||||
// Conntype parameter for OnSessionEstablished event
|
||||
@@ -130,7 +132,7 @@ public:
|
||||
typedef std::vector<SIPAction*> SIPActionVector;
|
||||
|
||||
// Session termination reason
|
||||
enum
|
||||
enum
|
||||
{
|
||||
Error,
|
||||
Timeout,
|
||||
@@ -139,35 +141,37 @@ enum
|
||||
RemoteBye,
|
||||
LocalCancel,
|
||||
RemoteCancel,
|
||||
Rejected, //Only as UAS, UAC has distinct onFailure callback
|
||||
Rejected, // Only as UAS, UAC has distinct onFailure callback
|
||||
Referred
|
||||
};
|
||||
|
||||
class UserAgent: public resip::ClientRegistrationHandler,
|
||||
public resip::InviteSessionHandler,
|
||||
public resip::DumShutdownHandler,
|
||||
public resip::ExternalLogger,
|
||||
class UserAgent : public resip::ClientRegistrationHandler,
|
||||
public resip::InviteSessionHandler,
|
||||
public resip::DumShutdownHandler,
|
||||
public resip::ExternalLogger,
|
||||
public resip::DnsResultSink,
|
||||
public resip::ClientSubscriptionHandler,
|
||||
public resip::ClientSubscriptionHandler,
|
||||
public resip::ServerSubscriptionHandler,
|
||||
public resip::ClientPagerMessageHandler,
|
||||
public resip::ClientPagerMessageHandler,
|
||||
public resip::ServerPagerMessageHandler,
|
||||
public resip::ClientPublicationHandler
|
||||
//public resip::InternalTransport::TransportLogger
|
||||
// public resip::InternalTransport::TransportLogger
|
||||
{
|
||||
friend class Account;
|
||||
friend class Session;
|
||||
friend class ResipSession;
|
||||
friend class NATDecorator;
|
||||
friend class WatcherQueue;
|
||||
|
||||
public:
|
||||
/* Compares two sip addresses. Returns true if they represent the same entity - user and domain are the same. Otherwise returns false. */
|
||||
static bool compareSipAddresses(const std::string& sip1, const std::string& sip2);
|
||||
/* Compares two sip addresses. Returns true if they represent the same entity - user and domain are the same.
|
||||
* Otherwise returns false. */
|
||||
static bool compareSipAddresses(const std::string& sip1, const std::string& sip2);
|
||||
static std::string formatSipAddress(const std::string& sip);
|
||||
static bool isSipAddressValid(const std::string& sip);
|
||||
static bool isSipAddressValid(const std::string& sip);
|
||||
struct SipAddress
|
||||
{
|
||||
bool mValid;
|
||||
bool mValid;
|
||||
std::string mScheme;
|
||||
std::string mUsername;
|
||||
std::string mDomain;
|
||||
@@ -181,113 +185,118 @@ public:
|
||||
|
||||
/* Brings user agent online. Basically it creates a signalling socket(s).
|
||||
This is asynchronous method. */
|
||||
void start();
|
||||
void start();
|
||||
|
||||
/* Shutdowns user agent. It closes all sessions, tries to unregister from server and disconnects from it.
|
||||
This is asynchronous method. onStop() event will be called later */
|
||||
void shutdown();
|
||||
void shutdown();
|
||||
|
||||
/* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything. onStop() is called in context of this method. */
|
||||
void stop();
|
||||
/* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything.
|
||||
* onStop() is called in context of this method. */
|
||||
void stop();
|
||||
|
||||
/* Checks if user agent is active (started). */
|
||||
bool active();
|
||||
bool active();
|
||||
|
||||
/* Used to refresh existing registration(s), publication, subscriptions. */
|
||||
void refresh();
|
||||
void refresh();
|
||||
|
||||
/* Runs sip & ice stacks. Event handlers are called in its context. */
|
||||
void process();
|
||||
void process();
|
||||
|
||||
/* Adds root cert in PEM format. Usable after start() call. */
|
||||
void addRootCert(const ByteBuffer& data);
|
||||
void addRootCert(const ByteBuffer& data);
|
||||
|
||||
PAccount createAccount(PVariantMap config);
|
||||
void deleteAccount(PAccount account);
|
||||
PAccount createAccount(PVariantMap config);
|
||||
void deleteAccount(PAccount account);
|
||||
|
||||
/* Creates session. Returns session ID. */
|
||||
PSession createSession(PAccount account);
|
||||
PSession createSession(PAccount account);
|
||||
|
||||
// Must be called when IP interface list is changed
|
||||
void updateInterfaceList();
|
||||
void updateInterfaceList();
|
||||
|
||||
// Called on new incoming session; providers shoukld
|
||||
virtual PDataProvider onProviderNeeded(const std::string& name) = 0;
|
||||
|
||||
// Called on new session offer
|
||||
virtual void onNewSession(PSession s) = 0;
|
||||
virtual void onNewSession(PSession s) = 0;
|
||||
|
||||
// Called when session is terminated
|
||||
virtual void onSessionTerminated(PSession s, int responsecode, int reason) = 0;
|
||||
virtual void onSessionTerminated(PSession s, int responsecode, int reason) = 0;
|
||||
|
||||
// Called when session is established ok i.e. after all ICE signalling is finished
|
||||
// Conntype is type of establish event - EV_SIP or EV_ICE
|
||||
virtual void onSessionEstablished(PSession s, int conntype, const RtpPair<InternetAddress>& p) = 0;
|
||||
virtual void onSessionEstablished(PSession s, int conntype, const RtpPair<InternetAddress>& p) = 0;
|
||||
|
||||
// Called when client session gets
|
||||
virtual void onSessionProvisional(PSession s, int code) = 0;
|
||||
virtual void onSessionProvisional(PSession s, int code) = 0;
|
||||
|
||||
// Called when user agent started
|
||||
virtual void onStart(int errorcode) = 0;
|
||||
virtual void onStart(int errorcode) = 0;
|
||||
|
||||
// Called when user agent stopped
|
||||
virtual void onStop() = 0;
|
||||
virtual void onStop() = 0;
|
||||
|
||||
// Called when account registered
|
||||
virtual void onAccountStart(PAccount account) = 0;
|
||||
virtual void onAccountStart(PAccount account) = 0;
|
||||
|
||||
// Called when account removed or failed (non zero error code)
|
||||
virtual void onAccountStop(PAccount account, int error) = 0;
|
||||
virtual void onAccountStop(PAccount account, int error) = 0;
|
||||
|
||||
// Called when connectivity checks failed.
|
||||
virtual void onConnectivityFailed(PSession s) = 0;
|
||||
virtual void onConnectivityFailed(PSession s) = 0;
|
||||
|
||||
// Called when new candidate is gathered
|
||||
virtual void onCandidateGathered(PSession s, const char* address);
|
||||
virtual void onCandidateGathered(PSession s, const char* address);
|
||||
|
||||
// Called when network change detected
|
||||
virtual void onNetworkChange(PSession s) = 0;
|
||||
virtual void onNetworkChange(PSession s) = 0;
|
||||
|
||||
// Called when all candidates are gathered
|
||||
virtual void onGathered(PSession s);
|
||||
virtual void onGathered(PSession s);
|
||||
|
||||
// Called when new connectivity check is finished
|
||||
virtual void onCheckFinished(PSession s, const char* description);
|
||||
virtual void onCheckFinished(PSession s, const char* description);
|
||||
|
||||
// Called when log message must be recorded
|
||||
virtual void onLog(const char* msg);
|
||||
virtual void onLog(const char* msg);
|
||||
|
||||
// Called when problem with SIP connection(s) detected
|
||||
virtual void onSipConnectionFailed() = 0;
|
||||
virtual void onSipConnectionFailed() = 0;
|
||||
|
||||
// Subscribe/publish presence methods
|
||||
virtual void onPublicationSuccess(PAccount acc);
|
||||
virtual void onPublicationTerminated(PAccount acc, int code);
|
||||
virtual void onClientObserverStart(PClientObserver observer);
|
||||
virtual void onServerObserverStart(PServerObserver observer);
|
||||
virtual void onClientObserverStop(PClientObserver observer, int code);
|
||||
virtual void onServerObserverStop(PServerObserver observer, int code);
|
||||
virtual void onPublicationSuccess(PAccount acc);
|
||||
virtual void onPublicationTerminated(PAccount acc, int code);
|
||||
virtual void onClientObserverStart(PClientObserver observer);
|
||||
virtual void onServerObserverStart(PServerObserver observer);
|
||||
virtual void onClientObserverStop(PClientObserver observer, int code);
|
||||
virtual void onServerObserverStop(PServerObserver observer, int code);
|
||||
|
||||
virtual void onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online, const std::string& content);
|
||||
virtual void onMessageArrived(PAccount account, const std::string& peer, const void* ptr, unsigned length);
|
||||
virtual void onMessageFailed(PAccount account, int id, const std::string& peer, int code, void* tag);
|
||||
virtual void onMessageSent(PAccount account, int id, const std::string& peer, void* tag);
|
||||
virtual void onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online,
|
||||
const std::string& content);
|
||||
virtual void onMessageArrived(PAccount account, const std::string& peer, const void* ptr, unsigned length);
|
||||
virtual void onMessageFailed(PAccount account, int id, const std::string& peer, int code, void* tag);
|
||||
virtual void onMessageSent(PAccount account, int id, const std::string& peer, void* tag);
|
||||
|
||||
// Configuration methods
|
||||
VariantMap& config();
|
||||
VariantMap& config();
|
||||
|
||||
public:
|
||||
// InviteSessionHandler implementation
|
||||
// InviteSessionHandler implementation
|
||||
#pragma region InviteSessionHandler implementation
|
||||
/// called when an initial INVITE or the intial response to an outoing invite
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override;
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override;
|
||||
/// called when an initial INVITE or the intial response to an outoing invite
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle, resip::InviteSession::OfferAnswerType oat,
|
||||
const resip::SipMessage& msg) override;
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle, resip::InviteSession::OfferAnswerType oat,
|
||||
const resip::SipMessage& msg) override;
|
||||
|
||||
/// Received a failure response from UAS
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an in-dialog provisional response is received that contains an SDP body
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&) override;
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&,
|
||||
const resip::SdpContents&) override;
|
||||
|
||||
/// called when dialog enters the Early state - typically after getting 18x
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage&) override;
|
||||
@@ -298,7 +307,8 @@ public:
|
||||
/// called when a dialog initiated as a UAS enters the connected state
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related=0) override;
|
||||
virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason,
|
||||
const resip::SipMessage* related = 0) override;
|
||||
|
||||
/// called when a fork that was created through a 1xx never receives a 2xx
|
||||
/// because another fork answered and this fork was canceled by a proxy.
|
||||
@@ -345,7 +355,8 @@ public:
|
||||
/// rejected using the server subscription. If the offer is accepted,
|
||||
/// DialogUsageManager::makeInviteSessionFromRefer can be used to create an
|
||||
/// InviteSession that will send notify messages using the ServerSubscription
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg) override;
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle,
|
||||
const resip::SipMessage& msg) override;
|
||||
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
@@ -353,7 +364,8 @@ public:
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an REFER message receives an accepted response
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg) override;
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle,
|
||||
const resip::SipMessage& msg) override;
|
||||
#pragma endregion
|
||||
|
||||
// ClientRegistrationHandler implementation
|
||||
@@ -367,7 +379,7 @@ public:
|
||||
|
||||
/// call on Retry-After failure.
|
||||
/// return values: -1 = fail, 0 = retry immediately, N = retry in N seconds
|
||||
int onRequestRetry(resip::ClientRegistrationHandle, int retrySeconds, const resip::SipMessage& response) override;
|
||||
int onRequestRetry(resip::ClientRegistrationHandle, int retrySeconds, const resip::SipMessage& response) override;
|
||||
|
||||
/// Called if registration fails, usage will be destroyed (unless a
|
||||
/// Registration retry interval is enabled in the Profile)
|
||||
@@ -377,14 +389,9 @@ public:
|
||||
|
||||
#pragma region ExternalLogger implementation
|
||||
/** return true to also do default logging, false to suppress default logging. */
|
||||
virtual bool operator()(resip::Log::Level level,
|
||||
const resip::Subsystem& subsystem,
|
||||
const resip::Data& appName,
|
||||
const char* file,
|
||||
int line,
|
||||
const resip::Data& message,
|
||||
const resip::Data& messageWithHeaders,
|
||||
const resip::Data& instanceName) override;
|
||||
virtual bool operator()(resip::Log::Level level, const resip::Subsystem& subsystem, const resip::Data& appName,
|
||||
const char* file, int line, const resip::Data& message,
|
||||
const resip::Data& messageWithHeaders, const resip::Data& instanceName) override;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region DnsResultSink implementation
|
||||
@@ -399,13 +406,13 @@ public:
|
||||
|
||||
#pragma region TransportLogger implementation
|
||||
void onSipMessage(int flow, const char* msg, unsigned int length, const sockaddr* addr, unsigned int addrlen);
|
||||
#pragma endregion
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ClientPublicationHandler
|
||||
void onSuccess(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
void onRemove(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
void onFailure(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
int onRequestRetry(resip::ClientPublicationHandle, int retrySeconds, const resip::SipMessage& status) override;
|
||||
int onRequestRetry(resip::ClientPublicationHandle, int retrySeconds, const resip::SipMessage& status) override;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region SubscriptionHandler
|
||||
@@ -413,13 +420,13 @@ public:
|
||||
void onUpdatePending(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
void onUpdateActive(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
|
||||
//unknown Subscription-State value
|
||||
// unknown Subscription-State value
|
||||
void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
int onRequestRetry(resip::ClientSubscriptionHandle, int retrySeconds, const resip::SipMessage& notify) override;
|
||||
int onRequestRetry(resip::ClientSubscriptionHandle, int retrySeconds, const resip::SipMessage& notify) override;
|
||||
|
||||
//subscription can be ended through a notify or a failure response.
|
||||
// subscription can be ended through a notify or a failure response.
|
||||
void onTerminated(resip::ClientSubscriptionHandle, const resip::SipMessage* msg) override;
|
||||
//not sure if this has any value.
|
||||
// not sure if this has any value.
|
||||
void onNewSubscription(resip::ClientSubscriptionHandle, const resip::SipMessage& notify) override;
|
||||
|
||||
/// called to allow app to adorn a message.
|
||||
@@ -438,56 +445,58 @@ public:
|
||||
|
||||
#pragma region PagerHandler
|
||||
void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status) override;
|
||||
void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr<resip::Contents> contents) override;
|
||||
void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status,
|
||||
std::unique_ptr<resip::Contents> contents) override;
|
||||
void onMessageArrived(resip::ServerPagerMessageHandle, const resip::SipMessage& message) override;
|
||||
#pragma endregion
|
||||
|
||||
void onDumCanBeDeleted() override;
|
||||
|
||||
protected:
|
||||
// Mutex to protect this instance
|
||||
Mutex mGuard;
|
||||
Mutex mGuard;
|
||||
|
||||
// Smart pointer to resiprocate's master profile instance. The stack configuration holds here.
|
||||
std::shared_ptr<resip::MasterProfile> mProfile;
|
||||
std::shared_ptr<resip::MasterProfile> mProfile;
|
||||
|
||||
// Resiprocate's SIP stack object pointer
|
||||
resip::SipStack* mStack;
|
||||
resip::SipStack* mStack;
|
||||
|
||||
// Resiprocate's dialog usage manager object pointer
|
||||
resip::DialogUsageManager* mDum;
|
||||
resip::DialogUsageManager* mDum;
|
||||
|
||||
// List of available transports. They are owned by SipStack - so there is no need to delete instances in UserAgent.
|
||||
std::vector<resip::InternalTransport*> mTransportList;
|
||||
|
||||
typedef std::map<int, PSession> SessionMap;
|
||||
typedef std::map<int, PSession> SessionMap;
|
||||
|
||||
// Session's map
|
||||
SessionMap mSessionMap;
|
||||
SessionMap mSessionMap;
|
||||
|
||||
// Used configuration
|
||||
VariantMap mConfig;
|
||||
VariantMap mConfig;
|
||||
|
||||
// Action vector
|
||||
SIPActionVector mActionVector;
|
||||
SIPActionVector mActionVector;
|
||||
|
||||
typedef std::map<int, PClientObserver> ClientObserverMap;
|
||||
ClientObserverMap mClientObserverMap;
|
||||
ClientObserverMap mClientObserverMap;
|
||||
|
||||
typedef std::map<int, PServerObserver> ServerObserverMap;
|
||||
ServerObserverMap mServerObserverMap;
|
||||
ServerObserverMap mServerObserverMap;
|
||||
|
||||
typedef std::set<PAccount> AccountSet;
|
||||
AccountSet mAccountSet;
|
||||
typedef std::set<PAccount> AccountSet;
|
||||
AccountSet mAccountSet;
|
||||
|
||||
// Constructs and sends INVITE to remote peer. Remote peer address is stored inside session object.
|
||||
void sendOffer(Session* session);
|
||||
void internalStopSession(Session& session);
|
||||
void processWatchingList();
|
||||
bool handleMultipartRelatedNotify(const resip::SipMessage& notify);
|
||||
void sendOffer(Session* session);
|
||||
void internalStopSession(Session& session);
|
||||
void processWatchingList();
|
||||
bool handleMultipartRelatedNotify(const resip::SipMessage& notify);
|
||||
|
||||
PSession getUserSession(int sessionId);
|
||||
PAccount getAccount(const resip::NameAddr& myAddr);
|
||||
PAccount getAccount(Account* account);
|
||||
PAccount getAccount(int sessionId);
|
||||
PSession getUserSession(int sessionId);
|
||||
PAccount getAccount(const resip::NameAddr& myAddr);
|
||||
PAccount getAccount(Account* account);
|
||||
PAccount getAccount(int sessionId);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
#include "EP_NetworkQueue.h"
|
||||
#include "EP_Engine.h"
|
||||
|
||||
WatcherQueue::WatcherQueue(UserAgent& ua)
|
||||
:mActiveId(0), mAgent(ua)
|
||||
{}
|
||||
WatcherQueue::WatcherQueue(UserAgent& ua) : mActiveId(0), mAgent(ua) {}
|
||||
|
||||
WatcherQueue::~WatcherQueue()
|
||||
{}
|
||||
WatcherQueue::~WatcherQueue() {}
|
||||
|
||||
int WatcherQueue::add(const std::string& peer, const std::string& package, void* tag)
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
|
||||
// Check if queue has similar item
|
||||
for (unsigned i=0; i<mItemList.size(); i++)
|
||||
for (unsigned i = 0; i < mItemList.size(); i++)
|
||||
{
|
||||
Item& item = mItemList[i];
|
||||
if (item.mTarget == peer && item.mPackage == package && item.mState != Item::State_Deleting)
|
||||
@@ -43,7 +40,7 @@ void WatcherQueue::remove(int id)
|
||||
ice::Lock l(mGuard);
|
||||
|
||||
// Check if queue has similar item
|
||||
for (auto& item: mItemList)
|
||||
for (auto& item : mItemList)
|
||||
{
|
||||
if (item.mId == id && id)
|
||||
{
|
||||
@@ -60,7 +57,7 @@ void WatcherQueue::refresh(int id)
|
||||
ice::Lock l(mGuard);
|
||||
|
||||
// Check if queue has similar item
|
||||
for (auto& item: mItemList)
|
||||
for (auto& item : mItemList)
|
||||
{
|
||||
if (item.mId == id && id)
|
||||
{
|
||||
@@ -77,7 +74,7 @@ void WatcherQueue::process()
|
||||
{
|
||||
// Find next item to process
|
||||
ItemList::iterator i = mItemList.begin();
|
||||
for (;i != mItemList.end() && !i->scheduled(); i++)
|
||||
for (; i != mItemList.end() && !i->scheduled(); i++)
|
||||
;
|
||||
if (i == mItemList.end())
|
||||
return;
|
||||
@@ -133,7 +130,7 @@ void WatcherQueue::process()
|
||||
|
||||
void WatcherQueue::onTerminated(int id, int code)
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
ice::Lock l(mGuard);
|
||||
ItemList::iterator i = findById(id);
|
||||
if (i != mItemList.end())
|
||||
{
|
||||
@@ -148,7 +145,7 @@ void WatcherQueue::onTerminated(int id, int code)
|
||||
|
||||
void WatcherQueue::onEstablished(int id, int code)
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
ice::Lock l(mGuard);
|
||||
ItemList::iterator i = findById(id);
|
||||
if (i != mItemList.end())
|
||||
{
|
||||
@@ -161,7 +158,7 @@ void WatcherQueue::onEstablished(int id, int code)
|
||||
|
||||
WatcherQueue::ItemList::iterator WatcherQueue::findById(int id)
|
||||
{
|
||||
for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++)
|
||||
for (ItemList::iterator i = mItemList.begin(); i != mItemList.end(); i++)
|
||||
if (i->mId == id)
|
||||
return i;
|
||||
return mItemList.end();
|
||||
@@ -170,7 +167,7 @@ WatcherQueue::ItemList::iterator WatcherQueue::findById(int id)
|
||||
void WatcherQueue::clear()
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++)
|
||||
for (ItemList::iterator i = mItemList.begin(); i != mItemList.end(); i++)
|
||||
{
|
||||
if (i->mHandle.isValid())
|
||||
i->mHandle->end();
|
||||
|
||||
@@ -27,26 +27,26 @@ public:
|
||||
State_Deleting
|
||||
};
|
||||
|
||||
resip::ClientSubscriptionHandle mHandle; // Subscription handle
|
||||
ResipSession* mSession = nullptr;
|
||||
State mState = State::State_None;
|
||||
std::string mTarget; // Target's address
|
||||
std::string mPackage; // Event package
|
||||
void* mTag = nullptr; // User tag
|
||||
int mId = 0; // Related session ID - it is always non-zero (zero is here for initialization only)
|
||||
resip::ClientSubscriptionHandle mHandle; // Subscription handle
|
||||
ResipSession* mSession = nullptr;
|
||||
State mState = State::State_None;
|
||||
std::string mTarget; // Target's address
|
||||
std::string mPackage; // Event package
|
||||
void* mTag = nullptr; // User tag
|
||||
int mId = 0; // Related session ID - it is always non-zero (zero is here for initialization only)
|
||||
|
||||
Item()
|
||||
{}
|
||||
Item() {}
|
||||
|
||||
bool scheduled()
|
||||
{
|
||||
return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete || mState == State_ScheduledToRefresh;
|
||||
return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete ||
|
||||
mState == State_ScheduledToRefresh;
|
||||
}
|
||||
};
|
||||
WatcherQueue(UserAgent& agent);
|
||||
~WatcherQueue();
|
||||
|
||||
int add(const std::string& peer, const std::string& package, void* tag);
|
||||
int add(const std::string& peer, const std::string& package, void* tag);
|
||||
void remove(int id);
|
||||
void refresh(int id);
|
||||
void clear();
|
||||
@@ -56,13 +56,13 @@ public:
|
||||
|
||||
protected:
|
||||
typedef std::vector<Item> ItemList;
|
||||
ItemList mItemList;
|
||||
ice::Mutex mGuard;
|
||||
UserAgent& mAgent;
|
||||
int mActiveId;
|
||||
ItemList mItemList;
|
||||
ice::Mutex mGuard;
|
||||
UserAgent& mAgent;
|
||||
int mActiveId;
|
||||
|
||||
void process();
|
||||
ItemList::iterator findById(int id);
|
||||
void process();
|
||||
ItemList::iterator findById(int id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,13 +9,9 @@
|
||||
#include <resip/stack/Pidf.hxx>
|
||||
#include <resip/dum/ClientSubscription.hxx>
|
||||
|
||||
ClientObserver::ClientObserver()
|
||||
{
|
||||
}
|
||||
ClientObserver::ClientObserver() {}
|
||||
|
||||
ClientObserver::~ClientObserver()
|
||||
{
|
||||
}
|
||||
ClientObserver::~ClientObserver() {}
|
||||
|
||||
void ClientObserver::refresh()
|
||||
{
|
||||
@@ -27,13 +23,12 @@ void ClientObserver::stop()
|
||||
{
|
||||
if (mHandle.isValid())
|
||||
mHandle->end();
|
||||
else
|
||||
else if (mSession)
|
||||
{
|
||||
mSession->runTerminatedEvent(ResipSession::Type_Subscription);
|
||||
if (mSession)
|
||||
{
|
||||
mSession->runTerminatedEvent(ResipSession::Type_Subscription);
|
||||
if (mSession)
|
||||
mSession->end();
|
||||
}
|
||||
mSession->end();
|
||||
}
|
||||
mSession = NULL;
|
||||
}
|
||||
|
||||
@@ -42,11 +37,7 @@ std::string ClientObserver::peer()
|
||||
return mPeer;
|
||||
}
|
||||
|
||||
ServerObserver::ServerObserver()
|
||||
:mState(State_Incoming)
|
||||
{
|
||||
|
||||
}
|
||||
ServerObserver::ServerObserver() : mState(State_Incoming) {}
|
||||
|
||||
ServerObserver::~ServerObserver()
|
||||
{
|
||||
|
||||
@@ -23,19 +23,20 @@ class ClientObserver
|
||||
{
|
||||
friend class Account;
|
||||
friend class UserAgent;
|
||||
|
||||
public:
|
||||
ClientObserver();
|
||||
~ClientObserver();
|
||||
|
||||
void refresh();
|
||||
void stop();
|
||||
void refresh();
|
||||
void stop();
|
||||
std::string peer();
|
||||
|
||||
protected:
|
||||
resip::ClientSubscriptionHandle mHandle;
|
||||
ResipSession* mSession;
|
||||
int mSessionId;
|
||||
std::string mPeer;
|
||||
ResipSession* mSession;
|
||||
int mSessionId;
|
||||
std::string mPeer;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ClientObserver> PClientObserver;
|
||||
@@ -43,6 +44,7 @@ typedef std::shared_ptr<ClientObserver> PClientObserver;
|
||||
class ServerObserver
|
||||
{
|
||||
friend class UserAgent;
|
||||
|
||||
public:
|
||||
ServerObserver();
|
||||
~ServerObserver();
|
||||
@@ -50,9 +52,9 @@ public:
|
||||
std::string peer() const;
|
||||
std::string package() const;
|
||||
|
||||
void accept();
|
||||
void update(std::string simpleId, bool online, std::string msg);
|
||||
void stop();
|
||||
void accept();
|
||||
void update(std::string simpleId, bool online, std::string msg);
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
enum State
|
||||
@@ -61,11 +63,11 @@ protected:
|
||||
State_Active,
|
||||
State_Closed
|
||||
};
|
||||
State mState;
|
||||
State mState;
|
||||
resip::ServerSubscriptionHandle mHandle;
|
||||
std::string mPeer, mPackage;
|
||||
resip::Uri mContact;
|
||||
int mSessionId;
|
||||
std::string mPeer, mPackage;
|
||||
resip::Uri mContact;
|
||||
int mSessionId;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ServerObserver> PServerObserver;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2007-2012 Dmytro Bogovych <dmytro.bogovych@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,11 +13,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
enum
|
||||
{
|
||||
CONFIRMATION_PT = 1,
|
||||
DATA_PT = 2
|
||||
CONFIRMATION_PT = 1,
|
||||
DATA_PT = 2
|
||||
};
|
||||
|
||||
#define CONFIRMATION_TIMEOUT 500
|
||||
@@ -39,266 +39,267 @@ enum
|
||||
|
||||
ReliableTunnel::ReliableTunnel(const char* streamname)
|
||||
{
|
||||
mStack.setEncryption(this);
|
||||
mStreamName = streamname;
|
||||
mBandwidth = 0;
|
||||
mExitSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
mDataSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
mStack.setEncryption(this);
|
||||
mStreamName = streamname;
|
||||
mBandwidth = 0;
|
||||
mExitSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
mDataSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
}
|
||||
|
||||
ReliableTunnel::~ReliableTunnel()
|
||||
{
|
||||
::CloseHandle(mDataSignal);
|
||||
::CloseHandle(mExitSignal);
|
||||
::CloseHandle(mDataSignal);
|
||||
::CloseHandle(mExitSignal);
|
||||
}
|
||||
|
||||
std::string ReliableTunnel::streamName()
|
||||
{
|
||||
return mStreamName;
|
||||
return mStreamName;
|
||||
}
|
||||
|
||||
std::string ReliableTunnel::streamProfile()
|
||||
{
|
||||
return "RTP/DP";
|
||||
return "RTP/DP";
|
||||
}
|
||||
|
||||
void ReliableTunnel::setDestinationAddress(InternetAddress& addr)
|
||||
{
|
||||
mDestination = addr;
|
||||
mDestination = addr;
|
||||
}
|
||||
|
||||
|
||||
void ReliableTunnel::queueData(const void* bufferptr, int buffersize)
|
||||
{
|
||||
assert(bufferptr != NULL);
|
||||
assert(buffersize != 0);
|
||||
assert(bufferptr != NULL);
|
||||
assert(buffersize != 0);
|
||||
|
||||
resip::Lock l(mNewQueuedGuard);
|
||||
mNewQueued.push_back(std::string((const char*)bufferptr, buffersize));
|
||||
|
||||
::SetEvent(mDataSignal);
|
||||
resip::Lock l(mNewQueuedGuard);
|
||||
mNewQueued.push_back(std::string((const char*)bufferptr, buffersize));
|
||||
|
||||
::SetEvent(mDataSignal);
|
||||
}
|
||||
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
void ReliableTunnel::sendData(InternetAddress& addr, const void* dataBuffer, unsigned int datasize)
|
||||
{
|
||||
switch (addr.type())
|
||||
{
|
||||
case AF_INET:
|
||||
mSocket4.sendDatagram(addr, dataBuffer, datasize);
|
||||
return;
|
||||
switch (addr.type())
|
||||
{
|
||||
case AF_INET:
|
||||
mSocket4.sendDatagram(addr, dataBuffer, datasize);
|
||||
return;
|
||||
|
||||
case AF_INET6:
|
||||
mSocket4.sendDatagram(addr, dataBuffer, datasize);
|
||||
return;
|
||||
}
|
||||
case AF_INET6:
|
||||
mSocket4.sendDatagram(addr, dataBuffer, datasize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ReliableTunnel::sessionEstablished(int conntype)
|
||||
{
|
||||
// Start worker thread
|
||||
if (conntype == EV_ICE)
|
||||
run();
|
||||
// Start worker thread
|
||||
if (conntype == EV_ICE)
|
||||
run();
|
||||
}
|
||||
|
||||
void ReliableTunnel::sessionTerminated()
|
||||
{
|
||||
// Stop worker thread
|
||||
::SetEvent(mExitSignal);
|
||||
shutdown();
|
||||
join();
|
||||
// Stop worker thread
|
||||
::SetEvent(mExitSignal);
|
||||
shutdown();
|
||||
join();
|
||||
}
|
||||
|
||||
void ReliableTunnel::updateSdpOffer(resip::SdpContents::Session::Medium& sdp)
|
||||
{
|
||||
// Get new destination port
|
||||
mDestination.setPort((unsigned short)sdp.port());
|
||||
|
||||
sdp.addCodec(resip::SdpContents::Session::Codec("rt", 104));
|
||||
// Get new destination port
|
||||
mDestination.setPort((unsigned short)sdp.port());
|
||||
|
||||
sdp.addCodec(resip::SdpContents::Session::Codec("rt", 104));
|
||||
}
|
||||
|
||||
void ReliableTunnel::setSocket(DatagramSocket& socket4, DatagramSocket& socket6)
|
||||
{
|
||||
mSocket4 = socket4;
|
||||
mSocket6 = socket6;
|
||||
mSocket4 = socket4;
|
||||
mSocket6 = socket6;
|
||||
}
|
||||
|
||||
|
||||
DatagramSocket& ReliableTunnel::socket(int family)
|
||||
{
|
||||
switch (family)
|
||||
{
|
||||
case AF_INET:
|
||||
return mSocket4;
|
||||
switch (family)
|
||||
{
|
||||
case AF_INET:
|
||||
return mSocket4;
|
||||
|
||||
case AF_INET6:
|
||||
return mSocket4;
|
||||
case AF_INET6:
|
||||
return mSocket4;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool ReliableTunnel::processSdpOffer(const resip::SdpContents::Session::Medium& media)
|
||||
{
|
||||
//check for default port number
|
||||
mDestination.setPort(media.port());
|
||||
|
||||
return true;
|
||||
// check for default port number
|
||||
mDestination.setPort(media.port());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReliableTunnel::thread()
|
||||
{
|
||||
// Construct event array
|
||||
while (true)
|
||||
{
|
||||
HANDLE eventarray[2] = { mDataSignal, mExitSignal };
|
||||
|
||||
DWORD rescode = ::WaitForMultipleObjects(2, eventarray, FALSE, INFINITE);
|
||||
if (rescode == WAIT_OBJECT_0)
|
||||
// Construct event array
|
||||
while (true)
|
||||
{
|
||||
resip::Lock l(mNewQueuedGuard);
|
||||
for (unsigned i = 0; i<mNewQueued.size(); i++)
|
||||
mStack.queueOutgoing(mNewQueued[i].c_str(), mNewQueued[i].size());
|
||||
mNewQueued.clear();
|
||||
|
||||
sendOutgoing();
|
||||
HANDLE eventarray[2] = {mDataSignal, mExitSignal};
|
||||
|
||||
DWORD rescode = ::WaitForMultipleObjects(2, eventarray, FALSE, INFINITE);
|
||||
if (rescode == WAIT_OBJECT_0)
|
||||
{
|
||||
resip::Lock l(mNewQueuedGuard);
|
||||
for (unsigned i = 0; i < mNewQueued.size(); i++)
|
||||
mStack.queueOutgoing(mNewQueued[i].c_str(), mNewQueued[i].size());
|
||||
mNewQueued.clear();
|
||||
|
||||
sendOutgoing();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ReliableTunnel::setBandwidth(unsigned int bytesPerSecond)
|
||||
{
|
||||
mBandwidth = bytesPerSecond;
|
||||
mBandwidth = bytesPerSecond;
|
||||
}
|
||||
|
||||
unsigned int ReliableTunnel::bandwidth()
|
||||
{
|
||||
return mBandwidth;
|
||||
return mBandwidth;
|
||||
}
|
||||
|
||||
void ReliableTunnel::processData(const void* dataptr, int datasize)
|
||||
{
|
||||
resip::Lock l(mStackGuard);
|
||||
mStack.processIncoming(dataptr, datasize);
|
||||
resip::Lock l(mStackGuard);
|
||||
mStack.processIncoming(dataptr, datasize);
|
||||
}
|
||||
|
||||
bool ReliableTunnel::hasData()
|
||||
{
|
||||
resip::Lock l(mStackGuard);
|
||||
|
||||
return mIncomingData.size() || mStack.hasAppData();
|
||||
resip::Lock l(mStackGuard);
|
||||
|
||||
return mIncomingData.size() || mStack.hasAppData();
|
||||
}
|
||||
|
||||
unsigned ReliableTunnel::getData(void* ptr, unsigned capacity)
|
||||
{
|
||||
resip::Lock l(mStackGuard);
|
||||
|
||||
char* dataOut = (char*)ptr;
|
||||
|
||||
while (capacity && hasData())
|
||||
{
|
||||
// Check if mIncomingData is empty
|
||||
if (!mIncomingData.size())
|
||||
{
|
||||
unsigned available = mStack.appData(NULL);
|
||||
if (!available)
|
||||
return 0;
|
||||
resip::Lock l(mStackGuard);
|
||||
|
||||
mIncomingData.resize(available);
|
||||
mIncomingData.rewind();
|
||||
mStack.appData(mIncomingData.mutableData());
|
||||
char* dataOut = (char*)ptr;
|
||||
|
||||
while (capacity && hasData())
|
||||
{
|
||||
// Check if mIncomingData is empty
|
||||
if (!mIncomingData.size())
|
||||
{
|
||||
unsigned available = mStack.appData(NULL);
|
||||
if (!available)
|
||||
return 0;
|
||||
|
||||
mIncomingData.resize(available);
|
||||
mIncomingData.rewind();
|
||||
mStack.appData(mIncomingData.mutableData());
|
||||
}
|
||||
|
||||
if (mIncomingData.size())
|
||||
{
|
||||
unsigned toCopy = min(capacity, mIncomingData.size());
|
||||
mIncomingData.dequeueBuffer(dataOut, toCopy);
|
||||
dataOut += toCopy;
|
||||
capacity -= toCopy;
|
||||
}
|
||||
}
|
||||
|
||||
if (mIncomingData.size())
|
||||
{
|
||||
unsigned toCopy = min(capacity, mIncomingData.size());
|
||||
mIncomingData.dequeueBuffer(dataOut, toCopy);
|
||||
dataOut += toCopy;
|
||||
capacity -= toCopy;
|
||||
}
|
||||
}
|
||||
|
||||
return dataOut - (char*)ptr;
|
||||
return dataOut - (char*)ptr;
|
||||
}
|
||||
|
||||
// Returns block size for encryption algorythm
|
||||
int ReliableTunnel::blockSize()
|
||||
{
|
||||
return 8;
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
||||
// Encrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value.
|
||||
void ReliableTunnel::encrypt(void* dataPtr, int dataSize)
|
||||
{
|
||||
if (mEncryptionKey.empty())
|
||||
return;
|
||||
if (mEncryptionKey.empty())
|
||||
return;
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
for (unsigned i=0; i<dataSize / blockSize(); i++)
|
||||
BF_ecb_encrypt((unsigned char*)dataPtr + i * blockSize(), (unsigned char*)dataPtr + i * blockSize(), &mCipher, BF_ENCRYPT);
|
||||
for (unsigned i = 0; i < dataSize / blockSize(); i++)
|
||||
BF_ecb_encrypt((unsigned char*)dataPtr + i * blockSize(), (unsigned char*)dataPtr + i * blockSize(), &mCipher,
|
||||
BF_ENCRYPT);
|
||||
#endif
|
||||
|
||||
#ifdef USE_CRYPTOPP
|
||||
for (unsigned i=0; i<dataSize / blockSize(); i++)
|
||||
mEncryptor.ProcessBlock((unsigned char*)dataPtr + i * blockSize());
|
||||
for (unsigned i = 0; i < dataSize / blockSize(); i++)
|
||||
mEncryptor.ProcessBlock((unsigned char*)dataPtr + i * blockSize());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Decrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value.
|
||||
void ReliableTunnel::decrypt(void* dataPtr, int dataSize)
|
||||
{
|
||||
if (mEncryptionKey.empty())
|
||||
return;
|
||||
if (mEncryptionKey.empty())
|
||||
return;
|
||||
#ifdef USE_OPENSSL
|
||||
for (unsigned i=0; i<dataSize / blockSize(); i++)
|
||||
BF_ecb_encrypt((unsigned char*)dataPtr + i * blockSize(), (unsigned char*)dataPtr + i * blockSize(), &mCipher, BF_DECRYPT);
|
||||
for (unsigned i = 0; i < dataSize / blockSize(); i++)
|
||||
BF_ecb_encrypt((unsigned char*)dataPtr + i * blockSize(), (unsigned char*)dataPtr + i * blockSize(), &mCipher,
|
||||
BF_DECRYPT);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_CRYPTOPP
|
||||
for (unsigned i=0; i<dataSize / blockSize(); i++)
|
||||
mDecryptor.ProcessBlock((unsigned char*)dataPtr + i * blockSize());
|
||||
for (unsigned i = 0; i < dataSize / blockSize(); i++)
|
||||
mDecryptor.ProcessBlock((unsigned char*)dataPtr + i * blockSize());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Calculates CRC
|
||||
unsigned ReliableTunnel::crc(const void* dataptr, int datasize)
|
||||
{
|
||||
unsigned long result;
|
||||
ICEImpl::CRC32 crc;
|
||||
crc.fullCrc((const unsigned char*)dataptr, datasize, &result);
|
||||
|
||||
return result;
|
||||
unsigned long result;
|
||||
ICEImpl::CRC32 crc;
|
||||
crc.fullCrc((const unsigned char*)dataptr, datasize, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ReliableTunnel::sendOutgoing()
|
||||
{
|
||||
// Check if stack has to send smth
|
||||
if (mStack.hasPacketToSend())
|
||||
{
|
||||
// Get data to send
|
||||
char buffer[2048];
|
||||
int length = sizeof(buffer);
|
||||
mStack.getPacketToSend(buffer, length);
|
||||
|
||||
// Send it over UDP
|
||||
sendData(this->mDestination, buffer, length);
|
||||
}
|
||||
// Check if stack has to send smth
|
||||
if (mStack.hasPacketToSend())
|
||||
{
|
||||
// Get data to send
|
||||
char buffer[2048];
|
||||
int length = sizeof(buffer);
|
||||
mStack.getPacketToSend(buffer, length);
|
||||
|
||||
// Send it over UDP
|
||||
sendData(this->mDestination, buffer, length);
|
||||
}
|
||||
}
|
||||
|
||||
void ReliableTunnel::setEncryptionKey(void* ptr, unsigned length)
|
||||
{
|
||||
#ifdef USE_OPENSSL
|
||||
BF_set_key(&mCipher, length, (const unsigned char*)ptr);
|
||||
BF_set_key(&mCipher, length, (const unsigned char*)ptr);
|
||||
#endif
|
||||
|
||||
#ifdef USE_CRYPTOPP
|
||||
mEncryptor.SetKey((unsigned char*)ptr, length);
|
||||
mDecryptor.SetKey((unsigned char*)ptr, length);
|
||||
mEncryptor.SetKey((unsigned char*)ptr, length);
|
||||
mDecryptor.SetKey((unsigned char*)ptr, length);
|
||||
#endif
|
||||
|
||||
// Save key
|
||||
mEncryptionKey = std::string((const char*)ptr, length);
|
||||
// Save key
|
||||
mEncryptionKey = std::string((const char*)ptr, length);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2007-2010 Dmytro Bogovych <dmytro.bogovych@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __RELIABLE_TUNNEL_H
|
||||
#define __RELIABLE_TUNNEL_H
|
||||
@@ -26,122 +26,121 @@
|
||||
|
||||
#include "../ICE/ICEReliableTransport.h"
|
||||
#ifdef USE_CRYPTOPP
|
||||
# include "../Libs/CryptoPP/blowfish.h"
|
||||
#include "../Libs/CryptoPP/blowfish.h"
|
||||
#endif
|
||||
#ifdef USE_OPENSSL
|
||||
# include "../Libs/openssl/include/openssl/blowfish.h"
|
||||
#include "../Libs/openssl/include/openssl/blowfish.h"
|
||||
#endif
|
||||
|
||||
class ReliableTunnel: public DataProvider, public resip::ThreadIf, public ICEImpl::ReliableTransport::Encryption
|
||||
class ReliableTunnel : public DataProvider, public resip::ThreadIf, public ICEImpl::ReliableTransport::Encryption
|
||||
{
|
||||
public:
|
||||
ReliableTunnel(const char* streamname);
|
||||
virtual ~ReliableTunnel();
|
||||
|
||||
// Returns provider RTP name
|
||||
virtual std::string streamName();
|
||||
|
||||
// Returns provider RTP profile name
|
||||
virtual std::string streamProfile();
|
||||
|
||||
// Sets destination IP address
|
||||
virtual void setDestinationAddress(InternetAddress& addr);
|
||||
ReliableTunnel(const char* streamname);
|
||||
virtual ~ReliableTunnel();
|
||||
|
||||
// Processes incoming data
|
||||
virtual void processData(const void* dataBuffer, int dataSize);
|
||||
// Returns provider RTP name
|
||||
virtual std::string streamName();
|
||||
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
virtual void sendData(InternetAddress& destination, const void* dataBuffer, unsigned int datasize);
|
||||
// Returns provider RTP profile name
|
||||
virtual std::string streamProfile();
|
||||
|
||||
// Updates SDP offer
|
||||
virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp);
|
||||
// Sets destination IP address
|
||||
virtual void setDestinationAddress(InternetAddress& addr);
|
||||
|
||||
// Called by user agent when session is terminated.
|
||||
virtual void sessionTerminated();
|
||||
// Processes incoming data
|
||||
virtual void processData(const void* dataBuffer, int dataSize);
|
||||
|
||||
// Called by user agent when session is started.
|
||||
virtual void sessionEstablished(int conntype);
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
virtual void sendData(InternetAddress& destination, const void* dataBuffer, unsigned int datasize);
|
||||
|
||||
// Updates SDP offer
|
||||
virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp);
|
||||
|
||||
// Called by user agent when session is terminated.
|
||||
virtual void sessionTerminated();
|
||||
|
||||
// Called by user agent when session is started.
|
||||
virtual void sessionEstablished(int conntype);
|
||||
|
||||
// Called by user agent to save media socket for this provider
|
||||
virtual void setSocket(DatagramSocket& socket4, DatagramSocket& socket6);
|
||||
|
||||
// Called by user agent to get media socket for this provider
|
||||
virtual DatagramSocket& socket(int family);
|
||||
virtual void setSocket(DatagramSocket& socket4, DatagramSocket& socket6);
|
||||
|
||||
// Called by user agent to process media stream description from remote peer.
|
||||
// Returns true if description is processed succesfully. Otherwise method returns false.
|
||||
virtual bool processSdpOffer(const resip::SdpContents::Session::Medium& media);
|
||||
// Called by user agent to get media socket for this provider
|
||||
virtual DatagramSocket& socket(int family);
|
||||
|
||||
virtual void thread();
|
||||
// Called by user agent to process media stream description from remote peer.
|
||||
// Returns true if description is processed succesfully. Otherwise method returns false.
|
||||
virtual bool processSdpOffer(const resip::SdpContents::Session::Medium& media);
|
||||
|
||||
// Enqueues outgoing packet to sending queue
|
||||
void queueData(const void* bufferPtr, int bufferSize);
|
||||
|
||||
void setBandwidth(unsigned int bytesPerSecond);
|
||||
unsigned int bandwidth();
|
||||
|
||||
// Checks if there is any received application data
|
||||
bool hasData();
|
||||
|
||||
// Reads received data. If ptr is NULL - the length of available data is returned.
|
||||
unsigned getData(void* ptr, unsigned capacity);
|
||||
virtual void thread();
|
||||
|
||||
void setEncryptionKey(void* ptr, unsigned length);
|
||||
// Enqueues outgoing packet to sending queue
|
||||
void queueData(const void* bufferPtr, int bufferSize);
|
||||
|
||||
void setBandwidth(unsigned int bytesPerSecond);
|
||||
unsigned int bandwidth();
|
||||
|
||||
// Checks if there is any received application data
|
||||
bool hasData();
|
||||
|
||||
// Reads received data. If ptr is NULL - the length of available data is returned.
|
||||
unsigned getData(void* ptr, unsigned capacity);
|
||||
|
||||
void setEncryptionKey(void* ptr, unsigned length);
|
||||
|
||||
protected:
|
||||
// SDP's stream name
|
||||
std::string mStreamName;
|
||||
// SDP's stream name
|
||||
std::string mStreamName;
|
||||
|
||||
// Transport stack
|
||||
ICEImpl::ReliableTransport mStack;
|
||||
|
||||
// Socket handles to operate
|
||||
DatagramSocket mSocket4;
|
||||
DatagramSocket mSocket6;
|
||||
// Transport stack
|
||||
ICEImpl::ReliableTransport mStack;
|
||||
|
||||
// Destination IP4/6 address
|
||||
InternetAddress mDestination;
|
||||
|
||||
// Win32 exit signal
|
||||
HANDLE mExitSignal;
|
||||
|
||||
// Win32 "new outgoing data" signal
|
||||
HANDLE mDataSignal;
|
||||
|
||||
// Mutex to protect queuing/sending outgoing data
|
||||
resip::Mutex mOutgoingMtx;
|
||||
|
||||
std::vector<std::string>
|
||||
mNewQueued;
|
||||
resip::Mutex mNewQueuedGuard;
|
||||
resip::Mutex mStackGuard;
|
||||
// Socket handles to operate
|
||||
DatagramSocket mSocket4;
|
||||
DatagramSocket mSocket6;
|
||||
|
||||
// Destination IP4/6 address
|
||||
InternetAddress mDestination;
|
||||
|
||||
// Win32 exit signal
|
||||
HANDLE mExitSignal;
|
||||
|
||||
// Win32 "new outgoing data" signal
|
||||
HANDLE mDataSignal;
|
||||
|
||||
// Mutex to protect queuing/sending outgoing data
|
||||
resip::Mutex mOutgoingMtx;
|
||||
|
||||
std::vector<std::string> mNewQueued;
|
||||
resip::Mutex mNewQueuedGuard;
|
||||
resip::Mutex mStackGuard;
|
||||
|
||||
unsigned int mBandwidth;
|
||||
std::string mEncryptionKey;
|
||||
|
||||
unsigned int mBandwidth;
|
||||
std::string mEncryptionKey;
|
||||
|
||||
#ifdef USE_CRYPTOPP
|
||||
CryptoPP::BlowfishEncryption mEncryptor;
|
||||
CryptoPP::BlowfishDecryption mDecryptor;
|
||||
CryptoPP::BlowfishEncryption mEncryptor;
|
||||
CryptoPP::BlowfishDecryption mDecryptor;
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
BF_KEY mCipher;
|
||||
BF_KEY mCipher;
|
||||
#endif
|
||||
|
||||
ICEImpl::ICEByteBuffer mIncomingData;
|
||||
ICEImpl::ICEByteBuffer mIncomingData;
|
||||
|
||||
// Returns block size for encryption algorythm
|
||||
int blockSize();
|
||||
|
||||
// Encrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value.
|
||||
void encrypt(void* dataPtr, int dataSize);
|
||||
// Returns block size for encryption algorythm
|
||||
int blockSize();
|
||||
|
||||
// Decrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value.
|
||||
void decrypt(void* dataPtr, int dataSize);
|
||||
// Encrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value.
|
||||
void encrypt(void* dataPtr, int dataSize);
|
||||
|
||||
// Calculates CRC
|
||||
unsigned crc(const void* dataptr, int datasize);
|
||||
// Decrypts dataPtr buffer inplace. dataSize must be odd to GetBlockSize() returned value.
|
||||
void decrypt(void* dataPtr, int dataSize);
|
||||
|
||||
void sendOutgoing();
|
||||
// Calculates CRC
|
||||
unsigned crc(const void* dataptr, int datasize);
|
||||
|
||||
void sendOutgoing();
|
||||
};
|
||||
#endif
|
||||
+115
-109
@@ -13,21 +13,18 @@
|
||||
|
||||
#define LOG_SUBSYSTEM "engine"
|
||||
|
||||
typedef resip::SdpContents::Session::Medium Medium;
|
||||
typedef resip::SdpContents::Session::Medium Medium;
|
||||
typedef resip::SdpContents::Session::MediumContainer MediumContainer;
|
||||
|
||||
#define IS_MULTIPLEX() mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool() ? SocketHeap::DoMultiplexing : SocketHeap::DontMultiplexing
|
||||
#define IS_MULTIPLEX() \
|
||||
mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool() ? SocketHeap::DoMultiplexing : SocketHeap::DontMultiplexing
|
||||
|
||||
|
||||
//------------ ResipSessionAppDialog ------------
|
||||
#pragma region ResipSessionAppDialog
|
||||
ResipSessionAppDialog::ResipSessionAppDialog(resip::HandleManager& ham) : AppDialog(ham)
|
||||
{
|
||||
}
|
||||
ResipSessionAppDialog::ResipSessionAppDialog(resip::HandleManager& ham) : AppDialog(ham) {}
|
||||
|
||||
ResipSessionAppDialog::~ResipSessionAppDialog()
|
||||
{
|
||||
}
|
||||
ResipSessionAppDialog::~ResipSessionAppDialog() {}
|
||||
#pragma endregion
|
||||
|
||||
|
||||
@@ -35,7 +32,7 @@ ResipSessionAppDialog::~ResipSessionAppDialog()
|
||||
|
||||
std::atomic_int ResipSession::InstanceCounter;
|
||||
|
||||
ResipSession::ResipSession(resip::DialogUsageManager& dum)
|
||||
ResipSession::ResipSession(resip::DialogUsageManager& dum)
|
||||
: resip::AppDialogSet(dum), mUserAgent(nullptr), mType(Type_None), mSessionId(0), mSession(0)
|
||||
{
|
||||
ResipSession::InstanceCounter++;
|
||||
@@ -54,7 +51,7 @@ ResipSession::~ResipSession()
|
||||
mSession->mResipSession = nullptr;
|
||||
runTerminatedEvent(Type_Auto, 0, 0);
|
||||
}
|
||||
catch(...)
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -94,7 +91,8 @@ void ResipSession::runTerminatedEvent(Type type, int code, int reason)
|
||||
case Type_Subscription:
|
||||
if (mSession)
|
||||
{
|
||||
UserAgent::ClientObserverMap::iterator observerIter = mUserAgent->mClientObserverMap.find(mSession->sessionId());
|
||||
UserAgent::ClientObserverMap::iterator observerIter =
|
||||
mUserAgent->mClientObserverMap.find(mSession->sessionId());
|
||||
if (observerIter != mUserAgent->mClientObserverMap.end())
|
||||
mUserAgent->onClientObserverStop(observerIter->second, code);
|
||||
}
|
||||
@@ -186,14 +184,9 @@ std::shared_ptr<resip::UserProfile> ResipSession::selectUASUserProfile(const res
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Session::Stream
|
||||
Session::Stream::Stream()
|
||||
:mRtcpAttr(false), mRtcpMuxAttr(false)
|
||||
{
|
||||
}
|
||||
Session::Stream::Stream() : mRtcpAttr(false), mRtcpMuxAttr(false) {}
|
||||
|
||||
Session::Stream::~Stream()
|
||||
{
|
||||
}
|
||||
Session::Stream::~Stream() {}
|
||||
|
||||
void Session::Stream::setProvider(PDataProvider provider)
|
||||
{
|
||||
@@ -261,7 +254,7 @@ void Session::Stream::setRtcpMuxAttr(bool value)
|
||||
std::atomic_int Session::InstanceCounter;
|
||||
|
||||
Session::Session(PAccount account)
|
||||
{
|
||||
{
|
||||
InstanceCounter++;
|
||||
mAccount = account;
|
||||
mSessionId = Session::generateId();
|
||||
@@ -290,14 +283,15 @@ Session::~Session()
|
||||
mResipSession->setSession(NULL);
|
||||
clearProvidersAndSockets();
|
||||
}
|
||||
catch(...)
|
||||
{}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
InstanceCounter--;
|
||||
}
|
||||
|
||||
void Session::start(const std::string& peer)
|
||||
{
|
||||
ICELogInfo( << "Attempt to start session to " << peer);
|
||||
ICELogInfo(<< "Attempt to start session to " << peer);
|
||||
Lock l(mGuard);
|
||||
|
||||
if (mResipSession)
|
||||
@@ -320,7 +314,7 @@ void Session::start(const std::string& peer)
|
||||
// Mark session as Initiator
|
||||
mRole = Session::Initiator;
|
||||
|
||||
resip::Data addrData(peer);
|
||||
resip::Data addrData(peer);
|
||||
resip::NameAddr addr(addrData);
|
||||
|
||||
// Save target address
|
||||
@@ -334,7 +328,7 @@ void Session::stop()
|
||||
{
|
||||
ICELogInfo(<< "Stopping session " << mSessionId);
|
||||
Lock l(mGuard);
|
||||
for (unsigned i=0; i<mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < mStreamList.size(); i++)
|
||||
{
|
||||
Session::Stream& dataStream = mStreamList[i];
|
||||
|
||||
@@ -344,8 +338,8 @@ void Session::stop()
|
||||
dataStream.provider()->sessionTerminated();
|
||||
|
||||
// Free socket
|
||||
SocketHeap::instance().freeSocketPair( dataStream.socket4() );
|
||||
SocketHeap::instance().freeSocketPair( dataStream.socket6() );
|
||||
SocketHeap::instance().freeSocketPair(dataStream.socket4());
|
||||
SocketHeap::instance().freeSocketPair(dataStream.socket6());
|
||||
|
||||
// Drop the references so the destructor's cleanup does not free them again
|
||||
dataStream.setSocket4(RtpPair<PDatagramSocket>());
|
||||
@@ -357,7 +351,7 @@ void Session::stop()
|
||||
mResipSession->runTerminatedEvent(ResipSession::Type_Call, 0, LocalBye);
|
||||
|
||||
if (mResipSession)
|
||||
mResipSession->end(); // Stop SIP session
|
||||
mResipSession->end(); // Stop SIP session
|
||||
}
|
||||
|
||||
void Session::accept()
|
||||
@@ -366,7 +360,8 @@ void Session::accept()
|
||||
|
||||
Lock locksession(mGuard);
|
||||
|
||||
// If ICE candidate gathering is not finished - just mark session as accepted. It will be accepted in ICE handling code.
|
||||
// If ICE candidate gathering is not finished - just mark session as accepted. It will be accepted in ICE handling
|
||||
// code.
|
||||
mAcceptedByUser = true;
|
||||
|
||||
if (mGatheredCandidates || mIceStack->state() == ice::IceNone)
|
||||
@@ -405,7 +400,7 @@ void Session::accept()
|
||||
|
||||
void Session::reject(int code)
|
||||
{
|
||||
ICELogInfo( << "Attempt to reject session " << mSessionId);
|
||||
ICELogInfo(<< "Attempt to reject session " << mSessionId);
|
||||
|
||||
Lock l(mGuard);
|
||||
|
||||
@@ -449,8 +444,8 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
|
||||
MT::Statistics stat;
|
||||
|
||||
// Iterate all session providers
|
||||
Stream* media = nullptr;
|
||||
for (Stream& stream: mStreamList)
|
||||
Stream* media = nullptr;
|
||||
for (Stream& stream : mStreamList)
|
||||
{
|
||||
if (!stream.provider())
|
||||
continue;
|
||||
@@ -473,7 +468,9 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
|
||||
info[SessionInfo_SentRtp] = static_cast<int>(stat.mSentRtp);
|
||||
info[SessionInfo_SentRtcp] = static_cast<int>(stat.mSentRtcp);
|
||||
if (stat.mFirstRtpTime)
|
||||
info[SessionInfo_Duration] = static_cast<int>(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - *(stat.mFirstRtpTime)).count());
|
||||
info[SessionInfo_Duration] = static_cast<int>(
|
||||
std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - *(stat.mFirstRtpTime))
|
||||
.count());
|
||||
else
|
||||
info[SessionInfo_Duration] = 0;
|
||||
|
||||
@@ -481,7 +478,8 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
|
||||
info[SessionInfo_PacketLoss] = static_cast<int>((stat.mPacketLoss * 1000) / stat.mReceivedRtp);
|
||||
|
||||
if (media && mIceStack)
|
||||
info[SessionInfo_AudioPeer] = mIceStack->remoteAddress(media->iceInfo().mStreamId, media->iceInfo().mComponentId.mRtp).toStdString();
|
||||
info[SessionInfo_AudioPeer] =
|
||||
mIceStack->remoteAddress(media->iceInfo().mStreamId, media->iceInfo().mComponentId.mRtp).toStdString();
|
||||
|
||||
info[SessionInfo_Jitter] = stat.mJitter;
|
||||
if (stat.mRttDelay.is_initialized())
|
||||
@@ -505,7 +503,8 @@ PAccount Session::account()
|
||||
return mAccount;
|
||||
}
|
||||
|
||||
void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize)
|
||||
void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr,
|
||||
unsigned receivedSize)
|
||||
{
|
||||
Lock l(mGuard);
|
||||
|
||||
@@ -513,7 +512,7 @@ void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const
|
||||
return;
|
||||
|
||||
// Check if it STUN packet and must be processed by ICE stack
|
||||
//ICELogDebug (<< "Received UDP packet from " << src.ip() << ":" << src.port());
|
||||
// ICELogDebug (<< "Received UDP packet from " << src.ip() << ":" << src.port());
|
||||
ice::ByteBuffer received(receivedPtr, receivedSize);
|
||||
received.setRemoteAddress(src);
|
||||
|
||||
@@ -531,7 +530,7 @@ void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const
|
||||
if (received.size() >= 4)
|
||||
{
|
||||
bool turnPrefix = false;
|
||||
for (unsigned i=0; i<mTurnPrefixList.size() && !turnPrefix; i++)
|
||||
for (unsigned i = 0; i < mTurnPrefixList.size() && !turnPrefix; i++)
|
||||
turnPrefix |= ice::Stack::isChannelData(received, mTurnPrefixList[i]);
|
||||
if (turnPrefix)
|
||||
received.erase(0, 4);
|
||||
@@ -546,7 +545,7 @@ void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const
|
||||
{
|
||||
ice::ByteBuffer buffer(receivedPtr, receivedSize);
|
||||
buffer.setRemoteAddress(src);
|
||||
/*bool processed = */mIceStack->processIncomingData(stream, component, buffer);
|
||||
/*bool processed = */ mIceStack->processIncomingData(stream, component, buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -594,20 +593,19 @@ void Session::onGathered(ice::Stack* stack, void* tag)
|
||||
|
||||
if (mRole == Initiator)
|
||||
mUserAgent->sendOffer(this);
|
||||
else
|
||||
if (mRole == Acceptor)
|
||||
{
|
||||
// Mark session as gathered ICE candidates
|
||||
mGatheredCandidates = true;
|
||||
else if (mRole == Acceptor)
|
||||
{
|
||||
// Mark session as gathered ICE candidates
|
||||
mGatheredCandidates = true;
|
||||
|
||||
// if AcceptSession was already called() on session - recall it again to make real work
|
||||
if (mAcceptedByUser)
|
||||
{
|
||||
// Check if session is needed here - because session can be terminated already
|
||||
if (mResipSession && mInviteHandle.isValid())
|
||||
accept();
|
||||
}
|
||||
// if AcceptSession was already called() on session - recall it again to make real work
|
||||
if (mAcceptedByUser)
|
||||
{
|
||||
// Check if session is needed here - because session can be terminated already
|
||||
if (mResipSession && mInviteHandle.isValid())
|
||||
accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Session::onSuccess(ice::Stack* stack, void* tag)
|
||||
@@ -616,7 +614,7 @@ void Session::onSuccess(ice::Stack* stack, void* tag)
|
||||
|
||||
RtpPair<InternetAddress> t;
|
||||
|
||||
for (unsigned i=0; i<this->mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < this->mStreamList.size(); i++)
|
||||
{
|
||||
PDataProvider p = mStreamList[i].provider();
|
||||
if (p)
|
||||
@@ -638,8 +636,8 @@ void Session::onSuccess(ice::Stack* stack, void* tag)
|
||||
|
||||
mUserAgent->onSessionEstablished(mUserAgent->getUserSession(mSessionId), EV_ICE, t);
|
||||
|
||||
//time to resend updated media info over SIP
|
||||
//TODO:
|
||||
// time to resend updated media info over SIP
|
||||
// TODO:
|
||||
}
|
||||
|
||||
void Session::onFailed(ice::Stack* stack, void* tag)
|
||||
@@ -647,17 +645,17 @@ void Session::onFailed(ice::Stack* stack, void* tag)
|
||||
ICELogError(<< "ICE connectivity check failed for session " << mSessionId);
|
||||
mUserAgent->onConnectivityFailed(mUserAgent->getUserSession(mSessionId));
|
||||
|
||||
//if (mInviteHandle.isValid())
|
||||
// mInviteHandle->end();
|
||||
// if (mInviteHandle.isValid())
|
||||
// mInviteHandle->end();
|
||||
}
|
||||
|
||||
void Session::onNetworkChange(ice::Stack *stack, void *tag)
|
||||
void Session::onNetworkChange(ice::Stack* stack, void* tag)
|
||||
{
|
||||
ICELogInfo(<< "Network change detected by ICE stack for session " << mSessionId);
|
||||
mUserAgent->onNetworkChange(mUserAgent->getUserSession(mSessionId));
|
||||
}
|
||||
|
||||
void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
|
||||
void Session::buildSdp(resip::SdpContents& sdp, SdpDirection sdpDirection)
|
||||
{
|
||||
sdp.session().name() = "ICE_UA";
|
||||
sdp.session().origin().user() = "user";
|
||||
@@ -675,8 +673,12 @@ void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
|
||||
ice::NetworkAddress defaultAddr = mIceStack->defaultAddress(mStreamList.front().iceInfo().mStreamId, ICE_RTP_ID);
|
||||
|
||||
// Set IP address for origin and connection
|
||||
sdp.session().origin().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6);
|
||||
sdp.session().connection().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6);
|
||||
sdp.session().origin().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET
|
||||
? resip::SdpContents::IP4
|
||||
: resip::SdpContents::IP6);
|
||||
sdp.session().connection().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET
|
||||
? resip::SdpContents::IP4
|
||||
: resip::SdpContents::IP6);
|
||||
|
||||
// Add ICE credentials
|
||||
if (mIceStack->state() > ice::IceNone)
|
||||
@@ -686,30 +688,30 @@ void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
|
||||
}
|
||||
|
||||
// Iterate media streams
|
||||
for (unsigned i=0; i<mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < mStreamList.size(); i++)
|
||||
{
|
||||
Stream& stream = mStreamList[i];
|
||||
if (!stream.provider())
|
||||
continue;
|
||||
DataProvider& provider = *mStreamList[i].provider();
|
||||
DataProvider& provider = *mStreamList[i].provider();
|
||||
|
||||
// Get default stream port
|
||||
ice::NetworkAddress rtpPort = mIceStack->defaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTP_ID),
|
||||
rtcpPort = mIceStack->defaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID);
|
||||
rtcpPort = mIceStack->defaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID);
|
||||
|
||||
// Define media stream SDP's header
|
||||
resip::SdpContents::Session::Medium media(resip::Data(provider.streamName()), rtpPort.port(), 0, resip::Data(provider.streamProfile()));
|
||||
resip::SdpContents::Session::Medium media(resip::Data(provider.streamName()), rtpPort.port(), 0,
|
||||
resip::Data(provider.streamProfile()));
|
||||
|
||||
// Add "rtcp" attribute
|
||||
if (mUserAgent->mConfig[CONFIG_RTCP_ATTR].asBool())
|
||||
{
|
||||
if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool())
|
||||
rtcpPort = rtpPort;
|
||||
else
|
||||
if (rtcpPort.isEmpty())
|
||||
else if (rtcpPort.isEmpty())
|
||||
{
|
||||
rtcpPort = rtpPort;
|
||||
rtcpPort.setPort( rtpPort.port() + 1);
|
||||
rtcpPort.setPort(rtpPort.port() + 1);
|
||||
}
|
||||
|
||||
media.addAttribute("rtcp", resip::Data(rtcpPort.port()));
|
||||
@@ -732,7 +734,7 @@ void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
|
||||
if (mIceStack->hasComponent(ii.mStreamId, ii.mComponentId.mRtcp))
|
||||
mIceStack->fillCandidateList(ii.mStreamId, ii.mComponentId.mRtcp, candidates);
|
||||
|
||||
for (unsigned c=0; c<candidates.size(); c++)
|
||||
for (unsigned c = 0; c < candidates.size(); c++)
|
||||
media.addAttribute("candidate", candidates[c].c_str());
|
||||
}
|
||||
|
||||
@@ -766,7 +768,7 @@ void Session::addProvider(PDataProvider provider)
|
||||
return;
|
||||
|
||||
// Avoid duplicating providers
|
||||
for (unsigned i=0; i<mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < mStreamList.size(); i++)
|
||||
if (mStreamList[i].provider() == provider)
|
||||
return;
|
||||
|
||||
@@ -777,18 +779,18 @@ void Session::addProvider(PDataProvider provider)
|
||||
{
|
||||
if (!streamIter->provider() && (streamIter->socket4().mRtp->isValid() || streamIter->socket6().mRtp->isValid()))
|
||||
{
|
||||
streamIter->setProvider( provider );
|
||||
streamIter->setProvider(provider);
|
||||
provider->setSocket(streamIter->socket4(), streamIter->socket6());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Stream s;
|
||||
s.setProvider( provider );
|
||||
s.setProvider(provider);
|
||||
|
||||
// Allocate socket for provider
|
||||
s.setSocket4( SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX()) );
|
||||
s.setSocket6( SocketHeap::instance().allocSocketPair(AF_INET6, this, IS_MULTIPLEX()) );
|
||||
s.setSocket4(SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX()));
|
||||
s.setSocket6(SocketHeap::instance().allocSocketPair(AF_INET6, this, IS_MULTIPLEX()));
|
||||
s.provider()->setSocket(s.socket4(), s.socket6());
|
||||
|
||||
// Create ICE stream/component
|
||||
@@ -797,10 +799,11 @@ void Session::addProvider(PDataProvider provider)
|
||||
ii.mPort4 = s.socket4().mRtp->localport();
|
||||
ii.mPort6 = s.socket6().mRtp->localport();
|
||||
|
||||
ii.mComponentId.mRtp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtp->localport(),
|
||||
s.socket6().mRtp->localport());
|
||||
ii.mComponentId.mRtp =
|
||||
mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtp->localport(), s.socket6().mRtp->localport());
|
||||
if (!mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool())
|
||||
ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtcp->localport(), s.socket6().mRtcp->localport());
|
||||
ii.mComponentId.mRtcp =
|
||||
mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtcp->localport(), s.socket6().mRtcp->localport());
|
||||
|
||||
s.setIceInfo(ii);
|
||||
|
||||
@@ -825,7 +828,7 @@ int Session::sessionId()
|
||||
}
|
||||
|
||||
std::atomic_int Session::IdGenerator;
|
||||
int Session::generateId()
|
||||
int Session::generateId()
|
||||
{
|
||||
return ++IdGenerator;
|
||||
}
|
||||
@@ -857,7 +860,7 @@ void Session::setTag(void* tag)
|
||||
|
||||
void Session::pause()
|
||||
{
|
||||
for (unsigned i=0; i<mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < mStreamList.size(); i++)
|
||||
{
|
||||
Stream& s = mStreamList[i];
|
||||
if (s.provider())
|
||||
@@ -868,7 +871,7 @@ void Session::pause()
|
||||
|
||||
void Session::resume()
|
||||
{
|
||||
for (unsigned i=0; i<mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < mStreamList.size(); i++)
|
||||
{
|
||||
Stream& s = mStreamList[i];
|
||||
if (s.provider())
|
||||
@@ -880,9 +883,9 @@ void Session::resume()
|
||||
void Session::refreshMediaPath()
|
||||
{
|
||||
// Recreate media sockets
|
||||
for (unsigned i=0; i<mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < mStreamList.size(); i++)
|
||||
{
|
||||
Stream& s= mStreamList[i];
|
||||
Stream& s = mStreamList[i];
|
||||
PDataProvider p = s.provider();
|
||||
if (!p)
|
||||
continue;
|
||||
@@ -891,7 +894,7 @@ void Session::refreshMediaPath()
|
||||
SocketHeap::instance().freeSocketPair(p->socket(AF_INET));
|
||||
|
||||
// Bring new socket to provider and stream
|
||||
RtpPair<PDatagramSocket> s4 = SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX() ),
|
||||
RtpPair<PDatagramSocket> s4 = SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX()),
|
||||
s6 = SocketHeap::instance().allocSocketPair(AF_INET6, this, IS_MULTIPLEX());
|
||||
|
||||
p->setSocket(s4, s6);
|
||||
@@ -912,11 +915,11 @@ void Session::refreshMediaPath()
|
||||
int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd, std::string iceUfrag,
|
||||
std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media)
|
||||
{
|
||||
bool iceRestart = false;
|
||||
bool iceRestart = false;
|
||||
|
||||
int mediaCompatible = 0;
|
||||
int mediaCompatible = 0;
|
||||
MediumContainer::const_iterator mediaIter;
|
||||
unsigned streamIndex = 0;
|
||||
unsigned streamIndex = 0;
|
||||
for (mediaIter = media.begin(); mediaIter != media.end(); ++mediaIter, ++streamIndex)
|
||||
{
|
||||
// Get reference to SDP description of remote stream
|
||||
@@ -929,7 +932,7 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
|
||||
|
||||
// Ask about provider if needed
|
||||
if (!stream.provider())
|
||||
stream.setProvider( mUserAgent->onProviderNeeded(remoteStream.name().c_str()) );
|
||||
stream.setProvider(mUserAgent->onProviderNeeded(remoteStream.name().c_str()));
|
||||
|
||||
// Check the stream validity
|
||||
if (!stream.provider())
|
||||
@@ -938,8 +941,8 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
|
||||
continue;
|
||||
|
||||
// See for rtcp & rtcp-mux attribute
|
||||
stream.setRtcpAttr( remoteStream.exists("rtcp") );
|
||||
stream.setRtcpMuxAttr( remoteStream.exists("rtcp-mux") );
|
||||
stream.setRtcpAttr(remoteStream.exists("rtcp"));
|
||||
stream.setRtcpMuxAttr(remoteStream.exists("rtcp-mux"));
|
||||
|
||||
// Set destination address
|
||||
if (!remoteStream.getConnections().empty())
|
||||
@@ -951,12 +954,12 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
|
||||
|
||||
targetAddr.mRtcp.setIp(remoteIp);
|
||||
if (stream.rtcpMuxAttr())
|
||||
targetAddr.mRtcp.setPort( remoteStream.port() );
|
||||
targetAddr.mRtcp.setPort(remoteStream.port());
|
||||
else if (stream.rtcpAttr())
|
||||
targetAddr.mRtcp.setPort(
|
||||
strx::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteStream.port() + 1));
|
||||
else
|
||||
if (stream.rtcpAttr())
|
||||
targetAddr.mRtcp.setPort( strx::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteStream.port() + 1 ) );
|
||||
else
|
||||
targetAddr.mRtcp.setPort( remoteStream.port() + 1);
|
||||
targetAddr.mRtcp.setPort(remoteStream.port() + 1);
|
||||
|
||||
stream.provider()->setDestinationAddress(targetAddr);
|
||||
|
||||
@@ -974,9 +977,9 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
|
||||
stream.setSocket4(SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX()));
|
||||
stream.setSocket6(SocketHeap::instance().allocSocketPair(AF_INET6, this, IS_MULTIPLEX()));
|
||||
}
|
||||
catch(...)
|
||||
catch (...)
|
||||
{
|
||||
ICELogError( << "Cannot create media socket.");
|
||||
ICELogError(<< "Cannot create media socket.");
|
||||
return 503;
|
||||
}
|
||||
|
||||
@@ -1005,13 +1008,15 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
|
||||
|
||||
// See what remote peer offers - offer only single ice component if it relies on multiplexing
|
||||
if (!targetAddr.multiplexed() && !mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool())
|
||||
ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, stream.socket4().mRtcp->localport(), stream.socket6().mRtcp->localport());
|
||||
ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, stream.socket4().mRtcp->localport(),
|
||||
stream.socket6().mRtcp->localport());
|
||||
stream.setIceInfo(ii);
|
||||
}
|
||||
|
||||
if (iceAvailable)
|
||||
{
|
||||
if (mIceStack->remotePassword(stream.iceInfo().mStreamId) != icePwd || mIceStack->remoteUfrag(stream.iceInfo().mStreamId) != iceUfrag)
|
||||
if (mIceStack->remotePassword(stream.iceInfo().mStreamId) != icePwd ||
|
||||
mIceStack->remoteUfrag(stream.iceInfo().mStreamId) != iceUfrag)
|
||||
{
|
||||
iceRestart = true;
|
||||
mIceStack->setRemotePassword(icePwd, stream.iceInfo().mStreamId);
|
||||
@@ -1020,10 +1025,10 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
|
||||
}
|
||||
|
||||
// Get remote ICE candidates vector
|
||||
const std::list<resip::Data> candidateList = remoteStream.getValues("candidate");
|
||||
const std::list<resip::Data> candidateList = remoteStream.getValues("candidate");
|
||||
|
||||
// Repackage information about remote candidates
|
||||
std::vector<std::string> candidateVector;
|
||||
std::vector<std::string> candidateVector;
|
||||
std::list<resip::Data>::const_iterator cit = candidateList.begin();
|
||||
|
||||
for (; cit != candidateList.end(); ++cit)
|
||||
@@ -1032,9 +1037,11 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
|
||||
if (candidateVector.empty())
|
||||
iceAvailable = false;
|
||||
|
||||
// Ask ICE stack to process this information. This call will remove also second component if it is not defined in remote sdp.
|
||||
// Ask ICE stack to process this information. This call will remove also second component if it is not defined
|
||||
// in remote sdp.
|
||||
if (iceAvailable)
|
||||
iceAvailable = mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteIp, remotePort, mUserAgent->mConfig[CONFIG_DEFERRELAYED].asBool());
|
||||
iceAvailable = mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteIp, remotePort,
|
||||
mUserAgent->mConfig[CONFIG_DEFERRELAYED].asBool());
|
||||
}
|
||||
|
||||
// See if there are compatible media streams
|
||||
@@ -1081,22 +1088,22 @@ int Session::release()
|
||||
|
||||
void Session::clearProvidersAndSockets()
|
||||
{
|
||||
for (unsigned i=0; i<mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < mStreamList.size(); i++)
|
||||
{
|
||||
Session::Stream& ds = mStreamList[i];
|
||||
|
||||
if (ds.provider())
|
||||
{
|
||||
ds.provider()->sessionDeleted();
|
||||
SocketHeap::instance().freeSocketPair( ds.socket4() );
|
||||
SocketHeap::instance().freeSocketPair( ds.socket6() );
|
||||
SocketHeap::instance().freeSocketPair(ds.socket4());
|
||||
SocketHeap::instance().freeSocketPair(ds.socket6());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Session::clearProviders()
|
||||
{
|
||||
for (unsigned i=0; i<mStreamList.size(); i++)
|
||||
for (unsigned i = 0; i < mStreamList.size(); i++)
|
||||
{
|
||||
Session::Stream& ds = mStreamList[i];
|
||||
|
||||
@@ -1132,14 +1139,13 @@ void Session::processQueuedOffer()
|
||||
//-------------- ResipSessionFactory ---------
|
||||
#pragma region ResipSessionFactory
|
||||
|
||||
ResipSessionFactory::ResipSessionFactory(UserAgent* agent)
|
||||
:mAgent(agent)
|
||||
{}
|
||||
ResipSessionFactory::ResipSessionFactory(UserAgent* agent) : mAgent(agent) {}
|
||||
|
||||
resip::AppDialogSet* ResipSessionFactory::createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg)
|
||||
{
|
||||
resip::AppDialogSet* ResipSessionFactory::createAppDialogSet(resip::DialogUsageManager& dum,
|
||||
const resip::SipMessage& msg)
|
||||
{
|
||||
ResipSession* s = new ResipSession(dum);
|
||||
s->setUa( mAgent );
|
||||
s->setUa(mAgent);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
+257
-259
@@ -49,365 +49,363 @@ class ResipSession;
|
||||
|
||||
enum SessionInfo
|
||||
{
|
||||
SessionInfo_RemoteSipAddress, // remote sip address
|
||||
SessionInfo_ReceivedTraffic, // amount of received traffic in session in bytes
|
||||
SessionInfo_SentTraffic, // amount of sent traffic in session in bytes
|
||||
SessionInfo_PacketLoss, // lost packets counter; returns number of 1/1000 fractions (0.1%)
|
||||
SessionInfo_AudioPeer, // remote peer rtp address in text
|
||||
SessionInfo_AudioCodec, // selected audio codec as text
|
||||
SessionInfo_DtmfInterface, // Pointer to DtmfQueue class; returned as void*
|
||||
SessionInfo_IceState,
|
||||
SessionInfo_NetworkMos,
|
||||
SessionInfo_PvqaMos,
|
||||
SessionInfo_PvqaReport,
|
||||
SessionInfo_SentRtp,
|
||||
SessionInfo_SentRtcp,
|
||||
SessionInfo_ReceivedRtp,
|
||||
SessionInfo_ReceivedRtcp,
|
||||
SessionInfo_LostRtp,
|
||||
SessionInfo_DroppedRtp,
|
||||
SessionInfo_Duration,
|
||||
SessionInfo_Jitter,
|
||||
SessionInfo_Rtt,
|
||||
SessionInfo_BitrateSwitchCounter, // It is for AMR codecs only
|
||||
SessionInfo_RemotePeer,
|
||||
SessionInfo_SSRC,
|
||||
SessionInfo_CngCounter, // For AMR codecs only
|
||||
SessionInfo_ReceivedRtpTraffic // amount of received RTP traffic in bytes, RTCP excluded
|
||||
SessionInfo_RemoteSipAddress, // remote sip address
|
||||
SessionInfo_ReceivedTraffic, // amount of received traffic in session in bytes
|
||||
SessionInfo_SentTraffic, // amount of sent traffic in session in bytes
|
||||
SessionInfo_PacketLoss, // lost packets counter; returns number of 1/1000 fractions (0.1%)
|
||||
SessionInfo_AudioPeer, // remote peer rtp address in text
|
||||
SessionInfo_AudioCodec, // selected audio codec as text
|
||||
SessionInfo_DtmfInterface, // Pointer to DtmfQueue class; returned as void*
|
||||
SessionInfo_IceState,
|
||||
SessionInfo_NetworkMos,
|
||||
SessionInfo_PvqaMos,
|
||||
SessionInfo_PvqaReport,
|
||||
SessionInfo_SentRtp,
|
||||
SessionInfo_SentRtcp,
|
||||
SessionInfo_ReceivedRtp,
|
||||
SessionInfo_ReceivedRtcp,
|
||||
SessionInfo_LostRtp,
|
||||
SessionInfo_DroppedRtp,
|
||||
SessionInfo_Duration,
|
||||
SessionInfo_Jitter,
|
||||
SessionInfo_Rtt,
|
||||
SessionInfo_BitrateSwitchCounter, // It is for AMR codecs only
|
||||
SessionInfo_RemotePeer,
|
||||
SessionInfo_SSRC,
|
||||
SessionInfo_CngCounter, // For AMR codecs only
|
||||
SessionInfo_ReceivedRtpTraffic // amount of received RTP traffic in bytes, RTCP excluded
|
||||
};
|
||||
|
||||
|
||||
class Session :
|
||||
public SocketSink,
|
||||
public ice::StageHandler
|
||||
class Session : public SocketSink, public ice::StageHandler
|
||||
{
|
||||
public:
|
||||
class Command
|
||||
{
|
||||
public:
|
||||
virtual void run(Session& s) = 0;
|
||||
};
|
||||
|
||||
// Describes ice stream/component
|
||||
struct IceInfo
|
||||
{
|
||||
IceInfo()
|
||||
:mStreamId(-1)
|
||||
class Command
|
||||
{
|
||||
mPort4 = mPort6 = 0;
|
||||
mComponentId.mRtp = mComponentId.mRtcp = -1;
|
||||
}
|
||||
public:
|
||||
virtual void run(Session& s) = 0;
|
||||
};
|
||||
|
||||
RtpPair<int> mComponentId;
|
||||
int mStreamId;
|
||||
unsigned short mPort4;
|
||||
unsigned short mPort6;
|
||||
};
|
||||
// Describes ice stream/component
|
||||
struct IceInfo
|
||||
{
|
||||
IceInfo() : mStreamId(-1)
|
||||
{
|
||||
mPort4 = mPort6 = 0;
|
||||
mComponentId.mRtp = mComponentId.mRtcp = -1;
|
||||
}
|
||||
|
||||
// Describes media stream (audio/video) in session
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
Stream();
|
||||
~Stream();
|
||||
RtpPair<int> mComponentId;
|
||||
int mStreamId;
|
||||
unsigned short mPort4;
|
||||
unsigned short mPort6;
|
||||
};
|
||||
|
||||
void setProvider(PDataProvider provider);
|
||||
PDataProvider provider();
|
||||
// Describes media stream (audio/video) in session
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
Stream();
|
||||
~Stream();
|
||||
|
||||
void setSocket4(const RtpPair<PDatagramSocket>& socket);
|
||||
RtpPair<PDatagramSocket>& socket4();
|
||||
void setProvider(PDataProvider provider);
|
||||
PDataProvider provider();
|
||||
|
||||
void setSocket6(const RtpPair<PDatagramSocket>& socket);
|
||||
RtpPair<PDatagramSocket>& socket6();
|
||||
void setSocket4(const RtpPair<PDatagramSocket>& socket);
|
||||
RtpPair<PDatagramSocket>& socket4();
|
||||
|
||||
void setIceInfo(const IceInfo& info);
|
||||
IceInfo iceInfo() const;
|
||||
void setSocket6(const RtpPair<PDatagramSocket>& socket);
|
||||
RtpPair<PDatagramSocket>& socket6();
|
||||
|
||||
// rtcpAttr/rtcpMuxAttr signals about corresponding sip attribute in offer/answer from remote peer
|
||||
bool rtcpAttr() const;
|
||||
void setRtcpAttr(bool value);
|
||||
void setIceInfo(const IceInfo& info);
|
||||
IceInfo iceInfo() const;
|
||||
|
||||
bool rtcpMuxAttr() const;
|
||||
void setRtcpMuxAttr(bool value);
|
||||
// rtcpAttr/rtcpMuxAttr signals about corresponding sip attribute in offer/answer from remote peer
|
||||
bool rtcpAttr() const;
|
||||
void setRtcpAttr(bool value);
|
||||
|
||||
protected:
|
||||
// Provider for corresponding stream
|
||||
PDataProvider mProvider;
|
||||
bool rtcpMuxAttr() const;
|
||||
void setRtcpMuxAttr(bool value);
|
||||
|
||||
// Socket for stream
|
||||
RtpPair<PDatagramSocket> mSocket4, mSocket6;
|
||||
protected:
|
||||
// Provider for corresponding stream
|
||||
PDataProvider mProvider;
|
||||
|
||||
bool mRtcpAttr;
|
||||
bool mRtcpMuxAttr;
|
||||
IceInfo mIceInfo;
|
||||
};
|
||||
// Socket for stream
|
||||
RtpPair<PDatagramSocket> mSocket4, mSocket6;
|
||||
|
||||
Session(PAccount account);
|
||||
virtual ~Session();
|
||||
bool mRtcpAttr;
|
||||
bool mRtcpMuxAttr;
|
||||
IceInfo mIceInfo;
|
||||
};
|
||||
|
||||
// Starts call to specified peer
|
||||
void start(const std::string& peer);
|
||||
Session(PAccount account);
|
||||
virtual ~Session();
|
||||
|
||||
// Stops call
|
||||
void stop();
|
||||
// Starts call to specified peer
|
||||
void start(const std::string& peer);
|
||||
|
||||
// Accepts call
|
||||
void accept();
|
||||
// Stops call
|
||||
void stop();
|
||||
|
||||
// Rejects call
|
||||
void reject(int code);
|
||||
// Accepts call
|
||||
void accept();
|
||||
|
||||
enum class InfoOptions
|
||||
{
|
||||
Standard = 0,
|
||||
Detailed = 1,
|
||||
};
|
||||
// Rejects call
|
||||
void reject(int code);
|
||||
|
||||
void getSessionInfo(InfoOptions options, VariantMap& result);
|
||||
enum class InfoOptions
|
||||
{
|
||||
Standard = 0,
|
||||
Detailed = 1,
|
||||
};
|
||||
|
||||
// Returns integer identifier of the session; it is unique amongst all session in application
|
||||
int id() const;
|
||||
void getSessionInfo(InfoOptions options, VariantMap& result);
|
||||
|
||||
// Returns owning account
|
||||
PAccount account();
|
||||
// Returns integer identifier of the session; it is unique amongst all session in application
|
||||
int id() const;
|
||||
|
||||
typedef std::map<std::string, std::string> UserHeaders;
|
||||
void setUserHeaders(const UserHeaders& headers);
|
||||
// Returns owning account
|
||||
PAccount account();
|
||||
|
||||
// Called when new media data are available for this session
|
||||
void onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize);
|
||||
typedef std::map<std::string, std::string> UserHeaders;
|
||||
void setUserHeaders(const UserHeaders& headers);
|
||||
|
||||
// Called when new candidate is gathered
|
||||
void onCandidateGathered(ice::Stack* stack, void* tag, const char* address);
|
||||
// Called when new media data are available for this session
|
||||
void onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize);
|
||||
|
||||
// Called when connectivity check is finished
|
||||
void onCheckFinished(ice::Stack* stack, void* tag, const char* checkDescription);
|
||||
// Called when new candidate is gathered
|
||||
void onCandidateGathered(ice::Stack* stack, void* tag, const char* address);
|
||||
|
||||
// Called when ICE candidates are gathered - with success or timeout.
|
||||
void onGathered(ice::Stack* stack, void* tag);
|
||||
// Called when connectivity check is finished
|
||||
void onCheckFinished(ice::Stack* stack, void* tag, const char* checkDescription);
|
||||
|
||||
// Called when ICE connectivity check is good at least for one of required streams
|
||||
void onSuccess(ice::Stack* stack, void* tag);
|
||||
// Called when ICE candidates are gathered - with success or timeout.
|
||||
void onGathered(ice::Stack* stack, void* tag);
|
||||
|
||||
// Called when ICE connectivity check is failed for all of required streams
|
||||
void onFailed(ice::Stack* stack, void* tag);
|
||||
// Called when ICE connectivity check is good at least for one of required streams
|
||||
void onSuccess(ice::Stack* stack, void* tag);
|
||||
|
||||
// Called when ICE stack detects network change during the call
|
||||
void onNetworkChange(ice::Stack* stack, void* tag);
|
||||
// Called when ICE connectivity check is failed for all of required streams
|
||||
void onFailed(ice::Stack* stack, void* tag);
|
||||
|
||||
// Fills SDP according to ICE and provider's data
|
||||
void buildSdp(resip::SdpContents& sdp, SdpDirection sdpDirection);
|
||||
// Called when ICE stack detects network change during the call
|
||||
void onNetworkChange(ice::Stack* stack, void* tag);
|
||||
|
||||
// Searches provider by its local port number
|
||||
PDataProvider findProviderByPort(int family, unsigned short port);
|
||||
// Fills SDP according to ICE and provider's data
|
||||
void buildSdp(resip::SdpContents& sdp, SdpDirection sdpDirection);
|
||||
|
||||
// Add provider to internal list
|
||||
void addProvider(PDataProvider provider);
|
||||
PDataProvider providerAt(int index);
|
||||
int getProviderCount();
|
||||
// Searches provider by its local port number
|
||||
PDataProvider findProviderByPort(int family, unsigned short port);
|
||||
|
||||
void setUserAgent(UserAgent* agent);
|
||||
UserAgent* userAgent();
|
||||
// Add provider to internal list
|
||||
void addProvider(PDataProvider provider);
|
||||
PDataProvider providerAt(int index);
|
||||
int getProviderCount();
|
||||
|
||||
// Pauses and resumes all providers; updates states
|
||||
void pause();
|
||||
void resume();
|
||||
void refreshMediaPath();
|
||||
void setUserAgent(UserAgent* agent);
|
||||
UserAgent* userAgent();
|
||||
|
||||
// Processes new sdp from offer. Returns response code (200 is ok, 488 bad codec, 503 internal error).
|
||||
// There are passing string objects by value; this is correct; this values will modified on the stack.
|
||||
int processSdp(uint64_t version, bool iceAvailable, std::string icePwd, const std::string iceUfrag,
|
||||
std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media);
|
||||
// Pauses and resumes all providers; updates states
|
||||
void pause();
|
||||
void resume();
|
||||
void refreshMediaPath();
|
||||
|
||||
// Session ID
|
||||
int mSessionId;
|
||||
// Processes new sdp from offer. Returns response code (200 is ok, 488 bad codec, 503 internal error).
|
||||
// There are passing string objects by value; this is correct; this values will modified on the stack.
|
||||
int processSdp(uint64_t version, bool iceAvailable, std::string icePwd, const std::string iceUfrag,
|
||||
std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media);
|
||||
|
||||
// Media streams collection
|
||||
std::vector<Stream> mStreamList;
|
||||
// Session ID
|
||||
int mSessionId;
|
||||
|
||||
// Smart pointer to ICE stack. Actually stack is created in CreateICEStack() method
|
||||
std::shared_ptr<ice::Stack> mIceStack;
|
||||
// Media streams collection
|
||||
std::vector<Stream> mStreamList;
|
||||
|
||||
// Pointer to owner user agent instance
|
||||
UserAgent* mUserAgent;
|
||||
// Smart pointer to ICE stack. Actually stack is created in CreateICEStack() method
|
||||
std::shared_ptr<ice::Stack> mIceStack;
|
||||
|
||||
// Remote peer SIP address
|
||||
resip::NameAddr mRemotePeer;
|
||||
// Pointer to owner user agent instance
|
||||
UserAgent* mUserAgent;
|
||||
|
||||
// Mutex to protect this instance
|
||||
Mutex mGuard;
|
||||
// Remote peer SIP address
|
||||
resip::NameAddr mRemotePeer;
|
||||
|
||||
// SDP's origin version for sending
|
||||
int mOriginVersion;
|
||||
uint64_t mRemoteOriginVersion;
|
||||
// Mutex to protect this instance
|
||||
Mutex mGuard;
|
||||
|
||||
// SDP's session version
|
||||
int mSessionVersion;
|
||||
// SDP's origin version for sending
|
||||
int mOriginVersion;
|
||||
uint64_t mRemoteOriginVersion;
|
||||
|
||||
// Marks if this session does not need OnNewSession event
|
||||
bool mAcceptedByEngine;
|
||||
bool mAcceptedByUser;
|
||||
// SDP's session version
|
||||
int mSessionVersion;
|
||||
|
||||
// Invite session handle
|
||||
resip::InviteSessionHandle mInviteHandle;
|
||||
// Marks if this session does not need OnNewSession event
|
||||
bool mAcceptedByEngine;
|
||||
bool mAcceptedByUser;
|
||||
|
||||
// Dialog set object pointer
|
||||
ResipSession* mResipSession;
|
||||
// Invite session handle
|
||||
resip::InviteSessionHandle mInviteHandle;
|
||||
|
||||
// Reference counter
|
||||
int mRefCount;
|
||||
// Dialog set object pointer
|
||||
ResipSession* mResipSession;
|
||||
|
||||
enum
|
||||
{
|
||||
Initiator = 1,
|
||||
Acceptor = 2
|
||||
};
|
||||
// Reference counter
|
||||
int mRefCount;
|
||||
|
||||
// Specifies session role - caller (Initiator) or callee (Acceptor)
|
||||
volatile int mRole;
|
||||
enum
|
||||
{
|
||||
Initiator = 1,
|
||||
Acceptor = 2
|
||||
};
|
||||
|
||||
// Marks if candidates are gather already
|
||||
volatile bool mGatheredCandidates;
|
||||
// Specifies session role - caller (Initiator) or callee (Acceptor)
|
||||
volatile int mRole;
|
||||
|
||||
// Marks if OnTerminated event was called already on session
|
||||
volatile bool mTerminated;
|
||||
// Marks if candidates are gather already
|
||||
volatile bool mGatheredCandidates;
|
||||
|
||||
// User friend remote peer's sip address
|
||||
std::string mRemoteAddress;
|
||||
// Marks if OnTerminated event was called already on session
|
||||
volatile bool mTerminated;
|
||||
|
||||
// Application specific data
|
||||
void* mTag;
|
||||
|
||||
// Used to count number of transistions to Connected state and avoid multiple onEstablished events.
|
||||
int mOfferAnswerCounter;
|
||||
// User friend remote peer's sip address
|
||||
std::string mRemoteAddress;
|
||||
|
||||
// List of turn prefixes related to sessioj
|
||||
std::vector<int> mTurnPrefixList;
|
||||
// Application specific data
|
||||
void* mTag;
|
||||
|
||||
// True if user agent has to send offer
|
||||
bool mHasToSendOffer;
|
||||
// Used to count number of transistions to Connected state and avoid multiple onEstablished events.
|
||||
int mOfferAnswerCounter;
|
||||
|
||||
// True if user agent has to enqueue offer after ice gather finished
|
||||
bool mSendOfferUpdateAfterIceGather;
|
||||
// List of turn prefixes related to sessioj
|
||||
std::vector<int> mTurnPrefixList;
|
||||
|
||||
// Related sip account
|
||||
PAccount mAccount;
|
||||
// True if user agent has to send offer
|
||||
bool mHasToSendOffer;
|
||||
|
||||
// User headers for INVITE transaction
|
||||
UserHeaders mUserHeaders;
|
||||
// True if user agent has to enqueue offer after ice gather finished
|
||||
bool mSendOfferUpdateAfterIceGather;
|
||||
|
||||
std::string remoteAddress() const;
|
||||
void setRemoteAddress(const std::string& address);
|
||||
// Related sip account
|
||||
PAccount mAccount;
|
||||
|
||||
void* tag();
|
||||
void setTag(void* tag);
|
||||
int sessionId();
|
||||
int increaseSdpVersion();
|
||||
int addRef();
|
||||
int release();
|
||||
// User headers for INVITE transaction
|
||||
UserHeaders mUserHeaders;
|
||||
|
||||
// Deletes providers and media sockets
|
||||
void clearProvidersAndSockets();
|
||||
std::string remoteAddress() const;
|
||||
void setRemoteAddress(const std::string& address);
|
||||
|
||||
// Deletes providers
|
||||
void clearProviders();
|
||||
void* tag();
|
||||
void setTag(void* tag);
|
||||
int sessionId();
|
||||
int increaseSdpVersion();
|
||||
int addRef();
|
||||
int release();
|
||||
|
||||
// Helper method to find audio provider for active sip stream
|
||||
AudioProvider* findProviderForActiveAudio();
|
||||
// Deletes providers and media sockets
|
||||
void clearProvidersAndSockets();
|
||||
|
||||
void processCommandList();
|
||||
void addCommand(Command* cmd);
|
||||
void enqueueOffer();
|
||||
void processQueuedOffer();
|
||||
static int generateId();
|
||||
static std::atomic_int IdGenerator;
|
||||
static std::atomic_int InstanceCounter;
|
||||
// Deletes providers
|
||||
void clearProviders();
|
||||
|
||||
// Helper method to find audio provider for active sip stream
|
||||
AudioProvider* findProviderForActiveAudio();
|
||||
|
||||
void processCommandList();
|
||||
void addCommand(Command* cmd);
|
||||
void enqueueOffer();
|
||||
void processQueuedOffer();
|
||||
static int generateId();
|
||||
static std::atomic_int IdGenerator;
|
||||
static std::atomic_int InstanceCounter;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Session> PSession;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Classes that provide the mapping between Application Data and DUM
|
||||
// Classes that provide the mapping between Application Data and DUM
|
||||
// dialogs/dialogsets
|
||||
//
|
||||
//
|
||||
// The DUM layer creates an AppDialog/AppDialogSet object for inbound/outbound
|
||||
// SIP Request that results in Dialog creation.
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
class ResipSessionAppDialog : public resip::AppDialog
|
||||
{
|
||||
public:
|
||||
ResipSessionAppDialog(resip::HandleManager& ham);
|
||||
virtual ~ResipSessionAppDialog();
|
||||
ResipSessionAppDialog(resip::HandleManager& ham);
|
||||
virtual ~ResipSessionAppDialog();
|
||||
};
|
||||
|
||||
class ResipSession: public resip::AppDialogSet
|
||||
class ResipSession : public resip::AppDialogSet
|
||||
{
|
||||
friend class UserAgent;
|
||||
friend class Account;
|
||||
friend class UserAgent;
|
||||
friend class Account;
|
||||
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
Type_None,
|
||||
Type_Registration,
|
||||
Type_Subscription,
|
||||
Type_Call,
|
||||
Type_Auto
|
||||
};
|
||||
static std::atomic_int InstanceCounter;
|
||||
enum Type
|
||||
{
|
||||
Type_None,
|
||||
Type_Registration,
|
||||
Type_Subscription,
|
||||
Type_Call,
|
||||
Type_Auto
|
||||
};
|
||||
static std::atomic_int InstanceCounter;
|
||||
|
||||
|
||||
ResipSession(resip::DialogUsageManager& dum);
|
||||
virtual ~ResipSession();
|
||||
virtual resip::AppDialog* createAppDialog(const resip::SipMessage& msg);
|
||||
virtual std::shared_ptr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage& msg);
|
||||
|
||||
void setType(Type type);
|
||||
Type type();
|
||||
|
||||
Session* session();
|
||||
void setSession(Session* session);
|
||||
|
||||
UserAgent* ua();
|
||||
void setUa(UserAgent* ua);
|
||||
|
||||
// Used for subscriptions/messages
|
||||
int sessionId();
|
||||
|
||||
// Used for subscriptions/messages
|
||||
void* tag() const;
|
||||
void setTag(void* tag);
|
||||
ResipSession(resip::DialogUsageManager& dum);
|
||||
virtual ~ResipSession();
|
||||
virtual resip::AppDialog* createAppDialog(const resip::SipMessage& msg);
|
||||
virtual std::shared_ptr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage& msg);
|
||||
|
||||
// Used for subscriptions/messages
|
||||
std::string remoteAddress() const;
|
||||
void setRemoteAddress(std::string address);
|
||||
void setType(Type type);
|
||||
Type type();
|
||||
|
||||
void runTerminatedEvent(Type type, int code = 0, int reason = 0);
|
||||
Session* session();
|
||||
void setSession(Session* session);
|
||||
|
||||
void setUASProfile(const std::shared_ptr<resip::UserProfile>& profile);
|
||||
UserAgent* ua();
|
||||
void setUa(UserAgent* ua);
|
||||
|
||||
// Used for subscriptions/messages
|
||||
int sessionId();
|
||||
|
||||
// Used for subscriptions/messages
|
||||
void* tag() const;
|
||||
void setTag(void* tag);
|
||||
|
||||
// Used for subscriptions/messages
|
||||
std::string remoteAddress() const;
|
||||
void setRemoteAddress(std::string address);
|
||||
|
||||
void runTerminatedEvent(Type type, int code = 0, int reason = 0);
|
||||
|
||||
void setUASProfile(const std::shared_ptr<resip::UserProfile>& profile);
|
||||
|
||||
protected:
|
||||
bool mTerminated;
|
||||
UserAgent* mUserAgent;
|
||||
Type mType;
|
||||
Session* mSession;
|
||||
int mSessionId;
|
||||
std::string mRemoteAddress;
|
||||
void* mTag;
|
||||
bool mOnWatchingStartSent;
|
||||
std::shared_ptr<resip::UserProfile> mUASProfile;
|
||||
bool mTerminated;
|
||||
UserAgent* mUserAgent;
|
||||
Type mType;
|
||||
Session* mSession;
|
||||
int mSessionId;
|
||||
std::string mRemoteAddress;
|
||||
void* mTag;
|
||||
bool mOnWatchingStartSent;
|
||||
std::shared_ptr<resip::UserProfile> mUASProfile;
|
||||
};
|
||||
|
||||
|
||||
class ResipSessionFactory : public resip::AppDialogSetFactory
|
||||
{
|
||||
public:
|
||||
ResipSessionFactory(UserAgent* agent);
|
||||
virtual resip::AppDialogSet* createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg);
|
||||
ResipSessionFactory(UserAgent* agent);
|
||||
virtual resip::AppDialogSet* createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg);
|
||||
|
||||
protected:
|
||||
UserAgent* mAgent;
|
||||
};
|
||||
UserAgent* mAgent;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user