diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 92004554e..9ce08dfa0 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -420,8 +420,25 @@ LLFloaterIMPanel::~LLFloaterIMPanel()
delete mSpeakers;
mSpeakers = NULL;
-
+
+ // End the text IM session if necessary
+ if(LLVoiceClient::instanceExists() && mOtherParticipantUUID.notNull())
+ {
+ switch(mDialog)
+ {
+ case IM_NOTHING_SPECIAL:
+ case IM_SESSION_P2P_INVITE:
+ LLVoiceClient::getInstance()->endUserIMSession(mOtherParticipantUUID);
+ break;
+
+ default:
+ // Appease the compiler
+ break;
+ }
+ }
+
//kicks you out of the voice channel if it is currently active
+
// HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
mVoiceChannel->deactivate();
@@ -1061,12 +1078,20 @@ void deliver_message(const std::string& utf8_text,
EInstantMessage dialog)
{
std::string name;
+ bool sent = false;
gAgent.buildFullname(name);
const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id);
U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE;
+ if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id)))
+ {
+ // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice.
+ sent = LLVoiceClient::getInstance()->sendTextMessage(other_participant_id, utf8_text);
+ }
+
+ if(!sent)
{
// Send message normally.
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index c5b7e66a7..54ca806de 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -354,7 +354,6 @@ BOOL LLVoiceClient::isSessionCallBackPossible(const LLUUID& id)
}
}
-/*
BOOL LLVoiceClient::sendTextMessage(const LLUUID& participant_id, const std::string& message)
{
if (mVoiceModule)
@@ -374,7 +373,6 @@ void LLVoiceClient::endUserIMSession(const LLUUID& participant_id)
mVoiceModule->endUserIMSession(participant_id);
}
}
-*/
//----------------------------------------------
// channels
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index a4a1dba5f..b8cf474cc 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -212,8 +212,8 @@ public:
//@{
virtual BOOL isSessionTextIMPossible(const LLUUID& id)=0;
virtual BOOL isSessionCallBackPossible(const LLUUID& id)=0;
- //virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message)=0;
- //virtual void endUserIMSession(const LLUUID &uuid)=0;
+ virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message)=0;
+ virtual void endUserIMSession(const LLUUID &uuid)=0;
//@}
// authorize the user
@@ -428,8 +428,8 @@ public:
//@{
BOOL isSessionTextIMPossible(const LLUUID& id);
BOOL isSessionCallBackPossible(const LLUUID& id);
- //BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message);
- //void endUserIMSession(const LLUUID &uuid);
+ BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message);
+ void endUserIMSession(const LLUUID &uuid);
//@}
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 8a5f2a299..ce1d09041 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -80,10 +80,10 @@ const int MAX_LOGIN_RETRIES = 12;
// Defines the maximum number of times(in a row) "stateJoiningSession" case for spatial channel is reached in stateMachine()
// which is treated as normal. If this number is exceeded we suspect there is a problem with connection
-// to voice server (EXT-4313). When voice works correctly, there is from 1 to 15 times. 1500 was chosen
+// to voice server (EXT-4313). When voice works correctly, there is from 1 to 15 times. 50 was chosen
// to make sure we don't make mistake when slight connection problems happen- situation when connection to server is
// blocked is VERY rare and it's better to sacrifice response time in this situation for the sake of stability.
-const int MAX_NORMAL_JOINING_SPATIAL_NUM = 1500;
+const int MAX_NORMAL_JOINING_SPATIAL_NUM = 50;
// How often to check for expired voice fonts in seconds
const F32 VOICE_FONT_EXPIRY_INTERVAL = 10.f;
@@ -478,21 +478,17 @@ bool LLVivoxVoiceClient::writeString(const std::string &str)
(const char*)str.data(),
&written);
- if (err == 0 && written == size)
+ if(err == 0)
{
// Success.
result = true;
}
- else if (err == 0 && written != size)
- {
- // Did a short write, log it for now
- LL_WARNS("Voice") << ") short write on socket sending data to vivox daemon." << "Sent " << written << "bytes instead of " << size << LL_ENDL;
- }
- else if (APR_STATUS_IS_EAGAIN(err))
- {
- char buf[MAX_STRING];
- LL_WARNS("Voice") << "EAGAIN error " << err << " (" << apr_strerror(err, buf, MAX_STRING) << ") sending data to vivox daemon." << LL_ENDL;
- }
+ // TODO: handle partial writes (written is number of bytes written)
+ // Need to set socket to non-blocking before this will work.
+// else if(APR_STATUS_IS_EAGAIN(err))
+// {
+// //
+// }
else
{
// Assume any socket error means something bad. For now, just close the socket.
@@ -1130,8 +1126,8 @@ void LLVivoxVoiceClient::stateMachine()
}
else
{
- // loop mic back to render device.
- tuningCaptureStartSendMessage(1); // 1-loop, zero, don't loop
+ // duration parameter is currently unused, per Mike S.
+ tuningCaptureStartSendMessage(10000);
setState(stateMicTuningRunning);
}
@@ -1568,8 +1564,6 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateSessionJoined
case stateSessionJoined: // session handle received
- if (mSpatialJoiningNum > 100)
- llwarns << "There seems to be problem with connecting to a voice channel. Frames to join were " << mSpatialJoiningNum << LL_ENDL;
mSpatialJoiningNum = 0;
// It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4
@@ -1668,7 +1662,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateLeavingSession
case stateLeavingSession: // waiting for terminate session response
// The handler for the Session.Terminate response will transition from here to stateSessionTerminated.
- // Fall through and clean up session before getting terminated event.
+ break;
//MARK: stateSessionTerminated
case stateSessionTerminated:
@@ -1678,7 +1672,6 @@ void LLVivoxVoiceClient::stateMachine()
if(mAudioSession)
{
- leaveAudioSession();
sessionState *oldSession = mAudioSession;
mAudioSession = NULL;
@@ -1838,7 +1831,6 @@ void LLVivoxVoiceClient::loginSendMessage()
<< "" << mAccountPassword << ""
<< "VerifyAnswer"
<< "false"
- << "0"
<< "Application"
<< "5"
<< (autoPostCrashDumps?"true":"")
@@ -2039,7 +2031,6 @@ void LLVivoxVoiceClient::leaveAudioSession()
case stateJoiningSession:
case stateSessionJoined:
case stateRunning:
- case stateSessionTerminated:
if(!mAudioSession->mHandle.empty())
{
@@ -2070,12 +2061,10 @@ void LLVivoxVoiceClient::leaveAudioSession()
case stateJoinSessionFailed:
case stateJoinSessionFailedWaiting:
setState(stateSessionTerminated);
- break;
- case stateLeavingSession: // managed to get back to this case statement before the media gets disconnected.
break;
default:
- LL_WARNS("Voice") << "called from unknown state " << getState() << LL_ENDL;
+ LL_WARNS("Voice") << "called from unknown state" << LL_ENDL;
break;
}
}
@@ -2128,7 +2117,6 @@ void LLVivoxVoiceClient::sessionMediaDisconnectSendMessage(sessionState *session
}
-/* obsolete
void LLVivoxVoiceClient::sessionTextDisconnectSendMessage(sessionState *session)
{
std::ostringstream stream;
@@ -2142,7 +2130,6 @@ void LLVivoxVoiceClient::sessionTextDisconnectSendMessage(sessionState *session)
writeString(stream.str());
}
-*/
void LLVivoxVoiceClient::getCaptureDevicesSendMessage()
{
@@ -2294,15 +2281,14 @@ void LLVivoxVoiceClient::tuningRenderStopSendMessage()
writeString(stream.str());
}
-void LLVivoxVoiceClient::tuningCaptureStartSendMessage(int loop)
+void LLVivoxVoiceClient::tuningCaptureStartSendMessage(int duration)
{
LL_DEBUGS("Voice") << "sending CaptureAudioStart" << LL_ENDL;
std::ostringstream stream;
stream
<< ""
- << "-1"
- << "" << loop << ""
+ << "" << duration << ""
<< "\n\n\n";
writeString(stream.str());
@@ -2516,8 +2502,6 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void)
{
std::ostringstream stream;
- if (getState() != stateRunning) return; // don't send position updates if we are transitioning between out of running.
-
if(mSpatialCoordsDirty)
{
LLVector3 l, u, a, vel;
@@ -2950,25 +2934,15 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
void LLVivoxVoiceClient::sessionConnectResponse(std::string &requestId, int statusCode, std::string &statusString)
{
sessionState *session = findSession(requestId);
- // 1026 is session already has media, somehow mediaconnect was called twice on the same session.
- // set the session info to reflect that the user is already connected.
- if (statusCode == 1026)
- {
- session->mVoiceEnabled = true;
- session->mMediaConnectInProgress = false;
- session->mMediaStreamState = streamStateConnected;
- //session->mTextStreamState = streamStateConnected;
- session->mErrorStatusCode = 0;
- }
- else if (statusCode != 0)
+ if(statusCode != 0)
{
LL_WARNS("Voice") << "Session.Connect response failure (" << statusCode << "): " << statusString << LL_ENDL;
- if (session)
+ if(session)
{
session->mMediaConnectInProgress = false;
session->mErrorStatusCode = statusCode;
session->mErrorStatusString = statusString;
- if (session == mAudioSession)
+ if(session == mAudioSession)
setState(stateJoinSessionFailed);
}
}
@@ -3164,7 +3138,7 @@ void LLVivoxVoiceClient::sessionRemovedEvent(
// Reset the media state (we now have no info)
session->mMediaStreamState = streamStateUnknown;
- //session->mTextStreamState = streamStateUnknown;
+ session->mTextStreamState = streamStateUnknown;
// Conditionally delete the session
reapSession(session);
@@ -3375,9 +3349,8 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent(
switch(state)
{
- case streamStateDisconnecting:
case streamStateIdle:
- // Standard "left audio session", Vivox state 'disconnected'
+ // Standard "left audio session"
session->mVoiceEnabled = false;
session->mMediaConnectInProgress = false;
leftAudioSession(session);
@@ -3387,7 +3360,6 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent(
session->mVoiceEnabled = true;
session->mMediaConnectInProgress = false;
joinedAudioSession(session);
- case streamStateConnecting: // do nothing, but prevents a warning getting into the logs.
break;
case streamStateRinging:
@@ -3422,7 +3394,6 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent(
}
}
-/* Obsolete
void LLVivoxVoiceClient::textStreamUpdatedEvent(
std::string &sessionHandle,
std::string &sessionGroupHandle,
@@ -3469,7 +3440,6 @@ void LLVivoxVoiceClient::textStreamUpdatedEvent(
}
}
}
- obsolete */
void LLVivoxVoiceClient::participantAddedEvent(
std::string &sessionHandle,
@@ -4290,7 +4260,7 @@ LLVivoxVoiceClient::sessionState* LLVivoxVoiceClient::startUserIMSession(const L
if(session->mHandle.empty())
{
// Session isn't active -- start it up.
- sessionCreateSendMessage(session, false, false);
+ sessionCreateSendMessage(session, false, true);
}
else
{
@@ -4301,7 +4271,6 @@ LLVivoxVoiceClient::sessionState* LLVivoxVoiceClient::startUserIMSession(const L
return session;
}
-/* obsolete
BOOL LLVivoxVoiceClient::sendTextMessage(const LLUUID& participant_id, const std::string& message)
{
bool result = false;
@@ -4326,8 +4295,7 @@ BOOL LLVivoxVoiceClient::sendTextMessage(const LLUUID& participant_id, const std
return result;
}
-*/
-/* obsolete
+
void LLVivoxVoiceClient::sendQueuedTextMessages(sessionState *session)
{
if(session->mTextStreamState == 1)
@@ -4356,9 +4324,7 @@ void LLVivoxVoiceClient::sendQueuedTextMessages(sessionState *session)
// Session isn't connected yet, defer until later.
}
}
- obsolete */
-/*
void LLVivoxVoiceClient::endUserIMSession(const LLUUID &uuid)
{
// Figure out if a session with the user exists
@@ -4368,7 +4334,7 @@ void LLVivoxVoiceClient::endUserIMSession(const LLUUID &uuid)
// found the session
if(!session->mHandle.empty())
{
- // sessionTextDisconnectSendMessage(session); // a SLim leftover, not used any more.
+ sessionTextDisconnectSendMessage(session);
}
}
else
@@ -4376,7 +4342,6 @@ void LLVivoxVoiceClient::endUserIMSession(const LLUUID &uuid)
LL_DEBUGS("Voice") << "Session not found for participant ID " << uuid << LL_ENDL;
}
}
-*/
bool LLVivoxVoiceClient::isValidChannel(std::string &sessionHandle)
{
return(findSession(sessionHandle) != NULL);
@@ -4720,8 +4685,6 @@ void LLVivoxVoiceClient::enforceTether(void)
void LLVivoxVoiceClient::updatePosition(void)
{
- // Throttle the position updates to one every 1/10 of a second if we are in an audio session at all
- if (mAudioSession == NULL) return;
LLViewerRegion *region = gAgent.getRegion();
if(region && isAgentAvatarValid())
@@ -6837,10 +6800,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
{
LLVivoxVoiceClient::getInstance()->sessionRemovedEvent(sessionHandle, sessionGroupHandle);
}
- else if (!stricmp(eventTypeCstr, "SessionGroupUpdatedEvent"))
- {
- //TODO, we don't process this event, but we should not WARN that we have received it.
- }
else if (!stricmp(eventTypeCstr, "SessionGroupAddedEvent"))
{
LLVivoxVoiceClient::getInstance()->sessionGroupAddedEvent(sessionGroupHandle);
@@ -6869,11 +6828,19 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
*/
LLVivoxVoiceClient::getInstance()->mediaCompletionEvent(sessionGroupHandle, mediaCompletionType);
}
- /* obsolete, let else statement complain if a text message arrives
else if (!stricmp(eventTypeCstr, "TextStreamUpdatedEvent"))
{
+ /*
+
+ c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg1
+ c1_m1000xFnPP04IpREWNkuw1cOXlhw==1
+ true
+ 1
+ true
+
+ */
LLVivoxVoiceClient::getInstance()->textStreamUpdatedEvent(sessionHandle, sessionGroupHandle, enabled, state, incoming);
- } */
+ }
else if (!stricmp(eventTypeCstr, "ParticipantAddedEvent"))
{
/*
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index ad7df8960..2d723184b 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -92,10 +92,10 @@ public:
virtual bool isParticipant(const LLUUID& speaker_id);
// Send a text message to the specified user, initiating the session if necessary.
- // virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message) const { return false; }
+ virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message);
// close any existing text IM session with the specified user
- //virtual void endUserIMSession(const LLUUID &uuid);
+ virtual void endUserIMSession(const LLUUID &uuid);
// 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.
@@ -242,8 +242,6 @@ protected:
streamStateIdle = 1,
streamStateConnected = 2,
streamStateRinging = 3,
- streamStateConnecting = 6, // same as Vivox session_media_connecting enum
- streamStateDisconnecting = 7, //Same as Vivox session_media_disconnecting enum
};
struct participantState
{
@@ -434,7 +432,7 @@ protected:
void tuningRenderStartSendMessage(const std::string& name, bool loop);
void tuningRenderStopSendMessage();
- void tuningCaptureStartSendMessage(int loop);
+ void tuningCaptureStartSendMessage(int duration);
void tuningCaptureStopSendMessage();
//----------------------------------
@@ -465,7 +463,7 @@ protected:
void accountLoginStateChangeEvent(std::string &accountHandle, int statusCode, std::string &statusString, int state);
void mediaCompletionEvent(std::string &sessionGroupHandle, std::string &mediaCompletionType);
void mediaStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, int statusCode, std::string &statusString, int state, bool incoming);
- // obsolete void textStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, bool enabled, int state, bool incoming);
+ void textStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, bool enabled, int state, bool incoming);
void sessionAddedEvent(std::string &uriString, std::string &alias, std::string &sessionHandle, std::string &sessionGroupHandle, bool isChannel, bool incoming, std::string &nameString, std::string &applicationString);
void sessionGroupAddedEvent(std::string &sessionGroupHandle);
void sessionRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle);
@@ -581,7 +579,7 @@ protected:
void sessionTerminateSendMessage(sessionState *session);
void sessionGroupTerminateSendMessage(sessionState *session);
void sessionMediaDisconnectSendMessage(sessionState *session);
- // void sessionTextDisconnectSendMessage(sessionState *session);
+ void sessionTextDisconnectSendMessage(sessionState *session);
@@ -743,7 +741,7 @@ private:
// start a text IM session with the specified user
// This will be asynchronous, the session may be established at a future time.
sessionState* startUserIMSession(const LLUUID& uuid);
- // obsolete void sendQueuedTextMessages(sessionState *session);
+ void sendQueuedTextMessages(sessionState *session);
void enforceTether(void);
diff --git a/indra/newview/skins/default/xui/en-us/panel_sound_devices.xml b/indra/newview/skins/default/xui/en-us/panel_sound_devices.xml
index b805e16ec..eb6f6a035 100644
--- a/indra/newview/skins/default/xui/en-us/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/en-us/panel_sound_devices.xml
@@ -43,7 +43,7 @@
+ tool_tip="Change the volume using this slider" width="120" />
Please wait