diff options
author | Roxanne Skelly <roxie@lindenlab.com> | 2024-03-13 11:33:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-13 11:33:13 -0700 |
commit | b32364ba49ab58656fc6b146e5db499022dc9512 (patch) | |
tree | 20b774948f8592e0834b9b55af79180463b06e58 /indra/newview/llvoicechannel.cpp | |
parent | b242d696ba03f66494dfca1f05a74ed1b15cd6e4 (diff) | |
parent | 76460e8c2c33af185ae8641775d5673fcdab0759 (diff) |
Merge pull request #116 from secondlife/roxie/webrtc-voice
WebRTC-based voice for Second Life
Diffstat (limited to 'indra/newview/llvoicechannel.cpp')
-rw-r--r-- | indra/newview/llvoicechannel.cpp | 317 |
1 files changed, 151 insertions, 166 deletions
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index b0eb8d962c..28e895584b 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -39,7 +39,6 @@ #include "llcorehttputil.h" LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap; -LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap; LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL; LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; LLVoiceChannel::channel_changed_signal_t LLVoiceChannel::sCurrentVoiceChannelChangedSignal; @@ -89,29 +88,18 @@ LLVoiceChannel::~LLVoiceChannel() } sVoiceChannelMap.erase(mSessionID); - sVoiceChannelURIMap.erase(mURI); } -void LLVoiceChannel::setChannelInfo( - const std::string& uri, - const std::string& credentials) +void LLVoiceChannel::setChannelInfo(const LLSD &channelInfo) { - setURI(uri); - - mCredentials = credentials; + mChannelInfo = channelInfo; if (mState == STATE_NO_CHANNEL_INFO) { - if (mURI.empty()) - { - LLNotificationsUtil::add("VoiceChannelJoinFailed", mNotifyArgs); - LL_WARNS("Voice") << "Received empty URI for channel " << mSessionName << LL_ENDL; - deactivate(); - } - else if (mCredentials.empty()) + if (mChannelInfo.isUndefined()) { LLNotificationsUtil::add("VoiceChannelJoinFailed", mNotifyArgs); - LL_WARNS("Voice") << "Received empty credentials for channel " << mSessionName << LL_ENDL; + LL_WARNS("Voice") << "Received empty channel info for channel " << mSessionName << LL_ENDL; deactivate(); } else @@ -130,9 +118,15 @@ void LLVoiceChannel::setChannelInfo( } } -void LLVoiceChannel::onChange(EStatusType type, const std::string &channelURI, bool proximal) +void LLVoiceChannel::onChange(EStatusType type, const LLSD& channelInfo, bool proximal) { - if (channelURI != mURI) + LL_DEBUGS("Voice") << "Incoming channel info: " << channelInfo << LL_ENDL; + LL_DEBUGS("Voice") << "Current channel info: " << mChannelInfo << LL_ENDL; + if (mChannelInfo.isUndefined()) + { + mChannelInfo = channelInfo; + } + if (!LLVoiceClient::getInstance()->compareChannels(mChannelInfo, channelInfo)) { return; } @@ -153,7 +147,7 @@ void LLVoiceChannel::handleStatusChange(EStatusType type) switch(type) { case STATUS_LOGIN_RETRY: - // no user notice + // no user notice break; case STATUS_LOGGED_IN: break; @@ -193,7 +187,7 @@ void LLVoiceChannel::handleError(EStatusType type) BOOL LLVoiceChannel::isActive() { // only considered active when currently bound channel matches what our channel - return callStarted() && LLVoiceClient::getInstance()->getCurrentChannel() == mURI; + return callStarted() && LLVoiceClient::getInstance()->isCurrentChannel(mChannelInfo); } BOOL LLVoiceChannel::callStarted() @@ -246,10 +240,8 @@ void LLVoiceChannel::activate() // activating the proximal channel between IM calls LLVoiceChannel* old_channel = sCurrentVoiceChannel; sCurrentVoiceChannel = this; - mCallDialogPayload["old_channel_name"] = ""; if (old_channel) { - mCallDialogPayload["old_channel_name"] = old_channel->getSessionName(); old_channel->deactivate(); } } @@ -257,7 +249,7 @@ void LLVoiceChannel::activate() if (mState == STATE_NO_CHANNEL_INFO) { // responsible for setting status to active - getChannelInfo(); + requestChannelInfo(); } else { @@ -270,7 +262,7 @@ void LLVoiceChannel::activate() sCurrentVoiceChannelChangedSignal(this->mSessionID); } -void LLVoiceChannel::getChannelInfo() +void LLVoiceChannel::requestChannelInfo() { // pretend we have everything we need if (sCurrentVoiceChannel == this) @@ -293,20 +285,6 @@ LLVoiceChannel* LLVoiceChannel::getChannelByID(const LLUUID& session_id) } } -//static -LLVoiceChannel* LLVoiceChannel::getChannelByURI(std::string uri) -{ - voice_channel_map_uri_t::iterator found_it = sVoiceChannelURIMap.find(uri); - if (found_it == sVoiceChannelURIMap.end()) - { - return NULL; - } - else - { - return found_it->second; - } -} - LLVoiceChannel* LLVoiceChannel::getCurrentVoiceChannel() { return sCurrentVoiceChannel; @@ -319,13 +297,6 @@ void LLVoiceChannel::updateSessionID(const LLUUID& new_session_id) sVoiceChannelMap.insert(std::make_pair(mSessionID, this)); } -void LLVoiceChannel::setURI(std::string uri) -{ - sVoiceChannelURIMap.erase(mURI); - mURI = uri; - sVoiceChannelURIMap.insert(std::make_pair(mURI, this)); -} - void LLVoiceChannel::setState(EState state) { switch(state) @@ -410,8 +381,11 @@ boost::signals2::connection LLVoiceChannel::setCurrentVoiceChannelChangedCallbac // LLVoiceChannelGroup // -LLVoiceChannelGroup::LLVoiceChannelGroup(const LLUUID& session_id, const std::string& session_name) : - LLVoiceChannel(session_id, session_name) +LLVoiceChannelGroup::LLVoiceChannelGroup(const LLUUID &session_id, + const std::string &session_name, + bool is_p2p) : + LLVoiceChannel(session_id, session_name), + mIsP2P(is_p2p) { mRetries = DEFAULT_RETRIES_COUNT; mIsRetrying = FALSE; @@ -424,7 +398,15 @@ void LLVoiceChannelGroup::deactivate() LLVoiceClient::getInstance()->leaveNonSpatialChannel(); } LLVoiceChannel::deactivate(); -} + + if (mIsP2P) + { + // void the channel info for p2p adhoc channels + // so we request it again, hence throwing up the + // connect dialogue on the other side. + setState(STATE_NO_CHANNEL_INFO); + } + } void LLVoiceChannelGroup::activate() { @@ -435,65 +417,64 @@ void LLVoiceChannelGroup::activate() if (callStarted()) { // we have the channel info, just need to use it now - LLVoiceClient::getInstance()->setNonSpatialChannel( - mURI, - mCredentials); + LLVoiceClient::getInstance()->setNonSpatialChannel(mChannelInfo, + mCallDirection == OUTGOING_CALL, + mIsP2P); - if (!gAgent.isInGroup(mSessionID)) // ad-hoc channel + if (mIsP2P) { - LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionID); - // Adding ad-hoc call participants to Recent People List. - // If it's an outgoing ad-hoc, we can use mInitialTargetIDs that holds IDs of people we - // called(both online and offline) as source to get people for recent (STORM-210). - if (session->isOutgoingAdHoc()) + LLIMModel::addSpeakersToRecent(mSessionID); + } + else + { + if (!gAgent.isInGroup(mSessionID)) // ad-hoc channel { - for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin(); - it!=session->mInitialTargetIDs.end();++it) + LLIMModel::LLIMSession *session = LLIMModel::getInstance()->findIMSession(mSessionID); + // Adding ad-hoc call participants to Recent People List. + // If it's an outgoing ad-hoc, we can use mInitialTargetIDs that holds IDs of people we + // called(both online and offline) as source to get people for recent (STORM-210). + if (session->isOutgoingAdHoc()) { - const LLUUID id = *it; - LLRecentPeople::instance().add(id); + for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin(); it != session->mInitialTargetIDs.end(); ++it) + { + const LLUUID id = *it; + LLRecentPeople::instance().add(id); + } + } + // If this ad-hoc is incoming then trying to get ids of people from mInitialTargetIDs + // would lead to EXT-8246. So in this case we get them from speakers list. + else + { + LLIMModel::addSpeakersToRecent(mSessionID); } - } - // If this ad-hoc is incoming then trying to get ids of people from mInitialTargetIDs - // would lead to EXT-8246. So in this case we get them from speakers list. - else - { - LLIMModel::addSpeakersToRecent(mSessionID); } } - //Mic default state is OFF on initiating/joining Ad-Hoc/Group calls - if (LLVoiceClient::getInstance()->getUserPTTState() && LLVoiceClient::getInstance()->getPTTIsToggle()) - { - LLVoiceClient::getInstance()->inputUserControlState(true); - } - + // Mic default state is OFF on initiating/joining Ad-Hoc/Group calls. It's on for P2P using the AdHoc infra. + + LLVoiceClient::getInstance()->setUserPTTState(mIsP2P); } } -void LLVoiceChannelGroup::getChannelInfo() +void LLVoiceChannelGroup::requestChannelInfo() { LLViewerRegion* region = gAgent.getRegion(); if (region) { std::string url = region->getCapability("ChatSessionRequest"); - LLCoros::instance().launch("LLVoiceChannelGroup::voiceCallCapCoro", - boost::bind(&LLVoiceChannelGroup::voiceCallCapCoro, this, url)); + LLCoros::instance().launch("LLVoiceChannelGroup::voiceCallCapCoro", + boost::bind(&LLVoiceChannelGroup::voiceCallCapCoro, this, url)); } } -void LLVoiceChannelGroup::setChannelInfo( - const std::string& uri, - const std::string& credentials) +void LLVoiceChannelGroup::setChannelInfo(const LLSD& channelInfo) { - setURI(uri); - - mCredentials = credentials; + mChannelInfo = channelInfo; if (mState == STATE_NO_CHANNEL_INFO) { - if(!mURI.empty() && !mCredentials.empty()) + if(!mChannelInfo.isUndefined()) { setState(STATE_READY); @@ -516,9 +497,9 @@ void LLVoiceChannelGroup::setChannelInfo( else if ( mIsRetrying ) { // we have the channel info, just need to use it now - LLVoiceClient::getInstance()->setNonSpatialChannel( - mURI, - mCredentials); + LLVoiceClient::getInstance()->setNonSpatialChannel(channelInfo, + mCallDirection == OUTGOING_CALL, + mIsP2P); } } @@ -556,7 +537,7 @@ void LLVoiceChannelGroup::handleError(EStatusType status) mIsRetrying = TRUE; mIgnoreNextSessionLeave = TRUE; - getChannelInfo(); + requestChannelInfo(); return; } else @@ -604,61 +585,62 @@ void LLVoiceChannelGroup::setState(EState state) void LLVoiceChannelGroup::voiceCallCapCoro(std::string url) { - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceCallCapCoro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceCallCapCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLSD postData; - postData["method"] = "call"; - postData["session-id"] = mSessionID; + LLSD postData; + postData["method"] = "call"; + postData["session-id"] = mSessionID; + LLSD altParams; + altParams["preferred_voice_server_type"] = gSavedSettings.getString("VoiceServerType"); + postData["alt_params"] = altParams; - LL_INFOS("Voice", "voiceCallCapCoro") << "Generic POST for " << url << LL_ENDL; + LL_INFOS("Voice", "voiceCallCapCoro") << "Generic POST for " << url << LL_ENDL; - LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); - if (!channelp) - { - LL_WARNS("Voice") << "Unable to retrieve channel with Id = " << mSessionID << LL_ENDL; - return; - } - - if (!status) - { - if (status == LLCore::HttpStatus(HTTP_FORBIDDEN)) - { - //403 == no ability - LLNotificationsUtil::add( - "VoiceNotAllowed", - channelp->getNotifyArgs()); - } - else - { - LLNotificationsUtil::add( - "VoiceCallGenericError", - channelp->getNotifyArgs()); - } - channelp->deactivate(); - return; - } + LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID); + if (!channelp) + { + LL_WARNS("Voice") << "Unable to retrieve channel with Id = " << mSessionID << LL_ENDL; + return; + } - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + if (!status) + { + if (status == LLCore::HttpStatus(HTTP_FORBIDDEN)) + { + //403 == no ability + LLNotificationsUtil::add( + "VoiceNotAllowed", + channelp->getNotifyArgs()); + } + else + { + LLNotificationsUtil::add( + "VoiceCallGenericError", + channelp->getNotifyArgs()); + } + channelp->deactivate(); + return; + } - LLSD::map_const_iterator iter; - for (iter = result.beginMap(); iter != result.endMap(); ++iter) - { - LL_DEBUGS("Voice") << "LLVoiceCallCapResponder::result got " - << iter->first << LL_ENDL; - } + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - channelp->setChannelInfo( - result["voice_credentials"]["channel_uri"].asString(), - result["voice_credentials"]["channel_credentials"].asString()); + LLSD::map_const_iterator iter; + for (iter = result.beginMap(); iter != result.endMap(); ++iter) + { + LL_DEBUGS("Voice") << "LLVoiceChannelGroup::voiceCallCapCoro got " + << iter->first << LL_ENDL; + } + LL_INFOS("Voice") << "LLVoiceChannelGroup::voiceCallCapCoro got " << result << LL_ENDL; + channelp->setChannelInfo(result["voice_credentials"]); } @@ -682,13 +664,14 @@ void LLVoiceChannelProximal::activate() if((LLVoiceChannel::sCurrentVoiceChannel != this) && (LLVoiceChannel::getState() == STATE_CONNECTED)) { // we're connected to a non-spatial channel, so disconnect. - LLVoiceClient::getInstance()->leaveNonSpatialChannel(); + LLVoiceClient::getInstance()->leaveNonSpatialChannel(); } + LLVoiceClient::getInstance()->activateSpatialChannel(true); LLVoiceChannel::activate(); } -void LLVoiceChannelProximal::onChange(EStatusType type, const std::string &channelURI, bool proximal) +void LLVoiceChannelProximal::onChange(EStatusType type, const LLSD& channelInfo, bool proximal) { if (!proximal) { @@ -758,19 +741,22 @@ void LLVoiceChannelProximal::deactivate() { setState(STATE_HUNG_UP); } + LLVoiceClient::getInstance()->activateSpatialChannel(false); } // // LLVoiceChannelP2P // -LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string& session_name, const LLUUID& other_user_id) : - LLVoiceChannelGroup(session_id, session_name), - mOtherUserID(other_user_id), - mReceivedCall(FALSE) +LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID &session_id, + const std::string &session_name, + const LLUUID &other_user_id, + LLVoiceP2POutgoingCallInterface* outgoing_call_interface) : + LLVoiceChannelGroup(session_id, session_name, true), + mOtherUserID(other_user_id), + mReceivedCall(FALSE), + mOutgoingCallInterface(outgoing_call_interface) { - // make sure URI reflects encoded version of other user's agent id - setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id)); } void LLVoiceChannelP2P::handleStatusChange(EStatusType type) @@ -837,23 +823,23 @@ void LLVoiceChannelP2P::activate() if (callStarted()) { // no session handle yet, we're starting the call - if (mSessionHandle.empty()) + if (mIncomingCallInterface == nullptr) { mReceivedCall = FALSE; - LLVoiceClient::getInstance()->callUser(mOtherUserID); + mOutgoingCallInterface->callUser(mOtherUserID); } // otherwise answering the call else { - if (!LLVoiceClient::getInstance()->answerInvite(mSessionHandle)) + if (!mIncomingCallInterface->answerInvite()) { mCallEndedByAgent = false; - mSessionHandle.clear(); + mIncomingCallInterface.reset(); handleError(ERROR_UNKNOWN); return; } - // using the session handle invalidates it. Clear it out here so we can't reuse it by accident. - mSessionHandle.clear(); + // using the incoming call interface invalidates it. Clear it out here so we can't reuse it by accident. + mIncomingCallInterface.reset(); } // Add the party to the list of people with which we've recently interacted. @@ -867,7 +853,17 @@ void LLVoiceChannelP2P::activate() } } -void LLVoiceChannelP2P::getChannelInfo() +void LLVoiceChannelP2P::deactivate() +{ + if (callStarted()) + { + mOutgoingCallInterface->hangup(); + } + LLVoiceChannel::deactivate(); +} + + +void LLVoiceChannelP2P::requestChannelInfo() { // pretend we have everything we need, since P2P doesn't use channel info if (sCurrentVoiceChannel == this) @@ -877,8 +873,9 @@ void LLVoiceChannelP2P::getChannelInfo() } // receiving session from other user who initiated call -void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::string &inURI) +void LLVoiceChannelP2P::setChannelInfo(const LLSD& channel_info) { + mChannelInfo = channel_info; BOOL needs_activate = FALSE; if (callStarted()) { @@ -893,28 +890,16 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s { // we are active and have priority, invite the other user again // under the assumption they will join this new session - mSessionHandle.clear(); - LLVoiceClient::getInstance()->callUser(mOtherUserID); + mOutgoingCallInterface->callUser(mOtherUserID); return; } } - mSessionHandle = handle; - - // The URI of a p2p session should always be the other end's SIP URI. - if(!inURI.empty()) - { - setURI(inURI); - } - else + mReceivedCall = TRUE; + if (!channel_info.isUndefined()) { - LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL; - // See LLVoiceClient::sessionAddedEvent() - setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); + mIncomingCallInterface = LLVoiceClient::getInstance()->getIncomingCallInterface(channel_info); } - - mReceivedCall = TRUE; - if (needs_activate) { activate(); @@ -932,7 +917,7 @@ void LLVoiceChannelP2P::setState(EState state) if (mReceivedCall && state == STATE_RINGING) { //TODO: remove or redirect this call status notification -// LLCallInfoDialog::show("answering", mNotifyArgs); + // LLCallInfoDialog::show("answering", mNotifyArgs); doSetState(state); return; } |