aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra
diff options
context:
space:
mode:
authorArmin Weatherwax2011-05-22 02:23:05 +0200
committerArmin Weatherwax2011-05-22 02:59:20 +0200
commitab350d3cb38e1bcba0bbc50cf92408cb41d543fb (patch)
tree4c390617db99ddb8929edfbbbaa09dd8e94aa0ed /linden/indra
parentAdd missing debug about stopping internet stream. (diff)
downloadmeta-impy-ab350d3cb38e1bcba0bbc50cf92408cb41d543fb.zip
meta-impy-ab350d3cb38e1bcba0bbc50cf92408cb41d543fb.tar.gz
meta-impy-ab350d3cb38e1bcba0bbc50cf92408cb41d543fb.tar.bz2
meta-impy-ab350d3cb38e1bcba0bbc50cf92408cb41d543fb.tar.xz
revamp the voice client.
* split the "voice" debug tag into several tags for usable filtering while debugging * remove debug-spam from user view by: * remove capability request spam by: * llstartup the voice client state engine when actually a region is present, and not the initial fake region. * don't request a capability to determine if (the very same) capability can be requested. * don't do it over and over as if a capability rezzed in like an avatar. Its available - or not (see llstartup). * unload the daemon if not used. * load vivox daemon depending on specific criteria in the caps * remove the partial implementation to load a specific daemon with via the openregion message or the login response. * discard obsolete caps. Tested and working on linux: Parcel changing, region changing, (SL) voice-disabled region private call, (SL) private call region changing, (OS) no voice <-> voice region changing, (OS) mumble <-> freeswitch region changing. To test: Mac, Win. Anything that needs to be tested and not mentioned above.
Diffstat (limited to 'linden/indra')
-rw-r--r--linden/indra/newview/app_settings/logcontrol.xml5
-rw-r--r--linden/indra/newview/app_settings/settings.xml17
-rw-r--r--linden/indra/newview/kowopenregionsettings.cpp8
-rw-r--r--linden/indra/newview/llstartup.cpp12
-rw-r--r--linden/indra/newview/llvoiceclient.cpp721
-rw-r--r--linden/indra/newview/llvoiceclient.h20
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{
141public: 141public:
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
186private: 188private:
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;
1008class LLVoiceClientCapResponder : public LLHTTPClient::Responder 1011class LLVoiceClientCapResponder : public LLHTTPClient::Responder
1009{ 1012{
1010public: 1013public:
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
1016private: 1019private:
1020 LLUUID mResponseID;
1017}; 1021};
1018 1022
1019void LLVoiceClientCapResponder::error(U32 status, const std::string& reason) 1023void 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
1352void LLVoiceClient::requestVoiceAccountProvision(S32 retries) 1359void 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
1484void 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
1435void LLVoiceClient::idle(void* user_data) 1661void 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
1538void LLVoiceClient::stateMachine() 1764void 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
2570void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAudio, bool startText) 2649void 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
2606void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio, bool startText) 2685void 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
2643void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session) 2722void 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
2661void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session) 2740void 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
2824void LLVoiceClient::clearCaptureDevices() 2903void 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
2830void LLVoiceClient::addCaptureDevice(const std::string& name) 2909void 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
2862void LLVoiceClient::clearRenderDevices() 2941void 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
2868void LLVoiceClient::addRenderDevice(const std::string& name) 2947void 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
2952void LLVoiceClient::tuningCaptureStartSendMessage(int duration) 3031void 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
2965void LLVoiceClient::tuningCaptureStopSendMessage() 3044void 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
3039void LLVoiceClient::giveUp() 3118void 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
3049static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel) 3124static 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
5059void LLVoiceClient::parcelChanged() 5134void 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
5206void LLVoiceClient::setSpatialChannel( 5321void 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
5453void LLVoiceClient::leaveNonSpatialChannel() 5574void 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
5768bool 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
5647std::string LLVoiceClient::getAudioSessionURI() 5780std::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
6526void LLVoiceClient::deleteAllSessions() 6659void 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
6541void LLVoiceClient::verifySessionState(void) 6674void 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);
667static std::string nameFromsipURI(const std::string &uri); 678static 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