From 10ec751e4366d726adcbef51c372d47bdbdc56a1 Mon Sep 17 00:00:00 2001 From: Dmytro Bogovych Date: Tue, 5 Nov 2024 11:41:56 +0300 Subject: [PATCH] - format source code (indentation 4 space --- src/engine/agent/Agent_AudioManager.cpp | 228 +-- src/engine/agent/Agent_AudioManager.h | 110 +- src/engine/agent/Agent_Impl.cpp | 44 +- src/engine/audio/Audio_WavFile.cpp | 8 +- src/engine/audio/Audio_WavFile.h | 28 +- src/engine/endpoint/EP_Account.cpp | 964 +++++------ src/engine/endpoint/EP_Account.h | 164 +- src/engine/endpoint/EP_DataProvider.cpp | 90 +- src/engine/endpoint/EP_DataProvider.h | 104 +- src/engine/endpoint/EP_Engine.cpp | 1932 ++++++++++++----------- src/engine/endpoint/EP_Engine.h | 604 +++---- src/engine/endpoint/EP_NetworkQueue.cpp | 252 +-- src/engine/endpoint/EP_NetworkQueue.h | 88 +- src/engine/endpoint/EP_Observer.cpp | 88 +- src/engine/endpoint/EP_Observer.h | 60 +- 15 files changed, 2383 insertions(+), 2381 deletions(-) diff --git a/src/engine/agent/Agent_AudioManager.cpp b/src/engine/agent/Agent_AudioManager.cpp index 5f93a367..27d4cf79 100644 --- a/src/engine/agent/Agent_AudioManager.cpp +++ b/src/engine/agent/Agent_AudioManager.cpp @@ -15,181 +15,181 @@ AudioManager::AudioManager() -:mTerminal(nullptr), mAudioMonitoring(nullptr) + :mTerminal(nullptr), mAudioMonitoring(nullptr) { - mPlayer.setDelegate(this); + mPlayer.setDelegate(this); } AudioManager::~AudioManager() { - // stop(); + // stop(); } AudioManager& AudioManager::instance() { - static std::shared_ptr GAudioManager; - - if (!GAudioManager) - GAudioManager = std::make_shared(); - - return *GAudioManager; + static std::shared_ptr GAudioManager; + + if (!GAudioManager) + GAudioManager = std::make_shared(); + + return *GAudioManager; } void AudioManager::setTerminal(MT::Terminal* terminal) { - mTerminal = terminal; + mTerminal = terminal; } MT::Terminal* AudioManager::terminal() { - return mTerminal; + return mTerminal; } void AudioManager::setAudioMonitoring(Audio::DataConnection* monitoring) { - mAudioMonitoring = monitoring; + mAudioMonitoring = monitoring; } Audio::DataConnection* AudioManager::audioMonitoring() { - return mAudioMonitoring; + return mAudioMonitoring; } #define LOCK_MANAGER std::unique_lock l(mGuard) void AudioManager::start(int usageId) { - assert(mTerminal); - LOCK_MANAGER; - - ICELogInfo(<< "Start main audio with usage id " << usageId); + assert(mTerminal); + LOCK_MANAGER; - if (mUsage.obtain(usageId) > 1) - return; + ICELogInfo(<< "Start main audio with usage id " << usageId); - if (Audio::OsEngine::instance()) - Audio::OsEngine::instance()->open(); + if (mUsage.obtain(usageId) > 1) + return; - if (!mAudioInput || !mAudioOutput) - { - // Disable AEC for now - because PVQA conflicts with speex AEC. - std::shared_ptr enumerator(Audio::Enumerator::make(usageId == atNull)); - if (!mTerminal->audio()) - { - auto audio = std::make_shared(); - audio->setAgc(true); - audio->setAec(false); - audio->setMonitoring(mAudioMonitoring); + if (Audio::OsEngine::instance()) + Audio::OsEngine::instance()->open(); - mTerminal->setAudio(audio); - } + if (!mAudioInput || !mAudioOutput) + { + // Disable AEC for now - because PVQA conflicts with speex AEC. + std::shared_ptr enumerator(Audio::Enumerator::make(usageId == atNull)); + if (!mTerminal->audio()) + { + auto audio = std::make_shared(); + audio->setAgc(true); + audio->setAec(false); + audio->setMonitoring(mAudioMonitoring); - if (!mAudioInput) - { - enumerator->open(Audio::myMicrophone); - int inputIndex = enumerator->indexOfDefaultDevice(); + mTerminal->setAudio(audio); + } - // Construct and set to terminal's audio pair input device - if (usageId != atNull) - mAudioInput = Audio::PInputDevice(Audio::InputDevice::make(enumerator->idAt(inputIndex))); - else - mAudioInput = Audio::PInputDevice(new Audio::NullInputDevice()); + if (!mAudioInput) + { + enumerator->open(Audio::myMicrophone); + int inputIndex = enumerator->indexOfDefaultDevice(); - mTerminal->audio()->setInput(mAudioInput); - } + // Construct and set to terminal's audio pair input device + if (usageId != atNull) + mAudioInput = Audio::PInputDevice(Audio::InputDevice::make(enumerator->idAt(inputIndex))); + else + mAudioInput = Audio::PInputDevice(new Audio::NullInputDevice()); - if (!mAudioOutput) - { - Audio::Enumerator *enumerator = Audio::Enumerator::make(usageId == atNull); - enumerator->open(Audio::mySpeaker); - int outputIndex = enumerator->indexOfDefaultDevice(); + mTerminal->audio()->setInput(mAudioInput); + } - // Construct and set terminal's audio pair output device - if (usageId != atNull) - { - if (outputIndex >= enumerator->count()) - outputIndex = 0; + if (!mAudioOutput) + { + Audio::Enumerator *enumerator = Audio::Enumerator::make(usageId == atNull); + enumerator->open(Audio::mySpeaker); + int outputIndex = enumerator->indexOfDefaultDevice(); - mAudioOutput = Audio::POutputDevice( - Audio::OutputDevice::make(enumerator->idAt(outputIndex))); - } - else - mAudioOutput = Audio::POutputDevice(new Audio::NullOutputDevice()); + // Construct and set terminal's audio pair output device + if (usageId != atNull) + { + if (outputIndex >= enumerator->count()) + outputIndex = 0; - mTerminal->audio()->setOutput(mAudioOutput); - } - } + mAudioOutput = Audio::POutputDevice( + Audio::OutputDevice::make(enumerator->idAt(outputIndex))); + } + else + mAudioOutput = Audio::POutputDevice(new Audio::NullOutputDevice()); - // Open audio - if (mAudioInput) - mAudioInput->open(); - if (mAudioOutput) - mAudioOutput->open(); + mTerminal->audio()->setOutput(mAudioOutput); + } + } + + // Open audio + if (mAudioInput) + mAudioInput->open(); + if (mAudioOutput) + mAudioOutput->open(); } void AudioManager::close() { - mUsage.clear(); - if (mAudioInput) - { - mAudioInput->close(); - mAudioInput.reset(); - } + mUsage.clear(); + if (mAudioInput) + { + mAudioInput->close(); + mAudioInput.reset(); + } - if (mAudioOutput) - { - mAudioOutput->close(); - mAudioOutput.reset(); - } - mPlayer.setOutput(Audio::POutputDevice()); + if (mAudioOutput) + { + mAudioOutput->close(); + mAudioOutput.reset(); + } + mPlayer.setOutput(Audio::POutputDevice()); } void AudioManager::stop(int usageId) { - LOCK_MANAGER; - - ICELogInfo( << "Stop main audio with usage id " << usageId); - if (mTerminal) - { - if (mTerminal->audio()) - mTerminal->audio()->player().release(usageId); - } + LOCK_MANAGER; - if (!mUsage.release(usageId)) - { - close(); + ICELogInfo( << "Stop main audio with usage id " << usageId); + if (mTerminal) + { + if (mTerminal->audio()) + mTerminal->audio()->player().release(usageId); + } - // Reset device pair on terminal side - mTerminal->setAudio(Audio::PDevicePair()); + if (!mUsage.release(usageId)) + { + close(); - if (Audio::OsEngine::instance()) - Audio::OsEngine::instance()->close(); - } + // Reset device pair on terminal side + mTerminal->setAudio(Audio::PDevicePair()); + + if (Audio::OsEngine::instance()) + Audio::OsEngine::instance()->close(); + } } void AudioManager::startPlayFile(int usageId, const std::string& path, AudioTarget target, LoopMode lm, int timelimit) { - // Check if file exists - Audio::PWavFileReader r = std::make_shared(); + // Check if file exists + Audio::PWavFileReader r = std::make_shared(); #ifdef TARGET_WIN - r->open(StringHelper::makeTstring(path)); + r->open(StringHelper::makeTstring(path)); #else - r->open(path); + r->open(path); #endif - if (!r->isOpened()) - { - ICELogError(<< "Cannot open file to play"); - return; - } + if (!r->isOpened()) + { + ICELogError(<< "Cannot open file to play"); + return; + } - // Delegate processing to existing audio device pair manager - mTerminal->audio()->player().add(usageId, r, lm == lmLoopAudio, timelimit); - start(usageId); + // Delegate processing to existing audio device pair manager + mTerminal->audio()->player().add(usageId, r, lm == lmLoopAudio, timelimit); + start(usageId); } void AudioManager::stopPlayFile(int usageId) { - stop(usageId); - mPlayer.release(usageId); + stop(usageId); + mPlayer.release(usageId); } void AudioManager::onFilePlayed(Audio::Player::PlaylistItem& item) @@ -198,9 +198,9 @@ void AudioManager::onFilePlayed(Audio::Player::PlaylistItem& item) void AudioManager::process() { - mPlayer.releasePlayed(); - std::vector ids; - mTerminal->audio()->player().retrieveUsageIds(ids); - for (unsigned i=0; i ids; + mTerminal->audio()->player().retrieveUsageIds(ids); + for (unsigned i=0; i UsageMap; - UsageCounter mUsage; - std::mutex mGuard; + std::map UsageMap; + UsageCounter mUsage; + std::mutex mGuard; }; #endif diff --git a/src/engine/agent/Agent_Impl.cpp b/src/engine/agent/Agent_Impl.cpp index 432d7c3e..85c43267 100644 --- a/src/engine/agent/Agent_Impl.cpp +++ b/src/engine/agent/Agent_Impl.cpp @@ -682,34 +682,34 @@ void AgentImpl::processUseStreamForSession(JsonCpp::Value& request, JsonCpp::Val } } else - if (actionText == "write") + if (actionText == "write") + { + if (path.empty()) { - if (path.empty()) - { - // Turn off recording from the stream - prov->writeFile(Audio::PWavFileWriter(), direction); - answer["status"] = Status_Ok; - } - else - { - Audio::PWavFileWriter writer = std::make_shared(); - if (!writer->open(strx::makeTstring(path), AUDIO_SAMPLERATE, AUDIO_CHANNELS)) - answer["status"] = Status_FailedToOpenFile; - else - { - prov->writeFile(writer, direction); - answer["status"] = Status_Ok; - } - } + // Turn off recording from the stream + prov->writeFile(Audio::PWavFileWriter(), direction); + answer["status"] = Status_Ok; } else - if (actionText == "mirror") + { + Audio::PWavFileWriter writer = std::make_shared(); + if (!writer->open(strx::makeTstring(path), AUDIO_SAMPLERATE, AUDIO_CHANNELS)) + answer["status"] = Status_FailedToOpenFile; + else { - prov->setupMirror(request["enable"].asBool()); + prov->writeFile(writer, direction); answer["status"] = Status_Ok; } - else - answer["status"] = Status_AccountNotFound; + } + } + else + if (actionText == "mirror") + { + prov->setupMirror(request["enable"].asBool()); + answer["status"] = Status_Ok; + } + else + answer["status"] = Status_AccountNotFound; } else answer["status"] = Status_NoMediaAction; diff --git a/src/engine/audio/Audio_WavFile.cpp b/src/engine/audio/Audio_WavFile.cpp index 6e4d8e54..adb9566f 100644 --- a/src/engine/audio/Audio_WavFile.cpp +++ b/src/engine/audio/Audio_WavFile.cpp @@ -66,10 +66,10 @@ std::string WavFileReader::readChunk() if (result == "fact") fread(&mDataLength, 4, 1, mHandle); else - if (result != "data") - fseek(mHandle, size, SEEK_CUR); - else - mDataLength = size; + if (result != "data") + fseek(mHandle, size, SEEK_CUR); + else + mDataLength = size; return result; } diff --git a/src/engine/audio/Audio_WavFile.h b/src/engine/audio/Audio_WavFile.h index d69882d4..5b170909 100644 --- a/src/engine/audio/Audio_WavFile.h +++ b/src/engine/audio/Audio_WavFile.h @@ -17,23 +17,23 @@ namespace Audio { - class WavFileReader - { - protected: +class WavFileReader +{ +protected: FILE* mHandle; uint16_t mChannels; uint16_t mBits; int mSamplerate; std::tstring mFileName; mutable std::recursive_mutex - mFileMtx; + mFileMtx; size_t mDataOffset; size_t mDataLength; Resampler mResampler; unsigned mLastError; std::string readChunk(); - public: +public: WavFileReader(); ~WavFileReader(); @@ -56,24 +56,24 @@ namespace Audio size_t size() const; unsigned lastError() const; - }; +}; - typedef std::shared_ptr PWavFileReader; +typedef std::shared_ptr PWavFileReader; - class WavFileWriter - { - protected: +class WavFileWriter +{ +protected: FILE* mHandle; /// Handle of audio file. std::tstring mFileName; /// Path to requested audio file. std::recursive_mutex mFileMtx; /// Mutex to protect this instance. size_t mWritten; /// Amount of written data (in bytes) size_t mLengthOffset; /// Position of length field. int mRate, - mChannels; + mChannels; void checkWriteResult(int result); - public: +public: WavFileWriter(); ~WavFileWriter(); @@ -82,9 +82,9 @@ namespace Audio bool isOpened(); size_t write(const void* buffer, size_t bytes); std::tstring filename(); - }; +}; - typedef std::shared_ptr PWavFileWriter; +typedef std::shared_ptr PWavFileWriter; } diff --git a/src/engine/endpoint/EP_Account.cpp b/src/engine/endpoint/EP_Account.cpp index 715f6878..bf622277 100644 --- a/src/engine/endpoint/EP_Account.cpp +++ b/src/engine/endpoint/EP_Account.cpp @@ -21,28 +21,28 @@ class NATDecorator: public resip::MessageDecorator { protected: - UserAgent& mUserAgent; - resip::SipMessage mMessage; + 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(); + 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 MessageDecorator* clone() const; + 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) + :mUserAgent(ua), mViaPort(0), mContactsPort(0) { } @@ -52,113 +52,113 @@ NATDecorator::~NATDecorator() 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; + // Make a copy to allow rollback + mMessage = msg; - std::stringstream dump; - mMessage.encode(dump); - //ICELogDebug(<< "Decorating message: \n" << dump.str()); + std::stringstream dump; + mMessage.encode(dump); + //ICELogDebug(<< "Decorating message: \n" << dump.str()); - // Check From: header and find the account - resip::NameAddr from; - if (msg.isRequest()) - from = msg.header(resip::h_From); - else - from = msg.header(resip::h_To); + // Check From: header and find the account + resip::NameAddr from; + if (msg.isRequest()) + from = msg.header(resip::h_From); + else + from = msg.header(resip::h_To); - PAccount account = mUserAgent.getAccount(from); - if (!account) - { - ICELogDebug(<< "Bad from header " << from.uri().getAor().c_str() << ". Will skip it"); - return; - } - - if (!account->mConfig->at(CONFIG_EXTERNALIP).asBool()) - return; - - if (!account->mExternalAddress.isEmpty()) - { -#ifdef MODIFY_VIA_BEHIND_NAT - if (msg.header(resip::h_Vias).size() > 0) + PAccount account = mUserAgent.getAccount(from); + if (!account) { - resip::Via& via = msg.header(resip::h_Vias).front(); - mViaHost = via.sentHost(); - mViaPort = via.sentPort(); - - via.sentHost() = resip::Data(account->mExternalAddress.ip()); - via.sentPort() = account->mExternalAddress.port(); + ICELogDebug(<< "Bad from header " << from.uri().getAor().c_str() << ". Will skip it"); + return; } + + if (!account->mConfig->at(CONFIG_EXTERNALIP).asBool()) + return; + + if (!account->mExternalAddress.isEmpty()) + { +#ifdef MODIFY_VIA_BEHIND_NAT + if (msg.header(resip::h_Vias).size() > 0) + { + resip::Via& via = msg.header(resip::h_Vias).front(); + mViaHost = via.sentHost(); + mViaPort = via.sentPort(); + + via.sentHost() = resip::Data(account->mExternalAddress.ip()); + via.sentPort() = account->mExternalAddress.port(); + } #endif - if (msg.header(resip::h_Contacts).size() > 0) - { - resip::Uri& uri = msg.header(resip::h_Contacts).front().uri(); - mContactsHost = uri.host(); - mContactsPort = uri.port(); - mContactsScheme = uri.scheme(); + if (msg.header(resip::h_Contacts).size() > 0) + { + resip::Uri& uri = msg.header(resip::h_Contacts).front().uri(); + mContactsHost = uri.host(); + mContactsPort = uri.port(); + mContactsScheme = uri.scheme(); - uri.host() = resip::Data(account->mExternalAddress.ip()); - uri.port() = account->mExternalAddress.port(); - if (account->mConfig->at(CONFIG_SIPS).asBool()) - { - //uri.scheme() = "sips"; - //uri.param(resip::p_transport) = "tls"; - } + uri.host() = resip::Data(account->mExternalAddress.ip()); + uri.port() = account->mExternalAddress.port(); + if (account->mConfig->at(CONFIG_SIPS).asBool()) + { + //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"; + } } - } } 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); - if (!account) - return; + // Check From: header and find the account + resip::NameAddr from = msg.header(resip::h_From); + PAccount account = mUserAgent.getAccount(from); + if (!account) + return; - if (!account->mExternalAddress.isEmpty()) - { -#ifdef MODIFY_VIA_BEHIND_NAT - if (msg.header(resip::h_Vias).size() > 0) + if (!account->mExternalAddress.isEmpty()) { - resip::Via& via = msg.header(resip::h_Vias).front(); - if ((via.sentHost() == resip::Data(account->mExternalAddress.ip())) && - (via.sentPort() == account->mExternalAddress.port())) - { - via.sentHost() = mViaHost; - via.sentPort() = mViaPort; - } - } +#ifdef MODIFY_VIA_BEHIND_NAT + if (msg.header(resip::h_Vias).size() > 0) + { + resip::Via& via = msg.header(resip::h_Vias).front(); + if ((via.sentHost() == resip::Data(account->mExternalAddress.ip())) && + (via.sentPort() == account->mExternalAddress.port())) + { + via.sentHost() = mViaHost; + via.sentPort() = mViaPort; + } + } #endif - if (msg.header(resip::h_Contacts).size() > 0) - { - resip::Uri& uri = msg.header(resip::h_Contacts).front().uri(); - if ((uri.host() == resip::Data(account->mExternalAddress.ip())) && - (uri.port() == account->mExternalAddress.port())) - { - uri.host() = mContactsHost; - uri.port() = mContactsPort; - //uri.scheme() = mContactsScheme; - } + if (msg.header(resip::h_Contacts).size() > 0) + { + resip::Uri& uri = msg.header(resip::h_Contacts).front().uri(); + if ((uri.host() == resip::Data(account->mExternalAddress.ip())) && + (uri.port() == account->mExternalAddress.port())) + { + uri.host() = mContactsHost; + uri.port() = mContactsPort; + //uri.scheme() = mContactsScheme; + } + } } - } } resip::MessageDecorator* NATDecorator::clone() const { - return new NATDecorator(mUserAgent); + return new NATDecorator(mUserAgent); } Account::Account(PVariantMap config, UserAgent& agent) - :mAgent(agent), mId(0), mConfig(config), mRegistrationState(RegistrationState::None), + :mAgent(agent), mId(0), mConfig(config), mRegistrationState(RegistrationState::None), mRegistration(NULL) { - mProfile = std::make_shared(agent.mProfile); - mId = Account::generateId(); - setup(*config); + mProfile = std::make_shared(agent.mProfile); + mId = Account::generateId(); + setup(*config); } Account::~Account() @@ -167,480 +167,480 @@ Account::~Account() void Account::setup(VariantMap &config) { - // Credentials - - if (!config.exists(CONFIG_USERNAME) || !config.exists(CONFIG_PASSWORD) || !config.exists(CONFIG_DOMAIN)) - throw Exception(ERR_NO_CREDENTIALS); + // Credentials - mProfile->clearDigestCredentials(); - 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()); + if (!config.exists(CONFIG_USERNAME) || !config.exists(CONFIG_PASSWORD) || !config.exists(CONFIG_DOMAIN)) + throw Exception(ERR_NO_CREDENTIALS); - // Proxy - mProfile->unsetOutboundProxy(); - if (config.exists(CONFIG_PROXY)) - { - if (!config[CONFIG_PROXY].asStdString().empty()) + mProfile->clearDigestCredentials(); + 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()); + + // Proxy + mProfile->unsetOutboundProxy(); + if (config.exists(CONFIG_PROXY)) { - resip::Uri proxyAddr; - proxyAddr.host() = resip::Data(config[CONFIG_PROXY].asStdString()); - proxyAddr.port() = 5060; - if (config.exists(CONFIG_PROXYPORT)) - { - if (config[CONFIG_PROXYPORT].asInt()) - proxyAddr.port() = config[CONFIG_PROXYPORT].asInt(); - } - if (config[CONFIG_SIPS].asBool()) - proxyAddr.param(resip::p_transport) = "tls"; + if (!config[CONFIG_PROXY].asStdString().empty()) + { + resip::Uri proxyAddr; + proxyAddr.host() = resip::Data(config[CONFIG_PROXY].asStdString()); + proxyAddr.port() = 5060; + if (config.exists(CONFIG_PROXYPORT)) + { + if (config[CONFIG_PROXYPORT].asInt()) + proxyAddr.port() = config[CONFIG_PROXYPORT].asInt(); + } + if (config[CONFIG_SIPS].asBool()) + proxyAddr.param(resip::p_transport) = "tls"; - mProfile->setOutboundProxy(proxyAddr); + mProfile->setOutboundProxy(proxyAddr); + } } - } - // NAT decorator - mProfile->setOutboundDecorator(std::make_shared(mAgent)); + // NAT decorator + mProfile->setOutboundDecorator(std::make_shared(mAgent)); - // Rinstance - if (config.exists(CONFIG_INSTANCE_ID)) - { - if (!config[CONFIG_INSTANCE_ID].asStdString().empty()) - mProfile->setInstanceId(config[CONFIG_INSTANCE_ID].asStdString().c_str()); - } - else - mProfile->setInstanceId(resip::Data::Empty); + // Rinstance + if (config.exists(CONFIG_INSTANCE_ID)) + { + if (!config[CONFIG_INSTANCE_ID].asStdString().empty()) + mProfile->setInstanceId(config[CONFIG_INSTANCE_ID].asStdString().c_str()); + } + else + mProfile->setInstanceId(resip::Data::Empty); - if (config.exists(CONFIG_REGID)) - mProfile->setRegId(config[CONFIG_REGID].asInt()); + if (config.exists(CONFIG_REGID)) + mProfile->setRegId(config[CONFIG_REGID].asInt()); - if (config.exists(CONFIG_RINSTANCE)) - mProfile->setRinstanceEnabled(config[CONFIG_RINSTANCE].asBool()); - else - mProfile->setRinstanceEnabled(true); + if (config.exists(CONFIG_RINSTANCE)) + mProfile->setRinstanceEnabled(config[CONFIG_RINSTANCE].asBool()); + else + mProfile->setRinstanceEnabled(true); - if (config.exists(CONFIG_RPORT)) - mProfile->setRportEnabled(config[CONFIG_RPORT].asBool()); - else - mProfile->setRportEnabled(true); + if (config.exists(CONFIG_RPORT)) + mProfile->setRportEnabled(config[CONFIG_RPORT].asBool()); + else + mProfile->setRportEnabled(true); - // From header - resip::NameAddr from; - if (config.exists(CONFIG_DISPLAYNAME)) - from.displayName() = resip::Data(config[CONFIG_DISPLAYNAME].asStdString().c_str()); + // From header + resip::NameAddr from; + if (config.exists(CONFIG_DISPLAYNAME)) + from.displayName() = resip::Data(config[CONFIG_DISPLAYNAME].asStdString().c_str()); - from.uri().scheme() = config[CONFIG_SIPS].asBool() ? "sips" : "sip"; - if (config[CONFIG_DOMAINPORT].asInt() != 0) - from.uri().port() = config[CONFIG_DOMAINPORT].asInt(); - else - from.uri().port();// = 5060; + from.uri().scheme() = config[CONFIG_SIPS].asBool() ? "sips" : "sip"; + if (config[CONFIG_DOMAINPORT].asInt() != 0) + from.uri().port() = config[CONFIG_DOMAINPORT].asInt(); + else + from.uri().port();// = 5060; - from.uri().user() = resip::Data(config[CONFIG_USERNAME].asStdString()); - from.uri().host() = resip::Data(config[CONFIG_DOMAIN].asStdString()); + from.uri().user() = resip::Data(config[CONFIG_USERNAME].asStdString()); + from.uri().host() = resip::Data(config[CONFIG_DOMAIN].asStdString()); - mProfile->setDefaultFrom(from); + mProfile->setDefaultFrom(from); - if (!CONFIG_EXISTS(CONFIG_REGISTERDURATION)) - CONFIG(CONFIG_REGISTERDURATION) = UA_REGISTRATION_TIME; + if (!CONFIG_EXISTS(CONFIG_REGISTERDURATION)) + CONFIG(CONFIG_REGISTERDURATION) = UA_REGISTRATION_TIME; } int Account::id() const { - return mId; + return mId; } void Account::start() { - ICELogInfo(<< "Starting account " << this->name()); - if (mRegistrationState != RegistrationState::None) - { - ICELogInfo(<< "Registration is active or in progress already."); - return; - } - if (!mAgent.mDum) - { - ICELogInfo(<< "DUM is not started yet."); - return; - } + ICELogInfo(<< "Starting account " << this->name()); + if (mRegistrationState != RegistrationState::None) + { + ICELogInfo(<< "Registration is active or in progress already."); + return; + } + if (!mAgent.mDum) + { + ICELogInfo(<< "DUM is not started yet."); + return; + } - // Create registration - mRegistration = new ResipSession(*mAgent.mDum); - auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, mConfig->at(CONFIG_REGISTERDURATION).asInt(), mRegistration); + // Create registration + mRegistration = new ResipSession(*mAgent.mDum); + 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())); + 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())); - mRegistrationState = RegistrationState::Registering; + mRegistrationState = RegistrationState::Registering; - // Send packet here - mAgent.mDum->send(regmessage); + // Send packet here + mAgent.mDum->send(regmessage); - // Check if STUN IP is required - bool noStunServerIp = !CONFIG_EXISTS(CONFIG_STUNSERVER_IP); - //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."); - mRefreshStunServerIpTimer.start(CONFIG(CONFIG_DNS_CACHE_TIME).asInt() * 1000); - mRefreshStunServerIpTimer.isTimeToSend(); - queryStunServerIp(); - } + // Check if STUN IP is required + bool noStunServerIp = !CONFIG_EXISTS(CONFIG_STUNSERVER_IP); + //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."); + mRefreshStunServerIpTimer.start(CONFIG(CONFIG_DNS_CACHE_TIME).asInt() * 1000); + mRefreshStunServerIpTimer.isTimeToSend(); + queryStunServerIp(); + } } void Account::stop() { - // Close presence publication - if (mPublication.isValid()) - { - mPublication->end(); - mPublication = resip::ClientPublicationHandle(); - } + // Close presence publication + if (mPublication.isValid()) + { + mPublication->end(); + mPublication = resip::ClientPublicationHandle(); + } - // Close client subscriptions + // Close client subscriptions - // Close registration - if (mRegistrationHandle.isValid()) - { - mRegistrationHandle->removeAll(); - mRegistrationHandle = resip::ClientRegistrationHandle(); - } - else - if (mRegistration) - { - mRegistration->end(); - } - mRegistration = NULL; - mRegistrationState = RegistrationState::None; + // Close registration + if (mRegistrationHandle.isValid()) + { + mRegistrationHandle->removeAll(); + mRegistrationHandle = resip::ClientRegistrationHandle(); + } + else + if (mRegistration) + { + mRegistration->end(); + } + mRegistration = NULL; + mRegistrationState = RegistrationState::None; } void Account::refresh() { - if (mRegistrationHandle.isValid()) - { - mRegistrationState = RegistrationState::Registering; - mRegistrationHandle->requestRefresh(); - } + if (mRegistrationHandle.isValid()) + { + mRegistrationState = RegistrationState::Registering; + mRegistrationHandle->requestRefresh(); + } - if (mPublication.isValid()) - { - mPublication->refresh(); - } + if (mPublication.isValid()) + { + mPublication->refresh(); + } } bool Account::active() { - return mRegistrationState == RegistrationState::Registered || - mRegistrationState == RegistrationState::Registering || - mRegistrationState == RegistrationState::Reregistering; + return mRegistrationState == RegistrationState::Registered || + mRegistrationState == RegistrationState::Registering || + mRegistrationState == RegistrationState::Reregistering; } std::string Account::name() { - return contact(SecureScheme::Nothing).uri().toString().c_str(); + return contact(SecureScheme::Nothing).uri().toString().c_str(); } Account::RegistrationState Account::registrationState() { - return mRegistrationState; + return mRegistrationState; } void Account::publishPresence(bool online, const std::string& content, int seconds) { - if (online == mPresenceOnline && content == mPresenceContent) - return; + if (online == mPresenceOnline && content == mPresenceContent) + return; - mPresenceOnline = online; - mPresenceContent = content; + mPresenceOnline = online; + mPresenceContent = content; - resip::Pidf p; - p.setEntity(contact(SecureScheme::Nothing).uri()); - p.setSimpleId(resip::Data(CONFIG(CONFIG_PRESENCE_ID).asStdString())); - p.setSimpleStatus(online, resip::Data(content)); + resip::Pidf p; + p.setEntity(contact(SecureScheme::Nothing).uri()); + p.setSimpleId(resip::Data(CONFIG(CONFIG_PRESENCE_ID).asStdString())); + p.setSimpleStatus(online, resip::Data(content)); - if (mPublication.isValid()) - mPublication->update(&p); - else - mAgent.mDum->send(mAgent.mDum->makePublication(contact(SecureScheme::TlsOnly), mProfile, p, resip::Symbols::Presence, seconds)); + if (mPublication.isValid()) + mPublication->update(&p); + else + mAgent.mDum->send(mAgent.mDum->makePublication(contact(SecureScheme::TlsOnly), mProfile, p, resip::Symbols::Presence, seconds)); } void Account::stopPublish() { - if (mPublication.isValid()) - mPublication->end(); + if (mPublication.isValid()) + mPublication->end(); } PClientObserver Account::observe(const std::string& target, const std::string& package, void* tag) { - // Add subscription functionality - PClientObserver observer(new ClientObserver()); - observer->mSession = new ResipSession(*mAgent.mDum); - observer->mSession->setRemoteAddress(target); - observer->mSession->setTag(tag); - observer->mSessionId = observer->mSession->sessionId(); - observer->mPeer = target; + // Add subscription functionality + PClientObserver observer(new ClientObserver()); + observer->mSession = new ResipSession(*mAgent.mDum); + observer->mSession->setRemoteAddress(target); + observer->mSession->setTag(tag); + observer->mSessionId = observer->mSession->sessionId(); + observer->mPeer = target; - std::shared_ptr msg; - 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(); + std::shared_ptr msg; + 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->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY); - - mAgent.mClientObserverMap[observer->mSessionId] = observer; - mAgent.mDum->send(msg); + 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); - return observer; + mAgent.mClientObserverMap[observer->mSessionId] = observer; + mAgent.mDum->send(msg); + + return observer; } /* Queues message to peer with specified mime type. Returns ID of message. */ int Account::sendMsg(const std::string& peer, const void* ptr, unsigned length, const std::string& mime, void* tag) { - ResipSession* s = new ResipSession(*mAgent.mDum); - s->setUa(&mAgent); - s->setTag(tag); - s->setRemoteAddress(peer); + ResipSession* s = new ResipSession(*mAgent.mDum); + s->setUa(&mAgent); + s->setTag(tag); + s->setRemoteAddress(peer); - // Find 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))); - else - type = resip::Mime(resip::Data(mime), resip::Data()); + // Find 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))); + else + type = resip::Mime(resip::Data(mime), resip::Data()); - resip::ClientPagerMessageHandle msgHandle = mAgent.mDum->makePagerMessage(resip::NameAddr(resip::Data(peer)), mProfile, s); - unique_ptr contentPtr(new resip::PlainContents(resip::Data(std::string((const char*)ptr, length)),type)); - int result = s->sessionId(); - msgHandle->page(std::move(contentPtr)); + resip::ClientPagerMessageHandle msgHandle = mAgent.mDum->makePagerMessage(resip::NameAddr(resip::Data(peer)), mProfile, s); + unique_ptr contentPtr(new resip::PlainContents(resip::Data(std::string((const char*)ptr, length)),type)); + int result = s->sessionId(); + msgHandle->page(std::move(contentPtr)); - return result; + return result; } resip::NameAddr Account::contact(SecureScheme ss) { - resip::NameAddr result; - switch (ss) - { - case SecureScheme::Nothing: - break; - case SecureScheme::SipsOnly: - result.uri().scheme() = mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip"; - break; - case SecureScheme::SipsAndTls: - result.uri().scheme() = mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip"; - if (mConfig->at(CONFIG_SIPS).asBool()) - result.uri().param(resip::p_transport) = "tls"; - break; - case SecureScheme::TlsOnly: - if (mConfig->at(CONFIG_SIPS).asBool()) - result.uri().param(resip::p_transport) = "tls"; - break; - } + resip::NameAddr result; + switch (ss) + { + case SecureScheme::Nothing: + break; + case SecureScheme::SipsOnly: + result.uri().scheme() = mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip"; + break; + case SecureScheme::SipsAndTls: + result.uri().scheme() = mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip"; + if (mConfig->at(CONFIG_SIPS).asBool()) + result.uri().param(resip::p_transport) = "tls"; + break; + case SecureScheme::TlsOnly: + if (mConfig->at(CONFIG_SIPS).asBool()) + result.uri().param(resip::p_transport) = "tls"; + break; + } - result.uri().user() = resip::Data(mConfig->at(CONFIG_USERNAME).asStdString()); - result.uri().host() = resip::Data(mConfig->at(CONFIG_DOMAIN).asStdString()); - result.uri().port() = mConfig->at(CONFIG_DOMAINPORT).asInt(); + result.uri().user() = resip::Data(mConfig->at(CONFIG_USERNAME).asStdString()); + result.uri().host() = resip::Data(mConfig->at(CONFIG_DOMAIN).asStdString()); + result.uri().port() = mConfig->at(CONFIG_DOMAINPORT).asInt(); - return result; + return result; } 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(); - - // Start lookup - mAgent.mStack->getDnsStub().lookup(resip::Data(target), this); - } - else - { - // Check if host name is ip already - std::string server = mConfig->at(CONFIG_STUNSERVER_NAME).asStdString(); - if (ice::NetworkAddress::isIp(server)) + if (!mConfig->exists(CONFIG_STUNSERVER_NAME)) { - mConfig->at(CONFIG_STUNSERVER_IP) = server; - mRefreshStunServerIpTimer.stop(); + // 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(); + + // Start lookup + mAgent.mStack->getDnsStub().lookup(resip::Data(target), this); } else - mAgent.mStack->getDnsStub().lookup(resip::Data(server), this); - } + { + // Check if host name is ip already + std::string server = mConfig->at(CONFIG_STUNSERVER_NAME).asStdString(); + if (ice::NetworkAddress::isIp(server)) + { + mConfig->at(CONFIG_STUNSERVER_IP) = server; + mRefreshStunServerIpTimer.stop(); + } + else + mAgent.mStack->getDnsStub().lookup(resip::Data(server), this); + } } void Account::prepareIceStack(Session *session, ice::AgentRole icerole) { - ice::ServerConfig config; - ice::NetworkAddress addr; - addr.setIp(mConfig->at(CONFIG_STUNSERVER_IP).asStdString()); - if (mConfig->at(CONFIG_STUNSERVER_PORT).asInt()) - addr.setPort(mConfig->at(CONFIG_STUNSERVER_PORT).asInt()); - else - addr.setPort(3478); + ice::ServerConfig config; + ice::NetworkAddress addr; + addr.setIp(mConfig->at(CONFIG_STUNSERVER_IP).asStdString()); + if (mConfig->at(CONFIG_STUNSERVER_PORT).asInt()) + addr.setPort(mConfig->at(CONFIG_STUNSERVER_PORT).asInt()); + else + addr.setPort(3478); - config.mServerList4.push_back(addr); - config.mRelay = mConfig->at(CONFIG_RELAY).asBool(); - if (mConfig->exists(CONFIG_ICETIMEOUT)) - config.mTimeout = mConfig->at(CONFIG_ICETIMEOUT).asInt(); + config.mServerList4.push_back(addr); + config.mRelay = mConfig->at(CONFIG_RELAY).asBool(); + if (mConfig->exists(CONFIG_ICETIMEOUT)) + config.mTimeout = mConfig->at(CONFIG_ICETIMEOUT).asInt(); - config.mUsername = mConfig->at(CONFIG_ICEUSERNAME).asStdString(); - config.mPassword = mConfig->at(CONFIG_ICEPASSWORD).asStdString(); + config.mUsername = mConfig->at(CONFIG_ICEUSERNAME).asStdString(); + config.mPassword = mConfig->at(CONFIG_ICEPASSWORD).asStdString(); - config.mUseIPv4 = mAgent.config()[CONFIG_IPV4].asBool(); - config.mUseIPv6 = mAgent.config()[CONFIG_IPV6].asBool(); - //config.mDetectNetworkChange = true; - //config.mNetworkCheckInterval = 5000; + config.mUseIPv4 = mAgent.config()[CONFIG_IPV4].asBool(); + config.mUseIPv6 = mAgent.config()[CONFIG_IPV6].asBool(); + //config.mDetectNetworkChange = true; + //config.mNetworkCheckInterval = 5000; - session->mIceStack = std::shared_ptr(ice::Stack::makeICEBox(config)); - session->mIceStack->setEventHandler(session, this); - session->mIceStack->setRole(icerole); + session->mIceStack = std::shared_ptr(ice::Stack::makeICEBox(config)); + session->mIceStack->setEventHandler(session, this); + session->mIceStack->setRole(icerole); } void Account::process() { - if (mRefreshStunServerIpTimer.isTimeToSend()) - queryStunServerIp(); + if (mRefreshStunServerIpTimer.isTimeToSend()) + queryStunServerIp(); } void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage &response) { - // Save registration handle - mRegistrationHandle = h; + // Save registration handle + mRegistrationHandle = h; - // Copy user info to registration handle - for (UserInfo::iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++) - mRegistrationHandle->setCustomHeader(resip::Data(iter->first.c_str()), resip::Data(iter->second.c_str())); + // Copy user info to registration handle + for (UserInfo::iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++) + 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(); + // Get the Via + 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(); + // Get the sent host + const resip::Data& sentHost = via.sentHost();//response.header(h_Contacts).front().uri().host(); - // Get the sentPort - int sentPort = via.sentPort(); + // Get the sentPort + int sentPort = via.sentPort(); - const resip::Data& sourceHost = response.getSource().toData(resip::UDP); - int rport = 0; - if (via.exists(resip::p_rport)) - rport = via.param(resip::p_rport).port(); + const resip::Data& sourceHost = response.getSource().toData(resip::UDP); + int rport = 0; + if (via.exists(resip::p_rport)) + rport = via.param(resip::p_rport).port(); - resip::Data received = ""; - if (via.exists(resip::p_received)) - received = via.param(resip::p_received); + resip::Data received = ""; + if (via.exists(resip::p_received)) + received = via.param(resip::p_received); - bool hostChanged = sentHost != received && received.size() > 0; - bool portChanged = sentPort != rport && rport != 0; + bool hostChanged = sentHost != received && received.size() > 0; + bool portChanged = sentPort != rport && rport != 0; - // Save external port and IP address - if (received.size() > 0 /*&& mConfig->at(CONFIG_EXTERNALIP).asBool()*/) - { - mExternalAddress.setIp(received.c_str()); - mExternalAddress.setPort(rport ? rport : sentPort); + // Save external port and IP address + if (received.size() > 0 /*&& mConfig->at(CONFIG_EXTERNALIP).asBool()*/) + { + mExternalAddress.setIp(received.c_str()); + mExternalAddress.setPort(rport ? rport : sentPort); - // Add new external address to domain list - if (mAgent.mStack) - mAgent.mStack->addAlias(resip::Data(mExternalAddress.ip()), mExternalAddress.port()); - if (mAgent.mDum) - mAgent.mDum->addDomain(resip::Data(mExternalAddress.ip())); - } + // Add new external address to domain list + if (mAgent.mStack) + mAgent.mStack->addAlias(resip::Data(mExternalAddress.ip()), mExternalAddress.port()); + if (mAgent.mDum) + mAgent.mDum->addDomain(resip::Data(mExternalAddress.ip())); + } - mUsedTransport = response.getReceivedTransportTuple().getType(); - //bool streamTransport = mUsedTransport == resip::TCP || mUsedTransport == resip::TLS; + mUsedTransport = response.getReceivedTransportTuple().getType(); + //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()) - { - //mRegistrationHandle->requestRefresh(); - // Unregister at first - mRegistrationHandle->removeAll(); - mRegistrationState = RegistrationState::Reregistering; - return; - } + // Retry registration for stream based transport too + if ( (hostChanged || portChanged) && mRegistrationState == RegistrationState::Registering /*&& !streamTransport*/ && mConfig->at(CONFIG_EXTERNALIP).asBool()) + { + //mRegistrationHandle->requestRefresh(); + // Unregister at first + mRegistrationHandle->removeAll(); + mRegistrationState = RegistrationState::Reregistering; + return; + } - // So here we registered ok - mRegistrationState = RegistrationState::Registered; - mAgent.onAccountStart(mAgent.getAccount(this)); + // So here we registered ok + mRegistrationState = RegistrationState::Registered; + mAgent.onAccountStart(mAgent.getAccount(this)); } 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) + // Check if this unregistering is a part of rport pr + if (mRegistrationState == RegistrationState::Reregistering) { - resip::Uri hostport(contact(SecureScheme::TlsOnly).uri()); - hostport.host() = resip::Data(mExternalAddress.ip()); - hostport.port() = mExternalAddress.port(); - if (mUsedTransport != resip::UDP) - { - const char* transportName = nullptr; - switch (mUsedTransport) + //if (/*this->mUseExternalIP && */response.getSource().getType() == resip::UDP) { - case resip::TCP: transportName = "tcp"; break; - case resip::TLS: transportName = "tls"; break; + resip::Uri hostport(contact(SecureScheme::TlsOnly).uri()); + hostport.host() = resip::Data(mExternalAddress.ip()); + hostport.port() = mExternalAddress.port(); + if (mUsedTransport != resip::UDP) + { + const char* transportName = nullptr; + switch (mUsedTransport) + { + 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->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())); - hostport.param(resip::p_transport) = resip::Data(transportName); - } - mProfile->setOverrideHostAndPort(hostport); - //mProfile->setDefaultFrom(from); + mAgent.mDum->send(regmessage); + return; + } + else + { + mRegistration = NULL; + mRegistrationState = RegistrationState::None; + mRegistrationHandle = resip::ClientRegistrationHandle(); + mAgent.onAccountStop(mAgent.getAccount(this), response.header(resip::h_StatusLine).statusCode()); } - 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())); - - mAgent.mDum->send(regmessage); - return; - } - else - { - mRegistration = NULL; - mRegistrationState = RegistrationState::None; - mRegistrationHandle = resip::ClientRegistrationHandle(); - mAgent.onAccountStop(mAgent.getAccount(this), response.header(resip::h_StatusLine).statusCode()); - } } void Account::onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response) { - // Reset registration handle - mRegistrationHandle = resip::ClientRegistrationHandle(); - mRegistrationState = RegistrationState::None; - mRegistration = NULL; - mAgent.onAccountStop(mAgent.getAccount(this), response.header(resip::h_StatusLine).statusCode()); + // Reset registration handle + mRegistrationHandle = resip::ClientRegistrationHandle(); + mRegistrationState = RegistrationState::None; + mRegistration = NULL; + mAgent.onAccountStop(mAgent.getAccount(this), response.header(resip::h_StatusLine).statusCode()); } void Account::onDnsResult(const resip::DNSResult& result) { - if (result.status == 0) - { - resip::Data foundAddress = result.records.front().host(); - 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. - if (mRegistrationState == RegistrationState::Registered) - mAgent.onAccountStart(mAgent.getAccount(this)); - } - else - { - ICELogError( << "Failed to resolve STUN or TURN server IP address."); - if (mRegistrationState == RegistrationState::Registered) + if (result.status == 0) { - int startCode = mConfig->at(CONFIG_STUNSERVER_NAME).asStdString().empty() ? 0 : 503; - mAgent.onAccountStop(mAgent.getAccount(this), startCode); + resip::Data foundAddress = result.records.front().host(); + 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. + if (mRegistrationState == RegistrationState::Registered) + mAgent.onAccountStart(mAgent.getAccount(this)); + } + else + { + 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; + mAgent.onAccountStop(mAgent.getAccount(this), startCode); + } } - } } void Account::onDnsResult(const resip::DNSResult&) @@ -650,50 +650,50 @@ void Account::onDnsResult(const resip::DNSResult&) void Account::onDnsResult(const resip::DNSResult& result) { - if (result.status == 0) - { - // Find lowest priority - int priority = 0x7FFFFFFF; - for (size_t i=0; i= weight) - { - index = i; - weight = result.records[i].weight(); - } - } + // Find lowest priority + int priority = 0x7FFFFFFF; + for (size_t i=0; iat(CONFIG_STUNSERVER_PORT) = result.records[index].port(); + size_t index = 0; + int weight = 0; - const char* host = result.records[index].target().c_str(); + for (size_t i=0; i= weight) + { + index = i; + weight = result.records[i].weight(); + } + } - ICELogInfo( << "Success to find STUN/TURN server on " << result.records[index].target().c_str() << - ":" << (int)result.records[index].port()); + mConfig->at(CONFIG_STUNSERVER_PORT) = result.records[index].port(); + + 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()); - if (inet_addr(host) == INADDR_NONE) - { - // Try to resolve domain name now - mAgent.mStack->getDnsStub().lookup(result.records[index].target(), this); - //mStack->getDnsStub().lookup(result.records[index].target(), this); + if (inet_addr(host) == INADDR_NONE) + { + // Try to resolve domain name now + mAgent.mStack->getDnsStub().lookup(result.records[index].target(), this); + //mStack->getDnsStub().lookup(result.records[index].target(), this); + } + else + { + mConfig->at(CONFIG_STUNSERVER_IP) = std::string(host); + } } else { - mConfig->at(CONFIG_STUNSERVER_IP) = std::string(host); + ICELogError( << "Failed to find STUN or TURN service for specified domain."); + //mAgent::shutdown(); } - } - else - { - ICELogError( << "Failed to find STUN or TURN service for specified domain."); - //mAgent::shutdown(); - } } @@ -709,38 +709,38 @@ void Account::onDnsResult(const resip::DNSResult&) 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(); - 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 - if (mConfig->exists(CONFIG_DOMAINPORT)) - return mConfig->at(CONFIG_DOMAINPORT).asInt() == p || !p; + std::string user = addr.uri().user().c_str(); + std::string domain = addr.uri().host().c_str(); + 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 + if (mConfig->exists(CONFIG_DOMAINPORT)) + return mConfig->at(CONFIG_DOMAINPORT).asInt() == p || !p; + else + return true; + } else - return true; - } - else - return false; + return false; } void Account::setUserInfo(const UserInfo &info) { - mUserInfo = info; - if (mRegistrationHandle.isValid()) - { - for (UserInfo::iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++) - mRegistrationHandle->setCustomHeader(resip::Data(iter->first.c_str()), resip::Data(iter->second.c_str())); - } + mUserInfo = info; + if (mRegistrationHandle.isValid()) + { + for (UserInfo::iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++) + mRegistrationHandle->setCustomHeader(resip::Data(iter->first.c_str()), resip::Data(iter->second.c_str())); + } } Account::UserInfo Account::getUserInfo() const { - return mUserInfo; + return mUserInfo; } std::atomic_int Account::IdGenerator; int Account::generateId() { - return ++IdGenerator; + return ++IdGenerator; } diff --git a/src/engine/endpoint/EP_Account.h b/src/engine/endpoint/EP_Account.h index edd796c9..1055ef36 100644 --- a/src/engine/endpoint/EP_Account.h +++ b/src/engine/endpoint/EP_Account.h @@ -24,118 +24,118 @@ class Session; class Account: public resip::DnsResultSink { -friend class UserAgent; -friend class NATDecorator; + friend class UserAgent; + friend class NATDecorator; public: - Account(PVariantMap config, UserAgent& agent); - ~Account(); + Account(PVariantMap config, UserAgent& agent); + ~Account(); - void start(); - void stop(); - void refresh(); - bool active(); - int id() const; + void start(); + void stop(); + void refresh(); + bool active(); + int id() const; - enum class RegistrationState - { - None, - Registering, - Reregistering, - Registered, - Unregistering - }; - RegistrationState registrationState(); + enum class RegistrationState + { + None, + Registering, + Reregistering, + Registered, + Unregistering + }; + RegistrationState registrationState(); - /* Publishes new presence information */ - void publishPresence(bool online, const std::string& content, int seconds = 600); + /* Publishes new presence information */ + void publishPresence(bool online, const std::string& content, int seconds = 600); - /* Stops publishing of presence */ - void stopPublish(); + /* Stops publishing of presence */ + void stopPublish(); - /* Starts observing on specified target / package */ - PClientObserver observe(const std::string& target, const std::string& package, void* tag); + /* Starts observing on specified target / package */ + 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); + /* 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); - /* Returns name of account - */ - std::string name(); + /* Returns name of account - */ + std::string name(); - /* Updates account with configuration */ - void setup(VariantMap& config); + /* Updates account with configuration */ + void setup(VariantMap& config); - /* Returns corresponding resiprocate profile */ - std::shared_ptr getUserProfile() const { return mProfile; } + /* Returns corresponding resiprocate profile */ + std::shared_ptr getUserProfile() const { return mProfile; } - typedef std::map UserInfo; - void setUserInfo(const UserInfo& info); - UserInfo getUserInfo() const; + typedef std::map UserInfo; + 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; + // Registration + ResipSession* mRegistration; + resip::ClientRegistrationHandle mRegistrationHandle; + resip::ClientPublicationHandle mPublication; + resip::TransportType mUsedTransport; - RegistrationState mRegistrationState; + RegistrationState mRegistrationState; - ice::NetworkAddress mExternalAddress; - std::shared_ptr mProfile; - UserAgent& mAgent; - bool mPresenceOnline; - std::string mPresenceContent; + ice::NetworkAddress mExternalAddress; + std::shared_ptr mProfile; + UserAgent& mAgent; + bool mPresenceOnline; + std::string mPresenceContent; - // Timer to refresh STUN server IP - ice::ICEScheduleTimer mRefreshStunServerIpTimer; + // Timer to refresh STUN server IP + ice::ICEScheduleTimer mRefreshStunServerIpTimer; - // Cached auth - resip::Auth mCachedAuth; + // Cached auth + resip::Auth mCachedAuth; - // Id of account - int mId; + // Id of account + int mId; - // User info about current state - UserInfo mUserInfo; + // User info about current state + UserInfo mUserInfo; - // List of client subscriptions sent from this account - typedef std::set ClientObserverSet; - ClientObserverSet mClientObserverSet; + // List of client subscriptions sent from this account + typedef std::set ClientObserverSet; + ClientObserverSet mClientObserverSet; - void process(); - // Method queries new stun server ip from dns (if stun server is specified as dns name) - void queryStunServerIp(); + void process(); + // Method queries new stun server ip from dns (if stun server is specified as dns name) + void queryStunServerIp(); - bool isResponsibleFor(const resip::NameAddr& addr); - enum class SecureScheme - { - SipsAndTls, - SipsOnly, - TlsOnly, - Nothing - }; + bool isResponsibleFor(const resip::NameAddr& addr); + enum class SecureScheme + { + SipsAndTls, + SipsOnly, + TlsOnly, + Nothing + }; - resip::NameAddr contact(SecureScheme ss = SecureScheme::SipsOnly); + 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); + // 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); #pragma region DnsResultSink implementation - void onDnsResult(const resip::DNSResult&); - void onDnsResult(const resip::DNSResult&); - void onDnsResult(const resip::DNSResult&); - void onDnsResult(const resip::DNSResult&); - void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); + void onDnsResult(const resip::DNSResult&); #pragma endregion - static int generateId(); - static std::atomic_int IdGenerator; + static int generateId(); + static std::atomic_int IdGenerator; }; typedef std::shared_ptr PAccount; diff --git a/src/engine/endpoint/EP_DataProvider.cpp b/src/engine/endpoint/EP_DataProvider.cpp index dcba1d49..0e11fee4 100644 --- a/src/engine/endpoint/EP_DataProvider.cpp +++ b/src/engine/endpoint/EP_DataProvider.cpp @@ -8,67 +8,67 @@ bool DataProvider::isSupported(const char* name) { - return !strcmp(name, "audio"); + 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() { - /*if (state() & STATE_SIPRECV) + /*if (state() & STATE_SIPRECV) setState( state() & ~STATE_SIPRECV );*/ - // Stop receive RTP stream - if (state() & (int)StreamState::Receiving) - setState( state() & ~(int)StreamState::Receiving ); - - mActive = mfPaused; + // Stop receive RTP stream + if (state() & (int)StreamState::Receiving) + setState( state() & ~(int)StreamState::Receiving ); + + mActive = mfPaused; } void DataProvider::resume() { - // Tell remote peer about resumed receiving in SDP - //setState( state() | STATE_SIPRECV ); + // Tell remote peer about resumed receiving in SDP + //setState( state() | STATE_SIPRECV ); - // Start receive RTP stream - setState( state() | (int)StreamState::Receiving ); - - mActive = mfActive; + // Start receive RTP stream + setState( state() | (int)StreamState::Receiving ); + + mActive = mfActive; } bool DataProvider::processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) { - // Process paused and inactive calls - if (media.exists("sendonly")) - { - 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 - { - mRemoteState = msSendRecv; - switch (mActive) + // Process paused and inactive calls + if (media.exists("sendonly")) { - case mfActive: - setState(state() | (int)StreamState::Sending | (int)StreamState::Receiving); - break; - - case mfPaused: - setState(state() | (int)StreamState::Sending ); - break; + mRemoteState = msSendonly; + setState(state() & ~(int)StreamState::Sending); } - } - return true; + 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 + { + mRemoteState = msSendRecv; + switch (mActive) + { + case mfActive: + setState(state() | (int)StreamState::Sending | (int)StreamState::Receiving); + break; + + case mfPaused: + setState(state() | (int)StreamState::Sending ); + break; + } + } + return true; } diff --git a/src/engine/endpoint/EP_DataProvider.h b/src/engine/endpoint/EP_DataProvider.h index 81bd92c5..070c7d16 100644 --- a/src/engine/endpoint/EP_DataProvider.h +++ b/src/engine/endpoint/EP_DataProvider.h @@ -19,70 +19,70 @@ class DataProvider { public: - enum MediaFlow - { - mfActive, - mfPaused - }; - - enum MediaState - { - msSendRecv, - msSendonly, - msRecvonly, - msInactive - }; + enum MediaFlow + { + mfActive, + mfPaused + }; - static bool isSupported(const char* name); + enum MediaState + { + msSendRecv, + msSendonly, + msRecvonly, + msInactive + }; - // Returns provider RTP name - virtual std::string streamName() = 0; - - // Returns provider RTP profile name - virtual std::string streamProfile() = 0; - - // Sets destination IP address - virtual void setDestinationAddress(const RtpPair& addr) = 0; + static bool isSupported(const char* name); - // Processes incoming data - virtual void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& address) = 0; + // Returns provider RTP name + virtual std::string streamName() = 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; - - // Updates SDP offer - virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) = 0; + // Returns provider RTP profile name + virtual std::string streamProfile() = 0; - // Called by user agent when session is deleted. Comes after sessionTerminated(). - virtual void sessionDeleted() = 0; + // Sets destination IP address + virtual void setDestinationAddress(const RtpPair& addr) = 0; - // Called by user agent when session is terminated. - virtual void sessionTerminated() = 0; + // Processes incoming data + virtual void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& address) = 0; - // Called by user agent when session is started. - virtual void sessionEstablished(int conntype) = 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; - // Called by user agent to save media socket for this provider - virtual void setSocket(const RtpPair& p4, const RtpPair& p6) = 0; - - // Called by user agent to get media socket for this provider - virtual RtpPair& socket(int family) = 0; + // Updates SDP offer + virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) = 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 unsigned state() = 0; - virtual void setState(unsigned state) = 0; - - virtual void pause(); - virtual void resume(); + // Called by user agent when session is deleted. Comes after sessionTerminated(). + virtual void sessionDeleted() = 0; - virtual MT::Statistics getStatistics() = 0; + // Called by user agent when session is terminated. + virtual void sessionTerminated() = 0; + + // Called by user agent when session is started. + virtual void sessionEstablished(int conntype) = 0; + + // Called by user agent to save media socket for this provider + virtual void setSocket(const RtpPair& p4, const RtpPair& p6) = 0; + + // Called by user agent to get media socket for this provider + virtual RtpPair& 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 unsigned state() = 0; + virtual void setState(unsigned state) = 0; + + virtual void pause(); + virtual void resume(); + + virtual MT::Statistics getStatistics() = 0; protected: - MediaFlow mActive; - MediaState mRemoteState; + MediaFlow mActive; + MediaState mRemoteState; }; typedef std::shared_ptr PDataProvider; diff --git a/src/engine/endpoint/EP_Engine.cpp b/src/engine/endpoint/EP_Engine.cpp index 5397d809..d76f9d5c 100644 --- a/src/engine/endpoint/EP_Engine.cpp +++ b/src/engine/endpoint/EP_Engine.cpp @@ -49,23 +49,23 @@ class TransportLogger: public resip::Transport::SipMessageLoggingHandler public: void outboundMessage(const resip::Tuple &source, const resip::Tuple &destination, const resip::SipMessage &msg) override { - std::ostringstream dest_buffer; dest_buffer << destination; - std::ostringstream msg_buffer; msg_buffer << msg; - std::string msg_text = msg_buffer.str(); + std::ostringstream dest_buffer; dest_buffer << destination; + std::ostringstream msg_buffer; msg_buffer << msg; + std::string msg_text = msg_buffer.str(); #if defined(TARGET_ANDROID) - if (msg_text.size() > 512) - { - ICELogDebug(<< "Sent to " << dest_buffer.str() << " :"); - msg_text = strx::prefixLines(msg_text, "<---"); + if (msg_text.size() > 512) + { + ICELogDebug(<< "Sent to " << dest_buffer.str() << " :"); + msg_text = strx::prefixLines(msg_text, "<---"); - auto lines = strx::split(msg_text); - for (const auto& l: lines) - ICELogDebug(<< l); - } - else - ICELogDebug(<< "Sent to " << dest_buffer.str() << "\n" << strx::prefixLines(msg_text, "<---")); + auto lines = strx::split(msg_text); + for (const auto& l: lines) + ICELogDebug(<< l); + } + else + ICELogDebug(<< "Sent to " << dest_buffer.str() << "\n" << strx::prefixLines(msg_text, "<---")); #else - ICELogDebug(<< "Sent to " << dest_buffer.str() << "\n" << strx::prefixLines(msg_text, "<---")); + ICELogDebug(<< "Sent to " << dest_buffer.str() << "\n" << strx::prefixLines(msg_text, "<---")); #endif } @@ -77,17 +77,17 @@ public: void inboundMessage(const resip::Tuple& source, const resip::Tuple& destination, const resip::SipMessage &msg) override { - std::ostringstream source_buffer; source_buffer << source; - std::ostringstream msg_buffer; msg_buffer << msg; - std::string msg_text = msg_buffer.str(); + std::ostringstream source_buffer; source_buffer << source; + std::ostringstream msg_buffer; msg_buffer << msg; + std::string msg_text = msg_buffer.str(); #if defined(TARGET_ANDROID) - if (msg_text.size() > 512) - { - ICELogDebug(<< "Received from " << source_buffer.str() << " :"); - msg_text = strx::prefixLines(msg_text, "--->"); - auto lines = strx::split(msg_text); - for (const auto& l: lines) - ICELogDebug(<< l); + if (msg_text.size() > 512) + { + ICELogDebug(<< "Received from " << source_buffer.str() << " :"); + msg_text = strx::prefixLines(msg_text, "--->"); + auto lines = strx::split(msg_text); + for (const auto& l: lines) + ICELogDebug(<< l); } else ICELogDebug(<< "Received from " << source_buffer.str() << "\n" << strx::prefixLines(msg_text, "<---")); @@ -101,530 +101,532 @@ public: //-------------- UserAgent ----------------------- UserAgent::UserAgent() { - mStack = nullptr; - mDum = nullptr; + mStack = nullptr; + mDum = nullptr; - mConfig[CONFIG_PRESENCE_ID] = std::string("device"); - mConfig[CONFIG_RTCP_ATTR] = true; + mConfig[CONFIG_PRESENCE_ID] = std::string("device"); + mConfig[CONFIG_RTCP_ATTR] = true; - // Create master profile - mProfile = std::make_shared(); - mProfile->clearSupportedMethods(); - mProfile->addSupportedMethod(resip::INVITE); - mProfile->addSupportedMethod(resip::BYE); - mProfile->addSupportedMethod(resip::CANCEL); - mProfile->addSupportedMethod(resip::REGISTER); - mProfile->addSupportedMethod(resip::NOTIFY); - mProfile->addSupportedMethod(resip::SUBSCRIBE); - mProfile->addSupportedMethod(resip::OPTIONS); - mProfile->addSupportedMethod(resip::UPDATE); - mProfile->addSupportedMethod(resip::MESSAGE); - mProfile->addSupportedMethod(resip::ACK); - mProfile->clearDigestCredentials(); - mProfile->unsetOutboundProxy(); + // Create master profile + mProfile = std::make_shared(); + mProfile->clearSupportedMethods(); + mProfile->addSupportedMethod(resip::INVITE); + mProfile->addSupportedMethod(resip::BYE); + mProfile->addSupportedMethod(resip::CANCEL); + mProfile->addSupportedMethod(resip::REGISTER); + mProfile->addSupportedMethod(resip::NOTIFY); + mProfile->addSupportedMethod(resip::SUBSCRIBE); + mProfile->addSupportedMethod(resip::OPTIONS); + mProfile->addSupportedMethod(resip::UPDATE); + mProfile->addSupportedMethod(resip::MESSAGE); + mProfile->addSupportedMethod(resip::ACK); + mProfile->clearDigestCredentials(); + mProfile->unsetOutboundProxy(); } UserAgent::~UserAgent() { - LOCK; + LOCK; - shutdown(); - mAccountSet.clear(); - mClientObserverMap.clear(); - mServerObserverMap.clear(); - mSessionMap.clear(); + shutdown(); + mAccountSet.clear(); + mClientObserverMap.clear(); + mServerObserverMap.clear(); + mSessionMap.clear(); } void UserAgent::start() { - ICELogInfo(<< "Attempt to start endpoint."); - LOCK; - if (mStack) - { - ICELogError(<<"Endpoint is started already."); - return; - } - - // Initialize resip loggег - resip::Log::initialize(resip::Log::OnlyExternal, resip::Log::Info, "Client", *this); - - // Build list of nameservers if specified - resip::DnsStub::NameserverList nslist; - - if (mConfig.exists(CONFIG_OWN_DNS)) - { - std::string line, t = mConfig[CONFIG_OWN_DNS].asStdString(); - std::stringstream ss(t); - - while (std::getline(ss, line)) + ICELogInfo(<< "Attempt to start endpoint."); + LOCK; + if (mStack) { - line = strx::trim(line); - ice::NetworkAddress addr(line.c_str(), 0); addr.setPort(80); // Fake port to make ICEAddress initialized - switch (addr.family()) - { - case AF_INET: nslist.push_back(resip::GenericIPAddress(*addr.sockaddr4())); break; - case AF_INET6: nslist.push_back(resip::GenericIPAddress(*addr.sockaddr6())); break; - } + ICELogError(<<"Endpoint is started already."); + return; } - } - - // Security will be deleted in stop() method (in Stack destructor) - resip::Security* s = nullptr; + + // Initialize resip loggег + resip::Log::initialize(resip::Log::OnlyExternal, resip::Log::Info, "Client", *this); + + // Build list of nameservers if specified + resip::DnsStub::NameserverList nslist; + + if (mConfig.exists(CONFIG_OWN_DNS)) + { + std::string line, t = mConfig[CONFIG_OWN_DNS].asStdString(); + std::stringstream ss(t); + + while (std::getline(ss, line)) + { + line = strx::trim(line); + ice::NetworkAddress addr(line.c_str(), 0); addr.setPort(80); // Fake port to make ICEAddress initialized + switch (addr.family()) + { + case AF_INET: nslist.push_back(resip::GenericIPAddress(*addr.sockaddr4())); break; + case AF_INET6: nslist.push_back(resip::GenericIPAddress(*addr.sockaddr6())); break; + } + } + } + + // Security will be deleted in stop() method (in Stack destructor) + resip::Security* s = nullptr; #if defined(TARGET_WIN) - s = new resip::WinSecurity(); + s = new resip::WinSecurity(); #elif defined(TARGET_OSX) - s = new resip::MacSecurity(); + s = new resip::MacSecurity(); #elif defined(TARGET_LINUX) - s = new resip::Security("/etc/ssl/certs"); + s = new resip::Security("/etc/ssl/certs"); #elif defined(TARGET_ANDROID) - s = new resip::Security(); + s = new resip::Security(); #endif - mStack = new resip::SipStack(s, nslist); + mStack = new resip::SipStack(s, nslist); - // Add root cert if specified - if (mConfig.exists(CONFIG_ROOTCERT)) - { - try + // Add root cert if specified + if (mConfig.exists(CONFIG_ROOTCERT)) { - resip::Data cert = resip::Data(mConfig[CONFIG_ROOTCERT].asStdString()); - mStack->getSecurity()->addRootCertPEM(cert); + try + { + resip::Data cert = resip::Data(mConfig[CONFIG_ROOTCERT].asStdString()); + mStack->getSecurity()->addRootCertPEM(cert); + } + catch(resip::BaseException& /*e*/) + { + ICELogError(<< "Failed to preload root certificate"); + } } - catch(resip::BaseException& /*e*/) - { - ICELogError(<< "Failed to preload root certificate"); - } - } - mStack->setTransportSipMessageLoggingHandler(std::make_shared()); + mStack->setTransportSipMessageLoggingHandler(std::make_shared()); - // Add transports - mTransportList.clear(); - resip::InternalTransport* t; + // Add transports + mTransportList.clear(); + resip::InternalTransport* t; #define ADD_TRANSPORT4(X) if ((t = dynamic_cast(mStack->addTransport(X, 0, resip::V4)))) { /*t->setTransportLogger(this);*/ mTransportList.push_back(t);} #define ADD_TRANSPORT6(X) if ((t = dynamic_cast(mStack->addTransport(X, 0, resip::V6)))) { /*t->setTransportLogger(this);*/ mTransportList.push_back(t);} - switch (mConfig[CONFIG_TRANSPORT].asInt()) - { - case TransportType_Any: - if (mConfig[CONFIG_IPV4].asBool()) + switch (mConfig[CONFIG_TRANSPORT].asInt()) { - ADD_TRANSPORT4(resip::TCP) - ADD_TRANSPORT4(resip::UDP) - ADD_TRANSPORT4(resip::TLS) + case TransportType_Any: + if (mConfig[CONFIG_IPV4].asBool()) + { + ADD_TRANSPORT4(resip::TCP) + ADD_TRANSPORT4(resip::UDP) + ADD_TRANSPORT4(resip::TLS) + } + if (mConfig[CONFIG_IPV6].asBool()) + { + ADD_TRANSPORT6(resip::TCP) + ADD_TRANSPORT6(resip::UDP) + ADD_TRANSPORT6(resip::TLS) + } + break; + + case TransportType_Udp: + if (mConfig[CONFIG_IPV4].asBool()) + ADD_TRANSPORT4(resip::UDP); + if (mConfig[CONFIG_IPV6].asBool()) + ADD_TRANSPORT6(resip::UDP); + break; + + case TransportType_Tcp: + if (mConfig[CONFIG_IPV4].asBool()) + ADD_TRANSPORT4(resip::TCP); + if (mConfig[CONFIG_IPV6].asBool()) + ADD_TRANSPORT6(resip::TCP); + break; + + case TransportType_Tls: + if (mConfig[CONFIG_IPV4].asBool()) + ADD_TRANSPORT4(resip::TLS); + if (mConfig[CONFIG_IPV6].asBool()) + ADD_TRANSPORT6(resip::TLS); + break; + + default: + assert(0); } - if (mConfig[CONFIG_IPV6].asBool()) - { - ADD_TRANSPORT6(resip::TCP) - ADD_TRANSPORT6(resip::UDP) - ADD_TRANSPORT6(resip::TLS) - } - break; - case TransportType_Udp: - if (mConfig[CONFIG_IPV4].asBool()) - ADD_TRANSPORT4(resip::UDP); - if (mConfig[CONFIG_IPV6].asBool()) - ADD_TRANSPORT6(resip::UDP); - break; + mDum = new resip::DialogUsageManager(*mStack); - case TransportType_Tcp: - if (mConfig[CONFIG_IPV4].asBool()) - ADD_TRANSPORT4(resip::TCP); - if (mConfig[CONFIG_IPV6].asBool()) - ADD_TRANSPORT6(resip::TCP); - break; + // Set the name of user agent + if (mConfig[CONFIG_USERAGENT].asBool()) + mProfile->setUserAgent(mConfig[CONFIG_USERAGENT].asStdString().c_str()); - case TransportType_Tls: - if (mConfig[CONFIG_IPV4].asBool()) - ADD_TRANSPORT4(resip::TLS); - if (mConfig[CONFIG_IPV6].asBool()) - ADD_TRANSPORT6(resip::TLS); - break; + // Configure rport + mProfile->setRportEnabled(mConfig[CONFIG_RPORT].asBool()); - default: - assert(0); - } - - mDum = new resip::DialogUsageManager(*mStack); + // Set keep-alive packets interval + if (mConfig.exists(CONFIG_KEEPALIVETIME)) + mProfile->setKeepAliveTimeForDatagram(mConfig[CONFIG_KEEPALIVETIME].asInt()); + else + mProfile->setKeepAliveTimeForDatagram(30); - // Set the name of user agent - if (mConfig[CONFIG_USERAGENT].asBool()) - mProfile->setUserAgent(mConfig[CONFIG_USERAGENT].asStdString().c_str()); - - // Configure rport - mProfile->setRportEnabled(mConfig[CONFIG_RPORT].asBool()); - - // Set keep-alive packets interval - if (mConfig.exists(CONFIG_KEEPALIVETIME)) - mProfile->setKeepAliveTimeForDatagram(mConfig[CONFIG_KEEPALIVETIME].asInt()); - else - mProfile->setKeepAliveTimeForDatagram(30); + int dnsCacheTime = mConfig.exists(CONFIG_DNS_CACHE_TIME) ? mConfig[CONFIG_DNS_CACHE_TIME].asInt() : 86400; + mStack->getDnsStub().setDnsCacheSize(65536); + mStack->getDnsStub().setDnsCacheTTL(dnsCacheTime); - int dnsCacheTime = mConfig.exists(CONFIG_DNS_CACHE_TIME) ? mConfig[CONFIG_DNS_CACHE_TIME].asInt() : 86400; - mStack->getDnsStub().setDnsCacheSize(65536); - mStack->getDnsStub().setDnsCacheTTL(dnsCacheTime); + // Disable statistics + mStack->statisticsManagerEnabled() = false; - // Disable statistics - mStack->statisticsManagerEnabled() = false; + // Allow wildcard certificates + mStack->getSecurity()->setAllowWildcardCertificates(true); - // Allow wildcard certificates - mStack->getSecurity()->setAllowWildcardCertificates(true); + // Add special body type + mProfile->addSupportedMimeType(resip::MESSAGE, resip::Mime("text", "plain")); + mProfile->addSupportedMimeType(resip::INVITE, resip::Mime("application", "ddp")); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Pidf::getStaticType()); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "simple-message-summary")); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("message", "sipfrag")); + mProfile->addSupportedMimeType(resip::OPTIONS, resip::Mime("application", "sdp")); - // Add special body type - mProfile->addSupportedMimeType(resip::MESSAGE, resip::Mime("text", "plain")); - mProfile->addSupportedMimeType(resip::INVITE, resip::Mime("application", "ddp")); - mProfile->addSupportedMimeType(resip::NOTIFY, resip::Pidf::getStaticType()); - mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "simple-message-summary")); - mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("message", "sipfrag")); - mProfile->addSupportedMimeType(resip::OPTIONS, resip::Mime("application", "sdp")); - - // xcap/rls - mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "xcap-diff+xml")); - mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "rlmi+xml")); - mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("multipart", "related")); - mProfile->addSupportedOptionTag(resip::Token("eventlist")); - - mDum->setMasterProfile(mProfile); - mDum->setClientRegistrationHandler(this); - mDum->setClientAuthManager(unique_ptr(new resip::ClientAuthManager())); + // xcap/rls + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "xcap-diff+xml")); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("application", "rlmi+xml")); + mProfile->addSupportedMimeType(resip::NOTIFY, resip::Mime("multipart", "related")); + mProfile->addSupportedOptionTag(resip::Token("eventlist")); - mDum->addClientSubscriptionHandler(resip::Symbols::Presence, this); - mDum->addClientSubscriptionHandler(resip::Data("message-summary"), this); - mDum->addServerSubscriptionHandler(resip::Symbols::Presence, this); - mDum->addServerSubscriptionHandler("refer", this); - mDum->addClientSubscriptionHandler("refer", this); - mDum->addClientPublicationHandler(resip::Symbols::Presence, this); - mDum->setInviteSessionHandler(this); - mDum->setClientPagerMessageHandler(this); - mDum->setServerPagerMessageHandler(this); + mDum->setMasterProfile(mProfile); + mDum->setClientRegistrationHandler(this); + mDum->setClientAuthManager(unique_ptr(new resip::ClientAuthManager())); - unique_ptr uac_dsf(new ResipSessionFactory(this)); - mDum->setAppDialogSetFactory(std::move(uac_dsf)); + mDum->addClientSubscriptionHandler(resip::Symbols::Presence, this); + mDum->addClientSubscriptionHandler(resip::Data("message-summary"), this); + mDum->addServerSubscriptionHandler(resip::Symbols::Presence, this); + mDum->addServerSubscriptionHandler("refer", this); + mDum->addClientSubscriptionHandler("refer", this); + mDum->addClientPublicationHandler(resip::Symbols::Presence, this); + mDum->setInviteSessionHandler(this); + mDum->setClientPagerMessageHandler(this); + mDum->setServerPagerMessageHandler(this); - // Fire onStart event if stun is not used or stun server ip is known - if (mConfig[CONFIG_STUNSERVER_NAME].asStdString().empty() || !mConfig[CONFIG_STUNSERVER_IP].asStdString().empty()) - onStart(0); + unique_ptr uac_dsf(new ResipSessionFactory(this)); + mDum->setAppDialogSetFactory(std::move(uac_dsf)); + + // Fire onStart event if stun is not used or stun server ip is known + if (mConfig[CONFIG_STUNSERVER_NAME].asStdString().empty() || !mConfig[CONFIG_STUNSERVER_IP].asStdString().empty()) + onStart(0); } void UserAgent::shutdown() { - if (!mStack) - return; + if (!mStack) + return; - ICELogInfo( << "Attempt to stop endpoint."); + ICELogInfo( << "Attempt to stop endpoint."); - { - LOCK; - for (auto& observerIter: mClientObserverMap) - observerIter.second->stop(); + { + LOCK; + for (auto& observerIter: mClientObserverMap) + observerIter.second->stop(); - for (auto& observerIter: mServerObserverMap) - observerIter.second->stop(); + for (auto& observerIter: mServerObserverMap) + observerIter.second->stop(); - for (auto& sessionIter: mSessionMap) - sessionIter.second->stop(); + for (auto& sessionIter: mSessionMap) + sessionIter.second->stop(); - for (auto& accountIter: mAccountSet) - accountIter->stop(); - } + for (auto& accountIter: mAccountSet) + accountIter->stop(); + } } bool UserAgent::active() { - LOCK; - return mStack != nullptr; + LOCK; + return mStack != nullptr; } void UserAgent::refresh() { - LOCK; + LOCK; - for (auto& acc: mAccountSet) - acc->refresh(); + for (auto& acc: mAccountSet) + acc->refresh(); - for (auto& observer: mClientObserverMap) - observer.second->refresh(); + for (auto& observer: mClientObserverMap) + observer.second->refresh(); } void UserAgent::onDumCanBeDeleted() { - delete mDum; mDum = nullptr; - delete mStack; mStack = nullptr; - - mClientObserverMap.clear(); - mServerObserverMap.clear(); + delete mDum; mDum = nullptr; + delete mStack; mStack = nullptr; - // Generate onStop event here - onStop(); + mClientObserverMap.clear(); + mServerObserverMap.clear(); + + // Generate onStop event here + onStop(); } void UserAgent::stop() { - LOCK; - if (!mStack || !mDum) - return; + LOCK; + if (!mStack || !mDum) + return; - // Clear transport list to avoid races - mTransportList.clear(); + // Clear transport list to avoid races + mTransportList.clear(); - // Dump statistics here - ICELogInfo(<< "Remaining " - << Session::InstanceCounter << " session(s), " - << ResipSession::InstanceCounter << " resip DialogSet(s), " - << resip::ClientRegistration::InstanceCounter << " ClientRegistration(s)"); + // Dump statistics here + ICELogInfo(<< "Remaining " + << Session::InstanceCounter << " session(s), " + << ResipSession::InstanceCounter << " resip DialogSet(s), " + << resip::ClientRegistration::InstanceCounter << " ClientRegistration(s)"); - mDum->shutdown(this); - onDumCanBeDeleted(); + mDum->shutdown(this); + onDumCanBeDeleted(); } void UserAgent::process() { - resip::FdSet fdset; - if (mStack && mDum) - { - bool connectionFailed = false; - - mStack->buildFdSet(fdset); - //unsigned int t1 = mStack->getTimeTillNextProcessMS(); - int ret = fdset.selectMilliSeconds(0); - if (ret >= 0) // Got any results or time to send new packets? + resip::FdSet fdset; + if (mStack && mDum) { - Lock l(mGuard); - //ICELogDebug(<< "Smth on SIP socket(s)"); - mStack->process(fdset); + bool connectionFailed = false; - // Check if there failed connections - for (unsigned transportIndex = 0; transportIndex < mTransportList.size(); transportIndex++) - if (mTransportList[transportIndex]->getConnectionsDeleted()) + mStack->buildFdSet(fdset); + //unsigned int t1 = mStack->getTimeTillNextProcessMS(); + int ret = fdset.selectMilliSeconds(0); + if (ret >= 0) // Got any results or time to send new packets? { - connectionFailed = true; - mTransportList[transportIndex]->resetConnectionsDeleted(); + Lock l(mGuard); + //ICELogDebug(<< "Smth on SIP socket(s)"); + mStack->process(fdset); + + // Check if there failed connections + for (unsigned transportIndex = 0; transportIndex < mTransportList.size(); transportIndex++) + if (mTransportList[transportIndex]->getConnectionsDeleted()) + { + connectionFailed = true; + mTransportList[transportIndex]->resetConnectionsDeleted(); + } + } + + { + Lock l(mGuard); + while (mDum->process()) + ; + } + + if (connectionFailed) + this->onSipConnectionFailed(); + } + + // Erase one terminated session. The rule is : seession must not have references from resiprocate and reference count has to be 1. + { + Lock l(mGuard); + SessionMap::iterator sessionIter; + for (sessionIter = mSessionMap.begin(); sessionIter != mSessionMap.end(); ++sessionIter) + { + if (sessionIter->second.use_count() == 1 && !sessionIter->second->mResipSession) + { + mSessionMap.erase(sessionIter); + break; + } } } - - { - Lock l(mGuard); - while (mDum->process()) - ; - } - - if (connectionFailed) - this->onSipConnectionFailed(); - } - - // Erase one terminated session. The rule is : seession must not have references from resiprocate and reference count has to be 1. - { - Lock l(mGuard); - SessionMap::iterator sessionIter; - for (sessionIter = mSessionMap.begin(); sessionIter != mSessionMap.end(); ++sessionIter) - { - if (sessionIter->second.use_count() == 1 && !sessionIter->second->mResipSession) - { - mSessionMap.erase(sessionIter); - break; - } - } - } #pragma region ICE packet generating - // Iterate available sessions - { - Lock l(mGuard); - - // Find all sessions - std::set idSet; - for (auto sessionIter = mSessionMap.begin(); sessionIter != mSessionMap.end(); ++sessionIter) - idSet.insert(sessionIter->first); - - // Now process session one by one checking if current is available yet - std::set::iterator resipIter; - for (resipIter = idSet.begin(); resipIter != idSet.end(); ++resipIter) + // Iterate available sessions { - auto sessionIter = mSessionMap.find(*resipIter); - if (sessionIter == mSessionMap.end()) - continue; + Lock l(mGuard); - // Extract reference to session - Session& session = *sessionIter->second; - - // Send queued offers if possible - session.processQueuedOffer(); + // Find all sessions + std::set idSet; + for (auto sessionIter = mSessionMap.begin(); sessionIter != mSessionMap.end(); ++sessionIter) + idSet.insert(sessionIter->first); - // Generate outgoing data while available - int iceStreamId = -1, iceComponentId = -1; void* iceTag = NULL; bool iceResponse; - ice::PByteBuffer buffer; - while ((buffer = session.mIceStack->generateOutgoingData(iceResponse, iceStreamId, iceComponentId, iceTag))) - { - // Find corresponding data provider - for (unsigned i=0; i < session.mStreamList.size(); ++i) + // Now process session one by one checking if current is available yet + std::set::iterator resipIter; + for (resipIter = idSet.begin(); resipIter != idSet.end(); ++resipIter) { - Session::Stream& stream = session.mStreamList[i]; + auto sessionIter = mSessionMap.find(*resipIter); + if (sessionIter == mSessionMap.end()) + continue; - if (stream.provider() && stream.iceInfo().mStreamId == iceStreamId) - { - // Send generated packet via provider's method to allow custom scheme of encryption - ICELogDebug(<<"Sending ICE packet to " << buffer->remoteAddress().toStdString() << " with " << buffer->comment()); + // Extract reference to session + Session& session = *sessionIter->second; - PDatagramSocket s = iceComponentId == ICE_RTP_ID ? stream.socket4().mRtp : stream.socket4().mRtcp; - stream.provider()->sendData(s, buffer->remoteAddress(), buffer->data(), buffer->size()); - break; - } - } // end of provider iterating - } + // Send queued offers if possible + session.processQueuedOffer(); + + // Generate outgoing data while available + int iceStreamId = -1, iceComponentId = -1; void* iceTag = NULL; bool iceResponse; + ice::PByteBuffer buffer; + while ((buffer = session.mIceStack->generateOutgoingData(iceResponse, iceStreamId, iceComponentId, iceTag))) + { + // Find corresponding data provider + for (unsigned i=0; i < session.mStreamList.size(); ++i) + { + Session::Stream& stream = session.mStreamList[i]; + + if (stream.provider() && stream.iceInfo().mStreamId == iceStreamId) + { + // Send generated packet via provider's method to allow custom scheme of encryption + ICELogDebug(<<"Sending ICE packet to " << buffer->remoteAddress().toStdString() << " with " << buffer->comment()); + + PDatagramSocket s = iceComponentId == ICE_RTP_ID ? stream.socket4().mRtp : stream.socket4().mRtcp; + stream.provider()->sendData(s, buffer->remoteAddress(), buffer->data(), buffer->size()); + break; + } + } // end of provider iterating + } + } } - } #pragma endregion - // TODO: see if there expired sessions - stopped and awaiting turn resources deallocation + // TODO: see if there expired sessions - stopped and awaiting turn resources deallocation } void UserAgent::addRootCert(const ByteBuffer& data) { - LOCK; - resip::Data b(data.data(), data.size()); - try { - mStack->getSecurity()->addRootCertPEM(b); - } - catch(...) { - // Ignore silently - } + LOCK; + if (!mStack) + return; + resip::Data b(data.data(), data.size()); + try { + mStack->getSecurity()->addRootCertPEM(b); + } + catch(...) { + // Ignore silently + } } PAccount UserAgent::createAccount(PVariantMap config) { - PAccount account(new Account(config, *this)); - mAccountSet.insert(account); - return account; + PAccount account(new Account(config, *this)); + mAccountSet.insert(account); + return account; } void UserAgent::deleteAccount(PAccount account) { - // Delete reference from internal list - AccountSet::iterator accountIter = mAccountSet.find(account); - if (accountIter != mAccountSet.end()) - mAccountSet.erase(accountIter); + // Delete reference from internal list + AccountSet::iterator accountIter = mAccountSet.find(account); + if (accountIter != mAccountSet.end()) + mAccountSet.erase(accountIter); } PSession UserAgent::createSession(PAccount account) { - LOCK; + LOCK; - // Create session object. ICE stack will be created as member of DemoAppDialogSet - PSession session(new Session(account)); - session->setUserAgent(this); - - // Save reference to session - mSessionMap[session->id()] = session; + // Create session object. ICE stack will be created as member of DemoAppDialogSet + PSession session(new Session(account)); + session->setUserAgent(this); - // Create ICE stack and configure it - account->prepareIceStack(session.get(), ice::RoleControlling); + // Save reference to session + mSessionMap[session->id()] = session; - return session; + // Create ICE stack and configure it + account->prepareIceStack(session.get(), ice::RoleControlling); + + return session; } std::string UserAgent::formatSipAddress(const std::string& sip) { - std::string result; - if (sip.size()) - { - if (sip.find("sip:") == std::string::npos && sip.find("sips:") == std::string::npos) - result = ""; - else - if (sip[0] != '<' && sip.find('<') == std::string::npos) - result = "<" + sip + ">"; - else - result = sip; - } - return result; + std::string result; + if (sip.size()) + { + if (sip.find("sip:") == std::string::npos && sip.find("sips:") == std::string::npos) + result = ""; + else + if (sip[0] != '<' && sip.find('<') == std::string::npos) + result = "<" + sip + ">"; + else + result = sip; + } + return result; } bool UserAgent::isSipAddressValid(const std::string& sip) { - bool result = false; - try - { - std::string s = sip; - if (s.find('<') == std::string::npos) - s = "<" + s; - if (s.find('>') == std::string::npos) - s += ">"; - - resip::Data d(formatSipAddress(s)); - resip::Uri uri(d); - result = uri.isWellFormed(); - if (result) + bool result = false; + try { - if (uri.user().empty() || uri.host().empty()) - result = false; + std::string s = sip; + if (s.find('<') == std::string::npos) + s = "<" + s; + if (s.find('>') == std::string::npos) + s += ">"; + + resip::Data d(formatSipAddress(s)); + resip::Uri uri(d); + result = uri.isWellFormed(); + if (result) + { + if (uri.user().empty() || uri.host().empty()) + result = false; + } + } + catch (...) + { + return result; } - } - catch (...) - { return result; - } - return result; } UserAgent::SipAddress UserAgent::parseSipAddress(const std::string& sip) { - SipAddress result; + SipAddress result; - result.mValid = isSipAddressValid(sip); - if (result.mValid) - { - resip::Data d(formatSipAddress(sip)); - resip::NameAddr nameaddr(d); - //resip::Uri uri(d); - if (!nameaddr.isWellFormed()) - result.mValid = false; - else + result.mValid = isSipAddressValid(sip); + if (result.mValid) { - result.mUsername = nameaddr.uri().user().c_str(); - result.mDomain = nameaddr.uri().host().c_str(); - if (nameaddr.uri().port()) - { - char porttext[32]; - sprintf(porttext, ":%u", (unsigned)nameaddr.uri().port()); - result.mDomain += porttext; - } + resip::Data d(formatSipAddress(sip)); + resip::NameAddr nameaddr(d); + //resip::Uri uri(d); + if (!nameaddr.isWellFormed()) + result.mValid = false; + else + { + result.mUsername = nameaddr.uri().user().c_str(); + result.mDomain = nameaddr.uri().host().c_str(); + if (nameaddr.uri().port()) + { + char porttext[32]; + sprintf(porttext, ":%u", (unsigned)nameaddr.uri().port()); + result.mDomain += porttext; + } - result.mScheme = nameaddr.uri().scheme().c_str(); - if (result.mScheme.find('<') == 0) - result.mScheme.erase(0, 1); - result.mDisplayname = nameaddr.displayName().c_str(); + result.mScheme = nameaddr.uri().scheme().c_str(); + if (result.mScheme.find('<') == 0) + result.mScheme.erase(0, 1); + result.mDisplayname = nameaddr.displayName().c_str(); - result.mValid &= !result.mUsername.empty() && !result.mDomain.empty(); + result.mValid &= !result.mUsername.empty() && !result.mDomain.empty(); + } } - } - return result; + return result; } bool UserAgent::compareSipAddresses(const std::string& sip1, const std::string& sip2) { - if (sip1.empty() || sip2.empty()) - return false; + if (sip1.empty() || sip2.empty()) + return false; - resip::Data d1(formatSipAddress(sip1)), d2(formatSipAddress(sip2)); - resip::Uri uri1(d1), uri2(d2); - - return uri1.getAorNoPort().uppercase() == uri2.getAorNoPort().uppercase(); + resip::Data d1(formatSipAddress(sip1)), d2(formatSipAddress(sip2)); + resip::Uri uri1(d1), uri2(d2); + + return uri1.getAorNoPort().uppercase() == uri2.getAorNoPort().uppercase(); } void UserAgent::onGathered(PSession s) { - ICELogInfo(<< "Session " << s->sessionId() << " gathered candidates"); + ICELogInfo(<< "Session " << s->sessionId() << " gathered candidates"); } // Called when new candidate is gathered void UserAgent::onCandidateGathered(PSession s, const char* address) { - ICELogInfo(<< "Session " << s->sessionId() << " gathered new candidate " << address); + ICELogInfo(<< "Session " << s->sessionId() << " gathered new candidate " << address); } @@ -640,80 +642,80 @@ void UserAgent::onLog(const char* msg) void UserAgent::sendOffer(Session* session) { - assert(session->mResipSession); + assert(session->mResipSession); - // Construct SDP - resip::SdpContents sdp; - session->buildSdp(sdp, Sdp_Offer); - - if (session->mOriginVersion == 1) - { - // Construct INVITE session - auto msg = mDum->makeInviteSession(session->mRemotePeer, session->account()->mProfile, &sdp, session->mResipSession); + // Construct SDP + resip::SdpContents sdp; + session->buildSdp(sdp, Sdp_Offer); - // Include user headers - for (Session::UserHeaders::const_iterator iter = session->mUserHeaders.begin(); iter != session->mUserHeaders.end(); iter++) + if (session->mOriginVersion == 1) { - const std::string& name = iter->first; - const std::string& value = iter->second; + // Construct INVITE session + auto msg = mDum->makeInviteSession(session->mRemotePeer, session->account()->mProfile, &sdp, session->mResipSession); - msg->header(resip::ExtensionHeader(name.c_str())).push_back(resip::StringCategory(value.c_str())); + // Include user headers + for (Session::UserHeaders::const_iterator iter = session->mUserHeaders.begin(); iter != session->mUserHeaders.end(); iter++) + { + const std::string& name = iter->first; + const std::string& value = iter->second; + + msg->header(resip::ExtensionHeader(name.c_str())).push_back(resip::StringCategory(value.c_str())); + } + mDum->send(msg); } - mDum->send(msg); - } - else - { - // Send SDP - resip::InviteSession* h = dynamic_cast(session->mInviteHandle.get()); - if (h) - h->provideOffer(sdp); else - ICELogError(<< "No cast to InviteSession"); - } + { + // Send SDP + resip::InviteSession* h = dynamic_cast(session->mInviteHandle.get()); + if (h) + h->provideOffer(sdp); + else + ICELogError(<< "No cast to InviteSession"); + } } #pragma region Registration handler void UserAgent::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response) { - ICELogInfo (<< "Registration got 200 response."); - Lock l(mGuard); + ICELogInfo (<< "Registration got 200 response."); + Lock l(mGuard); - // Find account by registration handle - PAccount account = getAccount(response.header(resip::h_From)); - if (account) - account->onSuccess(h, response); + // Find account by registration handle + PAccount account = getAccount(response.header(resip::h_From)); + if (account) + account->onSuccess(h, response); } // Called when all of my bindings have been removed void UserAgent::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response) { - ICELogInfo( << "Registration is removed."); + ICELogInfo( << "Registration is removed."); - Lock l(mGuard); - for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end(); accountIter++) - if ((*accountIter)->getUserProfile() == h->getUserProfile()) - (*accountIter)->onRemoved(h, response); + Lock l(mGuard); + for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end(); accountIter++) + if ((*accountIter)->getUserProfile() == h->getUserProfile()) + (*accountIter)->onRemoved(h, response); } - + /// call on Retry-After failure. /// return values: -1 = fail, 0 = retry immediately, N = retry in N seconds int UserAgent::onRequestRetry(resip::ClientRegistrationHandle h, int retrySeconds, const resip::SipMessage& response) { - return -1; + return -1; } // Called if registration fails, usage will be destroyed (unless a // Registration retry interval is enabled in the Profile) void UserAgent::onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response) { - ICELogInfo (<< "Registration failed with code " << response.header(resip::h_StatusLine).statusCode()); + ICELogInfo (<< "Registration failed with code " << response.header(resip::h_StatusLine).statusCode()); - Lock l(mGuard); - PAccount account = getAccount(response.header(resip::h_From)); - if (account) - account->onFailure(h, response); + Lock l(mGuard); + PAccount account = getAccount(response.header(resip::h_From)); + if (account) + account->onFailure(h, response); } @@ -728,21 +730,21 @@ bool UserAgent::operator()(resip::Log::Level level, const resip::Data& messageWithHeaders, const resip::Data& instanceName) { - std::string filename = file; - std::stringstream ss; + std::string filename = file; + std::stringstream ss; - ss << "File " << strx::extractFilename(filename).c_str() << ", line " << line << ": " << message.c_str(); - if (level <= resip::Log::Crit) - ICELogCritical(<< ss.str()) - else - if (level <= resip::Log::Warning) - ICELogError(<< ss.str().c_str()) - else - if (level < resip::Log::Debug) - ICELogInfo(<< ss.str().c_str()) - else - ICELogDebug(<< ss.str().c_str()) - return false; + ss << "File " << strx::extractFilename(filename).c_str() << ", line " << line << ": " << message.c_str(); + if (level <= resip::Log::Crit) + ICELogCritical(<< ss.str()) + else + if (level <= resip::Log::Warning) + ICELogError(<< ss.str().c_str()) + else + if (level < resip::Log::Debug) + ICELogInfo(<< ss.str().c_str()) + else + ICELogDebug(<< ss.str().c_str()) + return false; } #pragma region INVITE handler @@ -755,37 +757,37 @@ void UserAgent::onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSe void UserAgent::onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) { - ResipSession* rs = CAST2RESIPSESSION(h); - if (!rs) - { - h->reject(503); - return; - } + ResipSession* rs = CAST2RESIPSESSION(h); + if (!rs) + { + h->reject(503); + return; + } - // Find account - PAccount account = getAccount(h->myAddr()); - if (!account) - { - h->reject(503); - return; - } + // Find account + PAccount account = getAccount(h->myAddr()); + if (!account) + { + h->reject(503); + return; + } - // Bring new user session - PSession s = createSession(account); + // Bring new user session + PSession s = createSession(account); - rs->setSession(s.get()); - mSessionMap[s->sessionId()] = s; - - // Save remote address - s->setRemoteAddress(h->peerAddr().uri().getAor().c_str()); + rs->setSession(s.get()); + mSessionMap[s->sessionId()] = s; - ICELogInfo( << "Session " << s->sessionId() << ": incoming."); + // Save remote address + s->setRemoteAddress(h->peerAddr().uri().getAor().c_str()); - h->provisional(100); + ICELogInfo( << "Session " << s->sessionId() << ": incoming."); - // Create ICE stack and configure it - if (account) - account->prepareIceStack(s.get(), ice::RoleControlled); + h->provisional(100); + + // Create ICE stack and configure it + if (account) + account->prepareIceStack(s.get(), ice::RoleControlled); } /// Received a failure response from UAS @@ -793,7 +795,7 @@ void UserAgent::onFailure(resip::ClientInviteSessionHandle, const resip::SipMess { } - + /// called when an in-dialog provisional response is received that contains an SDP body void UserAgent::onEarlyMedia(resip::ClientInviteSessionHandle h, const resip::SipMessage&, const resip::SdpContents&) { @@ -803,15 +805,15 @@ void UserAgent::onEarlyMedia(resip::ClientInviteSessionHandle h, const resip::Si /// called when dialog enters the Early state - typically after getting 18x void UserAgent::onProvisional(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg) { - PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); - if (!s) - return; + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + if (!s) + return; - if (msg.isResponse()) - { - int responseCode = msg.header(resip::h_StatusLine).statusCode(); - onSessionProvisional(s, responseCode); - } + if (msg.isResponse()) + { + int responseCode = msg.header(resip::h_StatusLine).statusCode(); + onSessionProvisional(s, responseCode); + } } @@ -819,77 +821,77 @@ void UserAgent::onProvisional(resip::ClientInviteSessionHandle h, const resip::S /// called when a dialog initiated as a UAC enters the connected state void UserAgent::onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg) { - PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); - if (!s) - return; + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + if (!s) + return; - if (!s->mOfferAnswerCounter) - { - ICELogInfo (<< "Session " << s->sessionId() << ": connected."); - - // Transfer user headers - if (h.isValid()) - h->setUserHeaders(s->mUserHeaders); - - onSessionEstablished(s, EV_SIP, RtpPair()); - - for (unsigned i=0; imStreamList.size(); i++) + if (!s->mOfferAnswerCounter) { - if (s->mStreamList[i].provider()) - s->mStreamList[i].provider()->sessionEstablished(EV_SIP); + ICELogInfo (<< "Session " << s->sessionId() << ": connected."); + + // Transfer user headers + if (h.isValid()) + h->setUserHeaders(s->mUserHeaders); + + onSessionEstablished(s, EV_SIP, RtpPair()); + + for (unsigned i=0; imStreamList.size(); i++) + { + if (s->mStreamList[i].provider()) + s->mStreamList[i].provider()->sessionEstablished(EV_SIP); + } } - } - s->mOfferAnswerCounter++; + s->mOfferAnswerCounter++; } /// called when a dialog initiated as a UAS enters the connected state void UserAgent::onConnected(resip::InviteSessionHandle h, const resip::SipMessage& msg) { - ResipSession* resipSession = dynamic_cast(h->getAppDialogSet().get()); - if (!resipSession) - return; - PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + ResipSession* resipSession = dynamic_cast(h->getAppDialogSet().get()); + if (!resipSession) + return; + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); - if (!s) - return; + if (!s) + return; - ICELogInfo (<< "Session " << s->mSessionId << ": connected."); + ICELogInfo (<< "Session " << s->mSessionId << ": connected."); - // Transfer user headers - if (h.isValid()) - h->setUserHeaders(s->mUserHeaders); + // Transfer user headers + if (h.isValid()) + h->setUserHeaders(s->mUserHeaders); - onSessionEstablished(s, EV_SIP, RtpPair()); + onSessionEstablished(s, EV_SIP, RtpPair()); - for (unsigned i=0; imStreamList.size(); i++) - { - if (s->mStreamList[i].provider()) - s->mStreamList[i].provider()->sessionEstablished(EV_SIP); - } + for (unsigned i=0; imStreamList.size(); i++) + { + if (s->mStreamList[i].provider()) + s->mStreamList[i].provider()->sessionEstablished(EV_SIP); + } } void UserAgent::onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related) { - PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); - if (!s) - return; - - ICELogInfo( << "Session " << s->mSessionId << ": terminated."); + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + if (!s) + return; - int errorcode = 0; - if (related) - { - if (related->isResponse()) - errorcode = related->header(resip::h_StatusLine).statusCode(); - } - - if (s->mResipSession) - s->mResipSession->runTerminatedEvent(ResipSession::Type_Call, errorcode, (int)reason); - s->clearProviders(); + ICELogInfo( << "Session " << s->mSessionId << ": terminated."); - // TODO: run turn resource deallocation sequence here. Otherwise release user session object. + int errorcode = 0; + if (related) + { + if (related->isResponse()) + errorcode = related->header(resip::h_StatusLine).statusCode(); + } + + if (s->mResipSession) + s->mResipSession->runTerminatedEvent(ResipSession::Type_Call, errorcode, (int)reason); + s->clearProviders(); + + // TODO: run turn resource deallocation sequence here. Otherwise release user session object. } /// called when a fork that was created through a 1xx never receives a 2xx @@ -913,221 +915,221 @@ void UserAgent::onRedirected(resip::ClientInviteSessionHandle, const resip::SipM /// answering the call void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage& msg, const resip::SdpContents& sdp) { - // Check if session casts ok - ResipSession* resipSession = dynamic_cast(h->getAppDialogSet().get()); - if (!resipSession) - return; - Session* s = resipSession->session(); + // Check if session casts ok + ResipSession* resipSession = dynamic_cast(h->getAppDialogSet().get()); + if (!resipSession) + return; + Session* s = resipSession->session(); - bool iceAvailable = true; + bool iceAvailable = true; - ICELogInfo( << "Session " << s->mSessionId << ": got answer."); + ICELogInfo( << "Session " << s->mSessionId << ": got answer."); - // Check for remote ICE credentials - std::string icePwd, iceUfrag; - if (sdp.session().exists("ice-pwd")) - icePwd = sdp.session().getValues("ice-pwd").front().c_str(); - if (sdp.session().exists("ice-ufrag")) - iceUfrag = sdp.session().getValues("ice-ufrag").front().c_str(); + // Check for remote ICE credentials + std::string icePwd, iceUfrag; + if (sdp.session().exists("ice-pwd")) + icePwd = sdp.session().getValues("ice-pwd").front().c_str(); + if (sdp.session().exists("ice-ufrag")) + iceUfrag = sdp.session().getValues("ice-ufrag").front().c_str(); - if (s->mStreamList.size() < sdp.session().media().size()) - { - ICELogError( << "SDP answer has wrong number of streams"); - h->end(); - return; - } - - // Get default remote IP - std::string remoteDefaultIP; - if (sdp.session().isConnection()) - remoteDefaultIP = sdp.session().connection().getAddress().c_str(); - - bool mediasupported = false; - - // Iterate SDP's streams - std::list::const_iterator mediaIter; - unsigned streamIndex = 0; - for (mediaIter = sdp.session().media().begin(), streamIndex = 0; - mediaIter != sdp.session().media().end() && streamIndex < s->mStreamList.size(); - ++mediaIter, ++streamIndex) - { - Session::Stream& stream = s->mStreamList[streamIndex]; - const resip::SdpContents::Session::Medium& remoteStream = *mediaIter; - - // Update remote default ip if available - const std::list& streamConnections = remoteStream.getMediumConnections(); - if (streamConnections.size()) - remoteDefaultIP = streamConnections.front().getAddress().c_str(); - - if (remoteDefaultIP.empty()) - continue; - - // Check if stream is active - if (remoteStream.exists("inactive")) + if (s->mStreamList.size() < sdp.session().media().size()) { - // Move to next stream. - // Deactivate rejected provider - if (stream.provider()) - { - stream.provider()->sessionTerminated(); // close corresponding media - stream.setProvider( PDataProvider() ); // free provider - SocketHeap::instance().freeSocketPair( stream.socket4() ); // close provider's socket ip4 - SocketHeap::instance().freeSocketPair( stream.socket6() ); // close provider's socket ip6 - s->mIceStack->removeStream( stream.iceInfo().mStreamId ); // remove stream from ice stack - } - continue; + ICELogError( << "SDP answer has wrong number of streams"); + h->end(); + return; } - // Try to parse SDP with ICE stack - unsigned short remoteDefaultPort = remoteStream.port(); + // Get default remote IP + std::string remoteDefaultIP; + if (sdp.session().isConnection()) + remoteDefaultIP = sdp.session().connection().getAddress().c_str(); - // Extract remote ICE candidates vector - const std::list candidateList = remoteStream.getValues("candidate"); - if (candidateList.empty()) - iceAvailable = false; + bool mediasupported = false; - std::vector candidateVector; - std::list::const_iterator cit = candidateList.begin(); - for (; cit != candidateList.end(); ++cit) - candidateVector.push_back(cit->c_str()); - - if (remoteStream.exists("ice-pwd")) - icePwd = remoteStream.getValues("ice-pwd").front().c_str(); - if (remoteStream.exists("ice-ufrag")) - iceUfrag = remoteStream.getValues("ice-ufrag").front().c_str(); - - // ICEBox::processSdpOffer() may install permissions on TURN peer - so call it anyway. - // Also it can adjust number of ice components per stream; - // Corresponding turn allocation will be removed in this case. - try + // Iterate SDP's streams + std::list::const_iterator mediaIter; + unsigned streamIndex = 0; + for (mediaIter = sdp.session().media().begin(), streamIndex = 0; + mediaIter != sdp.session().media().end() && streamIndex < s->mStreamList.size(); + ++mediaIter, ++streamIndex) { - if (!s->mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteDefaultIP, remoteDefaultPort, mConfig[CONFIG_DEFERRELAYED].asBool())) + Session::Stream& stream = s->mStreamList[streamIndex]; + const resip::SdpContents::Session::Medium& remoteStream = *mediaIter; + + // Update remote default ip if available + const std::list& streamConnections = remoteStream.getMediumConnections(); + if (streamConnections.size()) + remoteDefaultIP = streamConnections.front().getAddress().c_str(); + + if (remoteDefaultIP.empty()) + continue; + + // Check if stream is active + if (remoteStream.exists("inactive")) + { + // Move to next stream. + // Deactivate rejected provider + if (stream.provider()) + { + stream.provider()->sessionTerminated(); // close corresponding media + stream.setProvider( PDataProvider() ); // free provider + SocketHeap::instance().freeSocketPair( stream.socket4() ); // close provider's socket ip4 + SocketHeap::instance().freeSocketPair( stream.socket6() ); // close provider's socket ip6 + s->mIceStack->removeStream( stream.iceInfo().mStreamId ); // remove stream from ice stack + } + continue; + } + + // Try to parse SDP with ICE stack + unsigned short remoteDefaultPort = remoteStream.port(); + + // Extract remote ICE candidates vector + const std::list candidateList = remoteStream.getValues("candidate"); + if (candidateList.empty()) + iceAvailable = false; + + std::vector candidateVector; + std::list::const_iterator cit = candidateList.begin(); + for (; cit != candidateList.end(); ++cit) + candidateVector.push_back(cit->c_str()); + + if (remoteStream.exists("ice-pwd")) + icePwd = remoteStream.getValues("ice-pwd").front().c_str(); + if (remoteStream.exists("ice-ufrag")) + iceUfrag = remoteStream.getValues("ice-ufrag").front().c_str(); + + // ICEBox::processSdpOffer() may install permissions on TURN peer - so call it anyway. + // Also it can adjust number of ice components per stream; + // Corresponding turn allocation will be removed in this case. + try + { + if (!s->mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteDefaultIP, remoteDefaultPort, mConfig[CONFIG_DEFERRELAYED].asBool())) + iceAvailable = false; + } + catch(...) + { + iceAvailable = false; + } + + // Process media description with provider + if (stream.provider()) + { + if (stream.provider()->processSdpOffer( remoteStream, Sdp_Answer )) + { + InternetAddress addr(remoteDefaultIP, remoteDefaultPort), addr2(remoteDefaultIP, remoteDefaultPort+1); + + // See if remote stream has "rtcp" or "rtcp-mux" attributes + if (remoteStream.exists("rtcp")) + addr2.setPort( strx::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteDefaultPort+1) ); + else + if (remoteStream.exists("rtcp-mux")) + addr2.setPort( remoteDefaultPort ); + stream.provider()->setDestinationAddress(RtpPair(addr, addr2)); + mediasupported = true; + } + } + } + + // Save session handle + if (!s->mInviteHandle.isValid()) + s->mInviteHandle = h; + + // Get ICE credentials + if (icePwd.size() && iceUfrag.size()) + { + s->mIceStack->setRemotePassword(icePwd); + s->mIceStack->setRemoteUfrag(iceUfrag); + } + else iceAvailable = false; - } - catch(...) + + // Reject session if there is no media + if (!mediasupported) { - iceAvailable = false; + ICELogError(<< "Session " << s->mSessionId << ": no supported media. Ending the session."); + h->end(); + return; } - // Process media description with provider - if (stream.provider()) + // Start connectivity checks now + ICELogInfo(<< "Session " << s->mSessionId << ": attempt to check connectivity."); + + if (iceAvailable) + s->mIceStack->checkConnectivity(); + else { - if (stream.provider()->processSdpOffer( remoteStream, Sdp_Answer )) - { - InternetAddress addr(remoteDefaultIP, remoteDefaultPort), addr2(remoteDefaultIP, remoteDefaultPort+1); - - // See if remote stream has "rtcp" or "rtcp-mux" attributes - if (remoteStream.exists("rtcp")) - addr2.setPort( strx::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteDefaultPort+1) ); - else - if (remoteStream.exists("rtcp-mux")) - addr2.setPort( remoteDefaultPort ); - stream.provider()->setDestinationAddress(RtpPair(addr, addr2)); - mediasupported = true; - } + if (!mConfig[CONFIG_RELAY].asBool()) + s->mIceStack->clear(); } - } - - // Save session handle - if (!s->mInviteHandle.isValid()) - s->mInviteHandle = h; - // Get ICE credentials - if (icePwd.size() && iceUfrag.size()) - { - s->mIceStack->setRemotePassword(icePwd); - s->mIceStack->setRemoteUfrag(iceUfrag); - } - else - iceAvailable = false; - - // Reject session if there is no media - if (!mediasupported) - { - ICELogError(<< "Session " << s->mSessionId << ": no supported media. Ending the session."); - h->end(); - return; - } - - // Start connectivity checks now - ICELogInfo(<< "Session " << s->mSessionId << ": attempt to check connectivity."); - - if (iceAvailable) - s->mIceStack->checkConnectivity(); - else - { - if (!mConfig[CONFIG_RELAY].asBool()) - s->mIceStack->clear(); - } - - uint64_t version = sdp.session().origin().getVersion(); - s->mRemoteOriginVersion = version; + uint64_t version = sdp.session().origin().getVersion(); + s->mRemoteOriginVersion = version; } /// Called when an SDP offer is received - must send an answer soon after this void UserAgent::onOffer(resip::InviteSessionHandle h, const resip::SipMessage& msg, const resip::SdpContents& sdp) { - PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); - if (!s) - { - h->reject(488); - return; - } + PSession s = getUserSession(CAST2RESIPSESSION(h)->mSessionId); + if (!s) + { + h->reject(488); + return; + } - bool iceAvailable = true; + bool iceAvailable = true; - ICELogInfo(<< "Session " << s->sessionId() << ": got offer."); - - // Check if sdp includes ICE ufrag/password - std::string icePwd, iceUfrag; - if (sdp.session().exists("ice-pwd")) - icePwd = sdp.session().getValues("ice-pwd").front().c_str(); - if (sdp.session().exists("ice-ufrag")) - iceUfrag = sdp.session().getValues("ice-ufrag").front().c_str(); + ICELogInfo(<< "Session " << s->sessionId() << ": got offer."); - //ice::Stack& ice = *s->mIceStack; + // Check if sdp includes ICE ufrag/password + std::string icePwd, iceUfrag; + if (sdp.session().exists("ice-pwd")) + icePwd = sdp.session().getValues("ice-pwd").front().c_str(); + if (sdp.session().exists("ice-ufrag")) + iceUfrag = sdp.session().getValues("ice-ufrag").front().c_str(); - uint64_t version = sdp.session().origin().getVersion(); - std::string remoteIp = sdp.session().connection().getAddress().c_str(); - int code; - if ((uint64_t)-1 == s->mRemoteOriginVersion) - { - code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media()); - } - else - if (version == s->mRemoteOriginVersion) - { - // Timer, answer with previous SDP - //session->processTimer(); - } - if (version == s->mRemoteOriginVersion+1) - { - // Updated offer. Here we must check if ICE has to be restarted. - code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media()); - } - s->mRemoteOriginVersion = version; - - if (code != 200) - { - h->reject(code); - return; - } + //ice::Stack& ice = *s->mIceStack; - // Save session handle - if (!s->mInviteHandle.isValid()) - s->mInviteHandle = h; + uint64_t version = sdp.session().origin().getVersion(); + std::string remoteIp = sdp.session().connection().getAddress().c_str(); + int code; + if ((uint64_t)-1 == s->mRemoteOriginVersion) + { + code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media()); + } + else + if (version == s->mRemoteOriginVersion) + { + // Timer, answer with previous SDP + //session->processTimer(); + } + if (version == s->mRemoteOriginVersion+1) + { + // Updated offer. Here we must check if ICE has to be restarted. + code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media()); + } + s->mRemoteOriginVersion = version; - // Save reference to resip session - s->mResipSession = CAST2RESIPSESSION(h); + if (code != 200) + { + h->reject(code); + return; + } - if (!s->mAcceptedByEngine) - { - // Do not call OnNewSession for this session in future - s->mAcceptedByEngine = true; - - // Notify about new session request - onNewSession(s); - } + // Save session handle + if (!s->mInviteHandle.isValid()) + s->mInviteHandle = h; + + // Save reference to resip session + s->mResipSession = CAST2RESIPSESSION(h); + + if (!s->mAcceptedByEngine) + { + // Do not call OnNewSession for this session in future + s->mAcceptedByEngine = true; + + // Notify about new session request + onNewSession(s); + } } /// called when an Invite w/out SDP is sent, or any other context which @@ -1195,19 +1197,19 @@ void UserAgent::onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscri void UserAgent::onDnsResult(const resip::DNSResult& result) { - if (result.status == 0) - { - resip::Data foundAddress = result.records.front().host(); - ICELogInfo( << "Success to resolve STUN/TURN address to " << foundAddress.c_str()); - mConfig[CONFIG_STUNSERVER_IP] = std::string(foundAddress.c_str()); - onStart(0); - } - else - { - ICELogError( << "Failed to resolve STUN or TURN server IP address."); - int startCode = mConfig[CONFIG_STUNSERVER_NAME].asStdString().empty() ? 0 : 503; - onStart(startCode); - } + if (result.status == 0) + { + resip::Data foundAddress = result.records.front().host(); + ICELogInfo( << "Success to resolve STUN/TURN address to " << foundAddress.c_str()); + mConfig[CONFIG_STUNSERVER_IP] = std::string(foundAddress.c_str()); + onStart(0); + } + else + { + ICELogError( << "Failed to resolve STUN or TURN server IP address."); + int startCode = mConfig[CONFIG_STUNSERVER_NAME].asStdString().empty() ? 0 : 503; + onStart(startCode); + } } void UserAgent::onDnsResult(const resip::DNSResult& result) @@ -1220,12 +1222,12 @@ void UserAgent::onDnsResult(const resip::DNSResult& result) void UserAgent::onDnsResult(const resip::DNSResult& result) { - ; + ; } void UserAgent::onDnsResult(const resip::DNSResult& result) { - ; + ; } #pragma endregion @@ -1233,34 +1235,34 @@ void UserAgent::onDnsResult(const resip::DNSResult& resul #pragma region Publication presence void UserAgent::onSuccess(resip::ClientPublicationHandle h, const resip::SipMessage& status) { - resip::NameAddr from = status.header(resip::h_To); - PAccount account = getAccount(from); - if (account) - account->mPublication = h; - onPublicationSuccess(account); + resip::NameAddr from = status.header(resip::h_To); + PAccount account = getAccount(from); + if (account) + account->mPublication = h; + onPublicationSuccess(account); } void UserAgent::onRemove(resip::ClientPublicationHandle, const resip::SipMessage& status) { - resip::NameAddr to = status.header(resip::h_To); - PAccount account = getAccount(to); - if (account) - account->mPublication = resip::ClientPublicationHandle(); - onPublicationTerminated(account, 0); + resip::NameAddr to = status.header(resip::h_To); + PAccount account = getAccount(to); + if (account) + account->mPublication = resip::ClientPublicationHandle(); + onPublicationTerminated(account, 0); } void UserAgent::onFailure(resip::ClientPublicationHandle, const resip::SipMessage& status) { - resip::NameAddr to = status.header(resip::h_To); - PAccount account = getAccount(to); - if (account) - account->mPublication = resip::ClientPublicationHandle(); - onPublicationTerminated(account, status.header(resip::h_StatusLine).statusCode()); + resip::NameAddr to = status.header(resip::h_To); + PAccount account = getAccount(to); + if (account) + account->mPublication = resip::ClientPublicationHandle(); + onPublicationTerminated(account, status.header(resip::h_StatusLine).statusCode()); } int UserAgent::onRequestRetry(resip::ClientPublicationHandle, int retrySeconds, const resip::SipMessage& status) { - return -1; + return -1; } @@ -1296,40 +1298,40 @@ void UserAgent::onPresenceUpdate(PClientObserver observer, const std::string& pe void UserAgent::onNewSubscription(resip::ServerSubscriptionHandle h, const resip::SipMessage& sub) { - ResipSession* s = CAST2RESIPSESSION(h); - - // Get the event package name - const char* event = sub.header(resip::h_Event).value().c_str(); - - // Get the remote party - const char* peer = sub.header(resip::h_From).uri().getAor().c_str(); - - PAccount account = getAccount(sub.header(resip::h_From)); - PServerObserver so(new ServerObserver()); - so->mHandle = h; - so->mPeer = peer; - so->mPackage = event; - so->mSessionId = s->sessionId(); + ResipSession* s = CAST2RESIPSESSION(h); - s->setRemoteAddress(peer); - mServerObserverMap[so->mSessionId] = so; - onServerObserverStart(so); + // Get the event package name + const char* event = sub.header(resip::h_Event).value().c_str(); + + // Get the remote party + const char* peer = sub.header(resip::h_From).uri().getAor().c_str(); + + PAccount account = getAccount(sub.header(resip::h_From)); + PServerObserver so(new ServerObserver()); + so->mHandle = h; + so->mPeer = peer; + so->mPackage = event; + so->mSessionId = s->sessionId(); + + s->setRemoteAddress(peer); + mServerObserverMap[so->mSessionId] = so; + onServerObserverStart(so); } void UserAgent::onTerminated(resip::ServerSubscriptionHandle h) { - if (!h.isValid()) - return; - ResipSession* s = CAST2RESIPSESSION(h); - if (!s) - return; + if (!h.isValid()) + return; + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; - ServerObserverMap::iterator observerIter = mServerObserverMap.find(s->sessionId()); - if (observerIter != mServerObserverMap.end()) - { - onServerObserverStop(observerIter->second, 0); - mServerObserverMap.erase(observerIter); - } + ServerObserverMap::iterator observerIter = mServerObserverMap.find(s->sessionId()); + if (observerIter != mServerObserverMap.end()) + { + onServerObserverStop(observerIter->second, 0); + mServerObserverMap.erase(observerIter); + } } void UserAgent::onServerObserverStart(PServerObserver observer) @@ -1342,173 +1344,173 @@ void UserAgent::onServerObserverStop(PServerObserver observer, int code) void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify) { - if (!h.isValid()) - return; - - ResipSession* s = CAST2RESIPSESSION(h); - if (!s) - return; - ClientObserverMap::iterator observerIter = mClientObserverMap.find(s->sessionId()); - if (observerIter == mClientObserverMap.end()) - { - h->rejectUpdate(); - h->end(); - return; - } - PClientObserver observer = observerIter->second; + if (!h.isValid()) + return; - std::vector availableContacts; - h->acceptUpdate(); - - // Find "from" header - resip::Uri from = notify.header(resip::h_From).uri(); - - // Find content - resip::Contents* contents = notify.getContents(); - if (contents) - { - // Check if pidf - if (resip::Pidf* pidf = dynamic_cast(contents)) + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + ClientObserverMap::iterator observerIter = mClientObserverMap.find(s->sessionId()); + if (observerIter == mClientObserverMap.end()) { - resip::Data body = pidf->getBodyData(); - bool online = pidf->getSimpleStatus(&body); - onPresenceUpdate(observer, observer->peer(), online, std::string(body.c_str(), body.size())); + h->rejectUpdate(); + h->end(); + return; } - else - if (resip::MultipartRelatedContents* mr = dynamic_cast(contents)) + PClientObserver observer = observerIter->second; + + std::vector availableContacts; + h->acceptUpdate(); + + // Find "from" header + resip::Uri from = notify.header(resip::h_From).uri(); + + // Find content + resip::Contents* contents = notify.getContents(); + if (contents) { - resip::MultipartRelatedContents::Parts& parts = mr->parts(); - for( resip::MultipartRelatedContents::Parts::const_iterator i = parts.begin(); i != parts.end(); ++i) - { - resip::Contents* c = *i; - assert( c ); - resip::Mime m = c->getType(); - if (resip::Rlmi* rlmi = dynamic_cast(c)) + // Check if pidf + if (resip::Pidf* pidf = dynamic_cast(contents)) { - resip::Data d = rlmi->getBodyData(); - // Workaround for XMLCursor bug - if (d.find(resip::Data(" tag in rlmi"); - } - else - { - for (bool hasRecord = c.firstChild(); hasRecord; hasRecord = c.nextSibling()) - { - if (c.getTag() != "resource") - { - ICELogError( << "Failed to find tag in rlmi"); - } - else - { - // Check if c has - - resip::XMLCursor::AttributeMap::const_iterator attrIter = c.getAttributes().find("uri"); - if (attrIter != c.getAttributes().end()) - { - // Save uri - resip::Data uri = attrIter->second; - - // Check if there is tag - bool instance = false; - for (bool hasChild = c.firstChild(); hasChild; hasChild = c.nextSibling()) - instance |= c.getTag() == "instance"; - c.parent(); - - // Save result - if (instance) - availableContacts.push_back( attrIter->second ); - } - } - } - } + resip::Data body = pidf->getBodyData(); + bool online = pidf->getSimpleStatus(&body); + onPresenceUpdate(observer, observer->peer(), online, std::string(body.c_str(), body.size())); } else - if (resip::Pidf* pidf = dynamic_cast(c)) - { - resip::Data body = pidf->getBodyData(); - bool online = pidf->getSimpleStatus(&body); - resip::Data entity = pidf->getEntity().getAorNoPort(); - if (entity.find("sip:") == resip::Data::npos && entity.find("sips:") == resip::Data::npos) - entity = resip::Data("sip:") + entity; - onPresenceUpdate(observer, entity.c_str(), online, std::string(body.c_str(), body.size())); - - // Drop corresponding record from availableContacts - std::vector::iterator ci = std::find(availableContacts.begin(), availableContacts.end(), entity); - if (ci != availableContacts.end()) - availableContacts.erase(ci); - } - } + if (resip::MultipartRelatedContents* mr = dynamic_cast(contents)) + { + resip::MultipartRelatedContents::Parts& parts = mr->parts(); + for( resip::MultipartRelatedContents::Parts::const_iterator i = parts.begin(); i != parts.end(); ++i) + { + resip::Contents* c = *i; + assert( c ); + resip::Mime m = c->getType(); + if (resip::Rlmi* rlmi = dynamic_cast(c)) + { + resip::Data d = rlmi->getBodyData(); + // Workaround for XMLCursor bug + if (d.find(resip::Data(" tag in rlmi"); + } + else + { + for (bool hasRecord = c.firstChild(); hasRecord; hasRecord = c.nextSibling()) + { + if (c.getTag() != "resource") + { + ICELogError( << "Failed to find tag in rlmi"); + } + else + { + // Check if c has + + resip::XMLCursor::AttributeMap::const_iterator attrIter = c.getAttributes().find("uri"); + if (attrIter != c.getAttributes().end()) + { + // Save uri + resip::Data uri = attrIter->second; + + // Check if there is tag + bool instance = false; + for (bool hasChild = c.firstChild(); hasChild; hasChild = c.nextSibling()) + instance |= c.getTag() == "instance"; + c.parent(); + + // Save result + if (instance) + availableContacts.push_back( attrIter->second ); + } + } + } + } + } + else + if (resip::Pidf* pidf = dynamic_cast(c)) + { + resip::Data body = pidf->getBodyData(); + bool online = pidf->getSimpleStatus(&body); + resip::Data entity = pidf->getEntity().getAorNoPort(); + if (entity.find("sip:") == resip::Data::npos && entity.find("sips:") == resip::Data::npos) + entity = resip::Data("sip:") + entity; + onPresenceUpdate(observer, entity.c_str(), online, std::string(body.c_str(), body.size())); + + // Drop corresponding record from availableContacts + std::vector::iterator ci = std::find(availableContacts.begin(), availableContacts.end(), entity); + if (ci != availableContacts.end()) + availableContacts.erase(ci); + } + } + } } - } - - for (unsigned i=0; iisResponse()) - code = msg->header(resip::h_StatusLine).statusCode(); - - // Remove subscription from list, call terminated event - rs->runTerminatedEvent(ResipSession::Type_Subscription, code, 0); + // TODO - check for refer notication + if (!h.isValid() || !msg) + return; + + ResipSession* rs = CAST2RESIPSESSION(h); + if (!rs) + return; + + // Find the response code if available + int code = 0; + if (msg->isResponse()) + code = msg->header(resip::h_StatusLine).statusCode(); + + // Remove subscription from list, call terminated event + rs->runTerminatedEvent(ResipSession::Type_Subscription, code, 0); } void UserAgent::onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify) { - if (!h.isValid()) - return; + if (!h.isValid()) + return; - // Find dialog set - ResipSession* s = CAST2RESIPSESSION(h); - if (!s) - return; - - if (!s->mOnWatchingStartSent) - { - s->mOnWatchingStartSent = true; - ClientObserverMap::iterator observerIter = mClientObserverMap.find(s->sessionId()); - if (observerIter != mClientObserverMap.end()) - onClientObserverStart(observerIter->second); - } + // Find dialog set + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + + if (!s->mOnWatchingStartSent) + { + s->mOnWatchingStartSent = true; + ClientObserverMap::iterator observerIter = mClientObserverMap.find(s->sessionId()); + if (observerIter != mClientObserverMap.end()) + onClientObserverStart(observerIter->second); + } } /// called to allow app to adorn a message. @@ -1533,45 +1535,45 @@ void UserAgent::onFlowTerminated(resip::ClientSubscriptionHandle) #pragma region PagerHandler void UserAgent::onSuccess(resip::ClientPagerMessageHandle h, const resip::SipMessage& status) { - if (!h.isValid()) - return; - ResipSession* s = CAST2RESIPSESSION(h); - if (!s) - return; - onMessageSent(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(), s->tag()); + if (!h.isValid()) + return; + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + onMessageSent(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(), s->tag()); } void UserAgent::onFailure(resip::ClientPagerMessageHandle h, const resip::SipMessage& status, std::unique_ptr contents) { - if (!h.isValid()) - return; - ResipSession* s = CAST2RESIPSESSION(h); - if (!s) - return; - onMessageFailed(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(), status.header(resip::h_StatusLine).statusCode(), s->tag()); + if (!h.isValid()) + return; + ResipSession* s = CAST2RESIPSESSION(h); + if (!s) + return; + onMessageFailed(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(), status.header(resip::h_StatusLine).statusCode(), s->tag()); } void UserAgent::onMessageArrived(resip::ServerPagerMessageHandle h, const resip::SipMessage& message) { - if (!h.isValid()) - return; - resip::NameAddr from = message.header(resip::h_From); - std::string peer(from.uri().getAor().c_str()); - PAccount account = getAccount(from); - h->send(h->accept()); - resip::Contents* c = message.getContents(); - if (!c) - onMessageArrived(account, peer, NULL, 0); - else - { - resip::Data d = c->getBodyData(); - onMessageArrived(account, peer, d.c_str(), d.size()); - } + if (!h.isValid()) + return; + resip::NameAddr from = message.header(resip::h_From); + std::string peer(from.uri().getAor().c_str()); + PAccount account = getAccount(from); + h->send(h->accept()); + resip::Contents* c = message.getContents(); + if (!c) + onMessageArrived(account, peer, NULL, 0); + else + { + resip::Data d = c->getBodyData(); + onMessageArrived(account, peer, d.c_str(), d.size()); + } } void UserAgent::updateInterfaceList() { - //ICEImpl::ICENetworkHelper::instance().reload(); + //ICEImpl::ICENetworkHelper::instance().reload(); } void UserAgent::onMessageArrived(PAccount /*account*/, const std::string& /*peer*/, const void* /*ptr*/, unsigned /*length*/) @@ -1588,7 +1590,7 @@ void UserAgent::onMessageSent(PAccount /*account*/, int /*id*/, const std::strin VariantMap& UserAgent::config() { - return mConfig; + return mConfig; } /*static void splitToHeaders(resip::Data& content, std::vector& output) @@ -1630,11 +1632,11 @@ VariantMap& UserAgent::config() void UserAgent::onSipMessage(int flow, const char* msg, unsigned int length, const sockaddr* addr, unsigned int addrlen) { - std::string d(msg, length); - ice::NetworkAddress address(*addr, addrlen); - std::string addressText = address.toStdString(); + std::string d(msg, length); + ice::NetworkAddress address(*addr, addrlen); + std::string addressText = address.toStdString(); - /*switch (flow) + /*switch (flow) { case resip::InternalTransport::TransportLogger::Flow_Received: ICELogDebug(<< "Received from " << addressText << ":" << "\n" @@ -1649,37 +1651,37 @@ void UserAgent::onSipMessage(int flow, const char* msg, unsigned int length, con PSession UserAgent::getUserSession(int sessionId) { - SessionMap::iterator sessionIter = mSessionMap.find(sessionId); - if (sessionIter != mSessionMap.end()) - return sessionIter->second; - else - return PSession(); + SessionMap::iterator sessionIter = mSessionMap.find(sessionId); + if (sessionIter != mSessionMap.end()) + return sessionIter->second; + else + return PSession(); } PAccount UserAgent::getAccount(const resip::NameAddr& myAddr) { - PAccount acc; - for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc; accountIter++) - if ((*accountIter)->isResponsibleFor(myAddr)) - acc = *accountIter; + PAccount acc; + for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc; accountIter++) + if ((*accountIter)->isResponsibleFor(myAddr)) + acc = *accountIter; - return acc; + return acc; } PAccount UserAgent::getAccount(Account* account) { - PAccount acc; - for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc; accountIter++) - if (accountIter->get() == account) - acc = *accountIter; + PAccount acc; + for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc; accountIter++) + if (accountIter->get() == account) + acc = *accountIter; - return acc; + return acc; } PAccount UserAgent::getAccount(int sessionId) { - auto profileIter = std::find_if(mAccountSet.begin(), mAccountSet.end(), [=](const AccountSet::value_type& v) {if (v->mRegistration) return v->mRegistration->sessionId() == sessionId; else return false;}); - return (profileIter != mAccountSet.end()) ? *profileIter : PAccount(); + auto profileIter = std::find_if(mAccountSet.begin(), mAccountSet.end(), [=](const AccountSet::value_type& v) {if (v->mRegistration) return v->mRegistration->sessionId() == sessionId; else return false;}); + return (profileIter != mAccountSet.end()) ? *profileIter : PAccount(); } #pragma endregion diff --git a/src/engine/endpoint/EP_Engine.h b/src/engine/endpoint/EP_Engine.h index aabe5b63..e264a21e 100644 --- a/src/engine/endpoint/EP_Engine.h +++ b/src/engine/endpoint/EP_Engine.h @@ -70,52 +70,52 @@ 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_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_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 }; // Conntype parameter for OnSessionEstablished event enum { - EV_SIP = 1, - EV_ICE = 2 + EV_SIP = 1, + EV_ICE = 2 }; class UserAgent; @@ -124,7 +124,7 @@ class UserAgent; class SIPAction { public: - virtual void Run(UserAgent& ua) = 0; + virtual void Run(UserAgent& ua) = 0; }; typedef std::vector SIPActionVector; @@ -132,15 +132,15 @@ typedef std::vector SIPActionVector; // Session termination reason enum { - Error, - Timeout, - Replaced, - LocalBye, - RemoteBye, - LocalCancel, - RemoteCancel, - Rejected, //Only as UAS, UAC has distinct onFailure callback - Referred + Error, + Timeout, + Replaced, + LocalBye, + RemoteBye, + LocalCancel, + RemoteCancel, + Rejected, //Only as UAS, UAC has distinct onFailure callback + Referred }; class UserAgent: public resip::ClientRegistrationHandler, @@ -153,238 +153,238 @@ class UserAgent: public resip::ClientRegistrationHandler, 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; + 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); - static std::string formatSipAddress(const std::string& sip); - static bool isSipAddressValid(const std::string& sip); - struct SipAddress - { - bool mValid; - std::string mScheme; - std::string mUsername; - std::string mDomain; - std::string mDisplayname; - }; + /* 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); + struct SipAddress + { + bool mValid; + std::string mScheme; + std::string mUsername; + std::string mDomain; + std::string mDisplayname; + }; - static SipAddress parseSipAddress(const std::string& sip); + static SipAddress parseSipAddress(const std::string& sip); - UserAgent(); - virtual ~UserAgent(); - - /* Brings user agent online. Basically it creates a signalling socket(s). + UserAgent(); + virtual ~UserAgent(); + + /* Brings user agent online. Basically it creates a signalling socket(s). This is asynchronous method. */ - void start(); - - /* Shutdowns user agent. It closes all sessions, tries to unregister from server and disconnects from it. + 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(); - - /* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything. onStop() is called in context of this method. */ - void stop(); + void shutdown(); - /* Checks if user agent is active (started). */ - bool active(); - - /* Used to refresh existing registration(s), publication, subscriptions. */ - void refresh(); + /* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything. onStop() is called in context of this method. */ + void stop(); - /* Runs sip & ice stacks. Event handlers are called in its context. */ - void process(); - - /* Adds root cert in PEM format. Usable after start() call. */ - void addRootCert(const ByteBuffer& data); + /* Checks if user agent is active (started). */ + bool active(); - PAccount createAccount(PVariantMap config); - void deleteAccount(PAccount account); + /* Used to refresh existing registration(s), publication, subscriptions. */ + void refresh(); - /* Creates session. Returns session ID. */ - PSession createSession(PAccount account); - - // Must be called when IP interface list is changed - void updateInterfaceList(); + /* Runs sip & ice stacks. Event handlers are called in its context. */ + void process(); - // Called on new incoming session; providers shoukld - virtual PDataProvider onProviderNeeded(const std::string& name) = 0; + /* Adds root cert in PEM format. Usable after start() call. */ + void addRootCert(const ByteBuffer& data); - // Called on new session offer - virtual void onNewSession(PSession s) = 0; - - // Called when session is terminated - 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& p) = 0; + PAccount createAccount(PVariantMap config); + void deleteAccount(PAccount account); - // Called when client session gets - virtual void onSessionProvisional(PSession s, int code) = 0; + /* Creates session. Returns session ID. */ + PSession createSession(PAccount account); - // Called when user agent started - virtual void onStart(int errorcode) = 0; - - // Called when user agent stopped - virtual void onStop() = 0; + // Must be called when IP interface list is changed + void updateInterfaceList(); - // Called when account registered - virtual void onAccountStart(PAccount account) = 0; + // Called on new incoming session; providers shoukld + virtual PDataProvider onProviderNeeded(const std::string& name) = 0; - // Called when account removed or failed (non zero error code) - virtual void onAccountStop(PAccount account, int error) = 0; + // Called on new session offer + virtual void onNewSession(PSession s) = 0; - // Called when connectivity checks failed. - virtual void onConnectivityFailed(PSession s) = 0; + // Called when session is terminated + virtual void onSessionTerminated(PSession s, int responsecode, int reason) = 0; - // Called when new candidate is gathered - virtual void onCandidateGathered(PSession s, const char* address); - - // Called when network change detected - virtual void onNetworkChange(PSession s) = 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& p) = 0; - // Called when all candidates are gathered - virtual void onGathered(PSession s); + // Called when client session gets + virtual void onSessionProvisional(PSession s, int code) = 0; - // Called when new connectivity check is finished - virtual void onCheckFinished(PSession s, const char* description); - - // Called when log message must be recorded - virtual void onLog(const char* msg); - - // Called when problem with SIP connection(s) detected - virtual void onSipConnectionFailed() = 0; + // Called when user agent started + virtual void onStart(int errorcode) = 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); + // Called when user agent stopped + virtual void onStop() = 0; - 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(); + // Called when account registered + virtual void onAccountStart(PAccount account) = 0; + + // Called when account removed or failed (non zero error code) + virtual void onAccountStop(PAccount account, int error) = 0; + + // Called when connectivity checks failed. + virtual void onConnectivityFailed(PSession s) = 0; + + // Called when new candidate is gathered + virtual void onCandidateGathered(PSession s, const char* address); + + // Called when network change detected + virtual void onNetworkChange(PSession s) = 0; + + // Called when all candidates are gathered + virtual void onGathered(PSession s); + + // Called when new connectivity check is finished + virtual void onCheckFinished(PSession s, const char* description); + + // Called when log message must be recorded + virtual void onLog(const char* msg); + + // Called when problem with SIP connection(s) detected + 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 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(); 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; + /// Received a failure response from UAS + virtual void onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override; - /// called when dialog enters the Early state - typically after getting 18x - virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage&) 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; - /// called when a dialog initiated as a UAC enters the connected state - virtual void onConnected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override; + /// called when dialog enters the Early state - typically after getting 18x + virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage&) override; - /// called when a dialog initiated as a UAS enters the connected state - virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + /// called when a dialog initiated as a UAC enters the connected state + virtual void onConnected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override; - virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related=0) override; + /// called when a dialog initiated as a UAS enters the connected state + virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg) 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. - virtual void onForkDestroyed(resip::ClientInviteSessionHandle) override; + virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related=0) override; - /// called when a 3xx with valid targets is encountered in an early dialog - /// This is different then getting a 3xx in onTerminated, as another - /// request will be attempted, so the DialogSet will not be destroyed. - /// Basically an onTermintated that conveys more information. - /// checking for 3xx respones in onTerminated will not work as there may - /// be no valid targets. - virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) 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. + virtual void onForkDestroyed(resip::ClientInviteSessionHandle) override; - /// called when an SDP answer is received - has nothing to do with user - /// answering the call - virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override; + /// called when a 3xx with valid targets is encountered in an early dialog + /// This is different then getting a 3xx in onTerminated, as another + /// request will be attempted, so the DialogSet will not be destroyed. + /// Basically an onTermintated that conveys more information. + /// checking for 3xx respones in onTerminated will not work as there may + /// be no valid targets. + virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override; - /// called when an SDP offer is received - must send an answer soon after this - virtual void onOffer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override; + /// called when an SDP answer is received - has nothing to do with user + /// answering the call + virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override; - /// called when an Invite w/out SDP is sent, or any other context which - /// requires an SDP offer from the user - virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg) override; - - /// called if an offer in a UPDATE or re-INVITE was rejected - not real - /// useful. A SipMessage is provided if one is available - virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg) override; - - /// called when INFO message is received - virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + /// called when an SDP offer is received - must send an answer soon after this + virtual void onOffer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override; - /// called when response to INFO message is received - virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override; - virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + /// called when an Invite w/out SDP is sent, or any other context which + /// requires an SDP offer from the user + virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg) override; - /// called when MESSAGE message is received - virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + /// called if an offer in a UPDATE or re-INVITE was rejected - not real + /// useful. A SipMessage is provided if one is available + virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg) override; - /// called when response to MESSAGE message is received - virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override; - virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + /// called when INFO message is received + virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg) override; - /// called when an REFER message is received. The refer is accepted or - /// 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; + /// called when response to INFO message is received + virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override; - virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + /// called when MESSAGE message is received + virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg) override; - /// called when an REFER message receives a failure response - virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + /// called when response to MESSAGE message is received + virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + virtual void onMessageFailure(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; + /// called when an REFER message is received. The refer is accepted or + /// 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 onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) override; + + /// called when an REFER message receives a failure response + 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; #pragma endregion - // ClientRegistrationHandler implementation +// ClientRegistrationHandler implementation #pragma region ClientRegistrationHandler implementation - /// Called when registraion succeeds or each time it is sucessfully - /// refreshed. - void onSuccess(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; + /// Called when registraion succeeds or each time it is sucessfully + /// refreshed. + void onSuccess(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; - // Called when all of my bindings have been removed - void onRemoved(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; - - /// 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; - - /// Called if registration fails, usage will be destroyed (unless a - /// Registration retry interval is enabled in the Profile) - void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; + // Called when all of my bindings have been removed + void onRemoved(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; + + /// 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; + + /// Called if registration fails, usage will be destroyed (unless a + /// Registration retry interval is enabled in the Profile) + void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response) override; #pragma endregion #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; + /** 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; #pragma endregion #pragma region DnsResultSink implementation @@ -402,92 +402,92 @@ public: #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; + 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; #pragma endregion #pragma region SubscriptionHandler - void onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify); - 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 - void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override; - int onRequestRetry(resip::ClientSubscriptionHandle, int retrySeconds, const resip::SipMessage& notify) override; - - //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. - void onNewSubscription(resip::ClientSubscriptionHandle, const resip::SipMessage& notify) override; + void onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify); + void onUpdatePending(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override; + void onUpdateActive(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override; - /// called to allow app to adorn a message. - void onReadyToSend(resip::ClientSubscriptionHandle, resip::SipMessage& msg) override; - void onNotifyNotReceived(resip::ClientSubscriptionHandle) override; + //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; - /// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket - /// errors, or missing CRLF keep alives pong responses from the server. - // Called only if clientOutbound is enabled on the UserProfile and the first hop server - /// supports RFC5626 (outbound). - /// Default implementation is to re-form the subscription using a new flow - void onFlowTerminated(resip::ClientSubscriptionHandle) override; - void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub) override; - void onTerminated(resip::ServerSubscriptionHandle) override; + //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. + void onNewSubscription(resip::ClientSubscriptionHandle, const resip::SipMessage& notify) override; + + /// called to allow app to adorn a message. + void onReadyToSend(resip::ClientSubscriptionHandle, resip::SipMessage& msg) override; + void onNotifyNotReceived(resip::ClientSubscriptionHandle) override; + + /// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket + /// errors, or missing CRLF keep alives pong responses from the server. + // Called only if clientOutbound is enabled on the UserProfile and the first hop server + /// supports RFC5626 (outbound). + /// Default implementation is to re-form the subscription using a new flow + void onFlowTerminated(resip::ClientSubscriptionHandle) override; + void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub) override; + void onTerminated(resip::ServerSubscriptionHandle) override; #pragma endregion #pragma region PagerHandler - void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status) override; - void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr contents) override; - void onMessageArrived(resip::ServerPagerMessageHandle, const resip::SipMessage& message) override; + void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status) override; + void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr contents) override; + void onMessageArrived(resip::ServerPagerMessageHandle, const resip::SipMessage& message) override; #pragma endregion - void onDumCanBeDeleted() override; + void onDumCanBeDeleted() override; protected: - // Mutex to protect this instance - Mutex mGuard; + // Mutex to protect this instance + Mutex mGuard; - // Smart pointer to resiprocate's master profile instance. The stack configuration holds here. - std::shared_ptr mProfile; - - // Resiprocate's SIP stack object pointer - resip::SipStack* mStack; - - // Resiprocate's dialog usage manager object pointer - resip::DialogUsageManager* mDum; - - // List of available transports. They are owned by SipStack - so there is no need to delete instances in UserAgent. - std::vector mTransportList; + // Smart pointer to resiprocate's master profile instance. The stack configuration holds here. + std::shared_ptr mProfile; - typedef std::map SessionMap; - - // Session's map - SessionMap mSessionMap; + // Resiprocate's SIP stack object pointer + resip::SipStack* mStack; - // Used configuration - VariantMap mConfig; + // Resiprocate's dialog usage manager object pointer + resip::DialogUsageManager* mDum; - // Action vector - SIPActionVector mActionVector; - - typedef std::map ClientObserverMap; - ClientObserverMap mClientObserverMap; + // List of available transports. They are owned by SipStack - so there is no need to delete instances in UserAgent. + std::vector mTransportList; - typedef std::map ServerObserverMap; - ServerObserverMap mServerObserverMap; - - typedef std::set AccountSet; - AccountSet mAccountSet; + typedef std::map SessionMap; - // 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); + // Session's map + SessionMap mSessionMap; - PSession getUserSession(int sessionId); - PAccount getAccount(const resip::NameAddr& myAddr); - PAccount getAccount(Account* account); - PAccount getAccount(int sessionId); + // Used configuration + VariantMap mConfig; + + // Action vector + SIPActionVector mActionVector; + + typedef std::map ClientObserverMap; + ClientObserverMap mClientObserverMap; + + typedef std::map ServerObserverMap; + ServerObserverMap mServerObserverMap; + + typedef std::set 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); + + PSession getUserSession(int sessionId); + PAccount getAccount(const resip::NameAddr& myAddr); + PAccount getAccount(Account* account); + PAccount getAccount(int sessionId); }; #endif diff --git a/src/engine/endpoint/EP_NetworkQueue.cpp b/src/engine/endpoint/EP_NetworkQueue.cpp index 33149e62..78ee692a 100644 --- a/src/engine/endpoint/EP_NetworkQueue.cpp +++ b/src/engine/endpoint/EP_NetworkQueue.cpp @@ -2,7 +2,7 @@ #include "EP_Engine.h" WatcherQueue::WatcherQueue(UserAgent& ua) -:mActiveId(0), mAgent(ua) + :mActiveId(0), mAgent(ua) {} WatcherQueue::~WatcherQueue() @@ -10,173 +10,173 @@ WatcherQueue::~WatcherQueue() int WatcherQueue::add(std::string peer, std::string package, void* tag) { - ice::Lock l(mGuard); + ice::Lock l(mGuard); - // Check if queue has similar item - for (unsigned i=0; isetUa(&mAgent); - item.mSession->setType(ResipSession::Type_Subscription); - item.mSession->setTag(tag); - item.mId = item.mSession->sessionId(); - item.mSession->setRemoteAddress(peer); - item.mTag = tag; - mItemList.push_back(item); - process(); + Item item; + item.mTarget = peer; + item.mPackage = package; + item.mTag = tag; + item.mState = Item::State_ScheduledToAdd; + item.mSession = new ResipSession(*mAgent.mDum); + item.mSession->setUa(&mAgent); + item.mSession->setType(ResipSession::Type_Subscription); + item.mSession->setTag(tag); + item.mId = item.mSession->sessionId(); + item.mSession->setRemoteAddress(peer); + item.mTag = tag; + mItemList.push_back(item); + process(); - return item.mId; + return item.mId; } void WatcherQueue::remove(int id) { - ice::Lock l(mGuard); + ice::Lock l(mGuard); - // Check if queue has similar item - for (unsigned i=0; ischeduled(); i++) - ; - if (i == mItemList.end()) - return; - - std::shared_ptr msg; - int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME; - - switch (i->mState) + while (!mActiveId) { - case Item::State_ScheduledToAdd: - if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_TIME)) - expires = mAgent.mConfig[CONFIG_SUBSCRIPTION_TIME].asInt(); - if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_REFRESHTIME)) - refresh = mAgent.mConfig[CONFIG_SUBSCRIPTION_REFRESHTIME].asInt(); + // Find next item to process + ItemList::iterator i = mItemList.begin(); + for (;i != mItemList.end() && !i->scheduled(); i++) + ; + if (i == mItemList.end()) + return; - msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(i->mTarget)), resip::Data(i->mPackage), - expires, refresh, i->mSession); - msg->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY); - mActiveId = i->mId; - i->mState = Item::State_Adding; - mAgent.mDum->send(msg); - break; + std::shared_ptr msg; + int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME; - case Item::State_ScheduledToDelete: - i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, 0, 0); - if (i->mHandle.isValid()) - { - mActiveId = i->mId; - i->mHandle->end(); - i->mState = Item::State_Deleting; - break; - } - else - mItemList.erase(i); - break; + switch (i->mState) + { + case Item::State_ScheduledToAdd: + if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_TIME)) + expires = mAgent.mConfig[CONFIG_SUBSCRIPTION_TIME].asInt(); + if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_REFRESHTIME)) + refresh = mAgent.mConfig[CONFIG_SUBSCRIPTION_REFRESHTIME].asInt(); - case Item::State_ScheduledToRefresh: - if (i->mHandle.isValid()) - { - mActiveId = i->mId; - i->mState = Item::State_Refreshing; - i->mHandle->requestRefresh(); - } - else - mItemList.erase(i); - break; + msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(i->mTarget)), resip::Data(i->mPackage), + expires, refresh, i->mSession); + msg->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY); + mActiveId = i->mId; + i->mState = Item::State_Adding; + mAgent.mDum->send(msg); + break; - default: - break; + case Item::State_ScheduledToDelete: + i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, 0, 0); + if (i->mHandle.isValid()) + { + mActiveId = i->mId; + i->mHandle->end(); + i->mState = Item::State_Deleting; + break; + } + else + mItemList.erase(i); + break; + + case Item::State_ScheduledToRefresh: + if (i->mHandle.isValid()) + { + mActiveId = i->mId; + i->mState = Item::State_Refreshing; + i->mHandle->requestRefresh(); + } + else + mItemList.erase(i); + break; + + default: + break; + } } - } } void WatcherQueue::onTerminated(int id, int code) { - ice::Lock l(mGuard); - ItemList::iterator i = findById(id); - if (i != mItemList.end()) - { - if (i->mSession) - i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, code, 0); - mItemList.erase(i); - if (i->mId == mActiveId) - mActiveId = 0; - } - process(); + ice::Lock l(mGuard); + ItemList::iterator i = findById(id); + if (i != mItemList.end()) + { + if (i->mSession) + i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, code, 0); + mItemList.erase(i); + if (i->mId == mActiveId) + mActiveId = 0; + } + process(); } void WatcherQueue::onEstablished(int id, int code) { - ice::Lock l(mGuard); - ItemList::iterator i = findById(id); - if (i != mItemList.end()) - { - i->mState = Item::State_Active; - if (i->mId == mActiveId) - mActiveId = 0; - } - process(); + ice::Lock l(mGuard); + ItemList::iterator i = findById(id); + if (i != mItemList.end()) + { + i->mState = Item::State_Active; + if (i->mId == mActiveId) + mActiveId = 0; + } + process(); } WatcherQueue::ItemList::iterator WatcherQueue::findById(int id) { - for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++) - if (i->mId == id) - return i; - return mItemList.end(); + for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++) + if (i->mId == id) + return i; + return mItemList.end(); } void WatcherQueue::clear() { - ice::Lock l(mGuard); - for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++) - { - if (i->mHandle.isValid()) - i->mHandle->end(); - } - mItemList.clear(); + ice::Lock l(mGuard); + for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++) + { + if (i->mHandle.isValid()) + i->mHandle->end(); + } + mItemList.clear(); } diff --git a/src/engine/endpoint/EP_NetworkQueue.h b/src/engine/endpoint/EP_NetworkQueue.h index 5ff753ee..6cc76b66 100644 --- a/src/engine/endpoint/EP_NetworkQueue.h +++ b/src/engine/endpoint/EP_NetworkQueue.h @@ -13,57 +13,57 @@ class UserAgent; class WatcherQueue { public: - struct Item - { - enum State + struct Item { - State_None, - State_Active, - State_ScheduledToAdd, - State_Adding, - State_ScheduledToRefresh, - State_Refreshing, - State_ScheduledToDelete, - State_Deleting + enum State + { + State_None, + State_Active, + State_ScheduledToAdd, + State_Adding, + State_ScheduledToRefresh, + State_Refreshing, + State_ScheduledToDelete, + State_Deleting + }; + + resip::ClientSubscriptionHandle mHandle; // Subscription handle + ResipSession* mSession; + State mState; + std::string mTarget; // Target's address + std::string mPackage; // Event package + void* mTag; // User tag + int mId; + + Item() + :mSession(NULL), mState(State_None), mTag(NULL), mId(0) + {} + + bool scheduled() + { + return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete || mState == State_ScheduledToRefresh; + } }; + WatcherQueue(UserAgent& agent); + ~WatcherQueue(); - resip::ClientSubscriptionHandle mHandle; // Subscription handle - ResipSession* mSession; - State mState; - std::string mTarget; // Target's address - std::string mPackage; // Event package - void* mTag; // User tag - int mId; + int add(std::string peer, std::string package, void* tag); + void remove(int id); + void refresh(int id); + void clear(); - Item() - :mSession(NULL), mState(State_None), mTag(NULL), mId(0) - {} - - bool scheduled() - { - return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete || mState == State_ScheduledToRefresh; - } - }; - WatcherQueue(UserAgent& agent); - ~WatcherQueue(); - - int add(std::string peer, std::string package, void* tag); - void remove(int id); - void refresh(int id); - void clear(); - - void onTerminated(int id, int code); - void onEstablished(int id, int code); + void onTerminated(int id, int code); + void onEstablished(int id, int code); protected: - typedef std::vector ItemList; - ItemList mItemList; - ice::Mutex mGuard; - UserAgent& mAgent; - int mActiveId; + typedef std::vector ItemList; + ItemList mItemList; + ice::Mutex mGuard; + UserAgent& mAgent; + int mActiveId; - void process(); - ItemList::iterator findById(int id); + void process(); + ItemList::iterator findById(int id); }; #endif diff --git a/src/engine/endpoint/EP_Observer.cpp b/src/engine/endpoint/EP_Observer.cpp index 0960f002..2a992773 100644 --- a/src/engine/endpoint/EP_Observer.cpp +++ b/src/engine/endpoint/EP_Observer.cpp @@ -19,88 +19,88 @@ ClientObserver::~ClientObserver() void ClientObserver::refresh() { - if (mHandle.isValid()) - mHandle->requestRefresh(); + if (mHandle.isValid()) + mHandle->requestRefresh(); } void ClientObserver::stop() { - if (mHandle.isValid()) - mHandle->end(); - else - if (mSession) - { - mSession->runTerminatedEvent(ResipSession::Type_Subscription); - if (mSession) - mSession->end(); - } - mSession = NULL; + if (mHandle.isValid()) + mHandle->end(); + else + if (mSession) + { + mSession->runTerminatedEvent(ResipSession::Type_Subscription); + if (mSession) + mSession->end(); + } + mSession = NULL; } std::string ClientObserver::peer() { - return mPeer; + return mPeer; } ServerObserver::ServerObserver() - :mState(State_Incoming) + :mState(State_Incoming) { } ServerObserver::~ServerObserver() { - stop(); + stop(); } std::string ServerObserver::peer() const { - return mPeer; + return mPeer; } std::string ServerObserver::package() const { - return mPackage; + return mPackage; } void ServerObserver::update(std::string simpleId, bool online, std::string msg) { - if (mState != State_Active) - return; + if (mState != State_Active) + return; - resip::Pidf p; - p.setEntity(mContact); - p.setSimpleId(resip::Data(simpleId)); - p.setSimpleStatus(online, resip::Data(msg)); + resip::Pidf p; + p.setEntity(mContact); + p.setSimpleId(resip::Data(simpleId)); + p.setSimpleStatus(online, resip::Data(msg)); - if (mHandle.isValid()) - mHandle->send(mHandle->update(&p)); + if (mHandle.isValid()) + mHandle->send(mHandle->update(&p)); } void ServerObserver::accept() { - if (mHandle.isValid() && mState == State_Incoming) - { - mState = State_Active; - mHandle->accept(); - } + if (mHandle.isValid() && mState == State_Incoming) + { + mState = State_Active; + mHandle->accept(); + } } void ServerObserver::stop() { - if (!mHandle.isValid()) - return; + if (!mHandle.isValid()) + return; - switch (mState) - { - case State_Incoming: - mHandle->reject(404); - break; - case State_Active: - mHandle->end(); - break; - default: - break; - } - mState = State_Closed; + switch (mState) + { + case State_Incoming: + mHandle->reject(404); + break; + case State_Active: + mHandle->end(); + break; + default: + break; + } + mState = State_Closed; } diff --git a/src/engine/endpoint/EP_Observer.h b/src/engine/endpoint/EP_Observer.h index 9698cf19..834b4e33 100644 --- a/src/engine/endpoint/EP_Observer.h +++ b/src/engine/endpoint/EP_Observer.h @@ -21,51 +21,51 @@ class ResipSession; class ClientObserver { - friend class Account; - friend class UserAgent; + friend class Account; + friend class UserAgent; public: - ClientObserver(); - ~ClientObserver(); + ClientObserver(); + ~ClientObserver(); - void refresh(); - void stop(); - std::string peer(); + void refresh(); + void stop(); + std::string peer(); protected: - resip::ClientSubscriptionHandle mHandle; - ResipSession* mSession; - int mSessionId; - std::string mPeer; + resip::ClientSubscriptionHandle mHandle; + ResipSession* mSession; + int mSessionId; + std::string mPeer; }; typedef std::shared_ptr PClientObserver; class ServerObserver { - friend class UserAgent; + friend class UserAgent; public: - ServerObserver(); - ~ServerObserver(); + ServerObserver(); + ~ServerObserver(); - std::string peer() const; - std::string package() const; + 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 - { - State_Incoming, - State_Active, - State_Closed - }; - State mState; - resip::ServerSubscriptionHandle mHandle; - std::string mPeer, mPackage; - resip::Uri mContact; - int mSessionId; + enum State + { + State_Incoming, + State_Active, + State_Closed + }; + State mState; + resip::ServerSubscriptionHandle mHandle; + std::string mPeer, mPackage; + resip::Uri mContact; + int mSessionId; }; typedef std::shared_ptr PServerObserver;