diff --git a/src/engine/audio/Audio_WavFile.cpp b/src/engine/audio/Audio_WavFile.cpp index 58197f82..f4a1baa5 100644 --- a/src/engine/audio/Audio_WavFile.cpp +++ b/src/engine/audio/Audio_WavFile.cpp @@ -33,7 +33,7 @@ WaveFormatEx; #define LOG_SUBSYSTEM "WavFileReader" -#define LOCK std::unique_lock lock(mFileMtx); +#define LOCK std::unique_lock lock(mFileMtx); using namespace Audio; diff --git a/src/engine/audio/Audio_WavFile.h b/src/engine/audio/Audio_WavFile.h index eb4f3c95..86087679 100644 --- a/src/engine/audio/Audio_WavFile.h +++ b/src/engine/audio/Audio_WavFile.h @@ -28,7 +28,7 @@ namespace Audio short mBits; int mRate; std::tstring mFileName; - mutable std::mutex mFileMtx; + mutable std::recursive_mutex mFileMtx; unsigned mDataOffset; unsigned mDataLength; Resampler mResampler; @@ -57,12 +57,13 @@ namespace Audio class WavFileWriter { protected: - FILE* mHandle; /// Handle of audio file. - std::tstring mFileName; /// Path to requested audio file. - std::mutex mFileMtx; /// Mutex to protect this instance. - int mWritten; /// Amount of written data (in bytes) - int mLengthOffset; /// Position of length field. - int mRate, mChannels; + FILE* mHandle; /// Handle of audio file. + std::tstring mFileName; /// Path to requested audio file. + std::recursive_mutex mFileMtx; /// Mutex to protect this instance. + int mWritten; /// Amount of written data (in bytes) + int mLengthOffset; /// Position of length field. + int mRate, + mChannels; void checkWriteResult(int result); diff --git a/src/engine/endpoint/EP_Session.cpp b/src/engine/endpoint/EP_Session.cpp index 59df0c3d..68f4f259 100644 --- a/src/engine/endpoint/EP_Session.cpp +++ b/src/engine/endpoint/EP_Session.cpp @@ -40,158 +40,158 @@ ResipSessionAppDialog::~ResipSessionAppDialog() resip::AtomicCounter ResipSession::InstanceCounter; ResipSession::ResipSession(resip::DialogUsageManager& dum) - : resip::AppDialogSet(dum), mUserAgent(NULL), mType(Type_None), mSessionId(0), mSession(0) + : resip::AppDialogSet(dum), mUserAgent(NULL), mType(Type_None), mSessionId(0), mSession(0) { - ResipSession::InstanceCounter.increment(); - mTag = NULL; - mTerminated = false; - mOnWatchingStartSent = false; - mSessionId = Session::generateId(); + ResipSession::InstanceCounter.increment(); + mTag = NULL; + mTerminated = false; + mOnWatchingStartSent = false; + mSessionId = Session::generateId(); } ResipSession::~ResipSession() { - try - { - // Detach from user session - if (mSession) - mSession->mResipSession = nullptr; - runTerminatedEvent(Type_Auto, 0, 0); - } - catch(...) - { - } + try + { + // Detach from user session + if (mSession) + mSession->mResipSession = nullptr; + runTerminatedEvent(Type_Auto, 0, 0); + } + catch(...) + { + } - ResipSession::InstanceCounter.decrement(); + ResipSession::InstanceCounter.decrement(); } resip::AppDialog* ResipSession::createAppDialog(const resip::SipMessage& msg) { - return new ResipSessionAppDialog(static_cast(mDum)); + return new ResipSessionAppDialog(static_cast(mDum)); } void ResipSession::runTerminatedEvent(Type type, int code, int reason) { - if (mTerminated) - return; - - Type t = type; - if (type == Type_Auto) - t = mType; - if (t == Type_None) - t = Type_Call; - - mTerminated = true; - if (mUserAgent) - { - switch (t) + if (mTerminated) + return; + + Type t = type; + if (type == Type_Auto) + t = mType; + if (t == Type_None) + t = Type_Call; + + mTerminated = true; + if (mUserAgent) { - case Type_Call: - if (mSession) - mUserAgent->onSessionTerminated(mUserAgent->getUserSession(mSessionId), code, reason); - break; + switch (t) + { + case Type_Call: + if (mSession) + mUserAgent->onSessionTerminated(mUserAgent->getUserSession(mSessionId), code, reason); + break; - case Type_Registration: - mUserAgent->onAccountStop(mUserAgent->getAccount(mSessionId), code); - break; + case Type_Registration: + mUserAgent->onAccountStop(mUserAgent->getAccount(mSessionId), code); + break; - case Type_Subscription: - if (mSession) - { - UserAgent::ClientObserverMap::iterator observerIter = mUserAgent->mClientObserverMap.find(mSession->sessionId()); - if (observerIter != mUserAgent->mClientObserverMap.end()) - mUserAgent->onClientObserverStop(observerIter->second, code); - } - break; + case Type_Subscription: + if (mSession) + { + UserAgent::ClientObserverMap::iterator observerIter = mUserAgent->mClientObserverMap.find(mSession->sessionId()); + if (observerIter != mUserAgent->mClientObserverMap.end()) + mUserAgent->onClientObserverStop(observerIter->second, code); + } + break; - default: - break; + default: + break; + } } - } } std::string ResipSession::remoteAddress() const { - return mRemoteAddress; + return mRemoteAddress; } void ResipSession::setRemoteAddress(std::string address) { - mRemoteAddress = address; + mRemoteAddress = address; } void ResipSession::setType(Type type) { - mType = type; + mType = type; } ResipSession::Type ResipSession::type() { - return mType; + return mType; } Session* ResipSession::session() { - return mSession; + return mSession; } void* ResipSession::tag() const { - return mTag; + return mTag; } void ResipSession::setTag(void* tag) { - mTag = tag; + mTag = tag; } void ResipSession::setSession(Session* session) { - mSession = session; - if (mSession) - mSessionId = mSession->sessionId(); + mSession = session; + if (mSession) + mSessionId = mSession->sessionId(); } UserAgent* ResipSession::ua() { - return mUserAgent; + return mUserAgent; } void ResipSession::setUa(UserAgent* ua) { - mUserAgent = ua; + mUserAgent = ua; } int ResipSession::sessionId() { - return mSessionId; + return mSessionId; } void ResipSession::setUASProfile(std::shared_ptr profile) { - mUASProfile = profile; + mUASProfile = profile; } resip::SharedPtr ResipSession::selectUASUserProfile(const resip::SipMessage& msg) { - assert(mUserAgent != nullptr); + assert(mUserAgent != nullptr); - if (mUserAgent) - { - PAccount account = mUserAgent->getAccount(msg.header(resip::h_To)); - if (account) - return account->getUserProfile(); - else - return mUserAgent->mProfile; - } - return resip::SharedPtr(); + if (mUserAgent) + { + PAccount account = mUserAgent->getAccount(msg.header(resip::h_To)); + if (account) + return account->getUserProfile(); + else + return mUserAgent->mProfile; + } + return resip::SharedPtr(); } #pragma endregion #pragma region Session::Stream Session::Stream::Stream() - :mRtcpAttr(false), mRtcpMuxAttr(false) + :mRtcpAttr(false), mRtcpMuxAttr(false) { } @@ -201,62 +201,62 @@ Session::Stream::~Stream() void Session::Stream::setProvider(PDataProvider provider) { - mProvider = provider; + mProvider = provider; } PDataProvider Session::Stream::provider() { - return mProvider; + return mProvider; } void Session::Stream::setSocket4(const RtpPair& socket) { - mSocket4 = socket; + mSocket4 = socket; } RtpPair& Session::Stream::socket4() { - return mSocket4; + return mSocket4; } void Session::Stream::setSocket6(const RtpPair& socket) { - mSocket6 = socket; + mSocket6 = socket; } RtpPair& Session::Stream::socket6() { - return mSocket6; + return mSocket6; } void Session::Stream::setIceInfo(const IceInfo& ii) { - mIceInfo = ii; + mIceInfo = ii; } Session::IceInfo Session::Stream::iceInfo() const { - return mIceInfo; + return mIceInfo; } bool Session::Stream::rtcpAttr() const { - return mRtcpAttr; + return mRtcpAttr; } void Session::Stream::setRtcpAttr(bool value) { - mRtcpAttr = value; + mRtcpAttr = value; } bool Session::Stream::rtcpMuxAttr() const { - return mRtcpMuxAttr; + return mRtcpMuxAttr; } void Session::Stream::setRtcpMuxAttr(bool value) { - mRtcpMuxAttr = value; + mRtcpMuxAttr = value; } #pragma endregion @@ -266,848 +266,847 @@ resip::AtomicCounter Session::InstanceCounter; Session::Session(PAccount account) { - InstanceCounter.increment(); - mAccount = account; - mSessionId = Session::generateId(); - mTag = NULL; - mAcceptedByEngine = false; - mAcceptedByUser = false; - mUserAgent = NULL; - mOriginVersion = 0; - mSessionVersion = 0; - mRole = Acceptor; - mGatheredCandidates = false; - mTerminated = false; - mRemoteOriginVersion = (UInt64)-1; - mResipSession = NULL; - mRefCount = 1; - mOfferAnswerCounter = 0; - mHasToSendOffer = false; - mSendOfferUpdateAfterIceGather = false; + InstanceCounter.increment(); + mAccount = account; + mSessionId = Session::generateId(); + mTag = NULL; + mAcceptedByEngine = false; + mAcceptedByUser = false; + mUserAgent = NULL; + mOriginVersion = 0; + mSessionVersion = 0; + mRole = Acceptor; + mGatheredCandidates = false; + mTerminated = false; + mRemoteOriginVersion = (UInt64)-1; + mResipSession = NULL; + mRefCount = 1; + mOfferAnswerCounter = 0; + mHasToSendOffer = false; + mSendOfferUpdateAfterIceGather = false; } Session::~Session() { - try - { - if (mResipSession) - mResipSession->setSession(NULL); - clearProvidersAndSockets(); - } - catch(...) - {} - InstanceCounter.decrement(); + try + { + if (mResipSession) + mResipSession->setSession(NULL); + clearProvidersAndSockets(); + } + catch(...) + {} + InstanceCounter.decrement(); } void Session::start(const std::string& peer) { - ICELogInfo( << "Attempt to start session to " << peer); - Lock l(mGuard); + ICELogInfo( << "Attempt to start session to " << peer); + Lock l(mGuard); - if (mResipSession) - { - ICELogError(<< "Session " << mSessionId << " is already started."); - return; - } - - // Save target address - mRemoteAddress = UserAgent::formatSipAddress(peer); + if (mResipSession) + { + ICELogError(<< "Session " << mSessionId << " is already started."); + return; + } - // Create resiprocate session - mResipSession = new ResipSession(*mUserAgent->mDum); - mResipSession->setSession(this); - mResipSession->setUa(mUserAgent); + // Save target address + mRemoteAddress = UserAgent::formatSipAddress(peer); - // Do not call OnNewSession for this session - mAcceptedByEngine = true; + // Create resiprocate session + mResipSession = new ResipSession(*mUserAgent->mDum); + mResipSession->setSession(this); + mResipSession->setUa(mUserAgent); - // Mark session as Initiator - mRole = Session::Initiator; + // Do not call OnNewSession for this session + mAcceptedByEngine = true; - resip::Data addrData(peer); - resip::NameAddr addr(addrData); + // Mark session as Initiator + mRole = Session::Initiator; - // Save target address - mRemotePeer = addr; + resip::Data addrData(peer); + resip::NameAddr addr(addrData); - // Start to gather ICE candidates (streams are created in addProvider() method) - mIceStack->gatherCandidates(); + // Save target address + mRemotePeer = addr; + + // Start to gather ICE candidates (streams are created in addProvider() method) + mIceStack->gatherCandidates(); } void Session::stop() { - ICELogInfo(<< "Stopping session " << mSessionId); - Lock l(mGuard); - for (unsigned i=0; isessionTerminated(); + Session::Stream& dataStream = mStreamList[i]; - // Free socket - SocketHeap::instance().freeSocketPair( dataStream.socket4() ); - SocketHeap::instance().freeSocketPair( dataStream.socket6() ); + if (dataStream.provider()) + { + // Notify provider about finished I/O + dataStream.provider()->sessionTerminated(); + + // Free socket + SocketHeap::instance().freeSocketPair( dataStream.socket4() ); + SocketHeap::instance().freeSocketPair( dataStream.socket6() ); + } } - } - if (mResipSession) - mResipSession->runTerminatedEvent(ResipSession::Type_Call, 0, LocalBye); + if (mResipSession) + mResipSession->runTerminatedEvent(ResipSession::Type_Call, 0, LocalBye); - if (mResipSession) - mResipSession->end(); // Stop SIP session + if (mResipSession) + mResipSession->end(); // Stop SIP session } void Session::accept() { - ICELogInfo(<< "Attempt to accept session " << mSessionId); + ICELogInfo(<< "Attempt to accept session " << mSessionId); - Lock locksession(mGuard); + Lock locksession(mGuard); - // If ICE candidate gathering is not finished - just mark session as accepted. It will be accepted in ICE handling code. - mAcceptedByUser = true; + // If ICE candidate gathering is not finished - just mark session as accepted. It will be accepted in ICE handling code. + mAcceptedByUser = true; - if (mGatheredCandidates || mIceStack->state() == ice::IceNone) - { - ICELogInfo(<< "Candidates are gathered for session " << mSessionId << ", build&send answer."); - - // Build SDP - resip::SdpContents sdp; - buildSdp(sdp, Sdp_Answer); - - resip::ServerInviteSession* sis = dynamic_cast(mInviteHandle.get()); - if (sis) + if (mGatheredCandidates || mIceStack->state() == ice::IceNone) { - /*if (mInviteHandle.isValid()) + ICELogInfo(<< "Candidates are gathered for session " << mSessionId << ", build&send answer."); + + // Build SDP + resip::SdpContents sdp; + buildSdp(sdp, Sdp_Answer); + + resip::ServerInviteSession* sis = dynamic_cast(mInviteHandle.get()); + if (sis) + { + /*if (mInviteHandle.isValid()) mInviteHandle->setUserHeaders(mUserHeaders);*/ - sis->setUserHeaders(mUserHeaders); - sis->provideAnswer(sdp); - sis->accept(); + sis->setUserHeaders(mUserHeaders); + sis->provideAnswer(sdp); + sis->accept(); + } + + // Reset mAcceptScheduled & mGatheredCandidates + mGatheredCandidates = false; + + // Start connectivity checks + if (mIceStack->state() > ice::IceNone) + { + ICELogInfo(<< "Start connectivity checks for session " << mSessionId); + mIceStack->checkConnectivity(); + } } - - // Reset mAcceptScheduled & mGatheredCandidates - mGatheredCandidates = false; - - // Start connectivity checks - if (mIceStack->state() > ice::IceNone) + else { - ICELogInfo(<< "Start connectivity checks for session " << mSessionId); - mIceStack->checkConnectivity(); + ICELogInfo(<< "ICE gathering is not finished yet for session " << mSessionId << " SDP build is deferred."); } - } - else - { - ICELogInfo(<< "ICE gathering is not finished yet for session " << mSessionId << " SDP build is deferred."); - } } void Session::reject(int code) { - ICELogInfo( << "Attempt to reject session " << mSessionId); + ICELogInfo( << "Attempt to reject session " << mSessionId); - Lock l(mGuard); + Lock l(mGuard); - if (mInviteHandle.isValid()) - { - mInviteHandle->reject(code); - ICELogInfo(<< "Session " << mSessionId << " is rejected."); - } - else - ICELogError(<< "Session " << mSessionId << " has not valid invite handle."); + if (mInviteHandle.isValid()) + { + mInviteHandle->reject(code); + ICELogInfo(<< "Session " << mSessionId << " is rejected."); + } + else + ICELogError(<< "Session " << mSessionId << " has not valid invite handle."); } AudioProvider* Session::findProviderForActiveAudio() { - for (unsigned streamIndex = 0; streamIndex < mStreamList.size(); streamIndex++) - { - PDataProvider p = mStreamList[streamIndex].provider(); - if (p) + for (unsigned streamIndex = 0; streamIndex < mStreamList.size(); streamIndex++) { - if (p->streamName() == "audio") - { - AudioProvider* audio = (AudioProvider*)p.get(); - if (audio->activeStream()) - return audio; - } + PDataProvider p = mStreamList[streamIndex].provider(); + if (p) + { + if (p->streamName() == "audio") + { + AudioProvider* audio = (AudioProvider*)p.get(); + if (audio->activeStream()) + return audio; + } + } } - } - return NULL; + return NULL; } void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info) { - Lock l(mGuard); + Lock l(mGuard); - // Retrieve remote sip address - info[SessionInfo_RemoteSipAddress] = remoteAddress(); - if (mIceStack) - info[SessionInfo_IceState] = mIceStack->state(); + // Retrieve remote sip address + info[SessionInfo_RemoteSipAddress] = remoteAddress(); + if (mIceStack) + info[SessionInfo_IceState] = mIceStack->state(); - // Get media stats - MT::Statistics stat; + // Get media stats + MT::Statistics stat; - // Iterate all session providers - stat.reset(); - Stream* media = NULL; - for (unsigned streamIndex = 0; streamIndex < mStreamList.size(); streamIndex++) - { - Stream& stream = mStreamList[streamIndex]; - if (stream.provider()) + // Iterate all session providers + stat.reset(); + Stream* media = NULL; + for (unsigned streamIndex = 0; streamIndex < mStreamList.size(); streamIndex++) { - media = &stream; - MT::Statistics s = stream.provider()->getStatistics(); + Stream& stream = mStreamList[streamIndex]; + if (stream.provider()) + { + media = &stream; + MT::Statistics s = stream.provider()->getStatistics(); #if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER) - if (options != InfoOptions::Standard) - { - //if (s.mPvqaMos == 0.0f) - // s.mPvqaMos = calculatePvqaMos(AUDIO_SAMPLERATE); - info[SessionInfo_PvqaMos] = s.mPvqaMos; - info[SessionInfo_PvqaReport] = s.mPvqaReport; - } + if (options != InfoOptions::Standard) + { + // This information is available AFTER audio stream is deleted + info[SessionInfo_PvqaMos] = s.mPvqaMos; + info[SessionInfo_PvqaReport] = s.mPvqaReport; + } #endif - info[SessionInfo_NetworkMos] = (float)s.calculateMos(4.14); - info[SessionInfo_AudioCodec] = s.mCodecName; + info[SessionInfo_NetworkMos] = (float)s.calculateMos(4.14); + info[SessionInfo_AudioCodec] = s.mCodecName; - stat += s; + stat += s; + } } - } - info[SessionInfo_ReceivedTraffic] = (int)stat.mReceived; - info[SessionInfo_SentTraffic] = (int)stat.mSent; - info[SessionInfo_ReceivedRtp] = stat.mReceivedRtp; - info[SessionInfo_ReceivedRtcp] = stat.mReceivedRtcp; - info[SessionInfo_LostRtp] = stat.mPacketLoss; - info[SessionInfo_SentRtp] = stat.mSentRtp; - info[SessionInfo_SentRtcp] = stat.mSentRtcp; - if (stat.mFirstRtpTime) - info[SessionInfo_Duration] = (int)std::chrono::duration_cast(std::chrono::system_clock::now() - *(stat.mFirstRtpTime)).count(); - else - info[SessionInfo_Duration] = 0; + info[SessionInfo_ReceivedTraffic] = (int)stat.mReceived; + info[SessionInfo_SentTraffic] = (int)stat.mSent; + info[SessionInfo_ReceivedRtp] = stat.mReceivedRtp; + info[SessionInfo_ReceivedRtcp] = stat.mReceivedRtcp; + info[SessionInfo_LostRtp] = stat.mPacketLoss; + info[SessionInfo_SentRtp] = stat.mSentRtp; + info[SessionInfo_SentRtcp] = stat.mSentRtcp; + if (stat.mFirstRtpTime) + info[SessionInfo_Duration] = (int)std::chrono::duration_cast(std::chrono::system_clock::now() - *(stat.mFirstRtpTime)).count(); + else + info[SessionInfo_Duration] = 0; - if (stat.mReceivedRtp) - info[SessionInfo_PacketLoss] = (stat.mPacketLoss * 1000) / stat.mReceivedRtp; + if (stat.mReceivedRtp) + info[SessionInfo_PacketLoss] = (stat.mPacketLoss * 1000) / stat.mReceivedRtp; - if (media) - info[SessionInfo_AudioPeer] = mIceStack->remoteAddress(media->iceInfo().mStreamId, media->iceInfo().mComponentId.mRtp).toStdString(); + if (media) + info[SessionInfo_AudioPeer] = mIceStack->remoteAddress(media->iceInfo().mStreamId, media->iceInfo().mComponentId.mRtp).toStdString(); - info[SessionInfo_Jitter] = stat.mJitter; - if (stat.mRttDelay.isInitialized()) - info[SessionInfo_Rtt] = (float)stat.mRttDelay.getCurrent() * 1000; + info[SessionInfo_Jitter] = stat.mJitter; + if (stat.mRttDelay.isInitialized()) + info[SessionInfo_Rtt] = (float)stat.mRttDelay.getCurrent() * 1000; #if defined(USE_AMR_CODEC) - info[SessionInfo_BitrateSwitchCounter] = stat.mBitrateSwitchCounter; + info[SessionInfo_BitrateSwitchCounter] = stat.mBitrateSwitchCounter; #endif - info[SessionInfo_SSRC] = stat.mSsrc; - info[SessionInfo_RemotePeer] = stat.mRemotePeer.toStdString(); + info[SessionInfo_SSRC] = stat.mSsrc; + info[SessionInfo_RemotePeer] = stat.mRemotePeer.toStdString(); } int Session::id() const { - return mSessionId; + return mSessionId; } PAccount Session::account() { - return mAccount; + return mAccount; } void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize) { - Lock l(mGuard); + Lock l(mGuard); - if (mTerminated) - return; + if (mTerminated) + return; - // Check if it STUN packet and must be processed by ICE stack - //ICELogDebug (<< "Received UDP packet from " << src.ip() << ":" << src.port()); - ice::ByteBuffer received(receivedPtr, receivedSize); - received.setRemoteAddress(src); + // Check if it STUN packet and must be processed by ICE stack + //ICELogDebug (<< "Received UDP packet from " << src.ip() << ":" << src.port()); + ice::ByteBuffer received(receivedPtr, receivedSize); + received.setRemoteAddress(src); - ice::ByteBuffer plain; + ice::ByteBuffer plain; - if (ice::Stack::isStun(received)) - { - // Check if it is Data indication packet - if (ice::Stack::isDataIndication(received, &plain)) + if (ice::Stack::isStun(received)) { - received = plain; + // Check if it is Data indication packet + if (ice::Stack::isDataIndication(received, &plain)) + { + received = plain; + } } - } - else // Check if packet is prefixed with TURN prefix - if (received.size() >= 4) - { - bool turnPrefix = false; - for (unsigned i=0; i= 4) + { + bool turnPrefix = false; + for (unsigned i=0; ifindStreamAndComponent(socket->family(), socket->localport(), &stream, &component)) + // Now process actual stun packet - it could be wrapped in Data Indication or Channel Data + if (ice::Stack::isStun(received)) { - ice::ByteBuffer buffer(receivedPtr, receivedSize); - buffer.setRemoteAddress(src); - processed = mIceStack->processIncomingData(stream, component, buffer); - } - } - else - { - // Find provider responsible for processing - PDataProvider provider = this->findProviderByPort(socket->family(), socket->localport()); - if (provider) - { - provider->processData(socket, receivedPtr, receivedSize, src); + // Try to process incoming data by ICE stack + int component = -1, stream = -1; + bool processed; + if (mIceStack->findStreamAndComponent(socket->family(), socket->localport(), &stream, &component)) + { + ice::ByteBuffer buffer(receivedPtr, receivedSize); + buffer.setRemoteAddress(src); + processed = mIceStack->processIncomingData(stream, component, buffer); + } } else { - // Just ignore these data + // Find provider responsible for processing + PDataProvider provider = this->findProviderByPort(socket->family(), socket->localport()); + if (provider) + { + provider->processData(socket, receivedPtr, receivedSize, src); + } + else + { + // Just ignore these data + } } - } } // Called when new candidate is gathered void Session::onCandidateGathered(ice::Stack* stack, void* tag, const char* address) { - mUserAgent->onCandidateGathered(mUserAgent->getUserSession(mSessionId), address); + mUserAgent->onCandidateGathered(mUserAgent->getUserSession(mSessionId), address); } // Called when connectivity check is finished void Session::onCheckFinished(ice::Stack* stack, void* tag, const char* checkDescription) { - mUserAgent->onCheckFinished(mUserAgent->getUserSession(mSessionId), checkDescription); + mUserAgent->onCheckFinished(mUserAgent->getUserSession(mSessionId), checkDescription); } void Session::onGathered(ice::Stack* stack, void* tag) { - Lock l(mGuard); - - // This part handles situation when network was changed and new ice candidate were gathered - if (mSendOfferUpdateAfterIceGather) - { - mSendOfferUpdateAfterIceGather = false; - enqueueOffer(); - return; - } + Lock l(mGuard); - // This is sending of initial offer/answer after first gather of ice candidates - mUserAgent->onGathered(mUserAgent->getUserSession(mSessionId)); - - if (mRole == Initiator) - mUserAgent->sendOffer(this); - else - if (mRole == Acceptor) - { - // Mark session as gathered ICE candidates - mGatheredCandidates = true; - - // if AcceptSession was already called() on session - recall it again to make real work - if (mAcceptedByUser) + // This part handles situation when network was changed and new ice candidate were gathered + if (mSendOfferUpdateAfterIceGather) { - // Check if session is needed here - because session can be terminated already - if (mResipSession && mInviteHandle.isValid()) - accept(); + mSendOfferUpdateAfterIceGather = false; + enqueueOffer(); + return; } - } + + // This is sending of initial offer/answer after first gather of ice candidates + mUserAgent->onGathered(mUserAgent->getUserSession(mSessionId)); + + if (mRole == Initiator) + mUserAgent->sendOffer(this); + else + if (mRole == Acceptor) + { + // Mark session as gathered ICE candidates + mGatheredCandidates = true; + + // if AcceptSession was already called() on session - recall it again to make real work + if (mAcceptedByUser) + { + // Check if session is needed here - because session can be terminated already + if (mResipSession && mInviteHandle.isValid()) + accept(); + } + } } void Session::onSuccess(ice::Stack* stack, void* tag) { - ICELogInfo(<< "ICE connectivity check succeed."); + ICELogInfo(<< "ICE connectivity check succeed."); - RtpPair t; + RtpPair t; - for (unsigned i=0; imStreamList.size(); i++) - { - PDataProvider p = mStreamList[i].provider(); - if (p) + for (unsigned i=0; imStreamList.size(); i++) { - // Set new destination address - t.mRtp = stack->remoteAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTP_ID); - // Check if there remote address for rtcp component + PDataProvider p = mStreamList[i].provider(); + if (p) + { + // Set new destination address + t.mRtp = stack->remoteAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTP_ID); + // Check if there remote address for rtcp component - t.mRtcp = stack->remoteAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID); - if (t.mRtcp.isEmpty()) - t.mRtcp = t.mRtp; + t.mRtcp = stack->remoteAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID); + if (t.mRtcp.isEmpty()) + t.mRtcp = t.mRtp; - p->setDestinationAddress(t); + p->setDestinationAddress(t); - // Notify provider about connectivity checks success - mStreamList[i].provider()->sessionEstablished(EV_ICE); + // Notify provider about connectivity checks success + mStreamList[i].provider()->sessionEstablished(EV_ICE); + } } - } - mUserAgent->onSessionEstablished(mUserAgent->getUserSession(mSessionId), EV_ICE, t); + mUserAgent->onSessionEstablished(mUserAgent->getUserSession(mSessionId), EV_ICE, t); - //time to resend updated media info over SIP - //TODO: + //time to resend updated media info over SIP + //TODO: } void Session::onFailed(ice::Stack* stack, void* tag) { - ICELogError(<< "ICE connectivity check failed for session " << mSessionId); - mUserAgent->onConnectivityFailed(mUserAgent->getUserSession(mSessionId)); + ICELogError(<< "ICE connectivity check failed for session " << mSessionId); + mUserAgent->onConnectivityFailed(mUserAgent->getUserSession(mSessionId)); - //if (mInviteHandle.isValid()) - // mInviteHandle->end(); + //if (mInviteHandle.isValid()) + // mInviteHandle->end(); } void Session::onNetworkChange(ice::Stack *stack, void *tag) { - ICELogInfo(<< "Network change detected by ICE stack for session " << mSessionId); - mUserAgent->onNetworkChange(mUserAgent->getUserSession(mSessionId)); + ICELogInfo(<< "Network change detected by ICE stack for session " << mSessionId); + mUserAgent->onNetworkChange(mUserAgent->getUserSession(mSessionId)); } void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection) { - sdp.session().name() = "ICE_UA"; - sdp.session().origin().user() = "user"; + sdp.session().name() = "ICE_UA"; + sdp.session().origin().user() = "user"; - // Set versions - sdp.version() = 0; - sdp.session().version() = mSessionVersion; - sdp.session().origin().getVersion() = ++mOriginVersion; - - // At least 1 stream must exists - if (mStreamList.empty()) - return; + // Set versions + sdp.version() = 0; + sdp.session().version() = mSessionVersion; + sdp.session().origin().getVersion() = ++mOriginVersion; - // Get default ip address for front stream - ice::NetworkAddress defaultAddr = mIceStack->defaultAddress(mStreamList.front().iceInfo().mStreamId, ICE_RTP_ID); + // At least 1 stream must exists + if (mStreamList.empty()) + return; - // Set IP address for origin and connection - sdp.session().origin().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6); - sdp.session().connection().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6); + // Get default ip address for front stream + ice::NetworkAddress defaultAddr = mIceStack->defaultAddress(mStreamList.front().iceInfo().mStreamId, ICE_RTP_ID); - // Add ICE credentials - if (mIceStack->state() > ice::IceNone) - { - sdp.session().addAttribute("ice-pwd", resip::Data(mIceStack->localPassword())); - sdp.session().addAttribute("ice-ufrag", resip::Data(mIceStack->localUfrag())); - } + // Set IP address for origin and connection + sdp.session().origin().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6); + sdp.session().connection().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6); - // Iterate media streams - for (unsigned i=0; idefaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTP_ID), - rtcpPort = mIceStack->defaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID); - - // Define media stream SDP's header - resip::SdpContents::Session::Medium media(resip::Data(provider.streamName()), rtpPort.port(), 0, resip::Data(provider.streamProfile())); - - // Add "rtcp" attribute - if (mUserAgent->mConfig[CONFIG_RTCP_ATTR].asBool()) + // Add ICE credentials + if (mIceStack->state() > ice::IceNone) { - if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) - rtcpPort = rtpPort; - else - if (rtcpPort.isEmpty()) - { - rtcpPort = rtpPort; - rtcpPort.setPort( rtpPort.port() + 1); - } - - media.addAttribute("rtcp", resip::Data(rtcpPort.port())); + sdp.session().addAttribute("ice-pwd", resip::Data(mIceStack->localPassword())); + sdp.session().addAttribute("ice-ufrag", resip::Data(mIceStack->localUfrag())); } - // Add "rtcp-mux" attribute - if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) - media.addAttribute("rtcp-mux"); - - // Ask provider about specific information - provider.updateSdpOffer(media, sdpDirection); - - // Add ICE information - std::vector candidates; - if (stream.iceInfo().mStreamId != -1) + // Iterate media streams + for (unsigned i=0; ifillCandidateList(ii.mStreamId, ii.mComponentId.mRtp, candidates); + Stream& stream = mStreamList[i]; + if (!stream.provider()) + continue; + DataProvider& provider = *mStreamList[i].provider(); - if (mIceStack->hasComponent(ii.mStreamId, ii.mComponentId.mRtcp)) - mIceStack->fillCandidateList(ii.mStreamId, ii.mComponentId.mRtcp, candidates); + // Get default stream port + ice::NetworkAddress rtpPort = mIceStack->defaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTP_ID), + rtcpPort = mIceStack->defaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID); - for (unsigned c=0; cmConfig[CONFIG_RTCP_ATTR].asBool()) + { + if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) + rtcpPort = rtpPort; + else + if (rtcpPort.isEmpty()) + { + rtcpPort = rtpPort; + rtcpPort.setPort( rtpPort.port() + 1); + } + + media.addAttribute("rtcp", resip::Data(rtcpPort.port())); + } + + // Add "rtcp-mux" attribute + if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) + media.addAttribute("rtcp-mux"); + + // Ask provider about specific information + provider.updateSdpOffer(media, sdpDirection); + + // Add ICE information + std::vector candidates; + if (stream.iceInfo().mStreamId != -1) + { + IceInfo ii = stream.iceInfo(); + mIceStack->fillCandidateList(ii.mStreamId, ii.mComponentId.mRtp, candidates); + + if (mIceStack->hasComponent(ii.mStreamId, ii.mComponentId.mRtcp)) + mIceStack->fillCandidateList(ii.mStreamId, ii.mComponentId.mRtcp, candidates); + + for (unsigned c=0; clocalport() == port || s.socket4().mRtcp->localport() == port) && family == AF_INET) - return s.provider(); - if ((s.socket6().mRtp->localport() == port || s.socket6().mRtcp->localport() == port) && family == AF_INET6) - return s.provider(); - } + if ((s.socket4().mRtp->localport() == port || s.socket4().mRtcp->localport() == port) && family == AF_INET) + return s.provider(); + if ((s.socket6().mRtp->localport() == port || s.socket6().mRtcp->localport() == port) && family == AF_INET6) + return s.provider(); + } - return PDataProvider(); + return PDataProvider(); } void Session::addProvider(PDataProvider provider) { - // Ignore NULL providers - if (!provider) - return; + // Ignore NULL providers + if (!provider) + return; - // Avoid duplicating providers - for (unsigned i=0; i::iterator streamIter; + // Avoid duplicating providers + for (unsigned i=0; iprovider() && (streamIter->socket4().mRtp->isValid() || streamIter->socket6().mRtp->isValid())) + // Find first non-filled record or create new one + std::vector::iterator streamIter; + + for (streamIter = mStreamList.begin(); streamIter != mStreamList.end(); ++streamIter) { - streamIter->setProvider( provider ); - provider->setSocket(streamIter->socket4(), streamIter->socket6()); - return; + if (!streamIter->provider() && (streamIter->socket4().mRtp->isValid() || streamIter->socket6().mRtp->isValid())) + { + streamIter->setProvider( provider ); + provider->setSocket(streamIter->socket4(), streamIter->socket6()); + return; + } } - } - - Stream s; - s.setProvider( provider ); - - // Allocate socket for provider - s.setSocket4( SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX()) ); - s.setSocket6( SocketHeap::instance().allocSocketPair(AF_INET6, this, DOMULTIPLEX()) ); - s.provider()->setSocket(s.socket4(), s.socket6()); - // Create ICE stream/component - IceInfo ii; - ii.mStreamId = mIceStack->addStream(); - ii.mPort4 = s.socket4().mRtp->localport(); - ii.mPort6 = s.socket6().mRtp->localport(); + Stream s; + s.setProvider( provider ); - ii.mComponentId.mRtp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtp->localport(), - s.socket6().mRtp->localport()); - if (!mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) - ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtcp->localport(), s.socket6().mRtcp->localport()); + // Allocate socket for provider + s.setSocket4( SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX()) ); + s.setSocket6( SocketHeap::instance().allocSocketPair(AF_INET6, this, DOMULTIPLEX()) ); + s.provider()->setSocket(s.socket4(), s.socket6()); - s.setIceInfo(ii); + // Create ICE stream/component + IceInfo ii; + ii.mStreamId = mIceStack->addStream(); + ii.mPort4 = s.socket4().mRtp->localport(); + ii.mPort6 = s.socket6().mRtp->localport(); - mStreamList.push_back(s); + ii.mComponentId.mRtp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtp->localport(), + s.socket6().mRtp->localport()); + if (!mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) + ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtcp->localport(), s.socket6().mRtcp->localport()); + + s.setIceInfo(ii); + + mStreamList.push_back(s); } PDataProvider Session::providerAt(int index) { - if (mStreamList.size() > unsigned(index)) - return mStreamList[index].provider(); - return PDataProvider(); + if (mStreamList.size() > unsigned(index)) + return mStreamList[index].provider(); + return PDataProvider(); } int Session::getProviderCount() { - return mStreamList.size(); + return mStreamList.size(); } int Session::sessionId() { - return mSessionId; + return mSessionId; } resip::AtomicCounter Session::IdGenerator; int Session::generateId() { - return (int)IdGenerator.increment(); + return (int)IdGenerator.increment(); } std::string Session::remoteAddress() const { - return mRemoteAddress; + return mRemoteAddress; } void Session::setRemoteAddress(const std::string& address) { - mRemoteAddress = address; + mRemoteAddress = address; } void Session::setUserHeaders(const UserHeaders& headers) { - mUserHeaders = headers; + mUserHeaders = headers; } void* Session::tag() { - return mTag; + return mTag; } void Session::setTag(void* tag) { - mTag = tag; + mTag = tag; } void Session::pause() { - for (unsigned i=0; ipause(); - } - enqueueOffer(); + for (unsigned i=0; ipause(); + } + enqueueOffer(); } void Session::resume() { - for (unsigned i=0; iresume(); - } - enqueueOffer(); + for (unsigned i=0; iresume(); + } + enqueueOffer(); } void Session::refreshMediaPath() { - // Recreate media sockets - for (unsigned i=0; isocket(AF_INET)); + // Close old socket + SocketHeap::instance().freeSocketPair(p->socket(AF_INET)); - // Bring new socket to provider and stream - RtpPair s4 = SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX() ), - s6 = SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX()); + // Bring new socket to provider and stream + RtpPair s4 = SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX() ), + s6 = SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX()); - p->setSocket(s4, s6); - s.setSocket4(s4); - s.setSocket6(s6); - } + p->setSocket(s4, s6); + s.setSocket4(s4); + s.setSocket6(s6); + } - // Recreate new ufrag/pwd and gather ice candidates - mIceStack->refreshPwdUfrag(); - mIceStack->gatherCandidates(); + // Recreate new ufrag/pwd and gather ice candidates + mIceStack->refreshPwdUfrag(); + mIceStack->gatherCandidates(); - // New offer will be enqueued after ice gather finished - mSendOfferUpdateAfterIceGather = true; - mHasToSendOffer = false; + // New offer will be enqueued after ice gather finished + mSendOfferUpdateAfterIceGather = true; + mHasToSendOffer = false; } // Received offer with new SDP int Session::processSdp(UInt64 version, bool iceAvailable, std::string icePwd, std::string iceUfrag, - std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media) + std::string remoteIp, const resip::SdpContents::Session::MediumContainer& media) { - bool iceRestart = false; + bool iceRestart = false; - int mediaCompatible = 0; - MediumContainer::const_iterator mediaIter; - unsigned streamIndex = 0; - for (mediaIter = media.begin(); mediaIter != media.end(); ++mediaIter, ++streamIndex) - { - // Get reference to SDP description of remote stream - const resip::SdpContents::Session::Medium& remoteStream = *mediaIter; - - // Get reference to local stream description - if (streamIndex >= mStreamList.size()) - mStreamList.push_back(Session::Stream()); - Session::Stream& stream = mStreamList[streamIndex]; - - // Ask about provider if needed - if (!stream.provider()) - stream.setProvider( mUserAgent->onProviderNeeded(remoteStream.name().c_str()) ); - - // Check the stream validity - if (!stream.provider()) - continue; - if (!stream.provider()->processSdpOffer(remoteStream, Sdp_Offer)) - continue; - - // See for rtcp & rtcp-mux attribute - stream.setRtcpAttr( remoteStream.exists("rtcp") ); - stream.setRtcpMuxAttr( remoteStream.exists("rtcp-mux") ); - - // Set destination address - if (!remoteStream.getConnections().empty()) - remoteIp = remoteStream.getConnections().front().getAddress().c_str(); - - RtpPair targetAddr; - targetAddr.mRtp.setIp(remoteIp); - targetAddr.mRtp.setPort(remoteStream.port()); - - targetAddr.mRtcp.setIp(remoteIp); - if (stream.rtcpMuxAttr()) - targetAddr.mRtcp.setPort( remoteStream.port() ); - else - if (stream.rtcpAttr()) - targetAddr.mRtcp.setPort( StringHelper::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteStream.port() + 1 ) ); - else - targetAddr.mRtcp.setPort( remoteStream.port() + 1); - - stream.provider()->setDestinationAddress(targetAddr); - - // Media is compatible; increase the counter and prepare ice stream/component - mediaCompatible++; - - // Get default remote port number - unsigned short remotePort = remoteStream.port(); - - // Create media socket if needed - if (!stream.socket4().mRtp) + int mediaCompatible = 0; + MediumContainer::const_iterator mediaIter; + unsigned streamIndex = 0; + for (mediaIter = media.begin(); mediaIter != media.end(); ++mediaIter, ++streamIndex) { - try - { - stream.setSocket4(SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX())); - stream.setSocket6(SocketHeap::instance().allocSocketPair(AF_INET6, this, DOMULTIPLEX())); - } - catch(...) - { - ICELogError( << "Cannot create media socket."); - return 503; - } + // Get reference to SDP description of remote stream + const resip::SdpContents::Session::Medium& remoteStream = *mediaIter; - // Update provider with socket references - stream.provider()->setSocket(stream.socket4(), stream.socket6()); - } - - - const std::list& iceUfragAttr = remoteStream.getValues("ice-ufrag"); - if (iceUfragAttr.size()) - iceUfrag = iceUfragAttr.front().c_str(); + // Get reference to local stream description + if (streamIndex >= mStreamList.size()) + mStreamList.push_back(Session::Stream()); + Session::Stream& stream = mStreamList[streamIndex]; - const std::list& icePwdAttr = remoteStream.getValues("ice-pwd"); - if (icePwdAttr.size()) - icePwd = icePwdAttr.front().c_str(); + // Ask about provider if needed + if (!stream.provider()) + stream.setProvider( mUserAgent->onProviderNeeded(remoteStream.name().c_str()) ); - // Create ICE stream; it will be created even if ice is not requested. - // The cause is we need to hold default address and possible STUN requests result - if (stream.iceInfo().mStreamId == -1) - { - IceInfo ii; - ii.mStreamId = mIceStack->addStream(); - ii.mPort4 = stream.socket4().mRtp->localport(); - ii.mPort6 = stream.socket6().mRtp->localport(); - ii.mComponentId.mRtp = mIceStack->addComponent(ii.mStreamId, NULL, ii.mPort4, ii.mPort6); + // Check the stream validity + if (!stream.provider()) + continue; + if (!stream.provider()->processSdpOffer(remoteStream, Sdp_Offer)) + continue; - // See what remote peer offers - offer only single ice component if it relies on multiplexing - if (!targetAddr.multiplexed() && !mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) - ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, stream.socket4().mRtcp->localport(), stream.socket6().mRtcp->localport()); - stream.setIceInfo(ii); + // See for rtcp & rtcp-mux attribute + stream.setRtcpAttr( remoteStream.exists("rtcp") ); + stream.setRtcpMuxAttr( remoteStream.exists("rtcp-mux") ); + + // Set destination address + if (!remoteStream.getConnections().empty()) + remoteIp = remoteStream.getConnections().front().getAddress().c_str(); + + RtpPair targetAddr; + targetAddr.mRtp.setIp(remoteIp); + targetAddr.mRtp.setPort(remoteStream.port()); + + targetAddr.mRtcp.setIp(remoteIp); + if (stream.rtcpMuxAttr()) + targetAddr.mRtcp.setPort( remoteStream.port() ); + else + if (stream.rtcpAttr()) + targetAddr.mRtcp.setPort( StringHelper::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteStream.port() + 1 ) ); + else + targetAddr.mRtcp.setPort( remoteStream.port() + 1); + + stream.provider()->setDestinationAddress(targetAddr); + + // Media is compatible; increase the counter and prepare ice stream/component + mediaCompatible++; + + // Get default remote port number + unsigned short remotePort = remoteStream.port(); + + // Create media socket if needed + if (!stream.socket4().mRtp) + { + try + { + stream.setSocket4(SocketHeap::instance().allocSocketPair(AF_INET, this, DOMULTIPLEX())); + stream.setSocket6(SocketHeap::instance().allocSocketPair(AF_INET6, this, DOMULTIPLEX())); + } + catch(...) + { + ICELogError( << "Cannot create media socket."); + return 503; + } + + // Update provider with socket references + stream.provider()->setSocket(stream.socket4(), stream.socket6()); + } + + + const std::list& iceUfragAttr = remoteStream.getValues("ice-ufrag"); + if (iceUfragAttr.size()) + iceUfrag = iceUfragAttr.front().c_str(); + + const std::list& icePwdAttr = remoteStream.getValues("ice-pwd"); + if (icePwdAttr.size()) + icePwd = icePwdAttr.front().c_str(); + + // Create ICE stream; it will be created even if ice is not requested. + // The cause is we need to hold default address and possible STUN requests result + if (stream.iceInfo().mStreamId == -1) + { + IceInfo ii; + ii.mStreamId = mIceStack->addStream(); + ii.mPort4 = stream.socket4().mRtp->localport(); + ii.mPort6 = stream.socket6().mRtp->localport(); + ii.mComponentId.mRtp = mIceStack->addComponent(ii.mStreamId, NULL, ii.mPort4, ii.mPort6); + + // See what remote peer offers - offer only single ice component if it relies on multiplexing + if (!targetAddr.multiplexed() && !mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool()) + ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, stream.socket4().mRtcp->localport(), stream.socket6().mRtcp->localport()); + stream.setIceInfo(ii); + } + + if (iceAvailable) + { + if (mIceStack->remotePassword(stream.iceInfo().mStreamId) != icePwd || mIceStack->remoteUfrag(stream.iceInfo().mStreamId) != iceUfrag) + { + iceRestart = true; + mIceStack->setRemotePassword(icePwd, stream.iceInfo().mStreamId); + mIceStack->setRemoteUfrag(iceUfrag, stream.iceInfo().mStreamId); + } + } + + // Get remote ICE candidates vector + const std::list candidateList = remoteStream.getValues("candidate"); + + // Repackage information about remote candidates + std::vector candidateVector; + std::list::const_iterator cit = candidateList.begin(); + + for (; cit != candidateList.end(); ++cit) + candidateVector.push_back(cit->c_str()); + + if (candidateVector.empty()) + iceAvailable = false; + + // Ask ICE stack to process this information. This call will remove also second component if it is not defined in remote sdp. + if (iceAvailable) + iceAvailable = mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteIp, remotePort, mUserAgent->mConfig[CONFIG_DEFERRELAYED].asBool()); } - if (iceAvailable) + // See if there are compatible media streams + if (!mediaCompatible) + return 488; // Not acceptable media + + // Start ICE check connectivity if required + if (iceRestart && iceAvailable) { - if (mIceStack->remotePassword(stream.iceInfo().mStreamId) != icePwd || mIceStack->remoteUfrag(stream.iceInfo().mStreamId) != iceUfrag) - { - iceRestart = true; - mIceStack->setRemotePassword(icePwd, stream.iceInfo().mStreamId); - mIceStack->setRemoteUfrag(iceUfrag, stream.iceInfo().mStreamId); - } + if (mIceStack->state() > ice::IceGathering) + mIceStack->checkConnectivity(); + else + mIceStack->gatherCandidates(); } - // Get remote ICE candidates vector - const std::list candidateList = remoteStream.getValues("candidate"); - - // Repackage information about remote candidates - std::vector candidateVector; - std::list::const_iterator cit = candidateList.begin(); - - for (; cit != candidateList.end(); ++cit) - candidateVector.push_back(cit->c_str()); - - if (candidateVector.empty()) - iceAvailable = false; - - // Ask ICE stack to process this information. This call will remove also second component if it is not defined in remote sdp. - if (iceAvailable) - iceAvailable = mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteIp, remotePort, mUserAgent->mConfig[CONFIG_DEFERRELAYED].asBool()); - } - - // See if there are compatible media streams - if (!mediaCompatible) - return 488; // Not acceptable media - - // Start ICE check connectivity if required - if (iceRestart && iceAvailable) - { - if (mIceStack->state() > ice::IceGathering) - mIceStack->checkConnectivity(); - else - mIceStack->gatherCandidates(); - } - - return 200; + return 200; } int Session::increaseSdpVersion() { - return ++mOriginVersion; + return ++mOriginVersion; } void Session::setUserAgent(UserAgent* agent) { - mUserAgent = agent; + mUserAgent = agent; } UserAgent* Session::userAgent() { - return mUserAgent; + return mUserAgent; } int Session::addRef() { - return ++mRefCount; + return ++mRefCount; } int Session::release() { - mRefCount--; - return mRefCount; + mRefCount--; + return mRefCount; } void Session::clearProvidersAndSockets() { - for (unsigned i=0; isessionDeleted(); - SocketHeap::instance().freeSocketPair( ds.socket4() ); - SocketHeap::instance().freeSocketPair( ds.socket6() ); + Session::Stream& ds = mStreamList[i]; + + if (ds.provider()) + { + ds.provider()->sessionDeleted(); + SocketHeap::instance().freeSocketPair( ds.socket4() ); + SocketHeap::instance().freeSocketPair( ds.socket6() ); + } } - } } void Session::clearProviders() { - for (unsigned i=0; isessionTerminated(); - } + if (ds.provider()) + ds.provider()->sessionTerminated(); + } } #pragma endregion @@ -1115,37 +1114,37 @@ void Session::clearProviders() void Session::enqueueOffer() { - mHasToSendOffer = true; - processQueuedOffer(); + mHasToSendOffer = true; + processQueuedOffer(); } void Session::processQueuedOffer() { - if (!mHasToSendOffer) - return; + if (!mHasToSendOffer) + return; - if (mInviteHandle.isValid()) - { - if (mInviteHandle->canProvideOffer()) + if (mInviteHandle.isValid()) { - mUserAgent->sendOffer(this); - mHasToSendOffer = false; + if (mInviteHandle->canProvideOffer()) + { + mUserAgent->sendOffer(this); + mHasToSendOffer = false; + } } - } } //-------------- ResipSessionFactory --------- #pragma region ResipSessionFactory ResipSessionFactory::ResipSessionFactory(UserAgent* agent) -:mAgent(agent) + :mAgent(agent) {} resip::AppDialogSet* ResipSessionFactory::createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg) { - ResipSession* s = new ResipSession(dum); - s->setUa( mAgent ); - return s; + ResipSession* s = new ResipSession(dum); + s->setUa( mAgent ); + return s; } diff --git a/src/engine/media/MT_SingleAudioStream.cpp b/src/engine/media/MT_SingleAudioStream.cpp index ed828b10..e445d0b9 100644 --- a/src/engine/media/MT_SingleAudioStream.cpp +++ b/src/engine/media/MT_SingleAudioStream.cpp @@ -13,7 +13,7 @@ using namespace MT; SingleAudioStream::SingleAudioStream(const CodecList::Settings& codecSettings, Statistics& stat) -:mReceiver(codecSettings, stat), mDtmfReceiver(stat) + :mReceiver(codecSettings, stat), mDtmfReceiver(stat) { } @@ -23,20 +23,20 @@ SingleAudioStream::~SingleAudioStream() void SingleAudioStream::process(std::shared_ptr packet) { - ICELogMedia(<< "Processing incoming RTP/RTCP packet"); - if (packet->GetPayloadType() == 101/*resip::Codec::TelephoneEvent.payloadType()*/) - mDtmfReceiver.add(packet); - else - mReceiver.add(packet); + ICELogMedia(<< "Processing incoming RTP/RTCP packet"); + if (packet->GetPayloadType() == 101/*resip::Codec::TelephoneEvent.payloadType()*/) + mDtmfReceiver.add(packet); + else + mReceiver.add(packet); } void SingleAudioStream::copyPcmTo(Audio::DataWindow& output, int needed) { - while (output.filled() < needed) - if (!mReceiver.getAudio(output)) - break; + while (output.filled() < needed) + if (!mReceiver.getAudio(output)) + break; - if (output.filled() < needed) - ICELogError(<< "Not enough data for speaker's mixer"); + if (output.filled() < needed) + ICELogError(<< "Not enough data for speaker's mixer"); }