diff options
-rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 50 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc.h | 4 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 22 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.cpp | 138 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.h | 110 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.cpp | 1002 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.h | 262 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.cpp | 218 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.h | 125 |
9 files changed, 911 insertions, 1020 deletions
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index dc5fd9657e..875f233e65 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -85,15 +85,15 @@ void LLAudioDeviceObserver::OnRenderData(const void *audio_samples, } LLCustomProcessor::LLCustomProcessor() : - mSampleRateHz(0), + mSampleRateHz(0), mNumChannels(0), mMicrophoneEnergy(0.0) -{ +{ memset(mSumVector, 0, sizeof(mSumVector)); } void LLCustomProcessor::Initialize(int sample_rate_hz, int num_channels) -{ +{ mSampleRateHz = sample_rate_hz; mNumChannels = num_channels; memset(mSumVector, 0, sizeof(mSumVector)); @@ -187,7 +187,7 @@ void LLWebRTCImpl::init() { // Initialize the audio devices on the Worker Thread mTuningDeviceModule = webrtc::CreateAudioDeviceWithDataObserver( - webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, + webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, mTaskQueueFactory.get(), std::unique_ptr<webrtc::AudioDeviceDataObserver>(mTuningAudioDeviceObserver)); @@ -198,7 +198,7 @@ void LLWebRTCImpl::init() mTuningDeviceModule->SetAudioDeviceSink(this); updateDevices(); }); - + mWorkerThread->BlockingCall( [this]() { @@ -426,7 +426,7 @@ void LLWebRTCImpl::setRenderDevice(const std::string &id) { mTuningDeviceModule->StopPlayout(); } - + mTuningDeviceModule->SetPlayoutDevice(tuningPlayoutDevice); mTuningDeviceModule->InitSpeaker(); mTuningDeviceModule->InitPlayout(); @@ -456,7 +456,7 @@ void LLWebRTCImpl::setRenderDevice(const std::string &id) mPeerDeviceModule->InitSpeaker(); mPeerDeviceModule->InitPlayout(); mPeerDeviceModule->StartPlayout(); - + } }); } @@ -466,7 +466,7 @@ void LLWebRTCImpl::updateDevices() { int16_t renderDeviceCount = mTuningDeviceModule->PlayoutDevices(); int16_t currentRenderDeviceIndex = mTuningDeviceModule->GetPlayoutDevice(); - + LLWebRTCVoiceDeviceList renderDeviceList; for (int16_t index = 0; index < renderDeviceCount; index++) { @@ -475,7 +475,7 @@ void LLWebRTCImpl::updateDevices() mTuningDeviceModule->PlayoutDeviceName(index, name, guid); renderDeviceList.emplace_back(name, guid, index == currentRenderDeviceIndex); } - + int16_t captureDeviceCount = mTuningDeviceModule->RecordingDevices(); int16_t currentCaptureDeviceIndex = mTuningDeviceModule->GetRecordingDevice(); @@ -533,7 +533,7 @@ LLWebRTCPeerConnectionInterface *LLWebRTCImpl::newPeerConnection() { rtc::scoped_refptr<LLWebRTCPeerConnectionImpl> peerConnection = rtc::scoped_refptr<LLWebRTCPeerConnectionImpl>(new rtc::RefCountedObject<LLWebRTCPeerConnectionImpl>()); peerConnection->init(this); - + mPeerConnections.emplace_back(peerConnection); peerConnection->enableSenderTracks(!mMute); return peerConnection.get(); @@ -703,7 +703,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection() webrtc::PeerConnectionInterface::RTCOfferAnswerOptions offerOptions; mPeerConnection->CreateOffer(this, offerOptions); }); - + return true; } @@ -759,7 +759,7 @@ void LLWebRTCPeerConnectionImpl::enableReceiverTracks(bool enable) void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp) { RTC_LOG(LS_INFO) << __FUNCTION__ << " Remote SDP: " << sdp; - + mWebRTCImpl->PostSignalingTask( [this, sdp]() { @@ -768,7 +768,7 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp) RTC_LOG(LS_INFO) << __FUNCTION__ << " " << mPeerConnection->peer_connection_state(); mPeerConnection->SetRemoteDescription(webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, sdp), rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>(this)); - } + } }); } @@ -801,8 +801,8 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute) } void LLWebRTCPeerConnectionImpl::resetMute() -{ - setMute(mMute); +{ + setMute(mMute); } void LLWebRTCPeerConnectionImpl::setReceiveVolume(float volume) @@ -893,7 +893,7 @@ void LLWebRTCPeerConnectionImpl::OnIceGatheringChange(webrtc::PeerConnectionInte webrtc_new_state = LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_NEW; return; } - + if (mAnswerReceived) { for (auto &observer : mSignalingObserverList) @@ -907,7 +907,7 @@ void LLWebRTCPeerConnectionImpl::OnIceGatheringChange(webrtc::PeerConnectionInte void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterface::PeerConnectionState new_state) { RTC_LOG(LS_ERROR) << __FUNCTION__ << " Peer Connection State Change " << new_state; - + switch (new_state) { case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected: @@ -929,7 +929,7 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf { observer->OnRenegotiationNeeded(); } - + break; } default: @@ -944,7 +944,7 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf static std::string iceCandidateToTrickleString(const webrtc::IceCandidateInterface *candidate) { std::ostringstream candidate_stream; - + candidate_stream << candidate->candidate().foundation() << " " << std::to_string(candidate->candidate().component()) << " " << @@ -952,7 +952,7 @@ static std::string iceCandidateToTrickleString(const webrtc::IceCandidateInterfa std::to_string(candidate->candidate().priority()) << " " << candidate->candidate().address().ipaddr().ToString() << " " << candidate->candidate().address().PortAsString() << " typ "; - + if (candidate->candidate().type() == cricket::LOCAL_PORT_TYPE) { candidate_stream << "host"; @@ -982,7 +982,7 @@ static std::string iceCandidateToTrickleString(const webrtc::IceCandidateInterfa { candidate_stream << " tcptype " << candidate->candidate().tcptype(); } - + return candidate_stream.str(); } @@ -990,7 +990,7 @@ static std::string iceCandidateToTrickleString(const webrtc::IceCandidateInterfa void LLWebRTCPeerConnectionImpl::OnIceCandidate(const webrtc::IceCandidateInterface *candidate) { RTC_LOG(LS_INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index(); - + if (!candidate) { RTC_LOG(LS_ERROR) << __FUNCTION__ << " No Ice Candidate Given"; @@ -1067,7 +1067,7 @@ void LLWebRTCPeerConnectionImpl::OnSuccess(webrtc::SessionDescriptionInterface * } void LLWebRTCPeerConnectionImpl::OnFailure(webrtc::RTCError error) -{ +{ RTC_LOG(LS_ERROR) << ToString(error.type()) << ": " << error.message(); } @@ -1100,7 +1100,7 @@ void LLWebRTCPeerConnectionImpl::OnSetRemoteDescriptionComplete(webrtc::RTCError } mCachedIceCandidates.clear(); OnIceGatheringChange(mPeerConnection->ice_gathering_state()); - + } // @@ -1164,7 +1164,7 @@ void LLWebRTCPeerConnectionImpl::sendData(const std::string& data, bool binary) } void LLWebRTCPeerConnectionImpl::setDataObserver(LLWebRTCDataObserver* observer) -{ +{ mDataObserverList.emplace_back(observer); } diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h index 789bde452e..43b48e79ab 100644 --- a/indra/llwebrtc/llwebrtc.h +++ b/indra/llwebrtc/llwebrtc.h @@ -30,7 +30,7 @@ * overall threading model than the viewer. * The native webrtc library is also compiled with clang, and has memory management * functions that conflict namespace-wise with those in the viewer. - * + * * Due to these differences, code from the viewer cannot be pulled in to this * dynamic library, so it remains very simple. */ @@ -56,7 +56,7 @@ namespace llwebrtc { -// LLWebRTCVoiceDevice is a simple representation of the +// LLWebRTCVoiceDevice is a simple representation of the // components of a device, used to communicate this // information to the viewer. diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index c2d0a4413e..16afec061e 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -153,12 +153,12 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS void setTuningMode(bool enable) override; float getTuningAudioLevel() override; float getPeerConnectionAudioLevel() override; - + // // AudioDeviceSink // void OnDevicesUpdated() override; - + // // Helpers // @@ -171,7 +171,7 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS { mWorkerThread->PostTask(std::move(task), location); } - + void PostSignalingTask(absl::AnyInvocable<void() &&> task, const webrtc::Location& location = webrtc::Location::Current()) { @@ -189,7 +189,7 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS { mWorkerThread->BlockingCall(std::move(functor), location); } - + void SignalingBlockingCall(rtc::FunctionView<void()> functor, const webrtc::Location& location = webrtc::Location::Current()) { @@ -205,7 +205,7 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS // Allows the LLWebRTCPeerConnectionImpl class to retrieve the // native webrtc PeerConnectionFactory. rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> getPeerConnectionFactory() - { + { return mPeerConnectionFactory; } @@ -242,7 +242,7 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS LLAudioDeviceObserver * mTuningAudioDeviceObserver; LLCustomProcessor * mPeerCustomProcessor; - + // peer connections std::vector<rtc::scoped_refptr<LLWebRTCPeerConnectionImpl>> mPeerConnections; }; @@ -270,7 +270,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, virtual void AddRef() const override = 0; virtual rtc::RefCountReleaseStatus Release() const override = 0; - + // // LLWebRTCPeerConnection // @@ -326,20 +326,20 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, // SetLocalDescriptionObserverInterface implementation. // void OnSetLocalDescriptionComplete(webrtc::RTCError error) override; - + // // DataChannelObserver implementation. // void OnStateChange() override; void OnMessage(const webrtc::DataBuffer& buffer) override; - + // Helpers void resetMute(); void enableSenderTracks(bool enable); void enableReceiverTracks(bool enable); protected: - + LLWebRTCImpl * mWebRTCImpl; rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory; @@ -358,7 +358,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, std::vector<LLWebRTCDataObserver *> mDataObserverList; rtc::scoped_refptr<webrtc::DataChannelInterface> mDataChannel; }; - + } #endif // LLWEBRTC_IMPL_H diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 9f99549829..33e76c14ae 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -1,25 +1,25 @@ - /** + /** * @file llvoiceclient.cpp * @brief Voice client delegation class implementation. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -81,10 +81,10 @@ LLVoiceHandler gVoiceHandler; std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus) { std::string result = "UNTRANSLATED"; - + // Prevent copy-paste errors when updating this list... #define CASE(x) case x: result = #x; break - + switch(inStatus) { CASE(STATUS_LOGIN_RETRY); @@ -107,9 +107,9 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv } break; } - + #undef CASE - + return result; } @@ -209,7 +209,7 @@ void LLVoiceClient::onSimulatorFeaturesReceived(const LLUUID& region_id) void LLVoiceClient::setSpatialVoiceModule(const std::string &voice_server_type) { LLVoiceModuleInterface *module = getVoiceModule(voice_server_type); - if (!module) + if (!module) { return; } @@ -264,7 +264,7 @@ void LLVoiceClient::terminate() const LLVoiceVersionInfo LLVoiceClient::getVersion() { - if (mSpatialVoiceModule) + if (mSpatialVoiceModule) { return mSpatialVoiceModule->getVersion(); } @@ -330,12 +330,12 @@ float LLVoiceClient::tuningGetEnergy(void) // devices bool LLVoiceClient::deviceSettingsAvailable() -{ +{ return LLWebRTCVoiceClient::getInstance()->deviceSettingsAvailable(); } bool LLVoiceClient::deviceSettingsUpdated() -{ +{ return LLWebRTCVoiceClient::getInstance()->deviceSettingsUpdated(); } @@ -363,7 +363,7 @@ const LLVoiceDeviceList& LLVoiceClient::getCaptureDevices() const LLVoiceDeviceList& LLVoiceClient::getRenderDevices() -{ +{ return LLWebRTCVoiceClient::getInstance()->getRenderDevices(); } @@ -379,7 +379,8 @@ void LLVoiceClient::getParticipantList(std::set<LLUUID> &participants) bool LLVoiceClient::isParticipant(const LLUUID &speaker_id) { - return LLWebRTCVoiceClient::getInstance()->isParticipant(speaker_id) || LLVivoxVoiceClient::getInstance()->isParticipant(speaker_id); + return LLWebRTCVoiceClient::getInstance()->isParticipant(speaker_id) || + LLVivoxVoiceClient::getInstance()->isParticipant(speaker_id); } @@ -388,14 +389,8 @@ bool LLVoiceClient::isParticipant(const LLUUID &speaker_id) BOOL LLVoiceClient::isSessionTextIMPossible(const LLUUID& id) { - if (mSpatialVoiceModule) - { - return mSpatialVoiceModule->isSessionTextIMPossible(id); - } - else - { - return FALSE; - } + // all sessions can do TextIM, as we no longer support PSTN + return TRUE; } BOOL LLVoiceClient::isSessionCallBackPossible(const LLUUID& id) @@ -409,7 +404,7 @@ BOOL LLVoiceClient::isSessionCallBackPossible(const LLUUID& id) bool LLVoiceClient::inProximalChannel() { - if (mSpatialVoiceModule) + if (mSpatialVoiceModule) { return mSpatialVoiceModule->inProximalChannel(); } @@ -552,7 +547,7 @@ void LLVoiceClient::updateMicMuteLogic() { // If not configured to use PTT, the mic should be open (otherwise the user will be unable to speak). bool new_mic_mute = false; - + if(mUsePTT) { // If configured to use PTT, track the user state. @@ -603,7 +598,7 @@ void LLVoiceClient::setUsePTT(bool usePTT) mUserPTTState = false; } mUsePTT = usePTT; - + updateMicMuteLogic(); } @@ -614,7 +609,7 @@ void LLVoiceClient::setPTTIsToggle(bool PTTIsToggle) // When the user turns off toggle, reset the current state. mUserPTTState = false; } - + mPTTIsToggle = PTTIsToggle; updateMicMuteLogic(); @@ -629,12 +624,12 @@ void LLVoiceClient::inputUserControlState(bool down) { if(mPTTIsToggle) { - if(down) // toggle open-mic state on 'down' + if(down) // toggle open-mic state on 'down' { toggleUserPTTState(); } } - else // set open-mic state as an absolute + else // set open-mic state as an absolute { setUserPTTState(down); } @@ -651,39 +646,23 @@ void LLVoiceClient::toggleUserPTTState(void) BOOL LLVoiceClient::getVoiceEnabled(const LLUUID& id) { - if (mNonSpatialVoiceModule) - { - return mNonSpatialVoiceModule->getVoiceEnabled(id); - } - else if (mSpatialVoiceModule) - { - return mSpatialVoiceModule->getVoiceEnabled(id); - } - else - { - return FALSE; - } + return isParticipant(id) ? TRUE : FALSE; } std::string LLVoiceClient::getDisplayName(const LLUUID& id) { - if (mNonSpatialVoiceModule) + std::string result = LLWebRTCVoiceClient::getInstance()->getDisplayName(id); + if (result.empty()) { - return mNonSpatialVoiceModule->getDisplayName(id); - } - else if (mSpatialVoiceModule) - { - return mSpatialVoiceModule->getDisplayName(id); - } - else - { - return std::string(); + result = LLVivoxVoiceClient::getInstance()->getDisplayName(id); } + return result; } bool LLVoiceClient::isVoiceWorking() const { - return LLVivoxVoiceClient::getInstance()->isVoiceWorking() || LLWebRTCVoiceClient::getInstance()->isVoiceWorking(); + return LLVivoxVoiceClient::getInstance()->isVoiceWorking() || + LLWebRTCVoiceClient::getInstance()->isVoiceWorking(); } BOOL LLVoiceClient::isParticipantAvatar(const LLUUID& id) @@ -698,48 +677,29 @@ BOOL LLVoiceClient::isOnlineSIP(const LLUUID& id) BOOL LLVoiceClient::getIsSpeaking(const LLUUID& id) { - return LLVivoxVoiceClient::getInstance()->getIsSpeaking(id) || LLWebRTCVoiceClient::getInstance()->getIsSpeaking(id); + return LLWebRTCVoiceClient::getInstance()->getIsSpeaking(id) || + LLVivoxVoiceClient::getInstance()->getIsSpeaking(id); } BOOL LLVoiceClient::getIsModeratorMuted(const LLUUID& id) { // don't bother worrying about p2p calls, as // p2p calls don't have mute. - if (mNonSpatialVoiceModule) - { - return mNonSpatialVoiceModule->getIsModeratorMuted(id); - } - else if (mSpatialVoiceModule) - { - return mSpatialVoiceModule->getIsModeratorMuted(id); - } - else - { - return FALSE; - } + return LLWebRTCVoiceClient::getInstance()->getIsModeratorMuted(id) || + LLVivoxVoiceClient::getInstance()->getIsModeratorMuted(id); } F32 LLVoiceClient::getCurrentPower(const LLUUID& id) -{ - return std::fmax(LLVivoxVoiceClient::getInstance()->getCurrentPower(id), LLWebRTCVoiceClient::getInstance()->getCurrentPower(id)); +{ + return std::fmax(LLVivoxVoiceClient::getInstance()->getCurrentPower(id), + LLWebRTCVoiceClient::getInstance()->getCurrentPower(id)); } BOOL LLVoiceClient::getOnMuteList(const LLUUID& id) { // don't bother worrying about p2p calls, as // p2p calls don't have mute. - if (mNonSpatialVoiceModule) - { - return mNonSpatialVoiceModule->getOnMuteList(id); - } - else if (mSpatialVoiceModule) - { - return mSpatialVoiceModule->getOnMuteList(id); - } - else - { - return FALSE; - } + return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat); } F32 LLVoiceClient::getUserVolume(const LLUUID& id) @@ -798,7 +758,7 @@ std::string LLVoiceClient::sipURIFromID(const LLUUID &id) { return mNonSpatialVoiceModule->sipURIFromID(id); } - else if (mSpatialVoiceModule) + else if (mSpatialVoiceModule) { return mSpatialVoiceModule->sipURIFromID(id); } @@ -854,7 +814,7 @@ class LLViewerRequiredVoiceVersion : public LLHTTPNode } LLVoiceVersionInfo versionInfo = voiceModule->getVersion(); - if (input.has("body") && input["body"].has("major_version") && + if (input.has("body") && input["body"].has("major_version") && input["body"]["major_version"].asInteger() > versionInfo.majorVersion) { if (!sAlertedUser) @@ -879,26 +839,26 @@ class LLViewerParcelVoiceInfo : public LLHTTPNode { //the parcel you are in has changed something about its //voice information - + //this is a misnomer, as it can also be when you are not in //a parcel at all. Should really be something like //LLViewerVoiceInfoChanged..... if ( input.has("body") ) { LLSD body = input["body"]; - + //body has "region_name" (str), "parcel_local_id"(int), //"voice_credentials" (map). - + //body["voice_credentials"] has "channel_uri" (str), //body["voice_credentials"] has "channel_credentials" (str) - + //if we really wanted to be extra careful, //we'd check the supplied //local parcel id to make sure it's for the same parcel //we believe we're in if ( body.has("voice_credentials") ) - { + { LLVoiceClient::getInstance()->setSpatialChannel(body["voice_credentials"]); } } @@ -941,7 +901,7 @@ void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, F32 vo bool LLSpeakerVolumeStorage::getSpeakerVolume(const LLUUID& speaker_id, F32& volume) { speaker_data_map_t::const_iterator it = mSpeakersData.find(speaker_id); - + if (it != mSpeakersData.end()) { volume = it->second; @@ -1020,9 +980,9 @@ void LLSpeakerVolumeStorage::load() if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings_llsd, file)) { LL_WARNS("Voice") << "failed to parse " << filename << LL_ENDL; - + } - + } for (LLSD::map_const_iterator iter = settings_llsd.beginMap(); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 79bca23fc4..46dd325e21 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -1,25 +1,25 @@ -/** +/** * @file llvoiceclient.h * @brief Declaration of LLVoiceClient class which is the interface to the voice client process. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -147,32 +147,32 @@ class LLVoiceModuleInterface public: LLVoiceModuleInterface() {} virtual ~LLVoiceModuleInterface() {} - + virtual void init(LLPumpIO *pump)=0; // Call this once at application startup (creates connector) virtual void terminate()=0; // Call this to clean up during shutdown - + virtual void updateSettings()=0; // call after loading settings and whenever they change - + virtual bool isVoiceWorking() const = 0; // connected to a voice server and voice channel - + virtual void setHidden(bool hidden)=0; // Hides the user from voice. virtual const LLVoiceVersionInfo& getVersion()=0; - + ///////////////////// /// @name Tuning //@{ virtual void tuningStart()=0; virtual void tuningStop()=0; virtual bool inTuningMode()=0; - + virtual void tuningSetMicVolume(float volume)=0; virtual void tuningSetSpeakerVolume(float volume)=0; virtual float tuningGetEnergy(void)=0; //@} - + ///////////////////// /// @name Devices //@{ @@ -180,36 +180,36 @@ public: // i.e. when the daemon is running and connected, and the device lists are populated. virtual bool deviceSettingsAvailable()=0; virtual bool deviceSettingsUpdated() = 0; - + // Requery the vivox daemon for the current list of input/output devices. // If you pass true for clearCurrentList, deviceSettingsAvailable() will be false until the query has completed // (use this if you want to know when it's done). // If you pass false, you'll have no way to know when the query finishes, but the device lists will not appear empty in the interim. virtual void refreshDeviceLists(bool clearCurrentList = true)=0; - + virtual void setCaptureDevice(const std::string& name)=0; virtual void setRenderDevice(const std::string& name)=0; - + virtual LLVoiceDeviceList& getCaptureDevices()=0; virtual LLVoiceDeviceList& getRenderDevices()=0; - + virtual void getParticipantList(std::set<LLUUID> &participants)=0; virtual bool isParticipant(const LLUUID& speaker_id)=0; //@} - + //////////////////////////// /// @ name Channel stuff //@{ // returns true iff the user is currently in a proximal (local spatial) channel. // Note that gestures should only fire if this returns true. virtual bool inProximalChannel()=0; - + virtual void setNonSpatialChannel(const LLSD& channelInfo, bool notify_on_first_join, bool hangup_on_last_leave)=0; - + virtual bool setSpatialChannel(const LLSD& channelInfo)=0; - + virtual void leaveNonSpatialChannel() = 0; virtual void processChannels(bool process) = 0; @@ -217,12 +217,12 @@ public: virtual bool compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) = 0; //@} - - + + ////////////////////////// /// @name p2p //@{ - + // initiate a call with a peer using the P2P interface, which only applies to some // voice server types. Otherwise, a group call should be used for P2P virtual LLVoiceP2POutgoingCallInterface* getOutgoingCallInterface() = 0; @@ -231,35 +231,33 @@ public: // answer or decline. virtual LLVoiceP2PIncomingCallInterfacePtr getIncomingCallInterface(const LLSD &voice_call_info) = 0; //@} - + ///////////////////////// /// @name Volume/gain //@{ virtual void setVoiceVolume(F32 volume)=0; virtual void setMicGain(F32 volume)=0; //@} - + ///////////////////////// /// @name enable disable voice and features //@{ virtual void setVoiceEnabled(bool enabled)=0; virtual void setMuteMic(bool muted)=0; // Set the mute state of the local mic. //@} - + ////////////////////////// /// @name nearby speaker accessors //@{ - virtual BOOL getVoiceEnabled(const LLUUID& id)=0; // true if we've received data for this avatar virtual std::string getDisplayName(const LLUUID& id)=0; virtual BOOL isParticipantAvatar(const LLUUID &id)=0; virtual BOOL getIsSpeaking(const LLUUID& id)=0; virtual BOOL getIsModeratorMuted(const LLUUID& id)=0; virtual F32 getCurrentPower(const LLUUID& id)=0; // "power" is related to "amplitude" in a defined way. I'm just not sure what the formula is... - virtual BOOL getOnMuteList(const LLUUID& id)=0; virtual F32 getUserVolume(const LLUUID& id)=0; - virtual void setUserVolume(const LLUUID& id, F32 volume)=0; // set's volume for specified agent, from 0-1 (where .5 is nominal) + virtual void setUserVolume(const LLUUID& id, F32 volume)=0; // set's volume for specified agent, from 0-1 (where .5 is nominal) //@} - + ////////////////////////// /// @name text chat //@{ @@ -267,25 +265,25 @@ public: virtual BOOL isSessionCallBackPossible(const LLUUID& id)=0; //virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message)=0; //@} - + // authorize the user virtual void userAuthorized(const std::string& user_id, const LLUUID &agentID)=0; - + ////////////////////////////// /// @name Status notification //@{ virtual void addObserver(LLVoiceClientStatusObserver* observer)=0; virtual void removeObserver(LLVoiceClientStatusObserver* observer)=0; virtual void addObserver(LLFriendObserver* observer)=0; - virtual void removeObserver(LLFriendObserver* observer)=0; + virtual void removeObserver(LLFriendObserver* observer)=0; virtual void addObserver(LLVoiceClientParticipantObserver* observer)=0; - virtual void removeObserver(LLVoiceClientParticipantObserver* observer)=0; + virtual void removeObserver(LLVoiceClientParticipantObserver* observer)=0; //@} - + virtual std::string sipURIFromID(const LLUUID &id)=0; //@} - + }; @@ -357,9 +355,9 @@ public: micro_changed_signal_t mMicroChangedSignal; void terminate(); // Call this to clean up during shutdown - + const LLVoiceVersionInfo getVersion(); - + static const F32 OVERDRIVEN_POWER_LEVEL; static const F32 VOLUME_MIN; @@ -374,18 +372,18 @@ public: void tuningStart(); void tuningStop(); bool inTuningMode(); - + void tuningSetMicVolume(float volume); void tuningSetSpeakerVolume(float volume); float tuningGetEnergy(void); - + // devices - + // This returns true when it's safe to bring up the "device settings" dialog in the prefs. // i.e. when the daemon is running and connected, and the device lists are populated. bool deviceSettingsAvailable(); bool deviceSettingsUpdated(); // returns true when the device list has been updated recently. - + // Requery the vivox daemon for the current list of input/output devices. // If you pass true for clearCurrentList, deviceSettingsAvailable() will be false until the query has completed // (use this if you want to know when it's done). @@ -402,7 +400,7 @@ public: //////////////////////////// // Channel stuff // - + // returns true iff the user is currently in a proximal (local spatial) channel. // Note that gestures should only fire if this returns true. bool inProximalChannel(); @@ -426,35 +424,35 @@ public: LLVoiceP2POutgoingCallInterface* getOutgoingCallInterface(const LLSD& voiceChannelInfo); LLVoiceP2PIncomingCallInterfacePtr getIncomingCallInterface(const LLSD &voiceCallInfo); - + ///////////////////////////// // Sending updates of current state - + void setVoiceVolume(F32 volume); void setMicGain(F32 volume); - void setUserVolume(const LLUUID& id, F32 volume); // set's volume for specified agent, from 0-1 (where .5 is nominal) + void setUserVolume(const LLUUID& id, F32 volume); // set's volume for specified agent, from 0-1 (where .5 is nominal) bool voiceEnabled(); void setMuteMic(bool muted); // Use this to mute the local mic (for when the client is minimized, etc), ignoring user PTT state. void setUserPTTState(bool ptt); bool getUserPTTState(); void toggleUserPTTState(void); - void inputUserControlState(bool down); // interpret any sort of up-down mic-open control input according to ptt-toggle prefs + void inputUserControlState(bool down); // interpret any sort of up-down mic-open control input according to ptt-toggle prefs void setVoiceEnabled(bool enabled); void setUsePTT(bool usePTT); void setPTTIsToggle(bool PTTIsToggle); - bool getPTTIsToggle(); + bool getPTTIsToggle(); void updateMicMuteLogic(); boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); } - + ///////////////////////////// // Accessors for data related to nearby speakers BOOL getVoiceEnabled(const LLUUID& id); // true if we've received data for this avatar - std::string getDisplayName(const LLUUID& id); + std::string getDisplayName(const LLUUID& id); BOOL isOnlineSIP(const LLUUID &id); BOOL isParticipantAvatar(const LLUUID &id); BOOL getIsSpeaking(const LLUUID& id); @@ -466,7 +464,7 @@ public: ///////////////////////////// void getParticipantList(std::set<LLUUID> &participants); bool isParticipant(const LLUUID& speaker_id); - + ////////////////////////// /// @name text chat //@{ @@ -474,7 +472,7 @@ public: BOOL isSessionCallBackPossible(const LLUUID& id); //BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message) const {return true;} ; //@} - + void setSpatialVoiceModule(const std::string& voice_server_type); void setNonSpatialVoiceModule(const std::string &voice_server_type); @@ -483,15 +481,15 @@ public: void onRegionChanged(); void onSimulatorFeaturesReceived(const LLUUID ®ion_id); - + void addObserver(LLVoiceClientStatusObserver* observer); void removeObserver(LLVoiceClientStatusObserver* observer); void addObserver(LLFriendObserver* observer); void removeObserver(LLFriendObserver* observer); void addObserver(LLVoiceClientParticipantObserver* observer); void removeObserver(LLVoiceClientParticipantObserver* observer); - - std::string sipURIFromID(const LLUUID &id); + + std::string sipURIFromID(const LLUUID &id); ////////////////////////// /// @name Voice effects @@ -517,7 +515,7 @@ protected: bool mPTTDirty; bool mPTT; - + bool mUsePTT; S32 mPTTMouseButton; KEY mPTTKey; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 1454342083..9a1fb925eb 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1,25 +1,25 @@ - /** + /** * @file LLVivoxVoiceClient.cpp * @brief Implementation of LLVivoxVoiceClient class which is the interface to the voice client process. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -96,7 +96,7 @@ namespace { // Don't send positional updates more frequently than this: const F32 UPDATE_THROTTLE_SECONDS = 0.5f; - // Timeout for connection to Vivox + // Timeout for connection to Vivox const F32 CONNECT_ATTEMPT_TIMEOUT = 300.0f; const F32 CONNECT_DNS_TIMEOUT = 5.0f; const int CONNECT_RETRY_MAX = 3; @@ -115,8 +115,8 @@ namespace { const F32 SESSION_JOIN_TIMEOUT = 30.0f; // Defines the maximum number of times(in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine() - // which is treated as normal. The is the number of frames to wait for a channel join before giving up. This was changed - // from the original count of 50 for two reason. Modern PCs have higher frame rates and sometimes the SLVoice process + // which is treated as normal. The is the number of frames to wait for a channel join before giving up. This was changed + // from the original count of 50 for two reason. Modern PCs have higher frame rates and sometimes the SLVoice process // backs up processing join requests. There is a log statement that records when channel joins take longer than 100 frames. const int MAX_NORMAL_JOINING_SPATIAL_NUM = 1500; @@ -135,17 +135,17 @@ namespace { static int scale_mic_volume(float volume) { - // incoming volume has the range [0.0 ... 2.0], with 1.0 as the default. - // Map it to Vivox levels as follows: 0.0 -> 30, 1.0 -> 50, 2.0 -> 70 + // incoming volume has the range [0.0 ... 2.0], with 1.0 as the default. + // Map it to Vivox levels as follows: 0.0 -> 30, 1.0 -> 50, 2.0 -> 70 return 30 + (int)(volume * 20.0f); } static int scale_speaker_volume(float volume) { - // incoming volume has the range [0.0 ... 1.0], with 0.5 as the default. - // Map it to Vivox levels as follows: 0.0 -> 30, 0.5 -> 50, 1.0 -> 70 + // incoming volume has the range [0.0 ... 1.0], with 0.5 as the default. + // Map it to Vivox levels as follows: 0.0 -> 30, 0.5 -> 50, 1.0 -> 70 return 30 + (int)(volume * 40.0f); - + } @@ -364,18 +364,18 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mVoiceVersion.minorVersion = 0; mVoiceVersion.mBuildVersion = ""; mVoiceVersion.serverVersion = ""; - + // gMuteListp isn't set up at this point, so we defer this until later. // gMuteListp->addObserver(&mutelist_listener); - + #if LL_DARWIN || LL_LINUX // HACK: THIS DOES NOT BELONG HERE // When the vivox daemon dies, the next write attempt on our socket generates a SIGPIPE, which kills us. // This should cause us to ignore SIGPIPE and handle the error through proper channels. // This should really be set up elsewhere. Where should it go? signal(SIGPIPE, SIG_IGN); - + // Since we're now launching the gateway with fork/exec instead of system(), we need to deal with zombie processes. // Ignoring SIGCHLD should prevent zombies from being created. Alternately, we could use wait(), but I'd rather not do that. signal(SIGCHLD, SIG_IGN); @@ -415,13 +415,13 @@ void LLVivoxVoiceClient::terminate() return; } - // needs to be done manually here since we will not get another pass in + // needs to be done manually here since we will not get another pass in // coroutines... that mechanism is long since gone. if (mIsLoggedIn) { logoutOfVivox(false); } - + if(sConnected) { breakVoiceConnection(false); @@ -442,7 +442,7 @@ void LLVivoxVoiceClient::terminate() void LLVivoxVoiceClient::cleanUp() { LL_DEBUGS("Voice") << LL_ENDL; - + deleteAllSessions(); deleteAllVoiceFonts(); deleteVoiceFontTemplates(); @@ -484,7 +484,7 @@ bool LLVivoxVoiceClient::writeString(const std::string &str) apr_status_t err; apr_size_t size = (apr_size_t)str.size(); apr_size_t written = size; - + //MARK: Turn this on to log outgoing XML // LL_DEBUGS("Voice") << "sending: " << str << LL_ENDL; @@ -493,7 +493,7 @@ bool LLVivoxVoiceClient::writeString(const std::string &str) mSocket->getSocket(), (const char*)str.data(), &written); - + if(err == 0 && written == size) { // Success. @@ -516,7 +516,7 @@ bool LLVivoxVoiceClient::writeString(const std::string &str) daemonDied(); } } - + return result; } @@ -527,7 +527,7 @@ void LLVivoxVoiceClient::connectorCreate() { std::ostringstream stream; std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); - + // Transition to stateConnectorStarted when the connector handle comes back. std::string vivoxLogLevel = gSavedSettings.getString("VivoxDebugLevel"); if ( vivoxLogLevel.empty() ) @@ -535,8 +535,8 @@ void LLVivoxVoiceClient::connectorCreate() vivoxLogLevel = "0"; } LL_DEBUGS("Voice") << "creating connector with log level " << vivoxLogLevel << LL_ENDL; - - stream + + stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.Create.1\">" << "<ClientName>V2 SDK</ClientName>" << "<AccountManagementServer>" << mVoiceAccountServerURI << "</AccountManagementServer>" @@ -552,7 +552,7 @@ void LLVivoxVoiceClient::connectorCreate() //<< "<Application></Application>" //Name can cause problems per vivox. << "<MaxCalls>12</MaxCalls>" << "</Request>\n\n\n"; - + writeString(stream.str()); } @@ -566,10 +566,10 @@ void LLVivoxVoiceClient::connectorShutdown() << "<ConnectorHandle>" << LLVivoxSecurity::getInstance()->connectorHandle() << "</ConnectorHandle>" << "</Request>" << "\n\n\n"; - + mShutdownComplete = false; mConnectorEstablished = false; - + writeString(stream.str()); } else @@ -601,7 +601,7 @@ void LLVivoxVoiceClient::setLoginInfo( { // Already logged in. LL_WARNS("Voice") << "Called while already logged in." << LL_ENDL; - + // Don't process another login. return; } @@ -616,14 +616,14 @@ void LLVivoxVoiceClient::setLoginInfo( } std::string debugSIPURIHostName = gSavedSettings.getString("VivoxDebugSIPURIHostName"); - + if( !debugSIPURIHostName.empty() ) { LL_INFOS("Voice") << "Overriding account server based on VivoxDebugSIPURIHostName: " << debugSIPURIHostName << LL_ENDL; mVoiceSIPURIHostName = debugSIPURIHostName; } - + if( mVoiceSIPURIHostName.empty() ) { // we have an empty account server name @@ -643,7 +643,7 @@ void LLVivoxVoiceClient::setLoginInfo( << mVoiceSIPURIHostName << LL_ENDL; } - + std::string debugAccountServerURI = gSavedSettings.getString("VivoxDebugVoiceAccountServerURI"); if( !debugAccountServerURI.empty() ) @@ -652,11 +652,11 @@ void LLVivoxVoiceClient::setLoginInfo( << debugAccountServerURI << LL_ENDL; mVoiceAccountServerURI = debugAccountServerURI; } - + if( mVoiceAccountServerURI.empty() ) { // If the account server URI isn't specified, construct it from the SIP URI hostname - mVoiceAccountServerURI = "https://www." + mVoiceSIPURIHostName + "/api2/"; + mVoiceAccountServerURI = "https://www." + mVoiceSIPURIHostName + "/api2/"; LL_INFOS("Voice") << "Inferring account server based on SIP URI Host name: " << mVoiceAccountServerURI << LL_ENDL; } @@ -667,11 +667,11 @@ void LLVivoxVoiceClient::idle(void* user_data) } //========================================================================= -// the following are methods to support the coroutine implementation of the -// voice connection and processing. They should only be called in the context +// the following are methods to support the coroutine implementation of the +// voice connection and processing. They should only be called in the context // of a coroutine. -// -// +// +// typedef enum e_voice_control_coro_state { @@ -820,7 +820,7 @@ void LLVivoxVoiceClient::voiceControlStateMachine(S32 &coro_state) case VOICE_STATE_SESSION_ESTABLISHED: { - // enable/disable the automatic VAD and explicitly set the initial values of + // enable/disable the automatic VAD and explicitly set the initial values of // the VAD variables ourselves when it is off - see SL-15072 for more details // note: we set the other parameters too even if the auto VAD is on which is ok unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto"); @@ -995,7 +995,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() { LLFile::rename(new_log, old_log); } - + std::string shutdown_timeout = gSavedSettings.getString("VivoxShutdownTimeout"); if (!shutdown_timeout.empty()) { @@ -1076,7 +1076,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() llcoro::suspendUntilTimeout(DAEMON_CONNECT_THROTTLE_SECONDS); } } - + //--------------------------------------------------------------------- if (sShuttingDown && !sConnected) { @@ -1094,7 +1094,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() { return false; } - + // MBW -- Note to self: pumps and pipes examples in // indra/test/io.cpp // indra/test/llpipeutil.{cpp|h} @@ -1132,7 +1132,7 @@ bool LLVivoxVoiceClient::provisionVoiceAccount() // *TODO* Pump a message for wake up. llcoro::suspend(); } - + if (sShuttingDown) { return false; @@ -1184,7 +1184,7 @@ bool LLVivoxVoiceClient::provisionVoiceAccount() else { provisioned = true; - } + } } while (!provisioned && ++retryCount <= PROVISION_RETRY_MAX && !sShuttingDown); if (sShuttingDown && !provisioned) @@ -1208,7 +1208,7 @@ bool LLVivoxVoiceClient::provisionVoiceAccount() { voiceSipUriHostname = result["voice_sip_uri_hostname"].asString(); } - + // this key is actually misnamed -- it will be an entire URI, not just a hostname. if (result.has("voice_account_server_name")) { @@ -1239,7 +1239,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection() { return false; } - + LLSD result; bool connected(false); bool giving_up(false); @@ -1358,7 +1358,7 @@ bool LLVivoxVoiceClient::loginToVivox() bool account_login(false); bool send_login(true); - do + do { mIsLoggingIn = true; if (send_login) @@ -1366,7 +1366,7 @@ bool LLVivoxVoiceClient::loginToVivox() loginSendMessage(); send_login = false; } - + LLSD result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult); if (sShuttingDown) @@ -1406,7 +1406,7 @@ bool LLVivoxVoiceClient::loginToVivox() // tell the user there is a problem LL_WARNS("Voice") << "login " << loginresp << " will retry login in " << timeout << " seconds." << LL_ENDL; - + if (!sShuttingDown) { // Todo: this is way to long, viewer can get stuck waiting during shutdown @@ -1511,7 +1511,7 @@ bool LLVivoxVoiceClient::retrieveVoiceFonts() mIsWaitingForFonts = true; LLSD result; - do + do { result = llcoro::suspendUntilEventOn(mVivoxPump); @@ -1546,7 +1546,7 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo() LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest capability not available in this region" << LL_ENDL; return false; } - + // update the parcel checkParcelChanged(true); @@ -1606,7 +1606,7 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo() } } - // set the spatial channel. If no voice credentials or uri are + // set the spatial channel. If no voice credentials or uri are // available, then we simply drop out of voice spatially. return setSpatialChannel(result["voice_credentials"]); } @@ -1661,7 +1661,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED); LL_WARNS() << "There seems to be problem with connection to voice server. Disabling voice chat abilities." << LL_ENDL; } - + // Increase mSpatialJoiningNum only for spatial sessions- it's normal to reach this case for // example for p2p many times while waiting for response, so it can't be used to detect errors if (mAudioSession && mAudioSession->mIsSpatial) @@ -1703,8 +1703,8 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) LLSD timeoutResult(LLSDMap("session", "timeout")); - // We are about to start a whole new session. Anything that MIGHT still be in our - // maildrop is going to be stale and cause us much wailing and gnashing of teeth. + // We are about to start a whole new session. Anything that MIGHT still be in our + // maildrop is going to be stale and cause us much wailing and gnashing of teeth. // Just flush it all out and start new. mVivoxPump.discard(); @@ -1747,25 +1747,25 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) } else if ((message == "failed") || (message == "removed") || (message == "timeout")) { // we will get a removed message if a voice call is declined. - - if (message == "failed") + + if (message == "failed") { int reason = result["reason"].asInteger(); LL_WARNS("Voice") << "Add and join failed for reason " << reason << LL_ENDL; - + if ( (reason == ERROR_VIVOX_NOT_LOGGED_IN) || (reason == ERROR_VIVOX_OBJECT_NOT_FOUND)) { LL_DEBUGS("Voice") << "Requesting reprovision and login." << LL_ENDL; requestRelog(); - } + } } else { LL_WARNS("Voice") << "session '" << message << "' " << LL_ENDL; } - + notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL); mIsJoiningSession = false; return false; @@ -1784,8 +1784,8 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) // Events that need to happen when a session is joined could go here. // send an initial positional information immediately upon joining. - // - // do an initial update for position and the camera position, then send a + // + // do an initial update for position and the camera position, then send a // positional update. updatePosition(); enforceTether(); @@ -1892,7 +1892,7 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait) notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL); // Always reset the terminate request flag when we get here. - // Some slower PCs have a race condition where they can switch to an incoming P2P call faster than the state machine leaves + // Some slower PCs have a race condition where they can switch to an incoming P2P call faster than the state machine leaves // the region chat. mSessionTerminateRequested = false; @@ -1927,7 +1927,7 @@ bool LLVivoxVoiceClient::waitForChannel() EVoiceWaitForChannelState state = VOICE_CHANNEL_STATE_LOGIN; - do + do { if (sShuttingDown) { @@ -2117,10 +2117,10 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) LL_DEBUGS("Voice") << "runSession terminate requested " << LL_ENDL; terminateAudioSession(true); } - // if a relog has been requested then addAndJoineSession + // if a relog has been requested then addAndJoineSession // failed in a spectacular way and we need to back out. // If this is not the case then we were simply trying to - // make a call and the other party rejected it. + // make a call and the other party rejected it. return !mRelogRequested; } @@ -2156,7 +2156,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) mAudioSession->mParticipantsChanged = false; notifyParticipantObservers(); } - + if (!inSpatialChannel()) { // When in a non-spatial channel, never send positional updates. @@ -2168,9 +2168,9 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) if (checkParcelChanged()) { - // *RIDER: I think I can just return here if the parcel has changed + // *RIDER: I think I can just return here if the parcel has changed // and grab the new voice channel from the outside loop. - // + // // if the parcel has changed, attempted to request the // cap for the parcel voice info. If we can't request it // then we don't have the cap URL so we do nothing and will @@ -2213,7 +2213,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL; } if (result.has("session")) - { + { if (result.has("handle")) { if (!mAudioSession) @@ -2318,7 +2318,7 @@ void LLVivoxVoiceClient::recordingAndPlaybackMode() int LLVivoxVoiceClient::voiceRecordBuffer() { - LLSD timeoutResult(LLSDMap("recplay", "stop")); + LLSD timeoutResult(LLSDMap("recplay", "stop")); LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL; @@ -2441,7 +2441,7 @@ void LLVivoxVoiceClient::logout() // Ensure that we'll re-request provisioning before logging in again mAccountPassword.clear(); mVoiceAccountServerURI.clear(); - + logoutSendMessage(); } @@ -2466,7 +2466,7 @@ void LLVivoxVoiceClient::logoutSendMessage() void LLVivoxVoiceClient::sessionGroupCreateSendMessage() { if(mAccountLoggedIn) - { + { std::ostringstream stream; LL_DEBUGS("Voice") << "creating session group" << LL_ENDL; @@ -2535,7 +2535,7 @@ void LLVivoxVoiceClient::sessionGroupAddSessionSendMessage(const sessionStatePtr { session->mMediaConnectInProgress = true; } - + std::string password; if(!session->mHash.empty()) { @@ -2560,7 +2560,7 @@ void LLVivoxVoiceClient::sessionGroupAddSessionSendMessage(const sessionStatePtr << "<PasswordHashAlgorithm>SHA1UserName</PasswordHashAlgorithm>" << "</Request>\n\n\n" ; - + writeString(stream.str()); } @@ -2572,7 +2572,7 @@ void LLVivoxVoiceClient::sessionMediaConnectSendMessage(const sessionStatePtr_t << LL_ENDL; session->mMediaConnectInProgress = true; - + std::ostringstream stream; stream @@ -2589,7 +2589,7 @@ void LLVivoxVoiceClient::sessionMediaConnectSendMessage(const sessionStatePtr_t void LLVivoxVoiceClient::sessionTextConnectSendMessage(const sessionStatePtr_t &session) { LL_DEBUGS("Voice") << "connecting text to session handle: " << session->mHandle << LL_ENDL; - + std::ostringstream stream; stream @@ -2630,7 +2630,7 @@ void LLVivoxVoiceClient::leaveAudioSession() time_t now = time(NULL); const size_t BUF_SIZE = 64; char time_str[BUF_SIZE]; /* Flawfinder: ignore */ - + strftime(time_str, BUF_SIZE, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); savepath += time_str; } @@ -2641,7 +2641,7 @@ void LLVivoxVoiceClient::leaveAudioSession() } else { - LL_WARNS("Voice") << "called with no session handle" << LL_ENDL; + LL_WARNS("Voice") << "called with no session handle" << LL_ENDL; } } else @@ -2658,12 +2658,12 @@ void LLVivoxVoiceClient::sessionTerminateSendMessage(const sessionStatePtr_t &se sessionGroupTerminateSendMessage(session); return; /* - LL_DEBUGS("Voice") << "Sending Session.Terminate with handle " << session->mHandle << LL_ENDL; + LL_DEBUGS("Voice") << "Sending Session.Terminate with handle " << session->mHandle << LL_ENDL; stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Terminate.1\">" << "<SessionHandle>" << session->mHandle << "</SessionHandle>" << "</Request>\n\n\n"; - + writeString(stream.str()); */ } @@ -2671,13 +2671,13 @@ void LLVivoxVoiceClient::sessionTerminateSendMessage(const sessionStatePtr_t &se void LLVivoxVoiceClient::sessionGroupTerminateSendMessage(const sessionStatePtr_t &session) { std::ostringstream stream; - - LL_DEBUGS("Voice") << "Sending SessionGroup.Terminate with handle " << session->mGroupHandle << LL_ENDL; + + LL_DEBUGS("Voice") << "Sending SessionGroup.Terminate with handle " << session->mGroupHandle << LL_ENDL; stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.Terminate.1\">" << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" << "</Request>\n\n\n"; - + writeString(stream.str()); } @@ -2687,17 +2687,17 @@ void LLVivoxVoiceClient::sessionMediaDisconnectSendMessage(const sessionStatePtr sessionGroupTerminateSendMessage(session); return; /* - LL_DEBUGS("Voice") << "Sending Session.MediaDisconnect with handle " << session->mHandle << LL_ENDL; + LL_DEBUGS("Voice") << "Sending Session.MediaDisconnect with handle " << session->mHandle << LL_ENDL; stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.MediaDisconnect.1\">" << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" << "<SessionHandle>" << session->mHandle << "</SessionHandle>" << "<Media>Audio</Media>" << "</Request>\n\n\n"; - + writeString(stream.str()); */ - + } @@ -2707,7 +2707,7 @@ void LLVivoxVoiceClient::getCaptureDevicesSendMessage() stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.GetCaptureDevices.1\">" << "</Request>\n\n\n"; - + writeString(stream.str()); } @@ -2717,7 +2717,7 @@ void LLVivoxVoiceClient::getRenderDevicesSendMessage() stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.GetRenderDevices.1\">" << "</Request>\n\n\n"; - + writeString(stream.str()); } @@ -2745,7 +2745,7 @@ void LLVivoxVoiceClient::setCaptureDevice(const std::string& name) if(!mCaptureDevice.empty()) { mCaptureDevice.clear(); - mCaptureDeviceDirty = true; + mCaptureDeviceDirty = true; } } else @@ -2753,7 +2753,7 @@ void LLVivoxVoiceClient::setCaptureDevice(const std::string& name) if(mCaptureDevice != name) { mCaptureDevice = name; - mCaptureDeviceDirty = true; + mCaptureDeviceDirty = true; } } } @@ -2763,7 +2763,7 @@ void LLVivoxVoiceClient::setDevicesListUpdated(bool state) } void LLVivoxVoiceClient::clearRenderDevices() -{ +{ LL_DEBUGS("Voice") << "called" << LL_ENDL; mRenderDevices.clear(); } @@ -2786,7 +2786,7 @@ void LLVivoxVoiceClient::setRenderDevice(const std::string& name) if(!mRenderDevice.empty()) { mRenderDevice.clear(); - mRenderDeviceDirty = true; + mRenderDeviceDirty = true; } } else @@ -2794,10 +2794,10 @@ void LLVivoxVoiceClient::setRenderDevice(const std::string& name) if(mRenderDevice != name) { mRenderDevice = name; - mRenderDeviceDirty = true; + mRenderDeviceDirty = true; } } - + } void LLVivoxVoiceClient::tuningStart() @@ -2830,7 +2830,7 @@ bool LLVivoxVoiceClient::inTuningMode() } void LLVivoxVoiceClient::tuningRenderStartSendMessage(const std::string& name, bool loop) -{ +{ mTuningAudioFile = name; std::ostringstream stream; stream @@ -2838,7 +2838,7 @@ void LLVivoxVoiceClient::tuningRenderStartSendMessage(const std::string& name, b << "<SoundFilePath>" << mTuningAudioFile << "</SoundFilePath>" << "<Loop>" << (loop?"1":"0") << "</Loop>" << "</Request>\n\n\n"; - + writeString(stream.str()); } @@ -2849,33 +2849,33 @@ void LLVivoxVoiceClient::tuningRenderStopSendMessage() << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.RenderAudioStop.1\">" << "<SoundFilePath>" << mTuningAudioFile << "</SoundFilePath>" << "</Request>\n\n\n"; - + writeString(stream.str()); } void LLVivoxVoiceClient::tuningCaptureStartSendMessage(int loop) { LL_DEBUGS("Voice") << "sending CaptureAudioStart" << LL_ENDL; - + std::ostringstream stream; stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.CaptureAudioStart.1\">" << "<Duration>-1</Duration>" << "<LoopToRenderDevice>" << loop << "</LoopToRenderDevice>" << "</Request>\n\n\n"; - + writeString(stream.str()); } void LLVivoxVoiceClient::tuningCaptureStopSendMessage() { LL_DEBUGS("Voice") << "sending CaptureAudioStop" << LL_ENDL; - + std::ostringstream stream; stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.CaptureAudioStop.1\">" << "</Request>\n\n\n"; - + writeString(stream.str()); mTuningEnergy = 0.0f; @@ -2894,7 +2894,7 @@ void LLVivoxVoiceClient::tuningSetMicVolume(float volume) void LLVivoxVoiceClient::tuningSetSpeakerVolume(float volume) { - int scaled_volume = scale_speaker_volume(volume); + int scaled_volume = scale_speaker_volume(volume); if(scaled_volume != mTuningSpeakerVolume) { @@ -2902,7 +2902,7 @@ void LLVivoxVoiceClient::tuningSetSpeakerVolume(float volume) mTuningSpeakerVolumeDirty = true; } } - + float LLVivoxVoiceClient::tuningGetEnergy(void) { return mTuningEnergy; @@ -2911,13 +2911,13 @@ float LLVivoxVoiceClient::tuningGetEnergy(void) bool LLVivoxVoiceClient::deviceSettingsAvailable() { bool result = true; - + if(!sConnected) result = false; - + if(mRenderDevices.empty()) result = false; - + return result; } bool LLVivoxVoiceClient::deviceSettingsUpdated() @@ -2928,7 +2928,7 @@ bool LLVivoxVoiceClient::deviceSettingsUpdated() // a hot swap event or a polling of the audio devices has been parsed since the last redraw of the input and output device panel. mDevicesListUpdated = false; // toggle the setting } - return updated; + return updated; } void LLVivoxVoiceClient::refreshDeviceLists(bool clearCurrentList) @@ -2961,9 +2961,9 @@ void LLVivoxVoiceClient::giveUp() static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel) { F32 nat[3], nup[3], nl[3]; // the new at, up, left vectors and the new position and velocity -// F32 nvel[3]; +// F32 nvel[3]; F64 npos[3]; - + // The original XML command was sent like this: /* << "<Position>" @@ -3021,7 +3021,7 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe left.mV[i] = nl[i]; pos.mdV[i] = npos[i]; } - + // This was the original transform done in the SDK nat[0] = at.mV[2]; nat[1] = 0; // y component of at vector is always 0, this was up[2] @@ -3075,7 +3075,7 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe left.mV[i] = nl[i]; pos.mdV[i] = npos[i]; } - + #endif } @@ -3085,7 +3085,7 @@ void LLVivoxVoiceClient::setHidden(bool hidden) if (mHidden && inSpatialChannel()) { - // get out of the channel entirely + // get out of the channel entirely leaveAudioSession(); } else @@ -3095,20 +3095,20 @@ void LLVivoxVoiceClient::setHidden(bool hidden) } void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) -{ +{ std::ostringstream stream; - + if (mSpatialCoordsDirty && inSpatialChannel()) { LLVector3 l, u, a, vel; LLVector3d pos; mSpatialCoordsDirty = false; - + // Always send both speaker and listener positions together. - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Set3DPosition.1\">" + stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Set3DPosition.1\">" << "<SessionHandle>" << getAudioSessionHandle() << "</SessionHandle>"; - + stream << "<SpeakerPosition>"; LLMatrix3 avatarRot = mAvatarRot.getMatrix3(); @@ -3124,7 +3124,7 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) // SLIM SDK: the old SDK was doing a transform on the passed coordinates that the new one doesn't do anymore. // The old transform is replicated by this function. oldSDKTransform(l, u, a, pos, vel); - + if (mHidden) { for (int i=0;i<3;++i) @@ -3132,7 +3132,7 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) pos.mdV[i] = VX_NULL_POSITION; } } - + stream << "<Position>" << "<X>" << pos.mdV[VX] << "</X>" @@ -3160,7 +3160,7 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) << "<Z>" << l.mV [VZ] << "</Z>" << "</LeftOrientation>" ; - + stream << "</SpeakerPosition>"; stream << "<ListenerPosition>"; @@ -3168,7 +3168,7 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) LLVector3d earPosition; LLVector3 earVelocity; LLMatrix3 earRot; - + switch(mEarLocation) { case earLocCamera: @@ -3177,13 +3177,13 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) earVelocity = mCameraVelocity; earRot = mCameraRot; break; - + case earLocAvatar: earPosition = mAvatarPosition; earVelocity = mAvatarVelocity; earRot = avatarRot; break; - + case earLocMixed: earPosition = mAvatarPosition; earVelocity = mAvatarVelocity; @@ -3198,9 +3198,9 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) pos = earPosition; vel = earVelocity; - + oldSDKTransform(l, u, a, pos, vel); - + if (mHidden) { for (int i=0;i<3;++i) @@ -3208,7 +3208,7 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) pos.mdV[i] = VX_NULL_POSITION; } } - + stream << "<Position>" << "<X>" << pos.mdV[VX] << "</X>" @@ -3241,19 +3241,19 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) stream << "<ReqDispositionType>1</ReqDispositionType>"; //do not generate responses for update requests stream << "</Request>\n\n\n"; - } - + } + if(mAudioSession && (mAudioSession->mVolumeDirty || mAudioSession->mMuteDirty)) { participantMap::iterator iter = mAudioSession->mParticipantsByURI.begin(); mAudioSession->mVolumeDirty = false; mAudioSession->mMuteDirty = false; - + for(; iter != mAudioSession->mParticipantsByURI.end(); iter++) { participantStatePtr_t p(iter->second); - + if(p->mVolumeDirty) { // Can't set volume/mute for yourself @@ -3262,7 +3262,7 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) // scale from the range 0.0-1.0 to vivox volume in the range 0-100 S32 volume = ll_round(p->mVolume / VOLUME_SCALE_VIVOX); bool mute = p->mOnMuteList; - + if(mute) { // SetParticipantMuteForMe doesn't work in p2p sessions. @@ -3273,16 +3273,16 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) // changing it to 0, so that we can return to it when unmuting. p->mVolumeSet = true; } - + if(volume == 0) { mute = true; } LL_DEBUGS("Voice") << "Setting volume/mute for avatar " << p->mAvatarID << " to " << volume << (mute?"/true":"/false") << LL_ENDL; - + // SLIM SDK: Send both volume and mute commands. - + // Send a "volume for me" command for the user. stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.SetParticipantVolumeForMe.1\">" << "<SessionHandle>" << getAudioSessionHandle() << "</SessionHandle>" @@ -3302,7 +3302,7 @@ void LLVivoxVoiceClient::sendPositionAndVolumeUpdate(void) << "</Request>\n\n\n"; } } - + p->mVolumeDirty = false; } } @@ -3322,13 +3322,13 @@ void LLVivoxVoiceClient::buildSetCaptureDevice(std::ostringstream &stream) if(mCaptureDeviceDirty) { LL_DEBUGS("Voice") << "Setting input device = \"" << mCaptureDevice << "\"" << LL_ENDL; - - stream + + stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetCaptureDevice.1\">" << "<CaptureDeviceSpecifier>" << mCaptureDevice << "</CaptureDeviceSpecifier>" << "</Request>" << "\n\n\n"; - + mCaptureDeviceDirty = false; } } @@ -3420,7 +3420,7 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates() * Because of the recurring voice cutout issues (SL-15072) we are going to try * to disable the automatic VAD (Voice Activity Detection) and set the associated * parameters directly. We will expose them via Debug Settings and that should - * let us iterate on a collection of values that work for us. Hopefully! + * let us iterate on a collection of values that work for us. Hopefully! * * From the VIVOX Docs: * @@ -3430,16 +3430,16 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates() * for the VAD to switch back to silence from speech mode after the last speech * frame has been detected. * - * VadNoiseFloor: A dimensionless value between 0 and + * VadNoiseFloor: A dimensionless value between 0 and * 20000 (default 576) that controls the maximum level at which the noise floor * may be set at by the VAD's noise tracking. Too low of a value will make noise - * tracking ineffective (A value of 0 disables noise tracking and the VAD then - * relies purely on the sensitivity property). Too high of a value will make + * tracking ineffective (A value of 0 disables noise tracking and the VAD then + * relies purely on the sensitivity property). Too high of a value will make * long speech classifiable as noise. * - * VadSensitivity: A dimensionless value between 0 and + * VadSensitivity: A dimensionless value between 0 and * 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds - * to decreasing the sensitivity of the VAD (i.e. '0' is most sensitive, + * to decreasing the sensitivity of the VAD (i.e. '0' is most sensitive, * while 100 is 'least sensitive') */ void LLVivoxVoiceClient::setupVADParams(unsigned int vad_auto, @@ -3487,7 +3487,7 @@ void LLVivoxVoiceClient::onVADSettingsChange() // Response/Event handlers void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle, std::string &versionID) -{ +{ LLSD result = LLSD::emptyMap(); if(statusCode == 0) @@ -3521,7 +3521,7 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st // this is usually fatal, but a long timeout might work result["connector"] = LLSD::Boolean(false); result["retry"] = LLSD::Real(CONNECT_ATTEMPT_TIMEOUT); - + LL_WARNS("Voice") << "Voice connection failed" << LL_ENDL; } else if (statusCode == 10006) // name resolution failure - a shorter retry may work @@ -3529,7 +3529,7 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st // some networks have slower DNS, but a short timeout might let it catch up result["connector"] = LLSD::Boolean(false); result["retry"] = LLSD::Real(CONNECT_DNS_TIMEOUT); - + LL_WARNS("Voice") << "Voice connection DNS lookup failed" << LL_ENDL; } else // unknown failure - give up @@ -3543,13 +3543,13 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st } void LLVivoxVoiceClient::loginResponse(int statusCode, std::string &statusString, std::string &accountHandle, int numberOfAliases) -{ +{ LLSD result = LLSD::emptyMap(); LL_DEBUGS("Voice") << "Account.Login response (" << statusCode << "): " << statusString << LL_ENDL; - + // Status code of 20200 means "bad password". We may want to special-case that at some point. - + if ( statusCode == HTTP_UNAUTHORIZED ) { // Login failure which is probably caused by the delay after a user's password being updated. @@ -3574,20 +3574,20 @@ void LLVivoxVoiceClient::loginResponse(int statusCode, std::string &statusString } void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statusCode, std::string &statusString, std::string &sessionHandle) -{ +{ sessionStatePtr_t session(findSessionBeingCreatedByURI(requestId)); - + if(session) { session->mCreateInProgress = false; } - + if(statusCode != 0) { LL_WARNS("Voice") << "Session.Create response failure (" << statusCode << "): " << statusString << LL_ENDL; if(session) { - session->mErrorStatusCode = statusCode; + session->mErrorStatusCode = statusCode; session->mErrorStatusString = statusString; if(session == mAudioSession) { @@ -3618,20 +3618,20 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu } void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId, int statusCode, std::string &statusString, std::string &sessionHandle) -{ +{ sessionStatePtr_t session(findSessionBeingCreatedByURI(requestId)); - + if(session) { session->mCreateInProgress = false; } - + if(statusCode != 0) { LL_WARNS("Voice") << "SessionGroup.AddSession response failure (" << statusCode << "): " << statusString << LL_ENDL; if(session) { - session->mErrorStatusCode = statusCode; + session->mErrorStatusCode = statusCode; session->mErrorStatusString = statusString; if(session == mAudioSession) { @@ -3692,7 +3692,7 @@ void LLVivoxVoiceClient::sessionConnectResponse(std::string &requestId, int stat } void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusString) -{ +{ if(statusCode != 0) { LL_WARNS("Voice") << "Account.Logout response failure: " << statusString << LL_ENDL; @@ -3710,21 +3710,21 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string & LL_WARNS("Voice") << "Connector.InitiateShutdown response failure: " << statusString << LL_ENDL; // Should this ever fail? do we care if it does? } - + sConnected = false; mShutdownComplete = true; - + LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false))); mVivoxPump.post(vivoxevent); } void LLVivoxVoiceClient::sessionAddedEvent( - std::string &uriString, - std::string &alias, - std::string &sessionHandle, - std::string &sessionGroupHandle, - bool isChannel, + std::string &uriString, + std::string &alias, + std::string &sessionHandle, + std::string &sessionGroupHandle, + bool isChannel, bool incoming, std::string &nameString, std::string &applicationString) @@ -3732,7 +3732,7 @@ void LLVivoxVoiceClient::sessionAddedEvent( sessionStatePtr_t session; LL_INFOS("Voice") << "session " << uriString << ", alias " << alias << ", name " << nameString << " handle " << sessionHandle << LL_ENDL; - + session = addSession(uriString, sessionHandle); if(session) { @@ -3740,19 +3740,19 @@ void LLVivoxVoiceClient::sessionAddedEvent( session->mIsChannel = isChannel; session->mIncoming = incoming; session->mAlias = alias; - + // Generate a caller UUID -- don't need to do this for channels if(!session->mIsChannel) { if(IDFromName(session->mSIPURI, session->mCallerID)) { - // Normal URI(base64-encoded UUID) + // Normal URI(base64-encoded UUID) } else if(!session->mAlias.empty() && IDFromName(session->mAlias, session->mCallerID)) { // Wrong URI, but an alias is available. Stash the incoming URI as an alternate session->mAlternateSIPURI = session->mSIPURI; - + // and generate a proper URI from the ID. setSessionURI(session, sipURIFromID(session->mCallerID)); } @@ -3761,7 +3761,7 @@ void LLVivoxVoiceClient::sessionAddedEvent( LL_INFOS("Voice") << "Could not generate caller id from uri, using hash of uri " << session->mSIPURI << LL_ENDL; session->mCallerID.generate(session->mSIPURI); session->mSynthesizedCallerID = true; - + // Can't look up the name in this case -- we have to extract it from the URI. std::string namePortion = nameFromsipURI(session->mSIPURI); if(namePortion.empty()) @@ -3769,14 +3769,14 @@ void LLVivoxVoiceClient::sessionAddedEvent( // Didn't seem to be a SIP URI, just use the whole provided name. namePortion = nameString; } - + // Some incoming names may be separated with an underscore instead of a space. Fix this. LLStringUtil::replaceChar(namePortion, '_', ' '); - + // Act like we just finished resolving the name (this stores it in all the right places) avatarNameResolved(session->mCallerID, namePortion); } - + LL_INFOS("Voice") << "caller ID: " << session->mCallerID << LL_ENDL; if(!session->mSynthesizedCallerID) @@ -3791,7 +3791,7 @@ void LLVivoxVoiceClient::sessionAddedEvent( void LLVivoxVoiceClient::sessionGroupAddedEvent(std::string &sessionGroupHandle) { LL_DEBUGS("Voice") << "handle " << sessionGroupHandle << LL_ENDL; - + #if USE_SESSION_GROUPS if(mMainSessionGroupHandle.empty()) { @@ -3818,7 +3818,7 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session) // The old session may now need to be deleted. reapSession(oldSession); } - + // This is the session we're joining. if(mIsJoiningSession) { @@ -3834,10 +3834,10 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session) participant->mIsSelf = true; lookupName(participant->mAvatarID); - LL_INFOS("Voice") << "added self as participant \"" << participant->mAccountName + LL_INFOS("Voice") << "added self as participant \"" << participant->mAccountName << "\" (" << participant->mAvatarID << ")"<< LL_ENDL; } - + if(!session->mIsChannel) { // this is a p2p session. Make sure the other end is added as a participant. @@ -3853,9 +3853,9 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session) participant->mDisplayName = session->mName; avatarNameResolved(participant->mAvatarID, session->mName); } - + // TODO: Question: Do we need to set up mAvatarID/mAvatarIDValid here? - LL_INFOS("Voice") << "added caller as participant \"" << participant->mAccountName + LL_INFOS("Voice") << "added caller as participant \"" << participant->mAccountName << "\" (" << participant->mAvatarID << ")"<< LL_ENDL; } } @@ -3863,11 +3863,11 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session) } void LLVivoxVoiceClient::sessionRemovedEvent( - std::string &sessionHandle, + std::string &sessionHandle, std::string &sessionGroupHandle) { LL_INFOS("Voice") << "handle " << sessionHandle << LL_ENDL; - + sessionStatePtr_t session(findSession(sessionHandle)); if(session) { @@ -3875,15 +3875,15 @@ void LLVivoxVoiceClient::sessionRemovedEvent( // This message invalidates the session's handle. Set it to empty. clearSessionHandle(session); - + // This also means that the session's session group is now empty. // Terminate the session group so it doesn't leak. sessionGroupTerminateSendMessage(session); - + // Reset the media state (we now have no info) session->mMediaStreamState = streamStateUnknown; //session->mTextStreamState = streamStateUnknown; - + // Conditionally delete the session reapSession(session); } @@ -3899,7 +3899,7 @@ void LLVivoxVoiceClient::reapSession(const sessionStatePtr_t &session) { if(session) { - + if(session->mCreateInProgress) { LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (create in progress)" << LL_ENDL; @@ -3921,7 +3921,7 @@ void LLVivoxVoiceClient::reapSession(const sessionStatePtr_t &session) // We don't have a reason to keep tracking this session, so just delete it. LL_DEBUGS("Voice") << "deleting session " << session->mSIPURI << LL_ENDL; deleteSession(session); - } + } } else { @@ -3933,32 +3933,32 @@ void LLVivoxVoiceClient::reapSession(const sessionStatePtr_t &session) bool LLVivoxVoiceClient::sessionNeedsRelog(const sessionStatePtr_t &session) { bool result = false; - + if(session) { // Only make this check for spatial channels (so it won't happen for group or p2p calls) if(session->mIsSpatial) - { + { std::string::size_type atsign; - + atsign = session->mSIPURI.find("@"); - + if(atsign != std::string::npos) { std::string urihost = session->mSIPURI.substr(atsign + 1); if(stricmp(urihost.c_str(), mVoiceSIPURIHostName.c_str())) { // The hostname in this URI is different from what we expect. This probably means we need to relog. - + // We could make a ProvisionVoiceAccountRequest and compare the result with the current values of // mVoiceSIPURIHostName and mVoiceAccountServerURI to be really sure, but this is a pretty good indicator. - + result = true; } } } } - + return result; } @@ -3974,9 +3974,9 @@ void LLVivoxVoiceClient::leftAudioSession(const sessionStatePtr_t &session) } void LLVivoxVoiceClient::accountLoginStateChangeEvent( - std::string &accountHandle, - int statusCode, - std::string &statusString, + std::string &accountHandle, + int statusCode, + std::string &statusString, int state) { LLSD levent = LLSD::emptyMap(); @@ -3988,9 +3988,9 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent( login_state_logging_in = 2, login_state_logging_out = 3, login_state_resetting = 4, - login_state_error=100 + login_state_error=100 */ - + LL_DEBUGS("Voice") << "state change event: " << state << LL_ENDL; switch(state) { @@ -4020,7 +4020,7 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent( mVivoxPump.post(levent); break; - + default: //Used to be a commented out warning LL_WARNS("Voice") << "unknown account state event: " << state << LL_ENDL; @@ -4057,24 +4057,24 @@ void LLVivoxVoiceClient::mediaCompletionEvent(std::string &sessionGroupHandle, s } void LLVivoxVoiceClient::mediaStreamUpdatedEvent( - std::string &sessionHandle, - std::string &sessionGroupHandle, - int statusCode, - std::string &statusString, - int state, + std::string &sessionHandle, + std::string &sessionGroupHandle, + int statusCode, + std::string &statusString, + int state, bool incoming) { sessionStatePtr_t session(findSession(sessionHandle)); - + LL_DEBUGS("Voice") << "session " << sessionHandle << ", status code " << statusCode << ", string \"" << statusString << "\"" << LL_ENDL; - + if(session) { // We know about this session - + // Save the state for later use session->mMediaStreamState = state; - + switch(statusCode) { case 0: @@ -4102,9 +4102,9 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent( session->mVoiceActive = true; session->mMediaConnectInProgress = false; joinedAudioSession(session); - case streamStateConnecting: // do nothing, but prevents a warning getting into the logs. + case streamStateConnecting: // do nothing, but prevents a warning getting into the logs. break; - + case streamStateRinging: if(incoming) { @@ -4123,13 +4123,13 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent( } } break; - + default: LL_WARNS("Voice") << "unknown state " << state << LL_ENDL; break; - + } - + } else { @@ -4139,12 +4139,12 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent( } void LLVivoxVoiceClient::participantAddedEvent( - std::string &sessionHandle, - std::string &sessionGroupHandle, - std::string &uriString, - std::string &alias, - std::string &nameString, - std::string &displayNameString, + std::string &sessionHandle, + std::string &sessionGroupHandle, + std::string &uriString, + std::string &alias, + std::string &nameString, + std::string &displayNameString, int participantType) { sessionStatePtr_t session(findSession(sessionHandle)); @@ -4155,7 +4155,7 @@ void LLVivoxVoiceClient::participantAddedEvent( { participant->mAccountName = nameString; - LL_DEBUGS("Voice") << "added participant \"" << participant->mAccountName + LL_DEBUGS("Voice") << "added participant \"" << participant->mAccountName << "\" (" << participant->mAvatarID << ")"<< LL_ENDL; if(participant->mAvatarIDValid) @@ -4177,7 +4177,7 @@ void LLVivoxVoiceClient::participantAddedEvent( // Problems with both of the above, fall back to the account name namePortion = nameString; } - + // Set the display name (which is a hint to the active speakers window not to do its own lookup) participant->mDisplayName = namePortion; avatarNameResolved(participant->mAvatarID, namePortion); @@ -4187,10 +4187,10 @@ void LLVivoxVoiceClient::participantAddedEvent( } void LLVivoxVoiceClient::participantRemovedEvent( - std::string &sessionHandle, - std::string &sessionGroupHandle, - std::string &uriString, - std::string &alias, + std::string &sessionHandle, + std::string &sessionGroupHandle, + std::string &uriString, + std::string &alias, std::string &nameString) { sessionStatePtr_t session(findSession(sessionHandle)); @@ -4215,20 +4215,20 @@ void LLVivoxVoiceClient::participantRemovedEvent( void LLVivoxVoiceClient::participantUpdatedEvent( - std::string &sessionHandle, - std::string &sessionGroupHandle, - std::string &uriString, - std::string &alias, - bool isModeratorMuted, - bool isSpeaking, - int volume, + std::string &sessionHandle, + std::string &sessionGroupHandle, + std::string &uriString, + std::string &alias, + bool isModeratorMuted, + bool isSpeaking, + int volume, F32 energy) { sessionStatePtr_t session(findSession(sessionHandle)); if(session) { participantStatePtr_t participant(session->findParticipant(uriString)); - + if(participant) { //LL_INFOS("Voice") << "Participant Update for " << participant->mDisplayName << LL_ENDL; @@ -4253,25 +4253,25 @@ void LLVivoxVoiceClient::participantUpdatedEvent( { participant->mVolume = (F32)volume * VOLUME_SCALE_VIVOX; } - - // *HACK: mantipov: added while working on EXT-3544 - /* - Sometimes LLVoiceClient::participantUpdatedEvent callback is called BEFORE - LLViewerChatterBoxSessionAgentListUpdates::post() sometimes AFTER. - - participantUpdatedEvent updates voice participant state in particular participantState::mIsModeratorMuted - Originally we wanted to update session Speaker Manager to fire LLSpeakerVoiceModerationEvent to fix the EXT-3544 bug. - Calling of the LLSpeakerMgr::update() method was added into LLIMMgr::processAgentListUpdates. - - But in case participantUpdatedEvent() is called after LLViewerChatterBoxSessionAgentListUpdates::post() - voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager - and event is not fired. - - So, we have to call LLSpeakerMgr::update() here. + + // *HACK: mantipov: added while working on EXT-3544 + /* + Sometimes LLVoiceClient::participantUpdatedEvent callback is called BEFORE + LLViewerChatterBoxSessionAgentListUpdates::post() sometimes AFTER. + + participantUpdatedEvent updates voice participant state in particular participantState::mIsModeratorMuted + Originally we wanted to update session Speaker Manager to fire LLSpeakerVoiceModerationEvent to fix the EXT-3544 bug. + Calling of the LLSpeakerMgr::update() method was added into LLIMMgr::processAgentListUpdates. + + But in case participantUpdatedEvent() is called after LLViewerChatterBoxSessionAgentListUpdates::post() + voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager + and event is not fired. + + So, we have to call LLSpeakerMgr::update() here. */ LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel(); - - // ignore session ID of local chat + + // ignore session ID of local chat if (voice_cnl && voice_cnl->getSessionID().notNull()) { LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(voice_cnl->getSessionID()); @@ -4300,10 +4300,10 @@ void LLVivoxVoiceClient::participantUpdatedEvent( } void LLVivoxVoiceClient::messageEvent( - std::string &sessionHandle, - std::string &uriString, - std::string &alias, - std::string &messageHeader, + std::string &sessionHandle, + std::string &uriString, + std::string &alias, + std::string &messageHeader, std::string &messageBody, std::string &applicationString) { @@ -4324,7 +4324,7 @@ void LLVivoxVoiceClient::messageEvent( const std::string endSpan = "</span>"; std::string::size_type start; std::string::size_type end; - + // Default to displaying the raw string, so the message gets through. message = messageBody; @@ -4336,38 +4336,38 @@ void LLVivoxVoiceClient::messageEvent( if(start != std::string::npos) { start += startMarker2.size(); - + if(end != std::string::npos) end -= start; - + message.assign(messageBody, start, end); } - else + else { // Didn't find a <body>, try looking for a <span> instead. start = messageBody.find(startSpan); start = messageBody.find(startMarker2, start); end = messageBody.find(endSpan); - + if(start != std::string::npos) { start += startMarker2.size(); - + if(end != std::string::npos) end -= start; - + message.assign(messageBody, start, end); - } + } } - } - + } + // LL_DEBUGS("Voice") << " raw message = \n" << message << LL_ENDL; // strip formatting tags { std::string::size_type start; std::string::size_type end; - + while((start = message.find('<')) != std::string::npos) { if((end = message.find('>', start + 1)) != std::string::npos) @@ -4382,7 +4382,7 @@ void LLVivoxVoiceClient::messageEvent( } } } - + // Decode ampersand-escaped chars { std::string::size_type mark = 0; @@ -4394,14 +4394,14 @@ void LLVivoxVoiceClient::messageEvent( message.replace(mark, 4, "<"); mark += 1; } - + mark = 0; while((mark = message.find(">", mark)) != std::string::npos) { message.replace(mark, 4, ">"); mark += 1; } - + mark = 0; while((mark = message.find("&", mark)) != std::string::npos) { @@ -4409,12 +4409,12 @@ void LLVivoxVoiceClient::messageEvent( mark += 1; } } - + // strip leading/trailing whitespace (since we always seem to get a couple newlines) LLStringUtil::trim(message); - + // LL_DEBUGS("Voice") << " stripped message = \n" << message << LL_ENDL; - + sessionStatePtr_t session(findSession(sessionHandle)); if(session) { @@ -4424,7 +4424,7 @@ void LLVivoxVoiceClient::messageEvent( LLChat chat; chat.mMuted = is_muted && !is_linden; - + if(!chat.mMuted) { chat.mFromID = session->mCallerID; @@ -4435,7 +4435,7 @@ void LLVivoxVoiceClient::messageEvent( { // TODO: Question: Return do not disturb mode response here? Or maybe when session is started instead? } - + LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL; LLIMMgr::getInstance()->addMessage(session->mIMSessionID, session->mCallerID, @@ -4448,14 +4448,14 @@ void LLVivoxVoiceClient::messageEvent( LLUUID::null, // default arg LLVector3::zero); // default arg } - } + } } } void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string ¬ificationType) { sessionStatePtr_t session(findSession(sessionHandle)); - + if(session) { participantStatePtr_t participant(session->findParticipant(uriString)); @@ -4518,11 +4518,11 @@ void LLVivoxVoiceClient::muteListChanged() if(mAudioSession) { participantMap::iterator iter = mAudioSession->mParticipantsByURI.begin(); - + for(; iter != mAudioSession->mParticipantsByURI.end(); iter++) { participantStatePtr_t p(iter->second); - + // Check to see if this participant is on the mute list already if(p->updateMuteState()) mAudioSession->mVolumeDirty = true; @@ -4532,18 +4532,18 @@ void LLVivoxVoiceClient::muteListChanged() ///////////////////////////// // Managing list of participants -LLVivoxVoiceClient::participantState::participantState(const std::string &uri) : - mURI(uri), - mPTT(false), - mIsSpeaking(false), - mIsModeratorMuted(false), - mLastSpokeTimestamp(0.f), - mPower(0.f), - mVolume(LLVoiceClient::VOLUME_DEFAULT), +LLVivoxVoiceClient::participantState::participantState(const std::string &uri) : + mURI(uri), + mPTT(false), + mIsSpeaking(false), + mIsModeratorMuted(false), + mLastSpokeTimestamp(0.f), + mPower(0.f), + mVolume(LLVoiceClient::VOLUME_DEFAULT), mUserVolume(0), - mOnMuteList(false), + mOnMuteList(false), mVolumeSet(false), - mVolumeDirty(false), + mVolumeDirty(false), mAvatarIDValid(false), mIsSelf(false) { @@ -4553,7 +4553,7 @@ LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::sessionState::addP { participantStatePtr_t result; bool useAlternateURI = false; - + // Note: this is mostly the body of LLVivoxVoiceClient::sessionState::findParticipant(), but since we need to know if it // matched the alternate SIP URI (so we can add it properly), we need to reproduce it here. { @@ -4575,14 +4575,14 @@ LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::sessionState::addP result = iter->second; } } - + if(!result) { // participant isn't already in one list or the other. result.reset(new participantState(useAlternateURI?mSIPURI:uri)); mParticipantsByURI.insert(participantMap::value_type(result->mURI, result)); mParticipantsChanged = true; - + // Try to do a reverse transform on the URI to get the GUID back. { LLUUID id; @@ -4598,12 +4598,12 @@ LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::sessionState::addP result->mAvatarID.generate(uri); } } - + if(result->updateMuteState()) { mMuteDirty = true; } - + mParticipantsByUUID.insert(participantUUIDMap::value_type(result->mAvatarID, result)); if (LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID, result->mVolume)) @@ -4611,10 +4611,10 @@ LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::sessionState::addP result->mVolumeDirty = true; mVolumeDirty = true; } - + LL_DEBUGS("Voice") << "participant \"" << result->mURI << "\" added." << LL_ENDL; } - + return result; } @@ -4643,9 +4643,9 @@ void LLVivoxVoiceClient::sessionState::removeParticipant(const LLVivoxVoiceClien { participantMap::iterator iter = mParticipantsByURI.find(participant->mURI); participantUUIDMap::iterator iter2 = mParticipantsByUUID.find(participant->mAvatarID); - + LL_DEBUGS("Voice") << "participant \"" << participant->mURI << "\" (" << participant->mAvatarID << ") removed." << LL_ENDL; - + if(iter == mParticipantsByURI.end()) { LL_WARNS("Voice") << "Internal error: participant " << participant->mURI << " not in URI map" << LL_ENDL; @@ -4676,7 +4676,7 @@ void LLVivoxVoiceClient::sessionState::removeAllParticipants() { removeParticipant(mParticipantsByURI.begin()->second); } - + if(!mParticipantsByUUID.empty()) { LL_WARNS("Voice") << "Internal error: empty URI map, non-empty UUID map" << LL_ENDL; @@ -4702,10 +4702,10 @@ void LLVivoxVoiceClient::sessionState::VerifySessions() void LLVivoxVoiceClient::getParticipantList(std::set<LLUUID> &participants) { - if(mAudioSession) + if(mProcessChannels && mAudioSession) { for(participantUUIDMap::iterator iter = mAudioSession->mParticipantsByUUID.begin(); - iter != mAudioSession->mParticipantsByUUID.end(); + iter != mAudioSession->mParticipantsByUUID.end(); iter++) { participants.insert(iter->first); @@ -4715,18 +4715,18 @@ void LLVivoxVoiceClient::getParticipantList(std::set<LLUUID> &participants) bool LLVivoxVoiceClient::isParticipant(const LLUUID &speaker_id) { - if(mAudioSession) + if(mProcessChannels && mAudioSession) { - return (mAudioSession->mParticipantsByUUID.find(speaker_id) != mAudioSession->mParticipantsByUUID.end()); + return (mAudioSession->mParticipantsByUUID.find(speaker_id) != mAudioSession->mParticipantsByUUID.end()); } - return false; + return false; } LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::sessionState::findParticipant(const std::string &uri) { participantStatePtr_t result; - + participantMap::iterator iter = mParticipantsByURI.find(uri); if(iter == mParticipantsByURI.end()) @@ -4743,7 +4743,7 @@ LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::sessionState::find { result = iter->second; } - + return result; } @@ -4763,12 +4763,12 @@ LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::sessionState::find LLVivoxVoiceClient::participantStatePtr_t LLVivoxVoiceClient::findParticipantByID(const LLUUID& id) { participantStatePtr_t result; - + if(mAudioSession) { result = mAudioSession->findParticipantByID(id); } - + return result; } @@ -4779,15 +4779,15 @@ bool LLVivoxVoiceClient::checkParcelChanged(bool update) { LLViewerRegion *region = gAgent.getRegion(); LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - + if(region && parcel) { S32 parcelLocalID = parcel->getLocalID(); std::string regionName = region->getName(); - + // LL_DEBUGS("Voice") << "Region name = \"" << regionName << "\", parcel local ID = " << parcelLocalID << ", cap URI = \"" << capURI << "\"" << LL_ENDL; - - // The region name starts out empty and gets filled in later. + + // The region name starts out empty and gets filled in later. // Also, the cap gets filled in a short time after the region cross, but a little too late for our purposes. // If either is empty, wait for the next time around. if(!regionName.empty()) @@ -4815,7 +4815,7 @@ bool LLVivoxVoiceClient::switchChannel( std::string hash) { bool needsSwitch = !mIsInChannel; - + if (mIsInChannel) { if (mSessionTerminateRequested) @@ -4892,7 +4892,7 @@ bool LLVivoxVoiceClient::switchChannel( mNextAudioSession->mReconnect = !no_reconnect; mNextAudioSession->mIsP2P = is_p2p; } - + if (mIsInChannel) { // If we're already in a channel, or if we're joining one, terminate @@ -4928,7 +4928,7 @@ bool LLVivoxVoiceClient::setSpatialChannel(const LLSD& channelInfo) mSpatialSessionCredentials = channelInfo["channel_credentials"].asString(); LL_DEBUGS("Voice") << "got spatial channel uri: \"" << mSpatialSessionURI << "\"" << LL_ENDL; - + if((mIsInChannel && mAudioSession && !(mAudioSession->mIsSpatial)) || (mNextAudioSession && !(mNextAudioSession->mIsSpatial))) { // User is in a non-spatial chat or joining a non-spatial chat. Don't switch channels. @@ -4997,9 +4997,9 @@ bool LLVivoxVoiceClient::isVoiceWorking() const // Currently this will be false only for PSTN callers into group chats, and PSTN p2p calls. BOOL LLVivoxVoiceClient::isParticipantAvatar(const LLUUID &id) { - BOOL result = TRUE; + BOOL result = TRUE; sessionStatePtr_t session(findSession(id)); - + if(session) { // this is a p2p session with the indicated caller, or the session with the specified UUID. @@ -5018,22 +5018,22 @@ BOOL LLVivoxVoiceClient::isParticipantAvatar(const LLUUID &id) } } } - + return result; } // Returns true if calling back the session URI after the session has closed is possible. -// Currently this will be false only for PSTN P2P calls. +// Currently this will be false only for PSTN P2P calls. BOOL LLVivoxVoiceClient::isSessionCallBackPossible(const LLUUID &session_id) { - BOOL result = TRUE; + BOOL result = TRUE; sessionStatePtr_t session(findSession(session_id)); - + if(session != NULL) { result = session->isCallBackPossible(); } - + return result; } @@ -5043,12 +5043,12 @@ BOOL LLVivoxVoiceClient::isSessionTextIMPossible(const LLUUID &session_id) { bool result = TRUE; sessionStatePtr_t session(findSession(session_id)); - + if(session != NULL) { result = session->isTextIMPossible(); } - + return result; } @@ -5056,15 +5056,15 @@ void LLVivoxVoiceClient::leaveNonSpatialChannel() { LL_DEBUGS("Voice") << "Request to leave spacial channel." << LL_ENDL; - // Make sure we don't rejoin the current session. + // Make sure we don't rejoin the current session. sessionStatePtr_t oldNextSession(mNextAudioSession); mNextAudioSession.reset(); - + // Most likely this will still be the current session at this point, but check it anyway. reapSession(oldNextSession); - + verifySessionState(); - + sessionTerminate(); } @@ -5075,8 +5075,10 @@ void LLVivoxVoiceClient::processChannels(bool process) bool LLVivoxVoiceClient::isCurrentChannel(const LLSD &channelInfo) { - if (channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE) + if (!mProcessChannels || (channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE)) + { return false; + } if (mAudioSession) { if (!channelInfo["sessionHandle"].asString().empty()) @@ -5098,12 +5100,12 @@ bool LLVivoxVoiceClient::compareChannels(const LLSD& channelInfo1, const LLSD& c bool LLVivoxVoiceClient::inProximalChannel() { bool result = false; - + if (mIsInChannel && !mSessionTerminateRequested) { result = inSpatialChannel(); } - + return result; } @@ -5114,7 +5116,7 @@ std::string LLVivoxVoiceClient::sipURIFromID(const LLUUID &id) result += nameFromID(id); result += "@"; result += mVoiceSIPURIHostName; - + return result; } @@ -5128,14 +5130,14 @@ std::string LLVivoxVoiceClient::sipURIFromAvatar(LLVOAvatar *avatar) result += "@"; result += mVoiceSIPURIHostName; } - + return result; } std::string LLVivoxVoiceClient::nameFromID(const LLUUID &uuid) { std::string result; - + if (uuid.isNull()) { //VIVOX, the uuid emtpy look for the mURIString and return that instead. //result.assign(uuid.mURIStringName); @@ -5144,31 +5146,31 @@ std::string LLVivoxVoiceClient::nameFromID(const LLUUID &uuid) } // Prepending this apparently prevents conflicts with reserved names inside the vivox code. result = "x"; - - // Base64 encode and replace the pieces of base64 that are less compatible + + // Base64 encode and replace the pieces of base64 that are less compatible // with e-mail local-parts. // See RFC-4648 "Base 64 Encoding with URL and Filename Safe Alphabet" result += LLBase64::encode(uuid.mData, UUID_BYTES); LLStringUtil::replaceChar(result, '+', '-'); LLStringUtil::replaceChar(result, '/', '_'); - + // If you need to transform a GUID to this form on the Mac OS X command line, this will do so: // echo -n x && (echo e669132a-6c43-4ee1-a78d-6c82fff59f32 |xxd -r -p |openssl base64|tr '/+' '_-') - + // The reverse transform can be done with: // echo 'x5mkTKmxDTuGnjWyC__WfMg==' |cut -b 2- -|tr '_-' '/+' |openssl base64 -d|xxd -p - + return result; } bool LLVivoxVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) { bool result = false; - + // SLIM SDK: The "name" may actually be a SIP URI such as: "sip:xFnPP04IpREWNkuw1cOXlhw==@bhr.vivox.com" // If it is, convert to a bare name before doing the transform. std::string name = nameFromsipURI(inName); - + // Doesn't look like a SIP URI, assume it's an actual name. if(name.empty()) name = inName; @@ -5176,7 +5178,7 @@ bool LLVivoxVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) // This will only work if the name is of the proper form. // As an example, the account name for Monroe Linden (UUID 1673cfd3-8229-4445-8d92-ec3570e5e587) is: // "xFnPP04IpREWNkuw1cOXlhw==" - + if((name.size() == 25) && (name[0] == 'x') && (name[23] == '=') && (name[24] == '=')) { // The name appears to have the right form. @@ -5186,7 +5188,7 @@ bool LLVivoxVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) LLStringUtil::replaceChar(temp, '-', '+'); LLStringUtil::replaceChar(temp, '_', '/'); - U8 rawuuid[UUID_BYTES + 1]; + U8 rawuuid[UUID_BYTES + 1]; int len = apr_base64_decode_binary(rawuuid, temp.c_str() + 1); if(len == UUID_BYTES) { @@ -5194,15 +5196,15 @@ bool LLVivoxVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) memcpy(uuid.mData, rawuuid, UUID_BYTES); result = true; } - } - + } + if(!result) { // VIVOX: not a standard account name, just copy the URI name mURIString field // and hope for the best. bpj uuid.setNull(); // VIVOX, set the uuid field to nulls } - + return result; } @@ -5230,19 +5232,19 @@ std::string LLVivoxVoiceClient::nameFromsipURI(const std::string &uri) { result = uri.substr(sipOffset + 4, atOffset - (sipOffset + 4)); } - + return result; } bool LLVivoxVoiceClient::inSpatialChannel(void) { bool result = false; - + if(mAudioSession) { result = mAudioSession->mIsSpatial; } - + return result; } @@ -5250,22 +5252,22 @@ bool LLVivoxVoiceClient::inSpatialChannel(void) LLSD LLVivoxVoiceClient::getAudioSessionChannelInfo() { LLSD result; - + if (mAudioSession) { result = mAudioSession->getVoiceChannelInfo(); } - + return result; } std::string LLVivoxVoiceClient::getAudioSessionHandle() { std::string result; - + if(mAudioSession) result = mAudioSession->mHandle; - + return result; } @@ -5284,11 +5286,11 @@ void LLVivoxVoiceClient::enforceTether(void) F32 camera_distance = (F32)camera_offset.magVec(); if(camera_distance > max_dist) { - tethered = mAvatarPosition + + tethered = mAvatarPosition + (max_dist / camera_distance) * camera_offset; } } - + if(dist_vec_squared(mCameraPosition, tethered) > 0.01) { mCameraPosition = tethered; @@ -5305,19 +5307,19 @@ void LLVivoxVoiceClient::updatePosition(void) LLMatrix3 rot; LLVector3d pos; LLQuaternion qrot; - + // TODO: If camera and avatar velocity are actually used by the voice system, we could compute them here... // They're currently always set to zero. - + // Send the current camera position to the voice code - rot.setRows(LLViewerCamera::getInstance()->getAtAxis(), LLViewerCamera::getInstance()->getLeftAxis (), LLViewerCamera::getInstance()->getUpAxis()); + rot.setRows(LLViewerCamera::getInstance()->getAtAxis(), LLViewerCamera::getInstance()->getLeftAxis (), LLViewerCamera::getInstance()->getUpAxis()); pos = gAgent.getRegion()->getPosGlobalFromRegion(LLViewerCamera::getInstance()->getOrigin()); - + LLVivoxVoiceClient::getInstance()->setCameraPosition( pos, // position LLVector3::zero, // velocity rot); // rotation matrix - + // Send the current avatar position to the voice code qrot = gAgentAvatarp->getRootJoint()->getWorldRotation(); pos = gAgentAvatarp->getPositionGlobal(); @@ -5325,7 +5327,7 @@ void LLVivoxVoiceClient::updatePosition(void) // TODO: Can we get the head offset from outside the LLVOAvatar? // pos += LLVector3d(mHeadOffset); pos += LLVector3d(0.f, 0.f, 1.f); - + LLVivoxVoiceClient::getInstance()->setAvatarPosition( pos, // position LLVector3::zero, // velocity @@ -5336,13 +5338,13 @@ void LLVivoxVoiceClient::updatePosition(void) void LLVivoxVoiceClient::setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot) { mCameraRequestedPosition = position; - + if(mCameraVelocity != velocity) { mCameraVelocity = velocity; mSpatialCoordsDirty = true; } - + if(mCameraRot != rot) { mCameraRot = rot; @@ -5357,19 +5359,19 @@ void LLVivoxVoiceClient::setAvatarPosition(const LLVector3d &position, const LLV mAvatarPosition = position; mSpatialCoordsDirty = true; } - + if(mAvatarVelocity != velocity) { mAvatarVelocity = velocity; mSpatialCoordsDirty = true; } - + // If the two rotations are not exactly equal test their dot product // to get the cos of the angle between them. // If it is too small, don't update. F32 rot_cos_diff = llabs(dot(mAvatarRot, rot)); if ((mAvatarRot != rot) && (rot_cos_diff < MINUSCULE_ANGLE_COS)) - { + { mAvatarRot = rot; mSpatialCoordsDirty = true; } @@ -5378,15 +5380,15 @@ void LLVivoxVoiceClient::setAvatarPosition(const LLVector3d &position, const LLV bool LLVivoxVoiceClient::channelFromRegion(LLViewerRegion *region, std::string &name) { bool result = false; - + if(region) { name = region->getName(); } - + if(!name.empty()) result = true; - + return result; } @@ -5416,14 +5418,14 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled) << " was "<< (mVoiceEnabled ? "enabled" : "disabled") << " coro "<< (mIsCoroutineActive ? "active" : "inactive") << LL_ENDL; - + if (enabled != mVoiceEnabled) { // TODO: Refactor this so we don't call into LLVoiceChannel, but simply // use the status observer mVoiceEnabled = enabled; LLVoiceClientStatusObserver::EStatusType status; - + if (enabled) { LL_DEBUGS("Voice") << "enabling" << LL_ENDL; @@ -5462,7 +5464,7 @@ void LLVivoxVoiceClient::setEarLocation(S32 loc) if(mEarLocation != loc) { LL_DEBUGS("Voice") << "Setting mEarLocation to " << loc << LL_ENDL; - + mEarLocation = loc; mSpatialCoordsDirty = true; } @@ -5470,7 +5472,7 @@ void LLVivoxVoiceClient::setEarLocation(S32 loc) void LLVivoxVoiceClient::setVoiceVolume(F32 volume) { - int scaled_volume = scale_speaker_volume(volume); + int scaled_volume = scale_speaker_volume(volume); if(scaled_volume != mSpeakerVolume) { @@ -5488,7 +5490,7 @@ void LLVivoxVoiceClient::setVoiceVolume(F32 volume) void LLVivoxVoiceClient::setMicGain(F32 volume) { int scaled_volume = scale_mic_volume(volume); - + if(scaled_volume != mMicVolume) { mMicVolume = scaled_volume; @@ -5498,29 +5500,19 @@ void LLVivoxVoiceClient::setMicGain(F32 volume) ///////////////////////////// // Accessors for data related to nearby speakers -BOOL LLVivoxVoiceClient::getVoiceEnabled(const LLUUID& id) -{ - BOOL result = FALSE; - participantStatePtr_t participant(findParticipantByID(id)); - if(participant) - { - // I'm not sure what the semantics of this should be. - // For now, if we have any data about the user that came through the chat channel, assume they're voice-enabled. - result = TRUE; - } - - return result; -} std::string LLVivoxVoiceClient::getDisplayName(const LLUUID& id) { std::string result; - participantStatePtr_t participant(findParticipantByID(id)); - if(participant) - { - result = participant->mDisplayName; - } - + if (mProcessChannels) + { + participantStatePtr_t participant(findParticipantByID(id)); + if (participant) + { + result = participant->mDisplayName; + } + } + return result; } @@ -5529,42 +5521,47 @@ std::string LLVivoxVoiceClient::getDisplayName(const LLUUID& id) BOOL LLVivoxVoiceClient::getIsSpeaking(const LLUUID& id) { BOOL result = FALSE; + if (mProcessChannels) + { + participantStatePtr_t participant(findParticipantByID(id)); + if (participant) + { + if (participant->mSpeakingTimeout.getElapsedTimeF32() > SPEAKING_TIMEOUT) + { + participant->mIsSpeaking = FALSE; + } + result = participant->mIsSpeaking; + } + } - participantStatePtr_t participant(findParticipantByID(id)); - if(participant) - { - if (participant->mSpeakingTimeout.getElapsedTimeF32() > SPEAKING_TIMEOUT) - { - participant->mIsSpeaking = FALSE; - } - result = participant->mIsSpeaking; - } - return result; } BOOL LLVivoxVoiceClient::getIsModeratorMuted(const LLUUID& id) { BOOL result = FALSE; - + if (!mProcessChannels) + { + return FALSE; + } participantStatePtr_t participant(findParticipantByID(id)); if(participant) { result = participant->mIsModeratorMuted; } - + return result; } F32 LLVivoxVoiceClient::getCurrentPower(const LLUUID& id) -{ +{ F32 result = 0; participantStatePtr_t participant(findParticipantByID(id)); if(participant) { result = participant->mPower; } - + return result; } @@ -5581,19 +5578,6 @@ BOOL LLVivoxVoiceClient::getUsingPTT(const LLUUID& id) // Does "using PTT" mean they're configured with a push-to-talk button? // For now, we know there's no PTT mechanism in place, so nobody is using it. } - - return result; -} - -BOOL LLVivoxVoiceClient::getOnMuteList(const LLUUID& id) -{ - BOOL result = FALSE; - - participantStatePtr_t participant(findParticipantByID(id)); - if(participant) - { - result = participant->mOnMuteList; - } return result; } @@ -5603,7 +5587,7 @@ F32 LLVivoxVoiceClient::getUserVolume(const LLUUID& id) { // Minimum volume will be returned for users with voice disabled F32 result = LLVoiceClient::VOLUME_MIN; - + participantStatePtr_t participant(findParticipantByID(id)); if(participant) { @@ -5651,21 +5635,21 @@ std::string LLVivoxVoiceClient::getGroupID(const LLUUID& id) { result = participant->mGroupID; } - + return result; } void LLVivoxVoiceClient::recordingLoopStart(int seconds, int deltaFramesPerControlFrame) { // LL_DEBUGS("Voice") << "sending SessionGroup.ControlRecording (Start)" << LL_ENDL; - + if(!mMainSessionGroupHandle.empty()) { std::ostringstream stream; stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlRecording.1\">" << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" - << "<RecordingControlType>Start</RecordingControlType>" + << "<RecordingControlType>Start</RecordingControlType>" << "<DeltaFramesPerControlFrame>" << deltaFramesPerControlFrame << "</DeltaFramesPerControlFrame>" << "<Filename>" << "" << "</Filename>" << "<EnableAudioRecordingEvents>false</EnableAudioRecordingEvents>" @@ -5687,7 +5671,7 @@ void LLVivoxVoiceClient::recordingLoopSave(const std::string& filename) stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlRecording.1\">" << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" - << "<RecordingControlType>Flush</RecordingControlType>" + << "<RecordingControlType>Flush</RecordingControlType>" << "<Filename>" << filename << "</Filename>" << "</Request>\n\n\n"; @@ -5705,7 +5689,7 @@ void LLVivoxVoiceClient::recordingStop() stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlRecording.1\">" << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" - << "<RecordingControlType>Stop</RecordingControlType>" + << "<RecordingControlType>Stop</RecordingControlType>" << "</Request>\n\n\n"; writeString(stream.str()); @@ -5722,7 +5706,7 @@ void LLVivoxVoiceClient::filePlaybackStart(const std::string& filename) stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlPlayback.1\">" << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" - << "<RecordingControlType>Start</RecordingControlType>" + << "<RecordingControlType>Start</RecordingControlType>" << "<Filename>" << filename << "</Filename>" << "</Request>\n\n\n"; @@ -5740,7 +5724,7 @@ void LLVivoxVoiceClient::filePlaybackStop() stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlPlayback.1\">" << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" - << "<RecordingControlType>Stop</RecordingControlType>" + << "<RecordingControlType>Stop</RecordingControlType>" << "</Request>\n\n\n"; writeString(stream.str()); @@ -5830,7 +5814,7 @@ bool LLVivoxVoiceClient::sessionState::isTextIMPossible() } -/*static*/ +/*static*/ LLVivoxVoiceClient::sessionState::ptr_t LLVivoxVoiceClient::sessionState::matchSessionByHandle(const std::string &handle) { sessionStatePtr_t result; @@ -5844,7 +5828,7 @@ LLVivoxVoiceClient::sessionState::ptr_t LLVivoxVoiceClient::sessionState::matchS return result; } -/*static*/ +/*static*/ LLVivoxVoiceClient::sessionState::ptr_t LLVivoxVoiceClient::sessionState::matchCreatingSessionByURI(const std::string &uri) { sessionStatePtr_t result; @@ -5891,7 +5875,7 @@ void LLVivoxVoiceClient::sessionState::for_each(sessionFunc_t func) std::for_each(mSession.begin(), mSession.end(), boost::bind(for_eachPredicate, _1, func)); } -// simple test predicates. +// simple test predicates. // *TODO: These should be made into lambdas when we can pull the trigger on newer C++ features. bool LLVivoxVoiceClient::sessionState::testByHandle(const LLVivoxVoiceClient::sessionState::wptr_t &a, std::string handle) { @@ -5945,28 +5929,28 @@ LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::findSession(const std: { result = iter->second; } - + return result; } LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::findSessionBeingCreatedByURI(const std::string &uri) -{ +{ sessionStatePtr_t result = sessionState::matchCreatingSessionByURI(uri); - + return result; } LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::findSession(const LLUUID &participant_id) { sessionStatePtr_t result = sessionState::matchSessionByParticipant(participant_id); - + return result; } LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::addSession(const std::string &uri, const std::string &handle) { sessionStatePtr_t result; - + if(handle.empty()) { // No handle supplied. @@ -5977,7 +5961,7 @@ LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::addSession(const std:: { // Check for an existing session with this handle sessionMap::iterator iter = mSessionsByHandle.find(handle); - + if(iter != mSessionsByHandle.end()) { result = iter->second; @@ -5987,7 +5971,7 @@ LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::addSession(const std:: if(!result) { // No existing session found. - + LL_DEBUGS("Voice") << "adding new session: handle \"" << handle << "\" URI " << uri << LL_ENDL; result = sessionState::createSession(); result->mSIPURI = uri; @@ -6000,8 +5984,8 @@ LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::addSession(const std:: if(!result->mHandle.empty()) { - // *TODO: Rider: This concerns me. There is a path (via switchChannel) where - // we do not track the session. In theory this means that we could end up with + // *TODO: Rider: This concerns me. There is a path (via switchChannel) where + // we do not track the session. In theory this means that we could end up with // a mAuidoSession that does not match the session tracked in mSessionsByHandle mSessionsByHandle.insert(sessionMap::value_type(result->mHandle, result)); } @@ -6009,7 +5993,7 @@ LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::addSession(const std:: else { // Found an existing session - + if(uri != result->mSIPURI) { // TODO: Should this be an internal error? @@ -6031,12 +6015,12 @@ LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::addSession(const std:: setSessionHandle(result, handle); } } - + LL_DEBUGS("Voice") << "returning existing session: handle " << handle << " URI " << uri << LL_ENDL; } verifySessionState(); - + return result; } @@ -6067,7 +6051,7 @@ void LLVivoxVoiceClient::clearSessionHandle(const sessionStatePtr_t &session) void LLVivoxVoiceClient::setSessionHandle(const sessionStatePtr_t &session, const std::string &handle) { // Have to remove the session from the handle-indexed map before changing the handle, or things will break badly. - + if(!session->mHandle.empty()) { // Remove session from the map if it should have been there. @@ -6086,7 +6070,7 @@ void LLVivoxVoiceClient::setSessionHandle(const sessionStatePtr_t &session, cons LL_WARNS("Voice") << "Attempt to remove session with handle " << session->mHandle << " not found in map!" << LL_ENDL; } } - + session->mHandle = handle; if(!handle.empty()) @@ -6148,7 +6132,7 @@ void LLVivoxVoiceClient::deleteAllSessions() const sessionStatePtr_t session = mSessionsByHandle.begin()->second; deleteSession(session); } - + } void LLVivoxVoiceClient::verifySessionState(void) @@ -6236,10 +6220,10 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta } } } - - LL_DEBUGS("Voice") - << " " << LLVoiceClientStatusObserver::status2string(status) - << ", session channelInfo " << getAudioSessionChannelInfo() + + LL_DEBUGS("Voice") + << " " << LLVoiceClientStatusObserver::status2string(status) + << ", session channelInfo " << getAudioSessionChannelInfo() << ", proximal is " << inSpatialChannel() << LL_ENDL; @@ -6330,7 +6314,7 @@ void LLVivoxVoiceClient::predAvatarNameResolution(const LLVivoxVoiceClient::sess { session->mTextInvitePending = false; - // We don't need to call LLIMMgr::getInstance()->addP2PSession() here. The first incoming message will create the panel. + // We don't need to call LLIMMgr::getInstance()->addP2PSession() here. The first incoming message will create the panel. } if (session->mVoiceInvitePending) { @@ -6884,7 +6868,7 @@ void LLVivoxVoiceClient::onClickVoiceEffect(const std::string& voice_effect_name } } -// it updates VoiceMorphing menu items in accordance with purchased properties +// it updates VoiceMorphing menu items in accordance with purchased properties void LLVivoxVoiceClient::updateVoiceMorphingMenu() { if (mVoiceFontListDirty) @@ -7125,7 +7109,7 @@ void LLVivoxVoiceClient::captureBufferPlayStopSendMessage() LLVivoxProtocolParser::LLVivoxProtocolParser() { parser = XML_ParserCreate(NULL); - + reset(); } @@ -7158,7 +7142,7 @@ void LLVivoxProtocolParser::reset() applicationString.clear(); } -//virtual +//virtual LLVivoxProtocolParser::~LLVivoxProtocolParser() { if (parser) @@ -7184,38 +7168,38 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl( istr.read(buf, sizeof(buf)); mInput.append(buf, istr.gcount()); } - + // Look for input delimiter(s) in the input buffer. If one is found, send the message to the xml parser. int start = 0; int delim; while((delim = mInput.find("\n\n\n", start)) != std::string::npos) - { - + { + // Reset internal state of the LLVivoxProtocolParser (no effect on the expat parser) reset(); - + XML_ParserReset(parser, NULL); XML_SetElementHandler(parser, ExpatStartTag, ExpatEndTag); XML_SetCharacterDataHandler(parser, ExpatCharHandler); - XML_SetUserData(parser, this); + XML_SetUserData(parser, this); XML_Parse(parser, mInput.data() + start, delim - start, false); - + LL_DEBUGS("VivoxProtocolParser") << "parsing: " << mInput.substr(start, delim - start) << LL_ENDL; start = delim + 3; } - + if(start != 0) mInput = mInput.substr(start); - + LL_DEBUGS("VivoxProtocolParser") << "at end, mInput is: " << mInput << LL_ENDL; - + if(!LLVivoxVoiceClient::sConnected) { // If voice has been disabled, we just want to close the socket. This does so. LL_INFOS("Voice") << "returning STATUS_STOP" << LL_ENDL; return STATUS_STOP; } - + return STATUS_OK; } @@ -7259,11 +7243,11 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) textBuffer.clear(); // only accumulate text if we're not ignoring tags. accumulateText = !ignoringTags; - + if (responseDepth == 0) - { + { isEvent = !stricmp("Event", tag); - + if (!stricmp("Response", tag) || isEvent) { // Grab the attributes @@ -7271,7 +7255,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) { const char *key = *attr++; const char *value = *attr++; - + if (!stricmp("requestId", key)) { requestId = value; @@ -7297,20 +7281,20 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) else { LL_DEBUGS("VivoxProtocolParser") << tag << " (" << responseDepth << ")" << LL_ENDL; - + // Ignore the InputXml stuff so we don't get confused if (!stricmp("InputXml", tag)) { ignoringTags = true; ignoreDepth = responseDepth; accumulateText = false; - + LL_DEBUGS("VivoxProtocolParser") << "starting ignore, ignoreDepth is " << ignoreDepth << LL_ENDL; } else if (!stricmp("CaptureDevices", tag)) { LLVivoxVoiceClient::getInstance()->clearCaptureDevices(); - } + } else if (!stricmp("RenderDevices", tag)) { LLVivoxVoiceClient::getInstance()->clearRenderDevices(); @@ -7322,7 +7306,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) else if (!stricmp("RenderDevice", tag)) { deviceString.clear(); - } + } else if (!stricmp("SessionFont", tag)) { id = 0; @@ -7357,9 +7341,9 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) void LLVivoxProtocolParser::EndTag(const char *tag) { const std::string& string = textBuffer; - + responseDepth--; - + if (ignoringTags) { if (ignoreDepth == responseDepth) @@ -7372,11 +7356,11 @@ void LLVivoxProtocolParser::EndTag(const char *tag) LL_DEBUGS("VivoxProtocolParser") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; } } - + if (!ignoringTags) { LL_DEBUGS("VivoxProtocolParser") << "processing tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; - + // Closing a tag. Finalize the text we've accumulated and reset if (!stricmp("ReturnCode", tag)) returnCode = strtol(string.c_str(), NULL, 10); @@ -7431,7 +7415,7 @@ void LLVivoxProtocolParser::EndTag(const char *tag) else if (!stricmp("DisplayName", tag)) displayNameString = string; else if (!stricmp("Device", tag)) - deviceString = string; + deviceString = string; else if (!stricmp("AccountName", tag)) nameString = string; else if (!stricmp("ParticipantType", tag)) @@ -7529,7 +7513,7 @@ void LLVivoxProtocolParser::EndTag(const char *tag) textBuffer.clear(); accumulateText= false; - + if (responseDepth == 0) { // We finished all of the XML, process the data @@ -7546,7 +7530,7 @@ void LLVivoxProtocolParser::CharData(const char *buffer, int length) This method is called for anything that isn't a tag, which can be text you want that lies between tags, and a lot of stuff you don't want like file formatting (tabs, spaces, CR/LF, etc). - + Only copy text if we are in accumulate mode... */ if (accumulateText) @@ -7573,14 +7557,14 @@ LLDate LLVivoxProtocolParser::expiryTimeStampToLLDate(const std::string& vivox_t void LLVivoxProtocolParser::processResponse(std::string tag) { LL_DEBUGS("VivoxProtocolParser") << tag << LL_ENDL; - + // SLIM SDK: the SDK now returns a statusCode of "200" (OK) for success. This is a change vs. previous SDKs. // According to Mike S., "The actual API convention is that responses with return codes of 0 are successful, regardless of the status code returned", // so I believe this will give correct behavior. - + if(returnCode == 0) statusCode = 0; - + if (isEvent) { const char *eventTypeCstr = eventTypeString.c_str(); @@ -7648,7 +7632,7 @@ void LLVivoxProtocolParser::processResponse(std::string tag) } else if (!stricmp(eventTypeCstr, "ParticipantAddedEvent")) { - /* + /* <Event type="ParticipantAddedEvent"> <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg4</SessionGroupHandle> <SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==4</SessionHandle> @@ -7680,12 +7664,12 @@ void LLVivoxProtocolParser::processResponse(std::string tag) // These are really spammy in tuning mode LLVivoxVoiceClient::getInstance()->auxAudioPropertiesEvent(energy); } - else if (!stricmp(eventTypeCstr, "MessageEvent")) + else if (!stricmp(eventTypeCstr, "MessageEvent")) { //TODO: This probably is not received any more, it was used to support SLim clients LLVivoxVoiceClient::getInstance()->messageEvent(sessionHandle, uriString, alias, messageHeader, messageBody, applicationString); } - else if (!stricmp(eventTypeCstr, "SessionNotificationEvent")) + else if (!stricmp(eventTypeCstr, "SessionNotificationEvent")) { //TODO: This probably is not received any more, it was used to support SLim clients LLVivoxVoiceClient::getInstance()->sessionNotificationEvent(sessionHandle, uriString, notificationType); @@ -7755,23 +7739,23 @@ void LLVivoxProtocolParser::processResponse(std::string tag) } else if (!stricmp(actionCstr, "Session.Create.1")) { - LLVivoxVoiceClient::getInstance()->sessionCreateResponse(requestId, statusCode, statusString, sessionHandle); + LLVivoxVoiceClient::getInstance()->sessionCreateResponse(requestId, statusCode, statusString, sessionHandle); } else if (!stricmp(actionCstr, "SessionGroup.AddSession.1")) { - LLVivoxVoiceClient::getInstance()->sessionGroupAddSessionResponse(requestId, statusCode, statusString, sessionHandle); + LLVivoxVoiceClient::getInstance()->sessionGroupAddSessionResponse(requestId, statusCode, statusString, sessionHandle); } else if (!stricmp(actionCstr, "Session.Connect.1")) { - LLVivoxVoiceClient::getInstance()->sessionConnectResponse(requestId, statusCode, statusString); + LLVivoxVoiceClient::getInstance()->sessionConnectResponse(requestId, statusCode, statusString); } else if (!stricmp(actionCstr, "Account.Logout.1")) { - LLVivoxVoiceClient::getInstance()->logoutResponse(statusCode, statusString); + LLVivoxVoiceClient::getInstance()->logoutResponse(statusCode, statusString); } else if (!stricmp(actionCstr, "Connector.InitiateShutdown.1")) { - LLVivoxVoiceClient::getInstance()->connectorShutdownResponse(statusCode, statusString); + LLVivoxVoiceClient::getInstance()->connectorShutdownResponse(statusCode, statusString); } else if (!stricmp(actionCstr, "Account.GetSessionFonts.1")) { @@ -7800,75 +7784,75 @@ void LLVivoxProtocolParser::processResponse(std::string tag) } else if (!stricmp(actionCstr, "Connector.AccountCreate.1")) { - + } else if (!stricmp(actionCstr, "Connector.MuteLocalMic.1")) { - + } else if (!stricmp(actionCstr, "Connector.MuteLocalSpeaker.1")) { - + } else if (!stricmp(actionCstr, "Connector.SetLocalMicVolume.1")) { - + } else if (!stricmp(actionCstr, "Connector.SetLocalSpeakerVolume.1")) { - + } else if (!stricmp(actionCstr, "Session.ListenerSetPosition.1")) { - + } else if (!stricmp(actionCstr, "Session.SpeakerSetPosition.1")) { - + } else if (!stricmp(actionCstr, "Session.AudioSourceSetPosition.1")) { - + } else if (!stricmp(actionCstr, "Session.GetChannelParticipants.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelCreate.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelUpdate.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelDelete.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelCreateAndInvite.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelFolderCreate.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelFolderUpdate.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelFolderDelete.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelAddModerator.1")) { - + } else if (!stricmp(actionCstr, "Account.ChannelDeleteModerator.1")) { - + } */ } @@ -7886,7 +7870,7 @@ LLVivoxSecurity::LLVivoxSecurity() random_value[b] = ll_rand() & 0xff; } mConnectorHandle = LLBase64::encode(random_value, VIVOX_TOKEN_BYTES); - + for (int b = 0; b < VIVOX_TOKEN_BYTES; b++) { random_value[b] = ll_rand() & 0xff; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 14f6422ebb..5cd9795f9e 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -1,25 +1,25 @@ -/** +/** * @file llvoicevivox.h * @brief Declaration of LLDiamondwareVoiceClient class which is the interface to the voice client process. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -81,12 +81,12 @@ public: //@{ void init(LLPumpIO *pump) override; // Call this once at application startup (creates connector) void terminate() override; // Call this to clean up during shutdown - + const LLVoiceVersionInfo& getVersion() override; - + void updateSettings() override; // call after loading settings and whenever they change - // Returns true if vivox has successfully logged in and is not in error state + // Returns true if vivox has successfully logged in and is not in error state bool isVoiceWorking() const override; ///////////////////// @@ -95,12 +95,12 @@ public: void tuningStart() override; void tuningStop() override; bool inTuningMode() override; - + void tuningSetMicVolume(float volume) override; void tuningSetSpeakerVolume(float volume) override; float tuningGetEnergy(void) override; //@} - + ///////////////////// /// @name Devices //@{ @@ -108,20 +108,20 @@ public: // i.e. when the daemon is running and connected, and the device lists are populated. bool deviceSettingsAvailable() override; bool deviceSettingsUpdated() override; //return if the list has been updated and never fetched, only to be called from the voicepanel. - + // Requery the vivox daemon for the current list of input/output devices. // If you pass true for clearCurrentList, deviceSettingsAvailable() will be false until the query has completed // (use this if you want to know when it's done). // If you pass false, you'll have no way to know when the query finishes, but the device lists will not appear empty in the interim. void refreshDeviceLists(bool clearCurrentList = true) override; - + void setCaptureDevice(const std::string& name) override; void setRenderDevice(const std::string& name) override; - + LLVoiceDeviceList& getCaptureDevices() override; LLVoiceDeviceList& getRenderDevices() override; //@} - + void getParticipantList(std::set<LLUUID> &participants) override; bool isParticipant(const LLUUID& speaker_id) override; @@ -129,41 +129,41 @@ public: // virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message) const {return false;}; // Returns true if calling back the session URI after the session has closed is possible. - // Currently this will be false only for PSTN P2P calls. - // NOTE: this will return true if the session can't be found. + // Currently this will be false only for PSTN P2P calls. + // NOTE: this will return true if the session can't be found. BOOL isSessionCallBackPossible(const LLUUID &session_id) override; - + // Returns true if the session can accepte text IM's. // Currently this will be false only for PSTN P2P calls. - // NOTE: this will return true if the session can't be found. + // NOTE: this will return true if the session can't be found. BOOL isSessionTextIMPossible(const LLUUID &session_id) override; - - + + //////////////////////////// /// @name Channel stuff //@{ // returns true iff the user is currently in a proximal (local spatial) channel. // Note that gestures should only fire if this returns true. bool inProximalChannel() override; - + void setNonSpatialChannel(const LLSD& channelInfo, bool notify_on_first_join, bool hangup_on_last_leave) override; - + bool setSpatialChannel(const LLSD& channelInfo) override; - + void leaveNonSpatialChannel() override; void processChannels(bool process) override; - + void leaveChannel(void); bool isCurrentChannel(const LLSD &channelInfo) override; bool compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) override; //@} - - + + ////////////////////////// /// @name LLVoiceP2POutgoingCallInterface //@{ @@ -178,39 +178,37 @@ public: bool answerInvite(const std::string &sessionHandle); void declineInvite(const std::string &sessionHandle); - + ///////////////////////// /// @name Volume/gain //@{ void setVoiceVolume(F32 volume) override; void setMicGain(F32 volume) override; //@} - + ///////////////////////// /// @name enable disable voice and features //@{ void setVoiceEnabled(bool enabled) override; void setMuteMic(bool muted) override; // Set the mute state of the local mic. //@} - + ////////////////////////// /// @name nearby speaker accessors //@{ - BOOL getVoiceEnabled(const LLUUID& id) override; // true if we've received data for this avatar std::string getDisplayName(const LLUUID& id) override; BOOL isParticipantAvatar(const LLUUID &id) override; BOOL getIsSpeaking(const LLUUID& id) override; BOOL getIsModeratorMuted(const LLUUID& id) override; F32 getCurrentPower(const LLUUID& id) override; // "power" is related to "amplitude" in a defined way. I'm just not sure what the formula is... - BOOL getOnMuteList(const LLUUID& id) override; F32 getUserVolume(const LLUUID& id) override; void setUserVolume(const LLUUID& id, F32 volume) override; // set's volume for specified agent, from 0-1 (where .5 is nominal) //@} - + // authorize the user virtual void userAuthorized(const std::string& user_id, const LLUUID &agentID) override; - + ////////////////////////////// /// @name Status notification //@{ @@ -221,7 +219,7 @@ public: void addObserver(LLVoiceClientParticipantObserver* observer) override; void removeObserver(LLVoiceClientParticipantObserver* observer) override; //@} - + std::string sipURIFromID(const LLUUID &id) override; //@} @@ -267,12 +265,12 @@ public: protected: ////////////////////// - // Vivox Specific definitions - + // Vivox Specific definitions + friend class LLVivoxVoiceClientMuteListObserver; - friend class LLVivoxVoiceClientFriendsObserver; + friend class LLVivoxVoiceClientFriendsObserver; + - enum streamState { streamStateUnknown = 0, @@ -281,16 +279,16 @@ protected: streamStateRinging = 3, streamStateConnecting = 6, // same as Vivox session_media_connecting enum streamStateDisconnecting = 7, //Same as Vivox session_media_disconnecting enum - }; + }; struct participantState { public: participantState(const std::string &uri); - + bool updateMuteState(); // true if mute state has changed bool isAvatar(); - + std::string mURI; LLUUID mAvatarID; std::string mAccountName; @@ -315,7 +313,7 @@ protected: typedef std::map<const std::string, participantStatePtr_t> participantMap; typedef std::map<const LLUUID, participantStatePtr_t> participantUUIDMap; - + struct sessionState { public: @@ -328,7 +326,7 @@ protected: ~sessionState(); LLSD getVoiceChannelInfo(); - + participantStatePtr_t addParticipant(const std::string &uri); void removeParticipant(const participantStatePtr_t &participant); void removeAllParticipants(); @@ -344,7 +342,7 @@ protected: bool isCallBackPossible(); bool isTextIMPossible(); bool isSpatial() { return mIsSpatial; } - + static void for_each(sessionFunc_t func); std::string mHandle; @@ -356,7 +354,7 @@ protected: std::string mHash; // Channel password std::string mErrorStatusString; std::queue<std::string> mTextMsgQueue; - + LLUUID mIMSessionID; LLUUID mCallerID; int mErrorStatusCode; @@ -403,7 +401,7 @@ protected: typedef boost::shared_ptr<sessionState> sessionStatePtr_t; typedef std::map<std::string, sessionStatePtr_t> sessionMap; - + /////////////////////////////////////////////////////// // Private Member Functions ////////////////////////////////////////////////////// @@ -415,17 +413,17 @@ protected: //@{ // Call this if the connection to the daemon terminates unexpectedly. It will attempt to reset everything and relaunch. void daemonDied(); - + // Call this if we're just giving up on voice (can't provision an account, etc.). It will clean up and go away. - void giveUp(); - + void giveUp(); + // write to the tvc bool writeString(const std::string &str); - + void connectorCreate(); - void connectorShutdown(); - void closeSocket(void); - + void connectorShutdown(); + void closeSocket(void); + // void requestVoiceAccountProvision(S32 retries = 3); void setLoginInfo( const std::string& account_name, @@ -434,14 +432,14 @@ protected: const std::string& voice_account_server_uri); void loginSendMessage(); void logout(); - void logoutSendMessage(); - - + void logoutSendMessage(); + + //@} - + //------------------------------------ // tuning - + void tuningRenderStartSendMessage(const std::string& name, bool loop); void tuningRenderStopSendMessage(); @@ -454,12 +452,12 @@ protected: void addCaptureDevice(const LLVoiceDevice& device); void clearRenderDevices(); void setDevicesListUpdated(bool state); - void addRenderDevice(const LLVoiceDevice& device); + void addRenderDevice(const LLVoiceDevice& device); void buildSetAudioDevices(std::ostringstream &stream); - + void getCaptureDevicesSendMessage(); void getRenderDevicesSendMessage(); - + // local audio updates, mic mute, speaker mute, mic volume and speaker volumes void sendLocalAudioUpdates(); @@ -486,9 +484,9 @@ protected: void auxAudioPropertiesEvent(F32 energy); void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString); void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string ¬ificationType); - + void muteListChanged(); - + ///////////////////////////// // VAD changes // disable auto-VAD and configure VAD parameters explicitly @@ -504,34 +502,34 @@ protected: void setEarLocation(S32 loc); - + ///////////////////////////// // Accessors for data related to nearby speakers // MBW -- XXX -- Not sure how to get this data out of the TVC BOOL getUsingPTT(const LLUUID& id); std::string getGroupID(const LLUUID& id); // group ID if the user is in group chat (empty string if not applicable) - + ///////////////////////////// // Recording controls void recordingLoopStart(int seconds = 3600, int deltaFramesPerControlFrame = 200); void recordingLoopSave(const std::string& filename); void recordingStop(); - + // Playback controls void filePlaybackStart(const std::string& filename); void filePlaybackStop(); void filePlaybackSetPaused(bool paused); void filePlaybackSetMode(bool vox = false, float speed = 1.0f); - + participantStatePtr_t findParticipantByID(const LLUUID& id); - + #if 0 //////////////////////////////////////// // voice sessions. typedef std::set<sessionStatePtr_t> sessionSet; - + typedef sessionSet::iterator sessionIterator; sessionIterator sessionsBegin(void); sessionIterator sessionsEnd(void); @@ -540,7 +538,7 @@ protected: sessionStatePtr_t findSession(const std::string &handle); sessionStatePtr_t findSessionBeingCreatedByURI(const std::string &uri); sessionStatePtr_t findSession(const LLUUID &participant_id); - + sessionStatePtr_t addSession(const std::string &uri, const std::string &handle = std::string()); void clearSessionHandle(const sessionStatePtr_t &session); void setSessionHandle(const sessionStatePtr_t &session, const std::string &handle); @@ -556,11 +554,11 @@ protected: // This is called in several places where the session _may_ need to be deleted. // It contains logic for whether to delete the session or keep it around. void reapSession(const sessionStatePtr_t &session); - + // Returns true if the session seems to indicate we've moved to a region on a different voice server bool sessionNeedsRelog(const sessionStatePtr_t &session); - - + + ////////////////////////////////////// // buddy list stuff, needed for SLIM later struct buddyListEntry @@ -580,13 +578,13 @@ protected: }; typedef std::map<std::string, buddyListEntry*> buddyListMap; - + ///////////////////////////// // session control messages void accountListBlockRulesSendMessage(); void accountListAutoAcceptRulesSendMessage(); - + void sessionGroupCreateSendMessage(); void sessionCreateSendMessage(const sessionStatePtr_t &session, bool startAudio = true, bool startText = false); void sessionGroupAddSessionSendMessage(const sessionStatePtr_t &session, bool startAudio = true, bool startText = false); @@ -597,20 +595,20 @@ protected: void sessionMediaDisconnectSendMessage(const sessionStatePtr_t &session); // void sessionTextDisconnectSendMessage(sessionState *session); - - + + // Pokes the state machine to leave the audio session next time around. - void sessionTerminate(); - + void sessionTerminate(); + // Pokes the state machine to shut down the connector and restart it. void requestRelog(); - + // Does the actual work to get out of the audio session void leaveAudioSession(); - + friend class LLVivoxVoiceClientCapResponder; - - + + void lookupName(const LLUUID &id); void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); void avatarNameResolved(const LLUUID &id, const std::string &name); @@ -630,10 +628,10 @@ protected: const S32 font_status, const bool template_font = false); void accountGetSessionFontsResponse(int statusCode, const std::string &statusString); - void accountGetTemplateFontsResponse(int statusCode, const std::string &statusString); + void accountGetTemplateFontsResponse(int statusCode, const std::string &statusString); private: - + LLVoiceVersionInfo mVoiceVersion; // Coroutine support methods @@ -675,21 +673,21 @@ private: // The larger it is the greater is possibility there is a problem with connection to voice server. // Introduced while fixing EXT-4313. int mSpatialJoiningNum; - + static void idle(void *user_data); - + LLHost mDaemonHost; LLSocket::ptr_t mSocket; - - // We should kill the voice daemon in case of connection alert + + // We should kill the voice daemon in case of connection alert bool mTerminateDaemon; - + friend class LLVivoxProtocolParser; - + std::string mAccountName; std::string mAccountPassword; std::string mAccountDisplayName; - + bool mTuningMode; float mTuningEnergy; std::string mTuningAudioFile; @@ -699,13 +697,13 @@ private: bool mTuningSpeakerVolumeDirty; bool mDevicesListUpdated; // set to true when the device list has been updated // and false when the panelvoicedevicesettings has queried for an update status. - + std::string mSpatialSessionURI; std::string mSpatialSessionCredentials; std::string mMainSessionGroupHandle; // handle of the "main" session group. - - std::string mChannelName; // Name of the channel to be looked up + + std::string mChannelName; // Name of the channel to be looked up sessionStatePtr_t mAudioSession; // Session state for the current audio session bool mAudioSessionChanged; // set to true when the above pointer gets changed, so observers can be notified. @@ -713,27 +711,27 @@ private: S32 mCurrentParcelLocalID; // Used to detect parcel boundary crossings std::string mCurrentRegionName; // Used to detect parcel boundary crossings - + bool mConnectorEstablished; // set by "Create Connector" response - bool mAccountLoggedIn; // set by login message + bool mAccountLoggedIn; // set by login message int mNumberOfAliases; U32 mCommandCookie; std::string mVoiceAccountServerURI; std::string mVoiceSIPURIHostName; - + int mLoginRetryCount; - + sessionMap mSessionsByHandle; // Active sessions, indexed by session handle. Sessions which are being initiated may not be in this map. #if 0 sessionSet mSessions; // All sessions, not indexed. This is the canonical session list. #endif - + bool mBuddyListMapPopulated; bool mBlockRulesListReceived; bool mAutoAcceptRulesListReceived; buddyListMap mBuddyListMap; - + LLVoiceDeviceList mCaptureDevices; LLVoiceDeviceList mRenderDevices; @@ -744,30 +742,30 @@ private: bool mIsInitialized; bool mShutdownComplete; - + bool checkParcelChanged(bool update = false); bool switchChannel(std::string uri = std::string(), bool spatial = true, bool no_reconnect = false, bool is_p2p = false, std::string hash = ""); void joinSession(const sessionStatePtr_t &session); - + std::string nameFromID(const LLUUID &id); bool IDFromName(const std::string name, LLUUID &uuid); std::string sipURIFromAvatar(LLVOAvatar *avatar); std::string sipURIFromName(std::string &name); - + // Returns the name portion of the SIP URI if the string looks vaguely like a SIP URI, or an empty string if not. - std::string nameFromsipURI(const std::string &uri); + std::string nameFromsipURI(const std::string &uri); bool inSpatialChannel(void); LLSD getAudioSessionChannelInfo(); std::string getAudioSessionHandle(); - + void setHidden(bool hidden) override; //virtual void sendPositionAndVolumeUpdate(void); - + void sendCaptureAndRenderDevices(); void buildSetCaptureDevice(std::ostringstream &stream); void buildSetRenderDevice(std::ostringstream &stream); - + void sendFriendsListUpdates(); @@ -778,9 +776,9 @@ private: #endif void enforceTether(void); - + bool mSpatialCoordsDirty; - + LLVector3d mCameraPosition; LLVector3d mCameraRequestedPosition; LLVector3 mCameraVelocity; @@ -789,30 +787,30 @@ private: LLVector3d mAvatarPosition; LLVector3 mAvatarVelocity; LLQuaternion mAvatarRot; - + bool mMuteMic; bool mMuteMicDirty; bool mHidden; //Set to true during teleport to hide the agent's position. - + // Set to true when the friends list is known to have changed. bool mFriendsListDirty; - + enum { earLocCamera = 0, // ear at camera earLocAvatar, // ear at avatar earLocMixed // ear at avatar location/camera direction }; - - S32 mEarLocation; - + + S32 mEarLocation; + bool mSpeakerVolumeDirty; bool mSpeakerMuteDirty; int mSpeakerVolume; int mMicVolume; bool mMicVolumeDirty; - + bool mVoiceEnabled; bool mProcessChannels; bool mWriteInProgress; @@ -826,7 +824,7 @@ private: typedef std::set<LLVoiceClientStatusObserver*> status_observer_set_t; status_observer_set_t mStatusObservers; - + void notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status); typedef std::set<LLFriendObserver*> friend_observer_set_t; @@ -933,7 +931,7 @@ private: }; -/** +/** * @class LLVivoxProtocolParser * @brief This class helps construct new LLIOPipe specializations * @see LLIOPipe @@ -946,12 +944,12 @@ class LLVivoxProtocolParser : public LLIOPipe public: LLVivoxProtocolParser(); virtual ~LLVivoxProtocolParser(); - + protected: /* @name LLIOPipe virtual implementations */ //@{ - /** + /** * @brief Process the data in buffer */ virtual EStatus process_impl( @@ -961,16 +959,16 @@ protected: LLSD& context, LLPumpIO* pump); //@} - + std::string mInput; - + // Expat control members XML_Parser parser; int responseDepth; bool ignoringTags; bool isEvent; int ignoreDepth; - + // Members for processing responses. The values are transient and only valid within a call to processResponse(). int returnCode; int statusCode; @@ -985,7 +983,7 @@ protected: std::string sessionGroupHandle; std::string alias; std::string applicationString; - + // Members for processing events. The values are transient and only valid within a call to processResponse(). std::string eventTypeString; int state; @@ -1024,19 +1022,19 @@ protected: S32 fontType; S32 fontStatus; std::string mediaCompletionType; - + // Members for processing text between tags std::string textBuffer; bool accumulateText; - + void reset(); - + void processResponse(std::string tag); - + static void XMLCALL ExpatStartTag(void *data, const char *el, const char **attr); static void XMLCALL ExpatEndTag(void *data, const char *el); static void XMLCALL ExpatCharHandler(void *data, const XML_Char *s, int len); - + void StartTag(const char *tag, const char **attr); void EndTag(const char *tag); void CharData(const char *buffer, int length); @@ -1063,7 +1061,7 @@ class LLVoiceVivoxStats : public LLSingleton<LLVoiceVivoxStats> LLSINGLETON(LLVoiceVivoxStats); LOG_CLASS(LLVoiceVivoxStats); virtual ~LLVoiceVivoxStats(); - + private: F64SecondsImplicit mStartTime; @@ -1071,7 +1069,7 @@ class LLVoiceVivoxStats : public LLSingleton<LLVoiceVivoxStats> F64 mConnectTime; U32 mConnectAttempts; - + F64 mProvisionTime; U32 mProvisionAttempts; diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 6eee8e70b2..02917d2135 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -1,25 +1,25 @@ - /** + /** * @file LLWebRTCVoiceClient.cpp * @brief Implementation of LLWebRTCVoiceClient class which is the interface to the voice client process. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2023, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -92,7 +92,7 @@ namespace { // Don't send positional updates more frequently than this: const F32 UPDATE_THROTTLE_SECONDS = 0.1f; - + // Cosine of a "trivially" small angle const F32 FOUR_DEGREES = 4.0f * (F_PI / 180.0f); const F32 MINUSCULE_ANGLE_COS = (F32) cos(0.5f * FOUR_DEGREES); @@ -302,12 +302,12 @@ void LLWebRTCVoiceClient::updateSettings() // Observers void LLWebRTCVoiceClient::addObserver(LLVoiceClientParticipantObserver *observer) -{ +{ mParticipantObservers.insert(observer); } void LLWebRTCVoiceClient::removeObserver(LLVoiceClientParticipantObserver *observer) -{ +{ mParticipantObservers.erase(observer); } @@ -323,12 +323,12 @@ void LLWebRTCVoiceClient::notifyParticipantObservers() } void LLWebRTCVoiceClient::addObserver(LLVoiceClientStatusObserver *observer) -{ +{ mStatusObservers.insert(observer); } void LLWebRTCVoiceClient::removeObserver(LLVoiceClientStatusObserver *observer) -{ +{ mStatusObservers.erase(observer); } @@ -352,7 +352,7 @@ void LLWebRTCVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESt } // skipped to avoid speak button blinking - if (status != LLVoiceClientStatusObserver::STATUS_JOINING && + if (status != LLVoiceClientStatusObserver::STATUS_JOINING && status != LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL && status != LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED) { @@ -368,11 +368,11 @@ void LLWebRTCVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESt } void LLWebRTCVoiceClient::addObserver(LLFriendObserver *observer) -{ +{ } void LLWebRTCVoiceClient::removeObserver(LLFriendObserver *observer) -{ +{ } //--------------------------------------------------- @@ -381,12 +381,12 @@ void LLWebRTCVoiceClient::removeObserver(LLFriendObserver *observer) // takes to process the various functions called in the loop // The loop does the following: // * gates whether we do channel processing depending on -// whether we're running a WebRTC voice channel or +// whether we're running a WebRTC voice channel or // one from another voice provider. // * If in spatial voice, it determines whether we've changed // parcels, whether region/parcel voice settings have changed, // etc. and manages whether the voice channel needs to change. -// * calls the state machines for the sessions to negotiate +// * calls the state machines for the sessions to negotiate // connection to various voice channels. // * Sends updates to the voice server when this agent's // voice levels, or positions have changed. @@ -485,7 +485,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro() updatePosition(); } } - + sessionState::processSessionStates(); if (mProcessChannels && voiceEnabled) { @@ -629,7 +629,7 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi } void LLWebRTCVoiceClient::clearRenderDevices() -{ +{ LL_DEBUGS("Voice") << "called" << LL_ENDL; mRenderDevices.clear(); } @@ -661,7 +661,7 @@ void LLWebRTCVoiceClient::tuningStart() } void LLWebRTCVoiceClient::tuningStop() -{ +{ if (mIsInTuningMode) { mWebRTCDeviceInterface->setTuningMode(false); @@ -680,7 +680,7 @@ void LLWebRTCVoiceClient::tuningSetMicVolume(float volume) } void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume) -{ +{ if (volume != mTuningSpeakerVolume) { @@ -708,17 +708,17 @@ float LLWebRTCVoiceClient::tuningGetEnergy(void) bool LLWebRTCVoiceClient::deviceSettingsAvailable() { bool result = true; - + if(mRenderDevices.empty() || mCaptureDevices.empty()) result = false; - + return result; } bool LLWebRTCVoiceClient::deviceSettingsUpdated() { bool updated = mDevicesListUpdated; mDevicesListUpdated = false; - return updated; + return updated; } void LLWebRTCVoiceClient::refreshDeviceLists(bool clearCurrentList) @@ -758,7 +758,7 @@ void LLWebRTCVoiceClient::setHidden(bool hidden) // status for a given channel. By filtering // on channel and region, these functions // can send various notifications to -// other parts of the viewer, as well as +// other parts of the viewer, as well as // managing housekeeping // A connection to a channel was successfully established, @@ -997,14 +997,14 @@ void LLWebRTCVoiceClient::sendPositionUpdate(bool force) // Update our own volume on our participant, so it'll show up // in the UI. This is done on all sessions, so switching // sessions retains consistent volume levels. -void LLWebRTCVoiceClient::updateOwnVolume() { +void LLWebRTCVoiceClient::updateOwnVolume() { F32 audio_level = 0.0; if (!mMuteMic && !mTuningMode) { audio_level = getAudioLevel(); } - sessionState::for_each(boost::bind(predUpdateOwnVolume, _1, audio_level)); + sessionState::for_each(boost::bind(predUpdateOwnVolume, _1, audio_level)); } //////////////////////////////////// @@ -1020,9 +1020,9 @@ BOOL LLWebRTCVoiceClient::isParticipantAvatar(const LLUUID &id) void LLWebRTCVoiceClient::getParticipantList(std::set<LLUUID> &participants) { - if (mSession) + if (mProcessChannels && mSession) { - for (participantUUIDMap::iterator iter = mSession->mParticipantsByUUID.begin(); + for (participantUUIDMap::iterator iter = mSession->mParticipantsByUUID.begin(); iter != mSession->mParticipantsByUUID.end(); iter++) { @@ -1033,7 +1033,7 @@ void LLWebRTCVoiceClient::getParticipantList(std::set<LLUUID> &participants) bool LLWebRTCVoiceClient::isParticipant(const LLUUID &speaker_id) { - if (mSession) + if (mProcessChannels && mSession) { return (mSession->mParticipantsByUUID.find(speaker_id) != mSession->mParticipantsByUUID.end()); } @@ -1089,28 +1089,27 @@ void LLWebRTCVoiceClient::removeParticipantByID(const std::string &channelID, co // participantState level participant management -LLWebRTCVoiceClient::participantState::participantState(const LLUUID& agent_id) : +LLWebRTCVoiceClient::participantState::participantState(const LLUUID& agent_id) : mURI(agent_id.asString()), mAvatarID(agent_id), - mIsSpeaking(false), - mIsModeratorMuted(false), - mLevel(0.f), - mVolume(LLVoiceClient::VOLUME_DEFAULT), - mOnMuteList(false) + mIsSpeaking(false), + mIsModeratorMuted(false), + mLevel(0.f), + mVolume(LLVoiceClient::VOLUME_DEFAULT) { } LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::addParticipant(const LLUUID& agent_id) { participantStatePtr_t result; - + participantUUIDMap::iterator iter = mParticipantsByUUID.find(agent_id); if (iter != mParticipantsByUUID.end()) { result = iter->second; } - + if(!result) { // participant isn't already in one list or the other. @@ -1119,31 +1118,16 @@ LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::ad result->mAvatarID = agent_id; LLWebRTCVoiceClient::getInstance()->lookupName(agent_id); - - result->updateMuteState(); LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID, result->mVolume); if (!LLWebRTCVoiceClient::sShuttingDown) { LLWebRTCVoiceClient::getInstance()->notifyParticipantObservers(); } - + LL_DEBUGS("Voice") << "Participant \"" << result->mURI << "\" added." << LL_ENDL; } - - return result; -} -bool LLWebRTCVoiceClient::participantState::updateMuteState() -{ - bool result = false; - - bool isMuted = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat); - if(mOnMuteList != isMuted) - { - mOnMuteList = isMuted; - result = true; - } return result; } @@ -1218,7 +1202,7 @@ bool LLWebRTCVoiceClient::startAdHocSession(const LLSD& channelInfo, bool notify std::string channelID = channelInfo["channel_uri"]; std::string credentials = channelInfo["channel_credentials"]; mNextSession = addSession(channelID, - sessionState::ptr_t(new adhocSessionState(channelID, + sessionState::ptr_t(new adhocSessionState(channelID, credentials, notify_on_first_join, hangup_on_last_leave))); @@ -1231,7 +1215,7 @@ bool LLWebRTCVoiceClient::isVoiceWorking() const } // Returns true if calling back the session URI after the session has closed is possible. -// Currently this will be false only for PSTN P2P calls. +// Currently this will be false only for PSTN P2P calls. BOOL LLWebRTCVoiceClient::isSessionCallBackPossible(const LLUUID &session_id) { sessionStatePtr_t session(findP2PSession(session_id)); @@ -1245,14 +1229,14 @@ void LLWebRTCVoiceClient::leaveNonSpatialChannel() // make sure we're not simply rejoining the current session deleteSession(mNextSession); - + leaveChannel(true); } // determine whether we're processing channels, or whether // another voice provider is. void LLWebRTCVoiceClient::processChannels(bool process) -{ +{ mProcessChannels = process; } @@ -1274,8 +1258,8 @@ bool LLWebRTCVoiceClient::inEstateChannel() bool LLWebRTCVoiceClient::inSpatialChannel() { bool result = true; - - if (mNextSession) + + if (mNextSession) { result = mNextSession->isSpatial(); } @@ -1283,7 +1267,7 @@ bool LLWebRTCVoiceClient::inSpatialChannel() { result = mSession->isSpatial(); } - + return result; } @@ -1323,8 +1307,11 @@ void LLWebRTCVoiceClient::leaveChannel(bool stopTalking) bool LLWebRTCVoiceClient::isCurrentChannel(const LLSD &channelInfo) { - if (channelInfo["voice_server_type"].asString() != WEBRTC_VOICE_SERVER_TYPE) + if (!mProcessChannels || (channelInfo["voice_server_type"].asString() != WEBRTC_VOICE_SERVER_TYPE)) + { return false; + } + if (mSession) { if (!channelInfo["sessionHandle"].asString().empty()) @@ -1339,7 +1326,7 @@ bool LLWebRTCVoiceClient::isCurrentChannel(const LLSD &channelInfo) bool LLWebRTCVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) { return (channelInfo1["voice_server_type"] == WEBRTC_VOICE_SERVER_TYPE) && - (channelInfo1["voice_server_type"] == channelInfo2["voice_server_type"]) && + (channelInfo1["voice_server_type"] == channelInfo2["voice_server_type"]) && (channelInfo1["sip_uri"] == channelInfo2["sip_uri"]); } @@ -1401,14 +1388,14 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled) << " was "<< (mVoiceEnabled ? "enabled" : "disabled") << " coro "<< (mIsCoroutineActive ? "active" : "inactive") << LL_ENDL; - + if (enabled != mVoiceEnabled) { // TODO: Refactor this so we don't call into LLVoiceChannel, but simply // use the status observer mVoiceEnabled = enabled; LLVoiceClientStatusObserver::EStatusType status; - + if (enabled) { LL_DEBUGS("Voice") << "enabling" << LL_ENDL; @@ -1446,53 +1433,32 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled) ///////////////////////////// // Accessors for data related to nearby speakers -BOOL LLWebRTCVoiceClient::getVoiceEnabled(const LLUUID& id) -{ - BOOL result = FALSE; - if (!mSession) - { - return FALSE; - } - participantStatePtr_t participant(mSession->findParticipantByID(id)); - if(participant) - { - // I'm not sure what the semantics of this should be. - // For now, if we have any data about the user that came through the chat channel, assume they're voice-enabled. - result = TRUE; - } - - return result; -} std::string LLWebRTCVoiceClient::getDisplayName(const LLUUID& id) { std::string result; - if (!mSession) - { - return result; - } - participantStatePtr_t participant(mSession->findParticipantByID(id)); - if(participant) + if (mProcessChannels && mSession) { - result = participant->mDisplayName; + participantStatePtr_t participant(mSession->findParticipantByID(id)); + if (participant) + { + result = participant->mDisplayName; + } } - return result; } BOOL LLWebRTCVoiceClient::getIsSpeaking(const LLUUID& id) { BOOL result = FALSE; - if (!mSession) - { - return result; - } - participantStatePtr_t participant(mSession->findParticipantByID(id)); - if(participant) + if (mProcessChannels && mSession) { - result = participant->mIsSpeaking; + participantStatePtr_t participant(mSession->findParticipantByID(id)); + if (participant) + { + result = participant->mIsSpeaking; + } } - return result; } @@ -1500,23 +1466,21 @@ BOOL LLWebRTCVoiceClient::getIsSpeaking(const LLUUID& id) BOOL LLWebRTCVoiceClient::getIsModeratorMuted(const LLUUID& id) { BOOL result = FALSE; - if (!mSession) - { - return result; - } - participantStatePtr_t participant(mSession->findParticipantByID(id)); - if(participant) + if (mProcessChannels && mSession) { - result = participant->mIsModeratorMuted; + participantStatePtr_t participant(mSession->findParticipantByID(id)); + if (participant) + { + result = participant->mIsModeratorMuted; + } } - return result; } F32 LLWebRTCVoiceClient::getCurrentPower(const LLUUID &id) { F32 result = 0.0; - if (!mSession) + if (!mProcessChannels || !mSession) { return result; } @@ -1531,25 +1495,12 @@ F32 LLWebRTCVoiceClient::getCurrentPower(const LLUUID &id) return result; } -BOOL LLWebRTCVoiceClient::getOnMuteList(const LLUUID& id) -{ - BOOL result = FALSE; - - participantStatePtr_t participant(mSession->findParticipantByID(id)); - if(participant) - { - result = participant->mOnMuteList; - } - - return result; -} - // External accessors. F32 LLWebRTCVoiceClient::getUserVolume(const LLUUID& id) { // Minimum volume will be returned for users with voice disabled F32 result = LLVoiceClient::VOLUME_MIN; - + participantStatePtr_t participant(mSession->findParticipantByID(id)); if(participant) { @@ -1619,7 +1570,7 @@ void LLWebRTCVoiceClient::predSetUserMute(const LLWebRTCVoiceClient::sessionStat std::map<std::string, LLWebRTCVoiceClient::sessionState::ptr_t> LLWebRTCVoiceClient::sessionState::mSessions; -LLWebRTCVoiceClient::sessionState::sessionState() : +LLWebRTCVoiceClient::sessionState::sessionState() : mHangupOnLastLeave(false), mNotifyOnFirstJoin(false), mMicGain(1.0), @@ -1803,7 +1754,7 @@ LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::findP2PSession(const { return result; } - + result.reset(); return result; } @@ -1943,12 +1894,17 @@ LLWebRTCVoiceClient::adhocSessionState::adhocSessionState(const std::string &cha } void LLWebRTCVoiceClient::predShutdownSession(const LLWebRTCVoiceClient::sessionStatePtr_t& session) -{ +{ session->shutdownAllConnections(); } void LLWebRTCVoiceClient::deleteSession(const sessionStatePtr_t &session) { + if (!session) + { + return; + } + // At this point, the session should be unhooked from all lists and all state should be consistent. session->shutdownAllConnections(); // If this is the current audio session, clean up the pointer which will soon be dangling. @@ -2004,7 +1960,7 @@ void LLWebRTCVoiceClient::avatarNameResolved(const LLUUID &id, const std::string // Leftover from vivox PTSN std::string LLWebRTCVoiceClient::sipURIFromID(const LLUUID& id) -{ +{ return id.asString(); } @@ -2014,7 +1970,7 @@ std::string LLWebRTCVoiceClient::sipURIFromID(const LLUUID& id) // These connections manage state transitions, negotiating webrtc connections, // and other such things for a single connection to a Secondlife WebRTC server. // Multiple of these connections may be active at once, in the case of -// cross-region voice, or when a new connection is being created before the old +// cross-region voice, or when a new connection is being created before the old // has a chance to shut down. LLVoiceWebRTCConnection::LLVoiceWebRTCConnection(const LLUUID ®ionID, const std::string &channelID) : mWebRTCAudioInterface(nullptr), @@ -2132,7 +2088,7 @@ void LLVoiceWebRTCConnection::onIceUpdateError(int retries, std::string url, LLS // Ice candidates may be streamed in before or after the SDP offer is available (see below) // This function determines whether candidates are available to send to the Secondlife WebRTC // server via the simulator. If so, and there are no more candidates, this code -// will make the cap call to the server sending up the ICE candidates. +// will make the cap call to the server sending up the ICE candidates. void LLVoiceWebRTCConnection::processIceUpdates() { if (mShutDown || LLWebRTCVoiceClient::isShuttingDown()) @@ -2211,7 +2167,7 @@ void LLVoiceWebRTCConnection::processIceUpdates() // to the type of session (audio, video) to characteristics (the encoder type.) // This SDP also serves as the 'ticket' to the server, security-wise. // The Offer is retrieved from the WebRTC library on the client, -// and is passed to the simulator via a CAP, which then passes +// and is passed to the simulator via a CAP, which then passes // it on to the Secondlife WebRTC server. void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp) @@ -2510,7 +2466,7 @@ void LLVoiceWebRTCConnection::OnVoiceConnectionRequestFailure(std::string url, i } -// Primary state machine for negotiating a single voice connection to the +// Primary state machine for negotiating a single voice connection to the // Secondlife WebRTC server. bool LLVoiceWebRTCConnection::connectionStateMachine() { @@ -2553,7 +2509,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() setVoiceConnectionState(VOICE_STATE_DISCONNECT); break; } - // Ask the sim to ask the Secondlife WebRTC server for a connection to + // Ask the sim to ask the Secondlife WebRTC server for a connection to // a given voice channel. On completion, we'll move on to the // VOICE_STATE_SESSION_ESTABLISHED via a callback on a webrtc thread. if (!requestVoiceConnection()) @@ -2708,7 +2664,7 @@ void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binar // that come from voice servers that aren't their primary // voice server. This will happen with cross-region voice // where a participant on a neighboring region may be - // connected to multiple servers. We don't want to + // connected to multiple servers. We don't want to // add new identical participants from all of those servers. if (voice_data[participant_id].isMember("j")) { @@ -2751,7 +2707,7 @@ void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binar F32 level = (F32) (voice_data[participant_id].get("p", Json::Value(participant->mLevel)).asInt()) / 128; // convert to decibles participant->mLevel = level; - + if (voice_data[participant_id].isMember("v")) { participant->mIsSpeaking = voice_data[participant_id].get("v", Json::Value(false)).asBool(); @@ -2821,7 +2777,7 @@ LLVoiceWebRTCSpatialConnection::LLVoiceWebRTCSpatialConnection(const LLUUID ® { } -LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection() +LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection() { if (LLWebRTCVoiceClient::isShuttingDown()) { diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index 3ff801ed56..0e8ac3a183 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -1,25 +1,25 @@ -/** +/** * @file llvoicewebrtc.h * @brief Declaration of LLWebRTCVoiceClient class which is the interface to the voice client process. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2023, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -76,12 +76,12 @@ public: void terminate() override; // Call this to clean up during shutdown static bool isShuttingDown() { return sShuttingDown; } - + const LLVoiceVersionInfo& getVersion() override; - + void updateSettings() override; // call after loading settings and whenever they change - // Returns true if WebRTC has successfully logged in and is not in error state + // Returns true if WebRTC has successfully logged in and is not in error state bool isVoiceWorking() const override; std::string sipURIFromID(const LLUUID &id) override; @@ -92,32 +92,32 @@ public: void tuningStart() override; void tuningStop() override; bool inTuningMode() override; - + void tuningSetMicVolume(float volume) override; void tuningSetSpeakerVolume(float volume) override; float tuningGetEnergy(void) override; //@} - + ///////////////////// /// @name Devices //@{ // This returns true when it's safe to bring up the "device settings" dialog in the prefs. bool deviceSettingsAvailable() override; bool deviceSettingsUpdated() override; //return if the list has been updated and never fetched, only to be called from the voicepanel. - + // Requery the WebRTC daemon for the current list of input/output devices. // If you pass true for clearCurrentList, deviceSettingsAvailable() will be false until the query has completed // (use this if you want to know when it's done). // If you pass false, you'll have no way to know when the query finishes, but the device lists will not appear empty in the interim. void refreshDeviceLists(bool clearCurrentList = true) override; - + void setCaptureDevice(const std::string& name) override; void setRenderDevice(const std::string& name) override; - + LLVoiceDeviceList& getCaptureDevices() override; LLVoiceDeviceList& getRenderDevices() override; - //@} - + //@} + void getParticipantList(std::set<LLUUID> &participants) override; bool isParticipant(const LLUUID& speaker_id) override; @@ -125,31 +125,31 @@ public: // virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message) const {return false;}; // Returns true if calling back the session URI after the session has closed is possible. - // Currently this will be false only for PSTN P2P calls. - // NOTE: this will return true if the session can't be found. + // Currently this will be false only for PSTN P2P calls. + // NOTE: this will return true if the session can't be found. BOOL isSessionCallBackPossible(const LLUUID &session_id) override; - + // WebRTC doesn't preclude text im BOOL isSessionTextIMPossible(const LLUUID &session_id) override { return TRUE; } - + //////////////////////////// /// @name Channel stuff //@{ // returns true iff the user is currently in a proximal (local spatial) channel. // Note that gestures should only fire if this returns true. bool inProximalChannel() override; - + void setNonSpatialChannel(const LLSD& channelInfo, bool notify_on_first_join, bool hangup_on_last_leave) override { startAdHocSession(channelInfo, notify_on_first_join, hangup_on_last_leave); } - - bool setSpatialChannel(const LLSD &channelInfo) override + + bool setSpatialChannel(const LLSD &channelInfo) override { processChannels(true); return true; } - + void leaveNonSpatialChannel() override; void processChannels(bool process) override; @@ -163,35 +163,32 @@ public: LLVoiceP2POutgoingCallInterface *getOutgoingCallInterface() override { return nullptr; } LLVoiceP2PIncomingCallInterfacePtr getIncomingCallInterface(const LLSD &voice_call_info) override { return nullptr; } - + ///////////////////////// /// @name Volume/gain //@{ void setVoiceVolume(F32 volume) override; void setMicGain(F32 volume) override; //@} - + ///////////////////////// /// @name enable disable voice and features //@{ void setVoiceEnabled(bool enabled) override; void setMuteMic(bool muted) override; // Set the mute state of the local mic. //@} - + ////////////////////////// /// @name nearby speaker accessors - //@{ - BOOL getVoiceEnabled(const LLUUID& id) override; // true if we've received data for this avatar std::string getDisplayName(const LLUUID& id) override; BOOL isParticipantAvatar(const LLUUID &id) override; BOOL getIsSpeaking(const LLUUID& id) override; BOOL getIsModeratorMuted(const LLUUID& id) override; F32 getCurrentPower(const LLUUID& id) override; // "power" is related to "amplitude" in a defined way. I'm just not sure what the formula is... - BOOL getOnMuteList(const LLUUID& id) override; F32 getUserVolume(const LLUUID& id) override; void setUserVolume(const LLUUID& id, F32 volume) override; // set's volume for specified agent, from 0-1 (where .5 is nominal) //@} - + ////////////////// /// @name LLMuteListObserver //@{ @@ -208,7 +205,7 @@ public: void OnConnectionFailure(const std::string &channelID, const LLUUID& regionID); void sendPositionUpdate(bool force); void updateOwnVolume(); - + ////////////////////////////// /// @name Status notification //@{ @@ -233,10 +230,9 @@ public: { public: participantState(const LLUUID& agent_id); - - bool updateMuteState(); // true if mute state has changed + bool isAvatar(); - + std::string mURI; LLUUID mAvatarID; std::string mDisplayName; @@ -245,7 +241,6 @@ public: F32 mVolume; // the gain applied to the participant bool mIsSpeaking; bool mIsModeratorMuted; - bool mOnMuteList; // true if this avatar is on the user's mute list (and should be muted) }; typedef boost::shared_ptr<participantState> participantStatePtr_t; @@ -256,7 +251,7 @@ public: protected: typedef std::map<const LLUUID, participantStatePtr_t> participantUUIDMap; - + class sessionState { public: @@ -267,7 +262,7 @@ public: static void addSession(const std::string &channelID, ptr_t& session); virtual ~sessionState(); - + participantStatePtr_t addParticipant(const LLUUID& agent_id); void removeParticipant(const participantStatePtr_t &participant); void removeAllParticipants(); @@ -284,14 +279,14 @@ public: virtual bool processConnectionStates(); virtual void sendData(const std::string &data); - + void setMuteMic(bool muted); void setMicGain(F32 volume); void setSpeakerVolume(F32 volume); void setUserVolume(const LLUUID& id, F32 volume); - + void setUserMute(const LLUUID& id, bool mute); - + static void for_each(sessionFunc_t func); static void reapEmptySessions(); @@ -305,7 +300,7 @@ public: std::string mHandle; std::string mChannelID; std::string mName; - + bool mMuted; // this session is muted. F32 mMicGain; // gain for this session. F32 mSpeakerVolume; // volume for this session. @@ -314,7 +309,7 @@ public: participantUUIDMap mParticipantsByUUID; - static bool hasSession(const std::string &sessionID) + static bool hasSession(const std::string &sessionID) { return mSessions.find(sessionID) != mSessions.end(); } bool mHangupOnLastLeave; // notify observers after the session becomes empty. @@ -398,7 +393,7 @@ public: void addCaptureDevice(const LLVoiceDevice& device); void clearRenderDevices(); - void addRenderDevice(const LLVoiceDevice& device); + void addRenderDevice(const LLVoiceDevice& device); void setDevicesListUpdated(bool state); ///////////////////////////// @@ -412,22 +407,22 @@ public: void setEarLocation(S32 loc); - + ///////////////////////////// // Accessors for data related to nearby speakers ///////////////////////////// sessionStatePtr_t findP2PSession(const LLUUID &agent_id); - + sessionStatePtr_t addSession(const std::string &channel_id, sessionState::ptr_t session); void deleteSession(const sessionStatePtr_t &session); - + // Does the actual work to get out of the audio session void leaveAudioSession(); - + friend class LLWebRTCVoiceClientCapResponder; - - + + void lookupName(const LLUUID &id); void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); void avatarNameResolved(const LLUUID &id, const std::string &name); @@ -448,7 +443,7 @@ private: //--- /// Clean up objects created during a voice session. void cleanUp(); - + bool mTuningMode; F32 mTuningMicGain; int mTuningSpeakerVolume; @@ -457,7 +452,7 @@ private: std::string mSpatialSessionCredentials; std::string mMainSessionGroupHandle; // handle of the "main" session group. - + sessionStatePtr_t mSession; // Session state for the current session sessionStatePtr_t mNextSession; // Session state for the session we're trying to join @@ -476,7 +471,7 @@ private: bool inEstateChannel(); LLSD getAudioSessionChannelInfo(); - + void setHidden(bool hidden) override; //virtual void enforceTether(); @@ -485,9 +480,9 @@ private: std::set<LLUUID> getNeighboringRegions() { return mNeighboringRegions; } LLVoiceVersionInfo mVoiceVersion; - + bool mSpatialCoordsDirty; - + LLVector3d mListenerPosition; LLVector3d mListenerRequestedPosition; LLVector3 mListenerVelocity; @@ -498,23 +493,23 @@ private: LLQuaternion mAvatarRot; std::set<LLUUID> mNeighboringRegions; // includes current region - + bool mMuteMic; bool mHidden; //Set to true during teleport to hide the agent's position. - + enum { earLocCamera = 0, // ear at camera earLocAvatar, // ear at avatar earLocMixed // ear at avatar location/camera direction }; - - S32 mEarLocation; - + + S32 mEarLocation; + float mSpeakerVolume; F32 mMicGain; - + bool mVoiceEnabled; bool mProcessChannels; @@ -525,7 +520,7 @@ private: typedef std::set<LLVoiceClientStatusObserver*> status_observer_set_t; status_observer_set_t mStatusObservers; - + void notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status); bool mIsInTuningMode; @@ -544,7 +539,7 @@ class LLVoiceWebRTCStats : public LLSingleton<LLVoiceWebRTCStats> LLSINGLETON(LLVoiceWebRTCStats); LOG_CLASS(LLVoiceWebRTCStats); virtual ~LLVoiceWebRTCStats(); - + private: F64SecondsImplicit mStartTime; @@ -552,7 +547,7 @@ class LLVoiceWebRTCStats : public LLSingleton<LLVoiceWebRTCStats> F64 mConnectTime; U32 mConnectAttempts; - + F64 mProvisionTime; U32 mProvisionAttempts; @@ -571,7 +566,7 @@ class LLVoiceWebRTCStats : public LLSingleton<LLVoiceWebRTCStats> LLSD read(); }; -class LLVoiceWebRTCConnection : +class LLVoiceWebRTCConnection : public llwebrtc::LLWebRTCSignalingObserver, public llwebrtc::LLWebRTCDataObserver { @@ -610,7 +605,7 @@ class LLVoiceWebRTCConnection : virtual void setMuteMic(bool muted); virtual void setMicGain(F32 volume); virtual void setSpeakerVolume(F32 volume); - + void setUserVolume(const LLUUID& id, F32 volume); void setUserMute(const LLUUID& id, bool mute); |