summaryrefslogtreecommitdiff
path: root/indra/newview/llvoicechannel.cpp
diff options
context:
space:
mode:
authorRoxanne Skelly <roxie@lindenlab.com>2024-03-13 11:33:13 -0700
committerGitHub <noreply@github.com>2024-03-13 11:33:13 -0700
commitb32364ba49ab58656fc6b146e5db499022dc9512 (patch)
tree20b774948f8592e0834b9b55af79180463b06e58 /indra/newview/llvoicechannel.cpp
parentb242d696ba03f66494dfca1f05a74ed1b15cd6e4 (diff)
parent76460e8c2c33af185ae8641775d5673fcdab0759 (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.cpp317
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;
}