diff options
-rw-r--r-- | linden/indra/newview/app_settings/logcontrol.xml | 5 | ||||
-rw-r--r-- | linden/indra/newview/app_settings/settings.xml | 17 | ||||
-rw-r--r-- | linden/indra/newview/kowopenregionsettings.cpp | 8 | ||||
-rw-r--r-- | linden/indra/newview/llstartup.cpp | 12 | ||||
-rw-r--r-- | linden/indra/newview/llvoiceclient.cpp | 721 | ||||
-rw-r--r-- | linden/indra/newview/llvoiceclient.h | 20 |
6 files changed, 474 insertions, 309 deletions
diff --git a/linden/indra/newview/app_settings/logcontrol.xml b/linden/indra/newview/app_settings/logcontrol.xml index c9e9127..f0db00f 100644 --- a/linden/indra/newview/app_settings/logcontrol.xml +++ b/linden/indra/newview/app_settings/logcontrol.xml | |||
@@ -90,7 +90,12 @@ | |||
90 | <!--<string>TextureCache</string>--> | 90 | <!--<string>TextureCache</string>--> |
91 | <!--<string>Throttle</string>--> | 91 | <!--<string>Throttle</string>--> |
92 | <!--<string>Voice</string>--> | 92 | <!--<string>Voice</string>--> |
93 | <!--<string>"VoiceCaps"</string>--> | ||
94 | <!--<string>VoiceSession</string>--> | ||
95 | <!--<string>VoiceDaemon</string>--> | ||
96 | <!--<string>VoiceDevice</string>--> | ||
93 | <!--<string>VivoxProtocolParser</string>--> | 97 | <!--<string>VivoxProtocolParser</string>--> |
98 | |||
94 | <!--<string>Wearable</string>--> | 99 | <!--<string>Wearable</string>--> |
95 | <!--<string>WindLight</string>--> | 100 | <!--<string>WindLight</string>--> |
96 | 101 | ||
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 24ff619..eac7674 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml | |||
@@ -39,16 +39,27 @@ | |||
39 | <key>Value</key> | 39 | <key>Value</key> |
40 | <integer>0</integer> | 40 | <integer>0</integer> |
41 | </map> | 41 | </map> |
42 | <key>VoiceModule</key> | 42 | <key>VoiceModuleMumble</key> |
43 | <map> | 43 | <map> |
44 | <key>Comment</key> | 44 | <key>Comment</key> |
45 | <string>Executable file that runs voice. Platform specific parts (like .exe on windows) are added automatically.</string> | 45 | <string>Executable file that runs mumble voice . Platform specific parts (like .exe on windows) are added automatically, paths are stripped off if present. Defaults to mumble if empty</string> |
46 | <key>Persist</key> | 46 | <key>Persist</key> |
47 | <integer>1</integer> | 47 | <integer>1</integer> |
48 | <key>Type</key> | 48 | <key>Type</key> |
49 | <string>String</string> | 49 | <string>String</string> |
50 | <key>Value</key> | 50 | <key>Value</key> |
51 | <string>SLVoice</string> | 51 | <string /> |
52 | </map> | ||
53 | <key>VoiceModuleVivox</key> | ||
54 | <map> | ||
55 | <key>Comment</key> | ||
56 | <string>Executable file that runs vivox voice. Platform specific parts (like .exe on windows) are added automatically, paths are stripped off if present. Defaults to SLVoice if empty.</string> | ||
57 | <key>Persist</key> | ||
58 | <integer>1</integer> | ||
59 | <key>Type</key> | ||
60 | <string>String</string> | ||
61 | <key>Value</key> | ||
62 | <string /> | ||
52 | </map> | 63 | </map> |
53 | 64 | ||
54 | <!-- end Aurora-specific settings --> | 65 | <!-- end Aurora-specific settings --> |
diff --git a/linden/indra/newview/kowopenregionsettings.cpp b/linden/indra/newview/kowopenregionsettings.cpp index 0c4bb38..6257147 100644 --- a/linden/indra/newview/kowopenregionsettings.cpp +++ b/linden/indra/newview/kowopenregionsettings.cpp | |||
@@ -36,7 +36,6 @@ | |||
36 | #include "llviewerobject.h" | 36 | #include "llviewerobject.h" |
37 | #include "llfloaterregioninfo.h" | 37 | #include "llfloaterregioninfo.h" |
38 | #include "llfloaterworldmap.h" | 38 | #include "llfloaterworldmap.h" |
39 | #include "llvoiceclient.h" | ||
40 | #include "viewertime.h" | 39 | #include "viewertime.h" |
41 | 40 | ||
42 | //DEBUG includes | 41 | //DEBUG includes |
@@ -205,12 +204,7 @@ class OpenRegionInfoUpdate : public LLHTTPNode | |||
205 | { | 204 | { |
206 | gHippoLimits->mAllowParcelWindLight = body["AllowParcelWindLight"].asInteger() == 1; | 205 | gHippoLimits->mAllowParcelWindLight = body["AllowParcelWindLight"].asInteger() == 1; |
207 | } | 206 | } |
208 | if ( body.has("Voice") ) | 207 | |
209 | { | ||
210 | gSavedSettings.setString("VoiceModule", body["Voice"].asString()); | ||
211 | //gVoiceClient->close(); | ||
212 | //gVoiceClient->start(); | ||
213 | } | ||
214 | 208 | ||
215 | if (limitschanged) | 209 | if (limitschanged) |
216 | gFloaterTools->updateToolsSizeLimits(); | 210 | gFloaterTools->updateToolsSizeLimits(); |
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index e29dc5a..b80a286 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp | |||
@@ -1884,8 +1884,7 @@ bool idle_startup() | |||
1884 | tmp = LLUserAuth::getInstance()->getResponse("max-agent-groups"); | 1884 | tmp = LLUserAuth::getInstance()->getResponse("max-agent-groups"); |
1885 | if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setMaxAgentGroups(atoi(tmp.c_str())); | 1885 | if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setMaxAgentGroups(atoi(tmp.c_str())); |
1886 | 1886 | ||
1887 | tmp = LLUserAuth::getInstance()->getResponse("VoiceConnector"); | 1887 | |
1888 | if (!tmp.empty()) gHippoGridManager->getConnectedGrid()->setVoiceConnector(tmp); | ||
1889 | gHippoGridManager->saveFile(); | 1888 | gHippoGridManager->saveFile(); |
1890 | gHippoLimits->setLimits(); | 1889 | gHippoLimits->setLimits(); |
1891 | 1890 | ||
@@ -1931,8 +1930,7 @@ bool idle_startup() | |||
1931 | } | 1930 | } |
1932 | // else llwarns << "MapServerURL empty"<< llendl; | 1931 | // else llwarns << "MapServerURL empty"<< llendl; |
1933 | 1932 | ||
1934 | // Pass the user information to the voice chat server interface. | 1933 | |
1935 | gVoiceClient->userAuthorized(firstname, lastname, gAgentID); | ||
1936 | } | 1934 | } |
1937 | else // if(successful_login) | 1935 | else // if(successful_login) |
1938 | { | 1936 | { |
@@ -2065,6 +2063,7 @@ bool idle_startup() | |||
2065 | LL_DEBUGS("AppInitStartupState") << "STATE_SEED_CAP_GRANTED" << LL_ENDL; | 2063 | LL_DEBUGS("AppInitStartupState") << "STATE_SEED_CAP_GRANTED" << LL_ENDL; |
2066 | update_texture_fetch(); | 2064 | update_texture_fetch(); |
2067 | 2065 | ||
2066 | |||
2068 | if ( gViewerWindow != NULL) | 2067 | if ( gViewerWindow != NULL) |
2069 | { // This isn't the first logon attempt, so show the UI | 2068 | { // This isn't the first logon attempt, so show the UI |
2070 | gViewerWindow->setNormalControlsVisible( TRUE ); | 2069 | gViewerWindow->setNormalControlsVisible( TRUE ); |
@@ -2123,6 +2122,9 @@ bool idle_startup() | |||
2123 | // | 2122 | // |
2124 | LL_INFOS("AppInit") << "Initializing communications..." << LL_ENDL; | 2123 | LL_INFOS("AppInit") << "Initializing communications..." << LL_ENDL; |
2125 | 2124 | ||
2125 | // Pass the user information to the voice chat server interface. | ||
2126 | gVoiceClient->userAuthorized(firstname, lastname, gAgentID); | ||
2127 | |||
2126 | // register callbacks for messages. . . do this after initial handshake to make sure that we don't catch any unwanted | 2128 | // register callbacks for messages. . . do this after initial handshake to make sure that we don't catch any unwanted |
2127 | register_viewer_callbacks(gMessageSystem); | 2129 | register_viewer_callbacks(gMessageSystem); |
2128 | 2130 | ||
@@ -2142,7 +2144,7 @@ bool idle_startup() | |||
2142 | gCacheName->addObserver(callback_cache_name); | 2144 | gCacheName->addObserver(callback_cache_name); |
2143 | 2145 | ||
2144 | // Load stored cache if possible | 2146 | // Load stored cache if possible |
2145 | LLAppViewer::instance()->loadNameCache(); | 2147 | LLAppViewer::instance()->loadNameCache(); |
2146 | 2148 | ||
2147 | // Start cache in not-running state until we figure out if we have | 2149 | // Start cache in not-running state until we figure out if we have |
2148 | // capabilities for display name lookup | 2150 | // capabilities for display name lookup |
diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp index 2266aab..115f6e8 100644 --- a/linden/indra/newview/llvoiceclient.cpp +++ b/linden/indra/newview/llvoiceclient.cpp | |||
@@ -139,22 +139,23 @@ class LLViewerVoiceAccountProvisionResponder : | |||
139 | public LLHTTPClient::Responder | 139 | public LLHTTPClient::Responder |
140 | { | 140 | { |
141 | public: | 141 | public: |
142 | LLViewerVoiceAccountProvisionResponder(int retries) | 142 | LLViewerVoiceAccountProvisionResponder(int retries, LLUUID response_id) |
143 | { | 143 | { |
144 | mRetries = retries; | 144 | mRetries = retries; |
145 | mResponseID = response_id; | ||
145 | } | 146 | } |
146 | 147 | ||
147 | virtual void error(U32 status, const std::string& reason) | 148 | virtual void error(U32 status, const std::string& reason) |
148 | { | 149 | { |
149 | if ( mRetries > 0 ) | 150 | if ( mRetries > 0 ) |
150 | { | 151 | { |
151 | LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, retrying. status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL; | 152 | LL_DEBUGS("VoiceCaps") << "ProvisionVoiceAccountRequest returned an error, retrying. status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL; |
152 | if ( gVoiceClient ) gVoiceClient->requestVoiceAccountProvision( | 153 | if ( gVoiceClient ) gVoiceClient->requestVoiceAccountProvision( |
153 | mRetries - 1); | 154 | mRetries - 1); |
154 | } | 155 | } |
155 | else | 156 | else |
156 | { | 157 | { |
157 | LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, too many retries (giving up). status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL; | 158 | LL_DEBUGS("VoiceCaps") << "ProvisionVoiceAccountRequest returned an error, too many retries (giving up). status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL; |
158 | if ( gVoiceClient ) gVoiceClient->giveUp(); | 159 | if ( gVoiceClient ) gVoiceClient->giveUp(); |
159 | } | 160 | } |
160 | } | 161 | } |
@@ -166,7 +167,7 @@ public: | |||
166 | std::string voice_sip_uri_hostname; | 167 | std::string voice_sip_uri_hostname; |
167 | std::string voice_account_server_uri; | 168 | std::string voice_account_server_uri; |
168 | 169 | ||
169 | LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << ll_pretty_print_sd(content) << LL_ENDL; | 170 | LL_DEBUGS("VoiceCaps") << "ProvisionVoiceAccountRequest response:" << ll_pretty_print_sd(content) << LL_ENDL; |
170 | 171 | ||
171 | if(content.has("voice_sip_uri_hostname")) | 172 | if(content.has("voice_sip_uri_hostname")) |
172 | voice_sip_uri_hostname = content["voice_sip_uri_hostname"].asString(); | 173 | voice_sip_uri_hostname = content["voice_sip_uri_hostname"].asString(); |
@@ -179,12 +180,14 @@ public: | |||
179 | content["username"].asString(), | 180 | content["username"].asString(), |
180 | content["password"].asString(), | 181 | content["password"].asString(), |
181 | voice_sip_uri_hostname, | 182 | voice_sip_uri_hostname, |
182 | voice_account_server_uri); | 183 | voice_account_server_uri, |
184 | mResponseID); | ||
183 | } | 185 | } |
184 | } | 186 | } |
185 | 187 | ||
186 | private: | 188 | private: |
187 | int mRetries; | 189 | int mRetries; |
190 | LLUUID mResponseID; | ||
188 | }; | 191 | }; |
189 | 192 | ||
190 | /** | 193 | /** |
@@ -364,7 +367,7 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl( | |||
364 | // If this message isn't set to be squelched, output the raw XML received. | 367 | // If this message isn't set to be squelched, output the raw XML received. |
365 | if(!squelchDebugOutput) | 368 | if(!squelchDebugOutput) |
366 | { | 369 | { |
367 | LL_DEBUGS("Voice") << "parsing: " << mInput.substr(start, delim - start) << LL_ENDL; | 370 | LL_DEBUGS("VivoxProtocolParser") << "parsing: " << mInput.substr(start, delim - start) << LL_ENDL; |
368 | } | 371 | } |
369 | 372 | ||
370 | start = delim + 3; | 373 | start = delim + 3; |
@@ -378,7 +381,7 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl( | |||
378 | if(!gVoiceClient->mConnected) | 381 | if(!gVoiceClient->mConnected) |
379 | { | 382 | { |
380 | // If voice has been disabled, we just want to close the socket. This does so. | 383 | // If voice has been disabled, we just want to close the socket. This does so. |
381 | LL_INFOS("Voice") << "returning STATUS_STOP" << LL_ENDL; | 384 | LL_INFOS("VivoxProtocolParser") << "returning STATUS_STOP" << LL_ENDL; |
382 | return STATUS_STOP; | 385 | return STATUS_STOP; |
383 | } | 386 | } |
384 | 387 | ||
@@ -1008,12 +1011,13 @@ static LLVoiceClientFriendsObserver *friendslist_listener = NULL; | |||
1008 | class LLVoiceClientCapResponder : public LLHTTPClient::Responder | 1011 | class LLVoiceClientCapResponder : public LLHTTPClient::Responder |
1009 | { | 1012 | { |
1010 | public: | 1013 | public: |
1011 | LLVoiceClientCapResponder(void){}; | 1014 | LLVoiceClientCapResponder(LLUUID response_id):mResponseID(response_id) {}; |
1012 | 1015 | ||
1013 | virtual void error(U32 status, const std::string& reason); // called with bad status codes | 1016 | virtual void error(U32 status, const std::string& reason); // called with bad status codes |
1014 | virtual void result(const LLSD& content); | 1017 | virtual void result(const LLSD& content); |
1015 | 1018 | ||
1016 | private: | 1019 | private: |
1020 | LLUUID mResponseID; | ||
1017 | }; | 1021 | }; |
1018 | 1022 | ||
1019 | void LLVoiceClientCapResponder::error(U32 status, const std::string& reason) | 1023 | void LLVoiceClientCapResponder::error(U32 status, const std::string& reason) |
@@ -1027,7 +1031,7 @@ void LLVoiceClientCapResponder::result(const LLSD& content) | |||
1027 | { | 1031 | { |
1028 | LLSD::map_const_iterator iter; | 1032 | LLSD::map_const_iterator iter; |
1029 | 1033 | ||
1030 | LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest response:" << ll_pretty_print_sd(content) << LL_ENDL; | 1034 | LL_DEBUGS("VoiceCaps") << "ParcelVoiceInfoRequest response:\n" << ll_pretty_print_sd(content) << LL_ENDL; |
1031 | 1035 | ||
1032 | if ( content.has("voice_credentials") ) | 1036 | if ( content.has("voice_credentials") ) |
1033 | { | 1037 | { |
@@ -1045,7 +1049,7 @@ void LLVoiceClientCapResponder::result(const LLSD& content) | |||
1045 | voice_credentials["channel_credentials"].asString(); | 1049 | voice_credentials["channel_credentials"].asString(); |
1046 | } | 1050 | } |
1047 | 1051 | ||
1048 | gVoiceClient->setSpatialChannel(uri, credentials); | 1052 | gVoiceClient->setSpatialChannel(uri, credentials, mResponseID); |
1049 | } | 1053 | } |
1050 | } | 1054 | } |
1051 | 1055 | ||
@@ -1126,6 +1130,8 @@ LLVoiceClient::LLVoiceClient() | |||
1126 | mAudioSessionChanged = false; | 1130 | mAudioSessionChanged = false; |
1127 | 1131 | ||
1128 | // Initial dirty state | 1132 | // Initial dirty state |
1133 | mAccountActive = false; | ||
1134 | mVAPRequested = false; | ||
1129 | mSpatialCoordsDirty = false; | 1135 | mSpatialCoordsDirty = false; |
1130 | mPTTDirty = true; | 1136 | mPTTDirty = true; |
1131 | mFriendsListDirty = true; | 1137 | mFriendsListDirty = true; |
@@ -1347,6 +1353,7 @@ void LLVoiceClient::userAuthorized(const std::string& firstName, const std::stri | |||
1347 | sConnectingToAgni = LLViewerLogin::getInstance()->isInProductionGrid(); | 1353 | sConnectingToAgni = LLViewerLogin::getInstance()->isInProductionGrid(); |
1348 | 1354 | ||
1349 | mAccountName = nameFromID(agentID); | 1355 | mAccountName = nameFromID(agentID); |
1356 | mAccountActive = true; | ||
1350 | } | 1357 | } |
1351 | 1358 | ||
1352 | void LLVoiceClient::requestVoiceAccountProvision(S32 retries) | 1359 | void LLVoiceClient::requestVoiceAccountProvision(S32 retries) |
@@ -1357,12 +1364,21 @@ void LLVoiceClient::requestVoiceAccountProvision(S32 retries) | |||
1357 | gAgent.getRegion()->getCapability( | 1364 | gAgent.getRegion()->getCapability( |
1358 | "ProvisionVoiceAccountRequest"); | 1365 | "ProvisionVoiceAccountRequest"); |
1359 | 1366 | ||
1360 | if ( url == "" ) return; | 1367 | if ( url.empty() ) |
1368 | { | ||
1369 | mVAPRequested = false; | ||
1370 | mAccountActive = false; | ||
1371 | setState(stateDisableCleanup); | ||
1372 | } | ||
1373 | |||
1374 | LL_DEBUGS("VoiceCaps") << "Got ProvisionVoiceAccountRequest capability: " | ||
1375 | << url << llendl; | ||
1361 | 1376 | ||
1377 | mVAPCapResponseID.generate(); | ||
1362 | LLHTTPClient::post( | 1378 | LLHTTPClient::post( |
1363 | url, | 1379 | url, |
1364 | LLSD(), | 1380 | LLSD(), |
1365 | new LLViewerVoiceAccountProvisionResponder(retries)); | 1381 | new LLViewerVoiceAccountProvisionResponder(retries, mVAPCapResponseID)); |
1366 | } | 1382 | } |
1367 | } | 1383 | } |
1368 | 1384 | ||
@@ -1370,11 +1386,44 @@ void LLVoiceClient::login( | |||
1370 | const std::string& account_name, | 1386 | const std::string& account_name, |
1371 | const std::string& password, | 1387 | const std::string& password, |
1372 | const std::string& voice_sip_uri_hostname, | 1388 | const std::string& voice_sip_uri_hostname, |
1373 | const std::string& voice_account_server_uri) | 1389 | const std::string& voice_account_server_uri, |
1390 | const LLUUID& response_id) | ||
1374 | { | 1391 | { |
1392 | if(response_id != mVAPCapResponseID) return; | ||
1393 | |||
1394 | std::string new_scheme; | ||
1395 | std::string old_scheme; | ||
1396 | if(!voice_account_server_uri.empty()) | ||
1397 | { | ||
1398 | new_scheme = voice_account_server_uri.substr(0, voice_account_server_uri.find("://")); | ||
1399 | } | ||
1400 | if(!mDaemonScheme.empty()) | ||
1401 | { | ||
1402 | old_scheme = mDaemonScheme; | ||
1403 | } | ||
1404 | else | ||
1405 | { | ||
1406 | old_scheme = new_scheme; | ||
1407 | } | ||
1408 | |||
1375 | mVoiceSIPURIHostName = voice_sip_uri_hostname; | 1409 | mVoiceSIPURIHostName = voice_sip_uri_hostname; |
1376 | mVoiceAccountServerURI = voice_account_server_uri; | 1410 | mVoiceAccountServerURI = voice_account_server_uri; |
1377 | 1411 | ||
1412 | |||
1413 | LL_DEBUGS("VoiceCaps") << "new_scheme: \"" << new_scheme << "\"" | ||
1414 | << "\nold_scheme: \"" << old_scheme << "\"" | ||
1415 | << "\ngateway running: " << ( isGatewayRunning() ? "true" : "false" ) << llendl; | ||
1416 | if(!isGatewayRunning() ) | ||
1417 | { | ||
1418 | loadDaemon(new_scheme); | ||
1419 | } | ||
1420 | else if(old_scheme != new_scheme) | ||
1421 | { | ||
1422 | mAccountActive = true; | ||
1423 | setState(stateDisableCleanup); | ||
1424 | } | ||
1425 | |||
1426 | |||
1378 | if(!mAccountHandle.empty()) | 1427 | if(!mAccountHandle.empty()) |
1379 | { | 1428 | { |
1380 | // Already logged in. | 1429 | // Already logged in. |
@@ -1432,6 +1481,183 @@ void LLVoiceClient::login( | |||
1432 | } | 1481 | } |
1433 | } | 1482 | } |
1434 | 1483 | ||
1484 | void LLVoiceClient::loadDaemon(const std::string& scheme) | ||
1485 | { | ||
1486 | |||
1487 | // Launch the voice daemon | ||
1488 | |||
1489 | |||
1490 | // *FIX:Mani - Using the executable dir instead | ||
1491 | // of mAppRODataDir, the working directory from which the app | ||
1492 | // is launched. | ||
1493 | //std::string exe_path = gDirUtilp->getAppRODataDir(); | ||
1494 | std::string exe_path = gDirUtilp->getExecutableDir(); | ||
1495 | exe_path += gDirUtilp->getDirDelimiter(); | ||
1496 | |||
1497 | #if LL_DARWIN | ||
1498 | exe_path += "../Resources/"; | ||
1499 | #endif | ||
1500 | |||
1501 | //exe_path += gSavedSettings.getString("VoiceModule"); | ||
1502 | llwarns << "Scheme: " << scheme << llendl; | ||
1503 | |||
1504 | std::string module; | ||
1505 | if (scheme == "tcp") | ||
1506 | { | ||
1507 | |||
1508 | module = gSavedSettings.getString("VoiceModuleMumble").empty() ? | ||
1509 | "mumble" : gSavedSettings.getString("VoiceModuleMumble"); | ||
1510 | } | ||
1511 | else | ||
1512 | { | ||
1513 | module = gSavedSettings.getString("VoiceModuleVivox").empty() ? | ||
1514 | "SLVoice" : gSavedSettings.getString("VoiceModuleVivox"); | ||
1515 | } | ||
1516 | |||
1517 | size_t pos_to_tst = module.find_last_of("/\\"); | ||
1518 | if( pos_to_tst != std::string::npos ) | ||
1519 | { | ||
1520 | module = module.substr(pos_to_tst+1); | ||
1521 | } | ||
1522 | |||
1523 | #if LL_WINDOWS | ||
1524 | std::string extension = ".exe"; | ||
1525 | if ( module.rfind(extension) != module.length()-extension.length()) | ||
1526 | { | ||
1527 | module.append(extension); | ||
1528 | } | ||
1529 | #endif | ||
1530 | |||
1531 | exe_path.append(module); | ||
1532 | |||
1533 | // See if the vivox executable exists | ||
1534 | llstat s; | ||
1535 | if(!LLFile::stat(exe_path, &s)) | ||
1536 | { | ||
1537 | // vivox executable exists. Build the command line and launch the daemon. | ||
1538 | // SLIM SDK: these arguments are no longer necessary. | ||
1539 | // std::string args = " -p tcp -h -c"; | ||
1540 | std::string args; | ||
1541 | std::string cmd; | ||
1542 | std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); | ||
1543 | |||
1544 | if(loglevel.empty()) | ||
1545 | { | ||
1546 | loglevel = "-1"; // turn logging off completely | ||
1547 | } | ||
1548 | |||
1549 | args += " -ll "; | ||
1550 | args += loglevel; | ||
1551 | |||
1552 | llwarns << "Voice loaded from: " << exe_path << " " << args << LL_ENDL; | ||
1553 | |||
1554 | #if LL_WINDOWS | ||
1555 | PROCESS_INFORMATION pinfo; | ||
1556 | STARTUPINFOA sinfo; | ||
1557 | memset(&sinfo, 0, sizeof(sinfo)); | ||
1558 | std::string exe_dir = gDirUtilp->getAppRODataDir(); | ||
1559 | |||
1560 | |||
1561 | // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string... | ||
1562 | char *args2 = new char[args.size() + 1]; | ||
1563 | strcpy(args2, args.c_str()); | ||
1564 | |||
1565 | if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo)) | ||
1566 | { | ||
1567 | // DWORD dwErr = GetLastError(); | ||
1568 | } | ||
1569 | else | ||
1570 | { | ||
1571 | // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on | ||
1572 | // CloseHandle(pinfo.hProcess); // stops leaks - nothing else | ||
1573 | sGatewayHandle = pinfo.hProcess; | ||
1574 | CloseHandle(pinfo.hThread); // stops leaks - nothing else | ||
1575 | } | ||
1576 | |||
1577 | delete[] args2; | ||
1578 | #else // LL_WINDOWS | ||
1579 | // This should be the same for mac and linux | ||
1580 | { | ||
1581 | std::vector<std::string> arglist; | ||
1582 | arglist.push_back(exe_path); | ||
1583 | |||
1584 | // Split the argument string into separate strings for each argument | ||
1585 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
1586 | boost::char_separator<char> sep(" "); | ||
1587 | tokenizer tokens(args, sep); | ||
1588 | tokenizer::iterator token_iter; | ||
1589 | |||
1590 | for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) | ||
1591 | { | ||
1592 | arglist.push_back(*token_iter); | ||
1593 | } | ||
1594 | |||
1595 | // create an argv vector for the child process | ||
1596 | char **fakeargv = new char*[arglist.size() + 1]; | ||
1597 | int i; | ||
1598 | for(i=0; i < arglist.size(); i++) | ||
1599 | fakeargv[i] = const_cast<char*>(arglist[i].c_str()); | ||
1600 | |||
1601 | fakeargv[i] = NULL; | ||
1602 | |||
1603 | fflush(NULL); // flush all buffers before the child inherits them | ||
1604 | pid_t id = vfork(); | ||
1605 | if(id == 0) | ||
1606 | { | ||
1607 | // child | ||
1608 | execv(exe_path.c_str(), fakeargv); | ||
1609 | |||
1610 | // If we reach this point, the exec failed. | ||
1611 | // Use _exit() instead of exit() per the vfork man page. | ||
1612 | _exit(0); | ||
1613 | } | ||
1614 | |||
1615 | // parent | ||
1616 | delete[] fakeargv; | ||
1617 | sGatewayPID = id; | ||
1618 | |||
1619 | } | ||
1620 | |||
1621 | #endif // LL_WINDOWS | ||
1622 | |||
1623 | mDaemonScheme = scheme; | ||
1624 | mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost").c_str(), gSavedSettings.getU32("VoicePort")); | ||
1625 | |||
1626 | // Dirty the states we'll need to sync with the daemon when it comes up. | ||
1627 | mPTTDirty = true; | ||
1628 | mMicVolumeDirty = true; | ||
1629 | mSpeakerVolumeDirty = true; | ||
1630 | mSpeakerMuteDirty = true; | ||
1631 | // These only need to be set if they're not default (i.e. empty string). | ||
1632 | mCaptureDeviceDirty = !mCaptureDevice.empty(); | ||
1633 | mRenderDeviceDirty = !mRenderDevice.empty(); | ||
1634 | |||
1635 | mMainSessionGroupHandle.clear(); | ||
1636 | |||
1637 | // kick in | ||
1638 | |||
1639 | mUpdateTimer.start(); | ||
1640 | mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS); | ||
1641 | |||
1642 | setState(stateDaemonLaunched); | ||
1643 | |||
1644 | //trigger parcel changed in the state engine | ||
1645 | mCurrentRegionName.append("kick in"); | ||
1646 | |||
1647 | |||
1648 | } | ||
1649 | else | ||
1650 | { | ||
1651 | LL_WARNS("Voice") << exe_path << " not found." << LL_ENDL; | ||
1652 | mAccountActive = false; | ||
1653 | setState(stateDisableCleanup); | ||
1654 | } | ||
1655 | |||
1656 | // we are done, re-allow ProvisionVoiceAccountRequest | ||
1657 | mVAPRequested = false; | ||
1658 | } | ||
1659 | |||
1660 | |||
1435 | void LLVoiceClient::idle(void* user_data) | 1661 | void LLVoiceClient::idle(void* user_data) |
1436 | { | 1662 | { |
1437 | LLVoiceClient* self = (LLVoiceClient*)user_data; | 1663 | LLVoiceClient* self = (LLVoiceClient*)user_data; |
@@ -1537,11 +1763,20 @@ void LLVoiceClient::start() | |||
1537 | 1763 | ||
1538 | void LLVoiceClient::stateMachine() | 1764 | void LLVoiceClient::stateMachine() |
1539 | { | 1765 | { |
1766 | if( stateJail == getState()) | ||
1767 | { | ||
1768 | return; | ||
1769 | } | ||
1770 | |||
1771 | if(gSavedSettings.getBOOL("CmdLineDisableVoice")) | ||
1772 | { | ||
1773 | // Voice is locked out, we must not launch the vivox daemon. | ||
1774 | setState(stateJail); | ||
1775 | } | ||
1540 | 1776 | ||
1541 | // Disable voice as long as the viewer is disconnected from the sim (login/relog) | 1777 | // Disable voice as long as the viewer is disconnected from the sim (login/relog) |
1542 | setVoiceEnabled(!gDisconnected | 1778 | setVoiceEnabled(!gDisconnected |
1543 | && gSavedSettings.getBOOL("EnableVoiceChat") | 1779 | && gSavedSettings.getBOOL("EnableVoiceChat") ); |
1544 | && !gSavedSettings.getBOOL("CmdLineDisableVoice") ); | ||
1545 | 1780 | ||
1546 | if(mVoiceEnabled) | 1781 | if(mVoiceEnabled) |
1547 | { | 1782 | { |
@@ -1560,12 +1795,8 @@ void LLVoiceClient::stateMachine() | |||
1560 | { | 1795 | { |
1561 | // if voice was turned off after the daemon was launched but before we could connect to it, we may need to issue a kill. | 1796 | // if voice was turned off after the daemon was launched but before we could connect to it, we may need to issue a kill. |
1562 | LL_WARNS("Voice") << "Disabling voice before connection to daemon, terminating." << LL_ENDL; | 1797 | LL_WARNS("Voice") << "Disabling voice before connection to daemon, terminating." << LL_ENDL; |
1563 | killGateway(); | ||
1564 | } | 1798 | } |
1565 | 1799 | ||
1566 | logout(); | ||
1567 | connectorShutdown(); | ||
1568 | |||
1569 | setState(stateDisableCleanup); | 1800 | setState(stateDisableCleanup); |
1570 | } | 1801 | } |
1571 | } | 1802 | } |
@@ -1580,42 +1811,23 @@ void LLVoiceClient::stateMachine() | |||
1580 | { | 1811 | { |
1581 | S32 parcelLocalID = parcel->getLocalID(); | 1812 | S32 parcelLocalID = parcel->getLocalID(); |
1582 | std::string regionName = region->getName(); | 1813 | std::string regionName = region->getName(); |
1583 | std::string capURI = region->getCapability("ParcelVoiceInfoRequest"); | 1814 | |
1584 | |||
1585 | // LL_DEBUGS("Voice") << "Region name = \"" << regionName << "\", parcel local ID = " << parcelLocalID << ", cap URI = \"" << capURI << "\"" << LL_ENDL; | ||
1586 | 1815 | ||
1587 | // The region name starts out empty and gets filled in later. | 1816 | // The region name starts out empty and gets filled in later. |
1588 | // Also, the cap gets filled in a short time after the region cross, but a little too late for our purposes. | 1817 | // Also, the cap gets filled in a short time after the region cross, but a little too late for our purposes. |
1589 | // If either is empty, wait for the next time around. | 1818 | // If either is empty, wait for the next time around. |
1590 | if(!regionName.empty()) | 1819 | if(/*getState() >= stateNoChannel &&*/ !regionName.empty()) |
1591 | { | 1820 | { |
1592 | if(!capURI.empty()) | 1821 | |
1593 | { | 1822 | if((parcelLocalID != mCurrentParcelLocalID) || (regionName != mCurrentRegionName)) |
1594 | if((parcelLocalID != mCurrentParcelLocalID) || (regionName != mCurrentRegionName)) | ||
1595 | { | ||
1596 | // We have changed parcels. Initiate a parcel channel lookup. | ||
1597 | mCurrentParcelLocalID = parcelLocalID; | ||
1598 | mCurrentRegionName = regionName; | ||
1599 | |||
1600 | parcelChanged(); | ||
1601 | } | ||
1602 | } | ||
1603 | else | ||
1604 | { | 1823 | { |
1605 | static int count = 0; | 1824 | // We have changed parcels. Initiate a parcel channel lookup. |
1606 | static int count2 = 0; | 1825 | mCurrentParcelLocalID = parcelLocalID; |
1607 | static int num = 1; | 1826 | mCurrentRegionName = regionName; |
1608 | ++count; | 1827 | |
1609 | if (count % num == 0) | 1828 | parcelChanged(); |
1610 | { | ||
1611 | LL_DEBUGS("Voice") << "region doesn't have ParcelVoiceInfoRequest capability. This is normal for a short time after teleporting, but bad if it persists for very long (" << count << ")." << LL_ENDL; | ||
1612 | if (num < 1000 && ++count2 == 10) | ||
1613 | { | ||
1614 | num *= 10; | ||
1615 | count2 = 0; | ||
1616 | } | ||
1617 | } | ||
1618 | } | 1829 | } |
1830 | |||
1619 | } | 1831 | } |
1620 | } | 1832 | } |
1621 | } | 1833 | } |
@@ -1624,22 +1836,34 @@ void LLVoiceClient::stateMachine() | |||
1624 | { | 1836 | { |
1625 | //MARK: stateDisableCleanup | 1837 | //MARK: stateDisableCleanup |
1626 | case stateDisableCleanup: | 1838 | case stateDisableCleanup: |
1627 | // Clean up and reset everything. | 1839 | // Clean up and reset everything. |
1840 | |||
1841 | mVAPCapResponseID.setNull(); | ||
1842 | mPIRCapResponseID.setNull(); | ||
1843 | |||
1844 | if(isGatewayRunning()) | ||
1845 | { | ||
1846 | killGateway(); | ||
1847 | } | ||
1848 | logoutSendMessage(); | ||
1849 | mConnected = false; | ||
1850 | |||
1851 | |||
1628 | closeSocket(); | 1852 | closeSocket(); |
1629 | deleteAllSessions(); | 1853 | deleteAllSessions(); |
1630 | deleteAllBuddies(); | 1854 | deleteAllBuddies(); |
1631 | 1855 | ||
1632 | mConnectorHandle.clear(); | 1856 | mConnectorHandle.clear(); |
1633 | mAccountHandle.clear(); | 1857 | mAccountHandle.clear(); |
1634 | mAccountPassword.clear(); | 1858 | mAccountPassword.clear(); |
1635 | mVoiceAccountServerURI.clear(); | 1859 | mVoiceAccountServerURI.clear(); |
1636 | 1860 | mVAPRequested = false; | |
1637 | setState(stateDisabled); | 1861 | setState(stateDisabled); |
1638 | break; | 1862 | break; |
1639 | 1863 | ||
1640 | //MARK: stateDisabled | 1864 | //MARK: stateDisabled |
1641 | case stateDisabled: | 1865 | case stateDisabled: |
1642 | if(mTuningMode || (mVoiceEnabled && !mAccountName.empty())) | 1866 | if(mTuningMode || (mVoiceEnabled && mAccountActive && !mAccountName.empty())) |
1643 | { | 1867 | { |
1644 | setState(stateStart); | 1868 | setState(stateStart); |
1645 | } | 1869 | } |
@@ -1647,165 +1871,26 @@ void LLVoiceClient::stateMachine() | |||
1647 | 1871 | ||
1648 | //MARK: stateStart | 1872 | //MARK: stateStart |
1649 | case stateStart: | 1873 | case stateStart: |
1650 | if(gSavedSettings.getBOOL("CmdLineDisableVoice")) | 1874 | { |
1875 | bool have_region = (NULL != gAgent.getRegion() ); | ||
1876 | if(mVoiceEnabled && !mVAPRequested && !mAccountName.empty() && have_region) | ||
1651 | { | 1877 | { |
1652 | // Voice is locked out, we must not launch the vivox daemon. | 1878 | mVAPRequested = true; |
1653 | setState(stateJail); | 1879 | requestVoiceAccountProvision(); |
1654 | } | 1880 | } |
1655 | else if(!isGatewayRunning()) | 1881 | } break; |
1656 | { | ||
1657 | if(true) | ||
1658 | { | ||
1659 | // Launch the voice daemon | ||
1660 | |||
1661 | // *FIX:Mani - Using the executable dir instead | ||
1662 | // of mAppRODataDir, the working directory from which the app | ||
1663 | // is launched. | ||
1664 | //std::string exe_path = gDirUtilp->getAppRODataDir(); | ||
1665 | std::string exe_path = gDirUtilp->getExecutableDir(); | ||
1666 | exe_path += gDirUtilp->getDirDelimiter(); | ||
1667 | #if LL_DARWIN | ||
1668 | exe_path += "../Resources/"; | ||
1669 | #endif | ||
1670 | exe_path += gSavedSettings.getString("VoiceModule"); | ||
1671 | #if LL_WINDOWS | ||
1672 | exe_path += ".exe"; | ||
1673 | #endif | ||
1674 | // See if the vivox executable exists | ||
1675 | llstat s; | ||
1676 | if(!LLFile::stat(exe_path, &s)) | ||
1677 | { | ||
1678 | // vivox executable exists. Build the command line and launch the daemon. | ||
1679 | // SLIM SDK: these arguments are no longer necessary. | ||
1680 | // std::string args = " -p tcp -h -c"; | ||
1681 | std::string args; | ||
1682 | std::string cmd; | ||
1683 | std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); | ||
1684 | |||
1685 | if(loglevel.empty()) | ||
1686 | { | ||
1687 | loglevel = "-1"; // turn logging off completely | ||
1688 | } | ||
1689 | |||
1690 | args += " -ll "; | ||
1691 | args += loglevel; | ||
1692 | |||
1693 | LL_DEBUGS("Voice") << "Args for SLVoice: " << args << LL_ENDL; | ||
1694 | |||
1695 | #if LL_WINDOWS | ||
1696 | PROCESS_INFORMATION pinfo; | ||
1697 | STARTUPINFOA sinfo; | ||
1698 | memset(&sinfo, 0, sizeof(sinfo)); | ||
1699 | std::string exe_dir = gDirUtilp->getAppRODataDir(); | ||
1700 | cmd = gSavedSettings.getString("VoiceModule"); | ||
1701 | cmd += ".exe"; | ||
1702 | cmd += args; | ||
1703 | |||
1704 | // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string... | ||
1705 | char *args2 = new char[args.size() + 1]; | ||
1706 | strcpy(args2, args.c_str()); | ||
1707 | |||
1708 | if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo)) | ||
1709 | { | ||
1710 | // DWORD dwErr = GetLastError(); | ||
1711 | } | ||
1712 | else | ||
1713 | { | ||
1714 | // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on | ||
1715 | // CloseHandle(pinfo.hProcess); // stops leaks - nothing else | ||
1716 | sGatewayHandle = pinfo.hProcess; | ||
1717 | CloseHandle(pinfo.hThread); // stops leaks - nothing else | ||
1718 | } | ||
1719 | |||
1720 | delete[] args2; | ||
1721 | #else // LL_WINDOWS | ||
1722 | // This should be the same for mac and linux | ||
1723 | { | ||
1724 | std::vector<std::string> arglist; | ||
1725 | arglist.push_back(exe_path); | ||
1726 | |||
1727 | // Split the argument string into separate strings for each argument | ||
1728 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | ||
1729 | boost::char_separator<char> sep(" "); | ||
1730 | tokenizer tokens(args, sep); | ||
1731 | tokenizer::iterator token_iter; | ||
1732 | |||
1733 | for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) | ||
1734 | { | ||
1735 | arglist.push_back(*token_iter); | ||
1736 | } | ||
1737 | |||
1738 | // create an argv vector for the child process | ||
1739 | char **fakeargv = new char*[arglist.size() + 1]; | ||
1740 | int i; | ||
1741 | for(i=0; i < arglist.size(); i++) | ||
1742 | fakeargv[i] = const_cast<char*>(arglist[i].c_str()); | ||
1743 | |||
1744 | fakeargv[i] = NULL; | ||
1745 | |||
1746 | fflush(NULL); // flush all buffers before the child inherits them | ||
1747 | pid_t id = vfork(); | ||
1748 | if(id == 0) | ||
1749 | { | ||
1750 | // child | ||
1751 | execv(exe_path.c_str(), fakeargv); | ||
1752 | |||
1753 | // If we reach this point, the exec failed. | ||
1754 | // Use _exit() instead of exit() per the vfork man page. | ||
1755 | _exit(0); | ||
1756 | } | ||
1757 | |||
1758 | // parent | ||
1759 | delete[] fakeargv; | ||
1760 | sGatewayPID = id; | ||
1761 | } | ||
1762 | #endif // LL_WINDOWS | ||
1763 | mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost").c_str(), gSavedSettings.getU32("VoicePort")); | ||
1764 | } | ||
1765 | else | ||
1766 | { | ||
1767 | LL_WARNS("Voice") << exe_path << " not found." << LL_ENDL; | ||
1768 | mVoiceEnabled = false; | ||
1769 | } | ||
1770 | } | ||
1771 | else | ||
1772 | { | ||
1773 | // SLIM SDK: port changed from 44124 to 44125. | ||
1774 | // We can connect to a client gateway running on another host. This is useful for testing. | ||
1775 | // To do this, launch the gateway on a nearby host like this: | ||
1776 | // vivox-gw.exe -p tcp -i 0.0.0.0:44125 | ||
1777 | // and put that host's IP address here. | ||
1778 | mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost"), gSavedSettings.getU32("VoicePort")); | ||
1779 | } | ||
1780 | |||
1781 | mUpdateTimer.start(); | ||
1782 | mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS); | ||
1783 | |||
1784 | setState(stateDaemonLaunched); | ||
1785 | |||
1786 | // Dirty the states we'll need to sync with the daemon when it comes up. | ||
1787 | mPTTDirty = true; | ||
1788 | mMicVolumeDirty = true; | ||
1789 | mSpeakerVolumeDirty = true; | ||
1790 | mSpeakerMuteDirty = true; | ||
1791 | // These only need to be set if they're not default (i.e. empty string). | ||
1792 | mCaptureDeviceDirty = !mCaptureDevice.empty(); | ||
1793 | mRenderDeviceDirty = !mRenderDevice.empty(); | ||
1794 | |||
1795 | mMainSessionGroupHandle.clear(); | ||
1796 | } | ||
1797 | break; | ||
1798 | 1882 | ||
1799 | //MARK: stateDaemonLaunched | 1883 | //MARK: stateDaemonLaunched |
1800 | case stateDaemonLaunched: | 1884 | case stateDaemonLaunched: |
1801 | if(mUpdateTimer.hasExpired()) | 1885 | if(mUpdateTimer.hasExpired()) |
1802 | { | 1886 | { |
1803 | LL_DEBUGS("Voice") << "Connecting to vivox daemon" << LL_ENDL; | 1887 | |
1804 | |||
1805 | mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS); | 1888 | mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS); |
1806 | 1889 | ||
1807 | if(!mSocket) | 1890 | if(!mSocket) |
1808 | { | 1891 | { |
1892 | LL_DEBUGS("VoiceDaemon") << "Connecting to voice daemon. Protocol: " | ||
1893 | << mDaemonScheme << LL_ENDL; | ||
1809 | mSocket = LLSocket::create(LLSocket::STREAM_TCP); | 1894 | mSocket = LLSocket::create(LLSocket::STREAM_TCP); |
1810 | } | 1895 | } |
1811 | 1896 | ||
@@ -1817,6 +1902,7 @@ void LLVoiceClient::stateMachine() | |||
1817 | else | 1902 | else |
1818 | { | 1903 | { |
1819 | // If the connect failed, the socket may have been put into a bad state. Delete it. | 1904 | // If the connect failed, the socket may have been put into a bad state. Delete it. |
1905 | LL_DEBUGS("VoiceDaemon") << "voice daemon not ready yet, retrying" << LL_ENDL; | ||
1820 | closeSocket(); | 1906 | closeSocket(); |
1821 | } | 1907 | } |
1822 | } | 1908 | } |
@@ -1871,24 +1957,16 @@ void LLVoiceClient::stateMachine() | |||
1871 | } | 1957 | } |
1872 | else if(!mAccountName.empty() && mVoiceEnabled) | 1958 | else if(!mAccountName.empty() && mVoiceEnabled) |
1873 | { | 1959 | { |
1874 | LLViewerRegion *region = gAgent.getRegion(); | 1960 | if ( mAccountPassword.empty() ) |
1875 | |||
1876 | if(region) | ||
1877 | { | 1961 | { |
1878 | if ( region->getCapability("ProvisionVoiceAccountRequest") != "" ) | 1962 | requestVoiceAccountProvision(); |
1879 | { | 1963 | } |
1880 | if ( mAccountPassword.empty() ) | 1964 | else |
1881 | { | 1965 | { |
1882 | requestVoiceAccountProvision(); | 1966 | setState(stateConnectorStart); |
1883 | } | ||
1884 | setState(stateConnectorStart); | ||
1885 | } | ||
1886 | else | ||
1887 | { | ||
1888 | LL_DEBUGS("Voice") << "region doesn't have ProvisionVoiceAccountRequest capability!" << LL_ENDL; | ||
1889 | } | ||
1890 | } | 1967 | } |
1891 | } | 1968 | } |
1969 | |||
1892 | break; | 1970 | break; |
1893 | 1971 | ||
1894 | //MARK: stateMicTuningStart | 1972 | //MARK: stateMicTuningStart |
@@ -2025,7 +2103,8 @@ void LLVoiceClient::stateMachine() | |||
2025 | if(mLoginRetryCount > MAX_LOGIN_RETRIES) | 2103 | if(mLoginRetryCount > MAX_LOGIN_RETRIES) |
2026 | { | 2104 | { |
2027 | LL_WARNS("Voice") << "too many login retries, giving up." << LL_ENDL; | 2105 | LL_WARNS("Voice") << "too many login retries, giving up." << LL_ENDL; |
2028 | setState(stateLoginFailed); | 2106 | mAccountActive = false; |
2107 | setState(stateDisableCleanup); | ||
2029 | } | 2108 | } |
2030 | else | 2109 | else |
2031 | { | 2110 | { |
@@ -2569,7 +2648,7 @@ void LLVoiceClient::sessionGroupCreateSendMessage() | |||
2569 | 2648 | ||
2570 | void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAudio, bool startText) | 2649 | void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAudio, bool startText) |
2571 | { | 2650 | { |
2572 | LL_DEBUGS("Voice") << "requesting create: " << session->mSIPURI << LL_ENDL; | 2651 | LL_DEBUGS("VoiceSession") << "requesting create: " << session->mSIPURI << LL_ENDL; |
2573 | 2652 | ||
2574 | session->mCreateInProgress = true; | 2653 | session->mCreateInProgress = true; |
2575 | if(startAudio) | 2654 | if(startAudio) |
@@ -2605,7 +2684,7 @@ void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAu | |||
2605 | 2684 | ||
2606 | void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio, bool startText) | 2685 | void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio, bool startText) |
2607 | { | 2686 | { |
2608 | LL_DEBUGS("Voice") << "requesting create: " << session->mSIPURI << LL_ENDL; | 2687 | LL_DEBUGS("VoiceSession") << "requesting create: " << session->mSIPURI << LL_ENDL; |
2609 | 2688 | ||
2610 | session->mCreateInProgress = true; | 2689 | session->mCreateInProgress = true; |
2611 | if(startAudio) | 2690 | if(startAudio) |
@@ -2642,7 +2721,7 @@ void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, boo | |||
2642 | 2721 | ||
2643 | void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session) | 2722 | void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session) |
2644 | { | 2723 | { |
2645 | LL_DEBUGS("Voice") << "connecting audio to session handle: " << session->mHandle << LL_ENDL; | 2724 | LL_DEBUGS("VoiceSession") << "connecting audio to session handle: " << session->mHandle << LL_ENDL; |
2646 | 2725 | ||
2647 | session->mMediaConnectInProgress = true; | 2726 | session->mMediaConnectInProgress = true; |
2648 | 2727 | ||
@@ -2660,7 +2739,7 @@ void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session) | |||
2660 | 2739 | ||
2661 | void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session) | 2740 | void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session) |
2662 | { | 2741 | { |
2663 | LL_DEBUGS("Voice") << "connecting text to session handle: " << session->mHandle << LL_ENDL; | 2742 | LL_DEBUGS("VoiceSession") << "connecting text to session handle: " << session->mHandle << LL_ENDL; |
2664 | 2743 | ||
2665 | std::ostringstream stream; | 2744 | std::ostringstream stream; |
2666 | 2745 | ||
@@ -2689,7 +2768,7 @@ void LLVoiceClient::leaveAudioSession() | |||
2689 | { | 2768 | { |
2690 | if(mAudioSession) | 2769 | if(mAudioSession) |
2691 | { | 2770 | { |
2692 | LL_DEBUGS("Voice") << "leaving session: " << mAudioSession->mSIPURI << LL_ENDL; | 2771 | LL_DEBUGS("VoiceSession") << "leaving session: " << mAudioSession->mSIPURI << LL_ENDL; |
2693 | 2772 | ||
2694 | switch(getState()) | 2773 | switch(getState()) |
2695 | { | 2774 | { |
@@ -2724,7 +2803,7 @@ void LLVoiceClient::leaveAudioSession() | |||
2724 | } | 2803 | } |
2725 | else | 2804 | else |
2726 | { | 2805 | { |
2727 | LL_WARNS("Voice") << "called with no session handle" << LL_ENDL; | 2806 | LL_WARNS("VoiceSession") << "called with no session handle" << LL_ENDL; |
2728 | setState(stateSessionTerminated); | 2807 | setState(stateSessionTerminated); |
2729 | } | 2808 | } |
2730 | break; | 2809 | break; |
@@ -2734,13 +2813,13 @@ void LLVoiceClient::leaveAudioSession() | |||
2734 | break; | 2813 | break; |
2735 | 2814 | ||
2736 | default: | 2815 | default: |
2737 | LL_WARNS("Voice") << "called from unknown state" << LL_ENDL; | 2816 | LL_WARNS("VoiceSession") << "called from unknown state" << LL_ENDL; |
2738 | break; | 2817 | break; |
2739 | } | 2818 | } |
2740 | } | 2819 | } |
2741 | else | 2820 | else |
2742 | { | 2821 | { |
2743 | LL_WARNS("Voice") << "called with no active session" << LL_ENDL; | 2822 | LL_WARNS("VoiceSession") << "called with no active session" << LL_ENDL; |
2744 | setState(stateSessionTerminated); | 2823 | setState(stateSessionTerminated); |
2745 | } | 2824 | } |
2746 | } | 2825 | } |
@@ -2749,7 +2828,7 @@ void LLVoiceClient::sessionTerminateSendMessage(sessionState *session) | |||
2749 | { | 2828 | { |
2750 | std::ostringstream stream; | 2829 | std::ostringstream stream; |
2751 | 2830 | ||
2752 | LL_DEBUGS("Voice") << "Sending Session.Terminate with handle " << session->mHandle << LL_ENDL; | 2831 | LL_DEBUGS("VoiceSession") << "Sending Session.Terminate with handle " << session->mHandle << LL_ENDL; |
2753 | stream | 2832 | stream |
2754 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Terminate.1\">" | 2833 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Terminate.1\">" |
2755 | << "<SessionHandle>" << session->mHandle << "</SessionHandle>" | 2834 | << "<SessionHandle>" << session->mHandle << "</SessionHandle>" |
@@ -2762,7 +2841,7 @@ void LLVoiceClient::sessionGroupTerminateSendMessage(sessionState *session) | |||
2762 | { | 2841 | { |
2763 | std::ostringstream stream; | 2842 | std::ostringstream stream; |
2764 | 2843 | ||
2765 | LL_DEBUGS("Voice") << "Sending SessionGroup.Terminate with handle " << session->mGroupHandle << LL_ENDL; | 2844 | LL_DEBUGS("VoiceSession") << "Sending SessionGroup.Terminate with handle " << session->mGroupHandle << LL_ENDL; |
2766 | stream | 2845 | stream |
2767 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.Terminate.1\">" | 2846 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.Terminate.1\">" |
2768 | << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" | 2847 | << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" |
@@ -2775,7 +2854,7 @@ void LLVoiceClient::sessionMediaDisconnectSendMessage(sessionState *session) | |||
2775 | { | 2854 | { |
2776 | std::ostringstream stream; | 2855 | std::ostringstream stream; |
2777 | 2856 | ||
2778 | LL_DEBUGS("Voice") << "Sending Session.MediaDisconnect with handle " << session->mHandle << LL_ENDL; | 2857 | LL_DEBUGS("VoiceSession") << "Sending Session.MediaDisconnect with handle " << session->mHandle << LL_ENDL; |
2779 | stream | 2858 | stream |
2780 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.MediaDisconnect.1\">" | 2859 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.MediaDisconnect.1\">" |
2781 | << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" | 2860 | << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" |
@@ -2791,7 +2870,7 @@ void LLVoiceClient::sessionTextDisconnectSendMessage(sessionState *session) | |||
2791 | { | 2870 | { |
2792 | std::ostringstream stream; | 2871 | std::ostringstream stream; |
2793 | 2872 | ||
2794 | LL_DEBUGS("Voice") << "Sending Session.TextDisconnect with handle " << session->mHandle << LL_ENDL; | 2873 | LL_DEBUGS("VoiceSession") << "Sending Session.TextDisconnect with handle " << session->mHandle << LL_ENDL; |
2795 | stream | 2874 | stream |
2796 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.TextDisconnect.1\">" | 2875 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.TextDisconnect.1\">" |
2797 | << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" | 2876 | << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" |
@@ -2823,13 +2902,13 @@ void LLVoiceClient::getRenderDevicesSendMessage() | |||
2823 | 2902 | ||
2824 | void LLVoiceClient::clearCaptureDevices() | 2903 | void LLVoiceClient::clearCaptureDevices() |
2825 | { | 2904 | { |
2826 | LL_DEBUGS("Voice") << "called" << LL_ENDL; | 2905 | LL_DEBUGS("VoiceDevice") << "called" << LL_ENDL; |
2827 | mCaptureDevices.clear(); | 2906 | mCaptureDevices.clear(); |
2828 | } | 2907 | } |
2829 | 2908 | ||
2830 | void LLVoiceClient::addCaptureDevice(const std::string& name) | 2909 | void LLVoiceClient::addCaptureDevice(const std::string& name) |
2831 | { | 2910 | { |
2832 | LL_DEBUGS("Voice") << name << LL_ENDL; | 2911 | LL_DEBUGS("VoiceDevice") << name << LL_ENDL; |
2833 | 2912 | ||
2834 | mCaptureDevices.push_back(name); | 2913 | mCaptureDevices.push_back(name); |
2835 | } | 2914 | } |
@@ -2861,13 +2940,13 @@ void LLVoiceClient::setCaptureDevice(const std::string& name) | |||
2861 | 2940 | ||
2862 | void LLVoiceClient::clearRenderDevices() | 2941 | void LLVoiceClient::clearRenderDevices() |
2863 | { | 2942 | { |
2864 | LL_DEBUGS("Voice") << "called" << LL_ENDL; | 2943 | LL_DEBUGS("VoiceDevice") << "called" << LL_ENDL; |
2865 | mRenderDevices.clear(); | 2944 | mRenderDevices.clear(); |
2866 | } | 2945 | } |
2867 | 2946 | ||
2868 | void LLVoiceClient::addRenderDevice(const std::string& name) | 2947 | void LLVoiceClient::addRenderDevice(const std::string& name) |
2869 | { | 2948 | { |
2870 | LL_DEBUGS("Voice") << name << LL_ENDL; | 2949 | LL_DEBUGS("VoiceDevice") << name << LL_ENDL; |
2871 | mRenderDevices.push_back(name); | 2950 | mRenderDevices.push_back(name); |
2872 | } | 2951 | } |
2873 | 2952 | ||
@@ -2951,7 +3030,7 @@ void LLVoiceClient::tuningRenderStopSendMessage() | |||
2951 | 3030 | ||
2952 | void LLVoiceClient::tuningCaptureStartSendMessage(int duration) | 3031 | void LLVoiceClient::tuningCaptureStartSendMessage(int duration) |
2953 | { | 3032 | { |
2954 | LL_DEBUGS("Voice") << "sending CaptureAudioStart" << LL_ENDL; | 3033 | LL_DEBUGS("VoiceDevice") << "sending CaptureAudioStart" << LL_ENDL; |
2955 | 3034 | ||
2956 | std::ostringstream stream; | 3035 | std::ostringstream stream; |
2957 | stream | 3036 | stream |
@@ -2964,7 +3043,7 @@ void LLVoiceClient::tuningCaptureStartSendMessage(int duration) | |||
2964 | 3043 | ||
2965 | void LLVoiceClient::tuningCaptureStopSendMessage() | 3044 | void LLVoiceClient::tuningCaptureStopSendMessage() |
2966 | { | 3045 | { |
2967 | LL_DEBUGS("Voice") << "sending CaptureAudioStop" << LL_ENDL; | 3046 | LL_DEBUGS("VoiceDevice") << "sending CaptureAudioStop" << LL_ENDL; |
2968 | 3047 | ||
2969 | std::ostringstream stream; | 3048 | std::ostringstream stream; |
2970 | stream | 3049 | stream |
@@ -3038,12 +3117,8 @@ void LLVoiceClient::daemonDied() | |||
3038 | 3117 | ||
3039 | void LLVoiceClient::giveUp() | 3118 | void LLVoiceClient::giveUp() |
3040 | { | 3119 | { |
3041 | // All has failed. Clean up and stop trying. | 3120 | mAccountActive = false; |
3042 | closeSocket(); | 3121 | setState(stateDisableCleanup); |
3043 | deleteAllSessions(); | ||
3044 | deleteAllBuddies(); | ||
3045 | |||
3046 | setState(stateJail); | ||
3047 | } | 3122 | } |
3048 | 3123 | ||
3049 | static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel) | 3124 | static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel) |
@@ -3378,7 +3453,7 @@ void LLVoiceClient::buildSetCaptureDevice(std::ostringstream &stream) | |||
3378 | { | 3453 | { |
3379 | if(mCaptureDeviceDirty) | 3454 | if(mCaptureDeviceDirty) |
3380 | { | 3455 | { |
3381 | LL_DEBUGS("Voice") << "Setting input device = \"" << mCaptureDevice << "\"" << LL_ENDL; | 3456 | LL_DEBUGS("VoiceDevice") << "Setting input device = \"" << mCaptureDevice << "\"" << LL_ENDL; |
3382 | 3457 | ||
3383 | stream | 3458 | stream |
3384 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetCaptureDevice.1\">" | 3459 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetCaptureDevice.1\">" |
@@ -4099,29 +4174,29 @@ void LLVoiceClient::reapSession(sessionState *session) | |||
4099 | { | 4174 | { |
4100 | if(!session->mHandle.empty()) | 4175 | if(!session->mHandle.empty()) |
4101 | { | 4176 | { |
4102 | LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (non-null session handle)" << LL_ENDL; | 4177 | LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (non-null session handle)" << LL_ENDL; |
4103 | } | 4178 | } |
4104 | else if(session->mCreateInProgress) | 4179 | else if(session->mCreateInProgress) |
4105 | { | 4180 | { |
4106 | LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (create in progress)" << LL_ENDL; | 4181 | LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (create in progress)" << LL_ENDL; |
4107 | } | 4182 | } |
4108 | else if(session->mMediaConnectInProgress) | 4183 | else if(session->mMediaConnectInProgress) |
4109 | { | 4184 | { |
4110 | LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (connect in progress)" << LL_ENDL; | 4185 | LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (connect in progress)" << LL_ENDL; |
4111 | } | 4186 | } |
4112 | else if(session == mAudioSession) | 4187 | else if(session == mAudioSession) |
4113 | { | 4188 | { |
4114 | LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (it's the current session)" << LL_ENDL; | 4189 | LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (it's the current session)" << LL_ENDL; |
4115 | } | 4190 | } |
4116 | else if(session == mNextAudioSession) | 4191 | else if(session == mNextAudioSession) |
4117 | { | 4192 | { |
4118 | LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (it's the next session)" << LL_ENDL; | 4193 | LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (it's the next session)" << LL_ENDL; |
4119 | } | 4194 | } |
4120 | else | 4195 | else |
4121 | { | 4196 | { |
4122 | // TODO: Question: Should we check for queued text messages here? | 4197 | // TODO: Question: Should we check for queued text messages here? |
4123 | // We don't have a reason to keep tracking this session, so just delete it. | 4198 | // We don't have a reason to keep tracking this session, so just delete it. |
4124 | LL_DEBUGS("Voice") << "deleting session " << session->mSIPURI << LL_ENDL; | 4199 | LL_DEBUGS("VoiceSession") << "deleting session " << session->mSIPURI << LL_ENDL; |
4125 | deleteSession(session); | 4200 | deleteSession(session); |
4126 | session = NULL; | 4201 | session = NULL; |
4127 | } | 4202 | } |
@@ -4179,17 +4254,17 @@ void LLVoiceClient::leftAudioSession( | |||
4179 | case stateJoinSessionFailed: | 4254 | case stateJoinSessionFailed: |
4180 | case stateJoinSessionFailedWaiting: | 4255 | case stateJoinSessionFailedWaiting: |
4181 | // normal transition | 4256 | // normal transition |
4182 | LL_DEBUGS("Voice") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL; | 4257 | LL_DEBUGS("VoiceSession") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL; |
4183 | setState(stateSessionTerminated); | 4258 | setState(stateSessionTerminated); |
4184 | break; | 4259 | break; |
4185 | 4260 | ||
4186 | case stateSessionTerminated: | 4261 | case stateSessionTerminated: |
4187 | // this will happen sometimes -- there are cases where we send the terminate and then go straight to this state. | 4262 | // this will happen sometimes -- there are cases where we send the terminate and then go straight to this state. |
4188 | LL_WARNS("Voice") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL; | 4263 | LL_WARNS("VoiceSession") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL; |
4189 | break; | 4264 | break; |
4190 | 4265 | ||
4191 | default: | 4266 | default: |
4192 | LL_WARNS("Voice") << "unexpected SessionStateChangeEvent (left session) in state " << state2string(getState()) << LL_ENDL; | 4267 | LL_WARNS("VoiceSession") << "unexpected SessionStateChangeEvent (left session) in state " << state2string(getState()) << LL_ENDL; |
4193 | setState(stateSessionTerminated); | 4268 | setState(stateSessionTerminated); |
4194 | break; | 4269 | break; |
4195 | } | 4270 | } |
@@ -4249,7 +4324,7 @@ void LLVoiceClient::mediaStreamUpdatedEvent( | |||
4249 | { | 4324 | { |
4250 | sessionState *session = findSession(sessionHandle); | 4325 | sessionState *session = findSession(sessionHandle); |
4251 | 4326 | ||
4252 | LL_DEBUGS("Voice") << "session " << sessionHandle << ", status code " << statusCode << ", string \"" << statusString << "\"" << LL_ENDL; | 4327 | LL_DEBUGS("VoiceSession") << "session " << sessionHandle << ", status code " << statusCode << ", string \"" << statusString << "\"" << LL_ENDL; |
4253 | 4328 | ||
4254 | if(session) | 4329 | if(session) |
4255 | { | 4330 | { |
@@ -4314,7 +4389,7 @@ void LLVoiceClient::mediaStreamUpdatedEvent( | |||
4314 | } | 4389 | } |
4315 | else | 4390 | else |
4316 | { | 4391 | { |
4317 | LL_WARNS("Voice") << "session " << sessionHandle << "not found"<< LL_ENDL; | 4392 | LL_WARNS("VoiceSession") << "session " << sessionHandle << "not found"<< LL_ENDL; |
4318 | } | 4393 | } |
4319 | } | 4394 | } |
4320 | 4395 | ||
@@ -4435,7 +4510,7 @@ void LLVoiceClient::participantRemovedEvent( | |||
4435 | } | 4510 | } |
4436 | else | 4511 | else |
4437 | { | 4512 | { |
4438 | LL_DEBUGS("Voice") << "unknown session " << sessionHandle << LL_ENDL; | 4513 | LL_DEBUGS("VoiceSession") << "unknown session " << sessionHandle << LL_ENDL; |
4439 | } | 4514 | } |
4440 | } | 4515 | } |
4441 | 4516 | ||
@@ -4479,7 +4554,7 @@ void LLVoiceClient::participantUpdatedEvent( | |||
4479 | } | 4554 | } |
4480 | else | 4555 | else |
4481 | { | 4556 | { |
4482 | LL_WARNS("Voice") << "unknown session " << sessionHandle << LL_ENDL; | 4557 | LL_WARNS("VoiceSession") << "unknown session " << sessionHandle << LL_ENDL; |
4483 | } | 4558 | } |
4484 | } | 4559 | } |
4485 | 4560 | ||
@@ -5058,22 +5133,34 @@ LLVoiceClient::participantState* LLVoiceClient::findParticipantByID(const LLUUID | |||
5058 | 5133 | ||
5059 | void LLVoiceClient::parcelChanged() | 5134 | void LLVoiceClient::parcelChanged() |
5060 | { | 5135 | { |
5061 | if(getState() >= stateNoChannel) | 5136 | if( (getState() >= stateNoChannel) && !inNonSpatialChannel() ) |
5062 | { | 5137 | { |
5063 | // If the user is logged in, start a channel lookup. | 5138 | // If the user is logged in, start a channel lookup, |
5064 | LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL; | 5139 | // but not if already in a private call/conference. |
5140 | mAccountActive = true; | ||
5065 | 5141 | ||
5066 | std::string url = gAgent.getRegion()->getCapability("ParcelVoiceInfoRequest"); | 5142 | std::string url = gAgent.getRegion()->getCapability("ParcelVoiceInfoRequest"); |
5067 | LLSD data; | 5143 | LL_DEBUGS("VoiceCaps") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << " cap url:" << url << LL_ENDL; |
5068 | LLHTTPClient::post( | 5144 | if(! url.empty() ) |
5069 | url, | 5145 | { |
5070 | data, | 5146 | mPIRCapResponseID.generate(); |
5071 | new LLVoiceClientCapResponder); | 5147 | LLSD data; |
5148 | LLHTTPClient::post( | ||
5149 | url, | ||
5150 | data, | ||
5151 | new LLVoiceClientCapResponder(mPIRCapResponseID)); | ||
5152 | } | ||
5153 | else | ||
5154 | { | ||
5155 | mAccountActive = false; | ||
5156 | setState(stateDisableCleanup); | ||
5157 | } | ||
5072 | } | 5158 | } |
5073 | else | 5159 | else |
5074 | { | 5160 | { |
5161 | mAccountActive = true; | ||
5075 | // The transition to stateNoChannel needs to kick this off again. | 5162 | // The transition to stateNoChannel needs to kick this off again. |
5076 | LL_WARNS("Voice") << "not logged in yet, deferring" << LL_ENDL; | 5163 | LL_DEBUGS("Voice") << "not logged in yet, deferring" << LL_ENDL; |
5077 | } | 5164 | } |
5078 | } | 5165 | } |
5079 | 5166 | ||
@@ -5086,12 +5173,40 @@ void LLVoiceClient::switchChannel( | |||
5086 | { | 5173 | { |
5087 | bool needsSwitch = false; | 5174 | bool needsSwitch = false; |
5088 | 5175 | ||
5089 | LL_DEBUGS("Voice") | 5176 | LL_DEBUGS("VoiceSession") |
5090 | << "called in state " << state2string(getState()) | 5177 | << "Switch channel called in state " << state2string(getState()) |
5091 | << " with uri \"" << uri << "\"" | 5178 | << " with uri \"" << uri << "\"" |
5092 | << (spatial?", spatial is true":", spatial is false") | 5179 | << (spatial?", spatial is true":", spatial is false") |
5093 | << LL_ENDL; | 5180 | << LL_ENDL; |
5094 | 5181 | ||
5182 | size_t new_uri_find_sip = std::string::npos; | ||
5183 | size_t old_uri_find_sip = std::string::npos; | ||
5184 | if(!uri.empty()) | ||
5185 | { | ||
5186 | new_uri_find_sip = uri.find("sip:"); | ||
5187 | } | ||
5188 | |||
5189 | if( mNextAudioSession | ||
5190 | && !( mNextAudioSession->mSIPURI.empty() ) | ||
5191 | && (mNextAudioSession->mSIPURI != uri) ) | ||
5192 | { | ||
5193 | old_uri_find_sip = mNextAudioSession->mSIPURI.find("sip:"); | ||
5194 | } | ||
5195 | else | ||
5196 | { | ||
5197 | |||
5198 | // just logged in or voice disabled land in SL, | ||
5199 | // anyway right daemon is already up | ||
5200 | old_uri_find_sip = new_uri_find_sip; | ||
5201 | } | ||
5202 | |||
5203 | if(old_uri_find_sip != new_uri_find_sip) | ||
5204 | { | ||
5205 | mAccountActive = true; | ||
5206 | setState(stateDisableCleanup); | ||
5207 | return; | ||
5208 | } | ||
5209 | |||
5095 | switch(getState()) | 5210 | switch(getState()) |
5096 | { | 5211 | { |
5097 | case stateJoinSessionFailed: | 5212 | case stateJoinSessionFailed: |
@@ -5148,7 +5263,7 @@ void LLVoiceClient::switchChannel( | |||
5148 | if(uri.empty()) | 5263 | if(uri.empty()) |
5149 | { | 5264 | { |
5150 | // Leave any channel we may be in | 5265 | // Leave any channel we may be in |
5151 | LL_DEBUGS("Voice") << "leaving channel" << LL_ENDL; | 5266 | LL_DEBUGS("VoiceSession") << "leaving channel" << LL_ENDL; |
5152 | 5267 | ||
5153 | sessionState *oldSession = mNextAudioSession; | 5268 | sessionState *oldSession = mNextAudioSession; |
5154 | mNextAudioSession = NULL; | 5269 | mNextAudioSession = NULL; |
@@ -5160,7 +5275,7 @@ void LLVoiceClient::switchChannel( | |||
5160 | } | 5275 | } |
5161 | else | 5276 | else |
5162 | { | 5277 | { |
5163 | LL_DEBUGS("Voice") << "switching to channel " << uri << LL_ENDL; | 5278 | LL_DEBUGS("VoiceSession") << "switching to channel " << uri << LL_ENDL; |
5164 | 5279 | ||
5165 | mNextAudioSession = addSession(uri); | 5280 | mNextAudioSession = addSession(uri); |
5166 | mNextAudioSession->mHash = hash; | 5281 | mNextAudioSession->mHash = hash; |
@@ -5205,8 +5320,14 @@ void LLVoiceClient::setNonSpatialChannel( | |||
5205 | 5320 | ||
5206 | void LLVoiceClient::setSpatialChannel( | 5321 | void LLVoiceClient::setSpatialChannel( |
5207 | const std::string &uri, | 5322 | const std::string &uri, |
5208 | const std::string &credentials) | 5323 | const std::string &credentials, |
5324 | const LLUUID& response_id) | ||
5209 | { | 5325 | { |
5326 | if (response_id != mPIRCapResponseID) | ||
5327 | { | ||
5328 | return; | ||
5329 | } | ||
5330 | |||
5210 | mSpatialSessionURI = uri; | 5331 | mSpatialSessionURI = uri; |
5211 | mSpatialSessionCredentials = credentials; | 5332 | mSpatialSessionCredentials = credentials; |
5212 | mAreaVoiceDisabled = mSpatialSessionURI.empty(); | 5333 | mAreaVoiceDisabled = mSpatialSessionURI.empty(); |
@@ -5282,7 +5403,7 @@ bool LLVoiceClient::sendTextMessage(const LLUUID& participant_id, const std::str | |||
5282 | } | 5403 | } |
5283 | else | 5404 | else |
5284 | { | 5405 | { |
5285 | LL_DEBUGS("Voice") << "Session not found for participant ID " << participant_id << LL_ENDL; | 5406 | LL_DEBUGS("VoiceSession") << "Session not found for participant ID " << participant_id << LL_ENDL; |
5286 | } | 5407 | } |
5287 | 5408 | ||
5288 | return result; | 5409 | return result; |
@@ -5331,7 +5452,7 @@ void LLVoiceClient::endUserIMSession(const LLUUID &uuid) | |||
5331 | } | 5452 | } |
5332 | else | 5453 | else |
5333 | { | 5454 | { |
5334 | LL_DEBUGS("Voice") << "Session not found for participant ID " << uuid << LL_ENDL; | 5455 | LL_DEBUGS("VoiceSession") << "Session not found for participant ID " << uuid << LL_ENDL; |
5335 | } | 5456 | } |
5336 | } | 5457 | } |
5337 | 5458 | ||
@@ -5452,7 +5573,7 @@ void LLVoiceClient::declineInvite(std::string &sessionHandle) | |||
5452 | 5573 | ||
5453 | void LLVoiceClient::leaveNonSpatialChannel() | 5574 | void LLVoiceClient::leaveNonSpatialChannel() |
5454 | { | 5575 | { |
5455 | LL_DEBUGS("Voice") | 5576 | LL_DEBUGS("VoiceSession") |
5456 | << "called in state " << state2string(getState()) | 5577 | << "called in state " << state2string(getState()) |
5457 | << LL_ENDL; | 5578 | << LL_ENDL; |
5458 | 5579 | ||
@@ -5644,6 +5765,18 @@ bool LLVoiceClient::inSpatialChannel(void) | |||
5644 | return result; | 5765 | return result; |
5645 | } | 5766 | } |
5646 | 5767 | ||
5768 | bool LLVoiceClient::inNonSpatialChannel(void) | ||
5769 | { | ||
5770 | bool result = false; | ||
5771 | |||
5772 | if(mAudioSession) | ||
5773 | result = !(mAudioSession->mIsSpatial); | ||
5774 | if(mNextAudioSession) | ||
5775 | result |= !(mNextAudioSession->mIsSpatial); | ||
5776 | |||
5777 | return result; | ||
5778 | } | ||
5779 | |||
5647 | std::string LLVoiceClient::getAudioSessionURI() | 5780 | std::string LLVoiceClient::getAudioSessionURI() |
5648 | { | 5781 | { |
5649 | std::string result; | 5782 | std::string result; |
@@ -6397,7 +6530,7 @@ LLVoiceClient::sessionState *LLVoiceClient::addSession(const std::string &uri, c | |||
6397 | { | 6530 | { |
6398 | // No existing session found. | 6531 | // No existing session found. |
6399 | 6532 | ||
6400 | LL_DEBUGS("Voice") << "adding new session: handle " << handle << " URI " << uri << LL_ENDL; | 6533 | LL_DEBUGS("VoiceSession") << "adding new session: handle " << handle << " URI " << uri << LL_ENDL; |
6401 | result = new sessionState(); | 6534 | result = new sessionState(); |
6402 | result->mSIPURI = uri; | 6535 | result->mSIPURI = uri; |
6403 | result->mHandle = handle; | 6536 | result->mHandle = handle; |
@@ -6416,7 +6549,7 @@ LLVoiceClient::sessionState *LLVoiceClient::addSession(const std::string &uri, c | |||
6416 | if(uri != result->mSIPURI) | 6549 | if(uri != result->mSIPURI) |
6417 | { | 6550 | { |
6418 | // TODO: Should this be an internal error? | 6551 | // TODO: Should this be an internal error? |
6419 | LL_DEBUGS("Voice") << "changing uri from " << result->mSIPURI << " to " << uri << LL_ENDL; | 6552 | LL_DEBUGS("VoiceSession") << "changing uri from " << result->mSIPURI << " to " << uri << LL_ENDL; |
6420 | setSessionURI(result, uri); | 6553 | setSessionURI(result, uri); |
6421 | } | 6554 | } |
6422 | 6555 | ||
@@ -6425,17 +6558,17 @@ LLVoiceClient::sessionState *LLVoiceClient::addSession(const std::string &uri, c | |||
6425 | if(handle.empty()) | 6558 | if(handle.empty()) |
6426 | { | 6559 | { |
6427 | // There's at least one race condition where where addSession was clearing an existing session handle, which caused things to break. | 6560 | // There's at least one race condition where where addSession was clearing an existing session handle, which caused things to break. |
6428 | LL_DEBUGS("Voice") << "NOT clearing handle " << result->mHandle << LL_ENDL; | 6561 | LL_DEBUGS("VoiceSession") << "NOT clearing handle " << result->mHandle << LL_ENDL; |
6429 | } | 6562 | } |
6430 | else | 6563 | else |
6431 | { | 6564 | { |
6432 | // TODO: Should this be an internal error? | 6565 | // TODO: Should this be an internal error? |
6433 | LL_DEBUGS("Voice") << "changing handle from " << result->mHandle << " to " << handle << LL_ENDL; | 6566 | LL_DEBUGS("VoiceSession") << "changing handle from " << result->mHandle << " to " << handle << LL_ENDL; |
6434 | setSessionHandle(result, handle); | 6567 | setSessionHandle(result, handle); |
6435 | } | 6568 | } |
6436 | } | 6569 | } |
6437 | 6570 | ||
6438 | LL_DEBUGS("Voice") << "returning existing session: handle " << handle << " URI " << uri << LL_ENDL; | 6571 | LL_DEBUGS("VoiceSession") << "returning existing session: handle " << handle << " URI " << uri << LL_ENDL; |
6439 | } | 6572 | } |
6440 | 6573 | ||
6441 | verifySessionState(); | 6574 | verifySessionState(); |
@@ -6455,14 +6588,14 @@ void LLVoiceClient::setSessionHandle(sessionState *session, const std::string &h | |||
6455 | { | 6588 | { |
6456 | if(iter->second != session) | 6589 | if(iter->second != session) |
6457 | { | 6590 | { |
6458 | LL_ERRS("Voice") << "Internal error: session mismatch!" << LL_ENDL; | 6591 | LL_ERRS("VoiceSession") << "Internal error: session mismatch!" << LL_ENDL; |
6459 | } | 6592 | } |
6460 | 6593 | ||
6461 | mSessionsByHandle.erase(iter); | 6594 | mSessionsByHandle.erase(iter); |
6462 | } | 6595 | } |
6463 | else | 6596 | else |
6464 | { | 6597 | { |
6465 | LL_ERRS("Voice") << "Internal error: session handle not found in map!" << LL_ENDL; | 6598 | LL_ERRS("VoiceSession") << "Internal error: session handle not found in map!" << LL_ENDL; |
6466 | } | 6599 | } |
6467 | } | 6600 | } |
6468 | 6601 | ||
@@ -6494,7 +6627,7 @@ void LLVoiceClient::deleteSession(sessionState *session) | |||
6494 | { | 6627 | { |
6495 | if(iter->second != session) | 6628 | if(iter->second != session) |
6496 | { | 6629 | { |
6497 | LL_ERRS("Voice") << "Internal error: session mismatch" << LL_ENDL; | 6630 | LL_ERRS("VoiceSession") << "Internal error: session mismatch" << LL_ENDL; |
6498 | } | 6631 | } |
6499 | mSessionsByHandle.erase(iter); | 6632 | mSessionsByHandle.erase(iter); |
6500 | } | 6633 | } |
@@ -6525,7 +6658,7 @@ void LLVoiceClient::deleteSession(sessionState *session) | |||
6525 | 6658 | ||
6526 | void LLVoiceClient::deleteAllSessions() | 6659 | void LLVoiceClient::deleteAllSessions() |
6527 | { | 6660 | { |
6528 | LL_DEBUGS("Voice") << "called" << LL_ENDL; | 6661 | LL_DEBUGS("VoiceSession") << "called" << LL_ENDL; |
6529 | 6662 | ||
6530 | while(!mSessions.empty()) | 6663 | while(!mSessions.empty()) |
6531 | { | 6664 | { |
@@ -6534,20 +6667,20 @@ void LLVoiceClient::deleteAllSessions() | |||
6534 | 6667 | ||
6535 | if(!mSessionsByHandle.empty()) | 6668 | if(!mSessionsByHandle.empty()) |
6536 | { | 6669 | { |
6537 | LL_ERRS("Voice") << "Internal error: empty session map, non-empty handle map" << LL_ENDL; | 6670 | LL_ERRS("VoiceSession") << "Internal error: empty session map, non-empty handle map" << LL_ENDL; |
6538 | } | 6671 | } |
6539 | } | 6672 | } |
6540 | 6673 | ||
6541 | void LLVoiceClient::verifySessionState(void) | 6674 | void LLVoiceClient::verifySessionState(void) |
6542 | { | 6675 | { |
6543 | // This is mostly intended for debugging problems with session state management. | 6676 | // This is mostly intended for debugging problems with session state management. |
6544 | LL_DEBUGS("Voice") << "Total session count: " << mSessions.size() << " , session handle map size: " << mSessionsByHandle.size() << LL_ENDL; | 6677 | LL_DEBUGS("VoiceSession") << "Total session count: " << mSessions.size() << " , session handle map size: " << mSessionsByHandle.size() << LL_ENDL; |
6545 | 6678 | ||
6546 | for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) | 6679 | for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) |
6547 | { | 6680 | { |
6548 | sessionState *session = *iter; | 6681 | sessionState *session = *iter; |
6549 | 6682 | ||
6550 | LL_DEBUGS("Voice") << "session " << session << ": handle " << session->mHandle << ", URI " << session->mSIPURI << LL_ENDL; | 6683 | LL_DEBUGS("VoiceSession") << "session " << session << ": handle " << session->mHandle << ", URI " << session->mSIPURI << LL_ENDL; |
6551 | 6684 | ||
6552 | if(!session->mHandle.empty()) | 6685 | if(!session->mHandle.empty()) |
6553 | { | 6686 | { |
@@ -6555,13 +6688,13 @@ void LLVoiceClient::verifySessionState(void) | |||
6555 | sessionMap::iterator i2 = mSessionsByHandle.find(&(session->mHandle)); | 6688 | sessionMap::iterator i2 = mSessionsByHandle.find(&(session->mHandle)); |
6556 | if(i2 == mSessionsByHandle.end()) | 6689 | if(i2 == mSessionsByHandle.end()) |
6557 | { | 6690 | { |
6558 | LL_ERRS("Voice") << "internal error (handle " << session->mHandle << " not found in session map)" << LL_ENDL; | 6691 | LL_ERRS("VoiceSession") << "internal error (handle " << session->mHandle << " not found in session map)" << LL_ENDL; |
6559 | } | 6692 | } |
6560 | else | 6693 | else |
6561 | { | 6694 | { |
6562 | if(i2->second != session) | 6695 | if(i2->second != session) |
6563 | { | 6696 | { |
6564 | LL_ERRS("Voice") << "internal error (handle " << session->mHandle << " in session map points to another session)" << LL_ENDL; | 6697 | LL_ERRS("VoiceSession") << "internal error (handle " << session->mHandle << " in session map points to another session)" << LL_ENDL; |
6565 | } | 6698 | } |
6566 | } | 6699 | } |
6567 | } | 6700 | } |
@@ -6574,13 +6707,13 @@ void LLVoiceClient::verifySessionState(void) | |||
6574 | sessionIterator i2 = mSessions.find(session); | 6707 | sessionIterator i2 = mSessions.find(session); |
6575 | if(i2 == mSessions.end()) | 6708 | if(i2 == mSessions.end()) |
6576 | { | 6709 | { |
6577 | LL_ERRS("Voice") << "internal error (session for handle " << session->mHandle << " not found in session map)" << LL_ENDL; | 6710 | LL_ERRS("VoiceSession") << "internal error (session for handle " << session->mHandle << " not found in session map)" << LL_ENDL; |
6578 | } | 6711 | } |
6579 | else | 6712 | else |
6580 | { | 6713 | { |
6581 | if(session->mHandle != (*i2)->mHandle) | 6714 | if(session->mHandle != (*i2)->mHandle) |
6582 | { | 6715 | { |
6583 | LL_ERRS("Voice") << "internal error (session for handle " << session->mHandle << " points to session with different handle " << (*i2)->mHandle << ")" << LL_ENDL; | 6716 | LL_ERRS("VoiceSession") << "internal error (session for handle " << session->mHandle << " points to session with different handle " << (*i2)->mHandle << ")" << LL_ENDL; |
6584 | } | 6717 | } |
6585 | } | 6718 | } |
6586 | } | 6719 | } |
@@ -7010,6 +7143,8 @@ class LLViewerParcelVoiceInfo : public LLHTTPNode | |||
7010 | { | 7143 | { |
7011 | LLSD body = input["body"]; | 7144 | LLSD body = input["body"]; |
7012 | 7145 | ||
7146 | LL_DEBUGS("VoiceCaps") << "ParcelVoiceInfo response: " | ||
7147 | << ll_pretty_print_sd(input) << LL_ENDL; | ||
7013 | //body has "region_name" (str), "parcel_local_id"(int), | 7148 | //body has "region_name" (str), "parcel_local_id"(int), |
7014 | //"voice_credentials" (map). | 7149 | //"voice_credentials" (map). |
7015 | 7150 | ||
@@ -7036,7 +7171,10 @@ class LLViewerParcelVoiceInfo : public LLHTTPNode | |||
7036 | voice_credentials["channel_credentials"].asString(); | 7171 | voice_credentials["channel_credentials"].asString(); |
7037 | } | 7172 | } |
7038 | 7173 | ||
7039 | gVoiceClient->setSpatialChannel(uri, credentials); | 7174 | LLUUID response_id; |
7175 | response_id.generate(); | ||
7176 | gVoiceClient->setPIRCapResponseID(response_id); | ||
7177 | gVoiceClient->setSpatialChannel(uri, credentials, response_id); | ||
7040 | } | 7178 | } |
7041 | } | 7179 | } |
7042 | } | 7180 | } |
@@ -7050,10 +7188,13 @@ class LLViewerRequiredVoiceVersion : public LLHTTPNode | |||
7050 | const LLSD& context, | 7188 | const LLSD& context, |
7051 | const LLSD& input) const | 7189 | const LLSD& input) const |
7052 | { | 7190 | { |
7191 | |||
7053 | //You received this messsage (most likely on region cross or | 7192 | //You received this messsage (most likely on region cross or |
7054 | //teleport) | 7193 | //teleport) |
7055 | if ( input.has("body") && input["body"].has("major_version") ) | 7194 | if ( input.has("body") && input["body"].has("major_version") ) |
7056 | { | 7195 | { |
7196 | LL_DEBUGS("VoiceCaps") << "RequiredVoiceVersion response: " | ||
7197 | << ll_pretty_print_sd(input)<< LL_ENDL; | ||
7057 | int major_voice_version = | 7198 | int major_voice_version = |
7058 | input["body"]["major_version"].asInteger(); | 7199 | input["body"]["major_version"].asInteger(); |
7059 | // int minor_voice_version = | 7200 | // int minor_voice_version = |
diff --git a/linden/indra/newview/llvoiceclient.h b/linden/indra/newview/llvoiceclient.h index 9ef3be9..fb59b4e 100644 --- a/linden/indra/newview/llvoiceclient.h +++ b/linden/indra/newview/llvoiceclient.h | |||
@@ -424,11 +424,15 @@ static void updatePosition(void); | |||
424 | const std::string& account_name, | 424 | const std::string& account_name, |
425 | const std::string& password, | 425 | const std::string& password, |
426 | const std::string& voice_sip_uri_hostname, | 426 | const std::string& voice_sip_uri_hostname, |
427 | const std::string& voice_account_server_uri); | 427 | const std::string& voice_account_server_uri, |
428 | const LLUUID& response_id); | ||
429 | |||
428 | void loginSendMessage(); | 430 | void loginSendMessage(); |
429 | void logout(); | 431 | void logout(); |
430 | void logoutSendMessage(); | 432 | void logoutSendMessage(); |
431 | 433 | ||
434 | void loadDaemon(const std::string& scheme); | ||
435 | |||
432 | void accountListBlockRulesSendMessage(); | 436 | void accountListBlockRulesSendMessage(); |
433 | void accountListAutoAcceptRulesSendMessage(); | 437 | void accountListAutoAcceptRulesSendMessage(); |
434 | 438 | ||
@@ -474,7 +478,8 @@ static void updatePosition(void); | |||
474 | const std::string &credentials); | 478 | const std::string &credentials); |
475 | void setSpatialChannel( | 479 | void setSpatialChannel( |
476 | const std::string &uri, | 480 | const std::string &uri, |
477 | const std::string &credentials); | 481 | const std::string &credentials, |
482 | const LLUUID& response_id); | ||
478 | // start a voice session with the specified user | 483 | // start a voice session with the specified user |
479 | void callUser(const LLUUID &uuid); | 484 | void callUser(const LLUUID &uuid); |
480 | 485 | ||
@@ -519,7 +524,7 @@ static void updatePosition(void); | |||
519 | 524 | ||
520 | void close(); | 525 | void close(); |
521 | void start(); | 526 | void start(); |
522 | 527 | void setPIRCapResponseID(const LLUUID& response_id){ mPIRCapResponseID = response_id; } | |
523 | private: | 528 | private: |
524 | 529 | ||
525 | // internal state for a simple state machine. This is used to deal with the asynchronous nature of some of the messages. | 530 | // internal state for a simple state machine. This is used to deal with the asynchronous nature of some of the messages. |
@@ -595,7 +600,13 @@ static void updatePosition(void); | |||
595 | std::string mAccountDisplayName; | 600 | std::string mAccountDisplayName; |
596 | std::string mAccountFirstName; | 601 | std::string mAccountFirstName; |
597 | std::string mAccountLastName; | 602 | std::string mAccountLastName; |
598 | 603 | ||
604 | bool mAccountActive; | ||
605 | bool mVAPRequested; | ||
606 | std::string mDaemonScheme; | ||
607 | LLUUID mVAPCapResponseID; | ||
608 | LLUUID mPIRCapResponseID; | ||
609 | |||
599 | bool mTuningMode; | 610 | bool mTuningMode; |
600 | float mTuningEnergy; | 611 | float mTuningEnergy; |
601 | std::string mTuningAudioFile; | 612 | std::string mTuningAudioFile; |
@@ -667,6 +678,7 @@ static std::string displayNameFromAvatar(LLVOAvatar *avatar); | |||
667 | static std::string nameFromsipURI(const std::string &uri); | 678 | static std::string nameFromsipURI(const std::string &uri); |
668 | 679 | ||
669 | bool inSpatialChannel(void); | 680 | bool inSpatialChannel(void); |
681 | bool inNonSpatialChannel(void); | ||
670 | std::string getAudioSessionURI(); | 682 | std::string getAudioSessionURI(); |
671 | std::string getAudioSessionHandle(); | 683 | std::string getAudioSessionHandle(); |
672 | 684 | ||