aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvoiceclient.cpp
diff options
context:
space:
mode:
authorDavid Seikel2011-06-04 00:17:28 +1000
committerDavid Seikel2011-06-04 00:17:28 +1000
commit492eaaf4eec82327116f2605e3d8becf94bec1b3 (patch)
treedcddd674cb4861445c3ec5aaa59325b99a437614 /linden/indra/newview/llvoiceclient.cpp
parentSet the real bare minimum prim size to 0.00001, as 0 sized objects cause bugs. (diff)
parentFixing the menu to actually use its color options reveals how broken the whol... (diff)
downloadmeta-impy-492eaaf4eec82327116f2605e3d8becf94bec1b3.zip
meta-impy-492eaaf4eec82327116f2605e3d8becf94bec1b3.tar.gz
meta-impy-492eaaf4eec82327116f2605e3d8becf94bec1b3.tar.bz2
meta-impy-492eaaf4eec82327116f2605e3d8becf94bec1b3.tar.xz
Merge branch 'next' of git://github.com/jacek/imprudence into next
Conflicts (manually merged): linden/indra/llcommon/llversionviewer.h linden/indra/llvfs/lldir.cpp linden/indra/llvfs/lldir_mac.cpp linden/indra/newview/CMakeLists.txt linden/indra/newview/English.lproj/InfoPlist.strings linden/indra/newview/Info-Imprudence.plist linden/indra/newview/Info-meta-impy.plist linden/indra/newview/llappviewer.cpp linden/indra/newview/llpanellogin.cpp linden/indra/newview/packaging/mac/Info.plist.in linden/indra/newview/res/viewerRes.rc linden/indra/newview/skins/default/xui/en-us/floater_about.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_advanced.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_skins.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_web.xml linden/indra/newview/skins/default/xui/zh/menu_viewer.xml linden/indra/newview/skins/default/xui/zh/panel_group_general.xml linden/indra/newview/viewer_manifest.py linden/indra/newview/viewerversion.cpp linden/indra/newview/viewerversion.h linden/install.xml Also some post merge tweaks.
Diffstat (limited to 'linden/indra/newview/llvoiceclient.cpp')
-rw-r--r--linden/indra/newview/llvoiceclient.cpp805
1 files changed, 484 insertions, 321 deletions
diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp
index 63362be..4b5d3ce 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
@@ -452,13 +455,13 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
452 } 455 }
453 } 456 }
454 } 457 }
455 LL_DEBUGS("VivoxProtocolParser") << tag << " (" << responseDepth << ")" << LL_ENDL; 458 LL_DEBUGS("VivoxProtocolParserTag") << tag << " (" << responseDepth << ")" << LL_ENDL;
456 } 459 }
457 else 460 else
458 { 461 {
459 if (ignoringTags) 462 if (ignoringTags)
460 { 463 {
461 LL_DEBUGS("VivoxProtocolParser") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; 464 LL_DEBUGS("VivoxProtocolParserTag") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL;
462 } 465 }
463 else 466 else
464 { 467 {
@@ -471,7 +474,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
471 ignoreDepth = responseDepth; 474 ignoreDepth = responseDepth;
472 accumulateText = false; 475 accumulateText = false;
473 476
474 LL_DEBUGS("VivoxProtocolParser") << "starting ignore, ignoreDepth is " << ignoreDepth << LL_ENDL; 477 LL_DEBUGS("VivoxProtocolParserTag") << "starting ignore, ignoreDepth is " << ignoreDepth << LL_ENDL;
475 } 478 }
476 else if (!stricmp("CaptureDevices", tag)) 479 else if (!stricmp("CaptureDevices", tag))
477 { 480 {
@@ -512,18 +515,18 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
512 { 515 {
513 if (ignoreDepth == responseDepth) 516 if (ignoreDepth == responseDepth)
514 { 517 {
515 LL_DEBUGS("VivoxProtocolParser") << "end of ignore" << LL_ENDL; 518 LL_DEBUGS("VivoxProtocolParserTag") << "end of ignore" << LL_ENDL;
516 ignoringTags = false; 519 ignoringTags = false;
517 } 520 }
518 else 521 else
519 { 522 {
520 LL_DEBUGS("VivoxProtocolParser") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; 523 LL_DEBUGS("VivoxProtocolParserTag") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL;
521 } 524 }
522 } 525 }
523 526
524 if (!ignoringTags) 527 if (!ignoringTags)
525 { 528 {
526 LL_DEBUGS("VivoxProtocolParser") << "processing tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; 529 LL_DEBUGS("VivoxProtocolParserTag") << "processing tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL;
527 530
528 // Closing a tag. Finalize the text we've accumulated and reset 531 // Closing a tag. Finalize the text we've accumulated and reset
529 if (!stricmp("ReturnCode", tag)) 532 if (!stricmp("ReturnCode", tag))
@@ -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;
@@ -1169,11 +1175,13 @@ LLVoiceClient::LLVoiceClient()
1169 // Ignoring SIGCHLD should prevent zombies from being created. Alternately, we could use wait(), but I'd rather not do that. 1175 // Ignoring SIGCHLD should prevent zombies from being created. Alternately, we could use wait(), but I'd rather not do that.
1170 signal(SIGCHLD, SIG_IGN); 1176 signal(SIGCHLD, SIG_IGN);
1171#endif 1177#endif
1172 1178 if(!gSavedSettings.getBOOL("CmdLineDisableVoice"))//no reason to lag non-voice users
1173 // set up state machine 1179 {
1174 setState(stateDisabled); 1180 // set up state machine
1175 1181 setState(stateDisabled);
1176 gIdleCallbacks.addFunction(idle, this); 1182
1183 gIdleCallbacks.addFunction(idle, this);
1184 }
1177} 1185}
1178 1186
1179//--------------------------------------------------- 1187//---------------------------------------------------
@@ -1347,22 +1355,33 @@ void LLVoiceClient::userAuthorized(const std::string& firstName, const std::stri
1347 sConnectingToAgni = LLViewerLogin::getInstance()->isInProductionGrid(); 1355 sConnectingToAgni = LLViewerLogin::getInstance()->isInProductionGrid();
1348 1356
1349 mAccountName = nameFromID(agentID); 1357 mAccountName = nameFromID(agentID);
1358 mAccountActive = true;
1350} 1359}
1351 1360
1352void LLVoiceClient::requestVoiceAccountProvision(S32 retries) 1361void LLVoiceClient::requestVoiceAccountProvision(S32 retries)
1353{ 1362{
1354 if ( gAgent.getRegion() && mVoiceEnabled ) 1363 LLViewerRegion* region = gAgent.getRegion();
1364 if ( mVoiceEnabled && region && region->capabilitiesReceived())
1355 { 1365 {
1356 std::string url = 1366 std::string url = region->getCapability("ProvisionVoiceAccountRequest");
1357 gAgent.getRegion()->getCapability( 1367
1358 "ProvisionVoiceAccountRequest"); 1368 if ( url.empty() )
1369 {
1370 mVAPRequested = false;
1371 mAccountActive = false;
1372 LL_DEBUGS("VoiceSession") << "Cancel Session: ProvisionVoiceAccountRequest capability empty."
1373 << llendl;
1374 setState(stateDisableCleanup);
1375 }
1359 1376
1360 if ( url == "" ) return; 1377 LL_DEBUGS("VoiceCaps") << "Got ProvisionVoiceAccountRequest capability: "
1378 << url << llendl;
1361 1379
1380 mVAPCapResponseID.generate();
1362 LLHTTPClient::post( 1381 LLHTTPClient::post(
1363 url, 1382 url,
1364 LLSD(), 1383 LLSD(),
1365 new LLViewerVoiceAccountProvisionResponder(retries)); 1384 new LLViewerVoiceAccountProvisionResponder(retries, mVAPCapResponseID));
1366 } 1385 }
1367} 1386}
1368 1387
@@ -1370,11 +1389,46 @@ void LLVoiceClient::login(
1370 const std::string& account_name, 1389 const std::string& account_name,
1371 const std::string& password, 1390 const std::string& password,
1372 const std::string& voice_sip_uri_hostname, 1391 const std::string& voice_sip_uri_hostname,
1373 const std::string& voice_account_server_uri) 1392 const std::string& voice_account_server_uri,
1393 const LLUUID& response_id)
1374{ 1394{
1395 if(response_id != mVAPCapResponseID) return;
1396
1397 std::string new_scheme;
1398 std::string old_scheme;
1399 if(!voice_account_server_uri.empty())
1400 {
1401 new_scheme = voice_account_server_uri.substr(0, voice_account_server_uri.find("://"));
1402 }
1403 if(!mDaemonScheme.empty())
1404 {
1405 old_scheme = mDaemonScheme;
1406 }
1407 else
1408 {
1409 old_scheme = new_scheme;
1410 }
1411
1375 mVoiceSIPURIHostName = voice_sip_uri_hostname; 1412 mVoiceSIPURIHostName = voice_sip_uri_hostname;
1376 mVoiceAccountServerURI = voice_account_server_uri; 1413 mVoiceAccountServerURI = voice_account_server_uri;
1377 1414
1415
1416 LL_DEBUGS("VoiceCaps") << "new_scheme: \"" << new_scheme << "\""
1417 << "\nold_scheme: \"" << old_scheme << "\""
1418 << "\ngateway running: " << ( isGatewayRunning() ? "true" : "false" ) << llendl;
1419 if(!isGatewayRunning() )
1420 {
1421 loadDaemon(new_scheme);
1422 }
1423 else if(old_scheme != new_scheme)
1424 {
1425 mAccountActive = true;
1426 LL_DEBUGS("VoiceSession") << "Cancel Session: Protocol changed."
1427 << llendl;
1428 setState(stateDisableCleanup);
1429 }
1430
1431
1378 if(!mAccountHandle.empty()) 1432 if(!mAccountHandle.empty())
1379 { 1433 {
1380 // Already logged in. 1434 // Already logged in.
@@ -1432,6 +1486,185 @@ void LLVoiceClient::login(
1432 } 1486 }
1433} 1487}
1434 1488
1489void LLVoiceClient::loadDaemon(const std::string& scheme)
1490{
1491
1492 // Launch the voice daemon
1493
1494
1495 // *FIX:Mani - Using the executable dir instead
1496 // of mAppRODataDir, the working directory from which the app
1497 // is launched.
1498 //std::string exe_path = gDirUtilp->getAppRODataDir();
1499 std::string exe_path = gDirUtilp->getExecutableDir();
1500 exe_path += gDirUtilp->getDirDelimiter();
1501
1502#if LL_DARWIN
1503 exe_path += "../Resources/";
1504#endif
1505
1506 //exe_path += gSavedSettings.getString("VoiceModule");
1507 llwarns << "Scheme: " << scheme << llendl;
1508
1509 std::string module;
1510 if (scheme == "tcp")
1511 {
1512
1513 module = gSavedSettings.getString("VoiceModuleMumble").empty() ?
1514 "mumble" : gSavedSettings.getString("VoiceModuleMumble");
1515 }
1516 else
1517 {
1518 module = gSavedSettings.getString("VoiceModuleVivox").empty() ?
1519 "SLVoice" : gSavedSettings.getString("VoiceModuleVivox");
1520 }
1521
1522 size_t pos_to_tst = module.find_last_of("/\\");
1523 if( pos_to_tst != std::string::npos )
1524 {
1525 module = module.substr(pos_to_tst+1);
1526 }
1527
1528#if LL_WINDOWS
1529 std::string extension = ".exe";
1530 if ( module.rfind(extension) != module.length()-extension.length())
1531 {
1532 module.append(extension);
1533 }
1534#endif
1535
1536 exe_path.append(module);
1537
1538 // See if the vivox executable exists
1539 llstat s;
1540 if(!LLFile::stat(exe_path, &s))
1541 {
1542 // vivox executable exists. Build the command line and launch the daemon.
1543 // SLIM SDK: these arguments are no longer necessary.
1544 // std::string args = " -p tcp -h -c";
1545 std::string args;
1546 std::string cmd;
1547 std::string loglevel = gSavedSettings.getString("VivoxDebugLevel");
1548
1549 if(loglevel.empty())
1550 {
1551 loglevel = "-1"; // turn logging off completely
1552 }
1553
1554 args += " -ll ";
1555 args += loglevel;
1556
1557 llwarns << "Voice loaded from: " << exe_path << " " << args << LL_ENDL;
1558
1559#if LL_WINDOWS
1560 PROCESS_INFORMATION pinfo;
1561 STARTUPINFOA sinfo;
1562 memset(&sinfo, 0, sizeof(sinfo));
1563 std::string exe_dir = gDirUtilp->getAppRODataDir();
1564
1565
1566 // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string...
1567 char *args2 = new char[args.size() + 1];
1568 strcpy(args2, args.c_str());
1569
1570 if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo))
1571 {
1572 // DWORD dwErr = GetLastError();
1573 }
1574 else
1575 {
1576 // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
1577 // CloseHandle(pinfo.hProcess); // stops leaks - nothing else
1578 sGatewayHandle = pinfo.hProcess;
1579 CloseHandle(pinfo.hThread); // stops leaks - nothing else
1580 }
1581
1582 delete[] args2;
1583#else // LL_WINDOWS
1584 // This should be the same for mac and linux
1585 {
1586 std::vector<std::string> arglist;
1587 arglist.push_back(exe_path);
1588
1589 // Split the argument string into separate strings for each argument
1590 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
1591 boost::char_separator<char> sep(" ");
1592 tokenizer tokens(args, sep);
1593 tokenizer::iterator token_iter;
1594
1595 for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
1596 {
1597 arglist.push_back(*token_iter);
1598 }
1599
1600 // create an argv vector for the child process
1601 char **fakeargv = new char*[arglist.size() + 1];
1602 int i;
1603 for(i=0; i < arglist.size(); i++)
1604 fakeargv[i] = const_cast<char*>(arglist[i].c_str());
1605
1606 fakeargv[i] = NULL;
1607
1608 fflush(NULL); // flush all buffers before the child inherits them
1609 pid_t id = vfork();
1610 if(id == 0)
1611 {
1612 // child
1613 execv(exe_path.c_str(), fakeargv);
1614
1615 // If we reach this point, the exec failed.
1616 // Use _exit() instead of exit() per the vfork man page.
1617 _exit(0);
1618 }
1619
1620 // parent
1621 delete[] fakeargv;
1622 sGatewayPID = id;
1623
1624 }
1625
1626#endif // LL_WINDOWS
1627
1628 mDaemonScheme = scheme;
1629 mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost").c_str(), gSavedSettings.getU32("VoicePort"));
1630
1631 // Dirty the states we'll need to sync with the daemon when it comes up.
1632 mPTTDirty = true;
1633 mMicVolumeDirty = true;
1634 mSpeakerVolumeDirty = true;
1635 mSpeakerMuteDirty = true;
1636 // These only need to be set if they're not default (i.e. empty string).
1637 mCaptureDeviceDirty = !mCaptureDevice.empty();
1638 mRenderDeviceDirty = !mRenderDevice.empty();
1639
1640 mMainSessionGroupHandle.clear();
1641
1642 // kick in
1643
1644 mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS);
1645 mUpdateTimer.start();
1646
1647 setState(stateDaemonLaunched);
1648
1649 //trigger parcel changed in the state engine
1650 mCurrentRegionName.append("kick in");
1651
1652
1653 }
1654 else
1655 {
1656 LL_WARNS("Voice") << exe_path << " not found." << LL_ENDL;
1657 mAccountActive = false;
1658 LL_DEBUGS("VoiceSession") << "Cancel Session: no module"
1659 << llendl;
1660 setState(stateDisableCleanup);
1661 }
1662
1663 // we are done, re-allow ProvisionVoiceAccountRequest
1664 mVAPRequested = false;
1665}
1666
1667
1435void LLVoiceClient::idle(void* user_data) 1668void LLVoiceClient::idle(void* user_data)
1436{ 1669{
1437 LLVoiceClient* self = (LLVoiceClient*)user_data; 1670 LLVoiceClient* self = (LLVoiceClient*)user_data;
@@ -1527,6 +1760,8 @@ void LLVoiceClient::setState(state inState)
1527} 1760}
1528void LLVoiceClient::close() 1761void LLVoiceClient::close()
1529{ 1762{
1763 LL_DEBUGS("VoiceSession") << "Cancel Session: LLVoiceClient::close() called."
1764 << llendl;
1530 setState(stateDisableCleanup); 1765 setState(stateDisableCleanup);
1531} 1766}
1532 1767
@@ -1537,11 +1772,20 @@ void LLVoiceClient::start()
1537 1772
1538void LLVoiceClient::stateMachine() 1773void LLVoiceClient::stateMachine()
1539{ 1774{
1775 if( stateJail == getState())
1776 {
1777 return;
1778 }
1779
1780 if(gSavedSettings.getBOOL("CmdLineDisableVoice"))
1781 {
1782 // Voice is locked out, we must not launch the vivox daemon.
1783 setState(stateJail);
1784 }
1540 1785
1541 // Disable voice as long as the viewer is disconnected from the sim (login/relog) 1786 // Disable voice as long as the viewer is disconnected from the sim (login/relog)
1542 setVoiceEnabled(!gDisconnected 1787 setVoiceEnabled(!gDisconnected
1543 && gSavedSettings.getBOOL("EnableVoiceChat") 1788 && gSavedSettings.getBOOL("EnableVoiceChat") );
1544 && !gSavedSettings.getBOOL("CmdLineDisableVoice") );
1545 1789
1546 if(mVoiceEnabled) 1790 if(mVoiceEnabled)
1547 { 1791 {
@@ -1560,12 +1804,10 @@ void LLVoiceClient::stateMachine()
1560 { 1804 {
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. 1805 // 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; 1806 LL_WARNS("Voice") << "Disabling voice before connection to daemon, terminating." << LL_ENDL;
1563 killGateway();
1564 } 1807 }
1565 1808 LL_DEBUGS("VoiceSession") << "Cancel Session: User turned off voice or logs off."
1566 logout(); 1809 << llendl;
1567 connectorShutdown(); 1810 mAccountActive = false;
1568
1569 setState(stateDisableCleanup); 1811 setState(stateDisableCleanup);
1570 } 1812 }
1571 } 1813 }
@@ -1574,47 +1816,21 @@ void LLVoiceClient::stateMachine()
1574 if(mVoiceEnabled) 1816 if(mVoiceEnabled)
1575 { 1817 {
1576 LLViewerRegion *region = gAgent.getRegion(); 1818 LLViewerRegion *region = gAgent.getRegion();
1577 LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); 1819 if(region && region->capabilitiesReceived())
1578
1579 if(region && parcel)
1580 { 1820 {
1581 S32 parcelLocalID = parcel->getLocalID(); 1821 LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
1582 std::string regionName = region->getName(); 1822 if(parcel)
1583 std::string capURI = region->getCapability("ParcelVoiceInfoRequest");
1584
1585// LL_DEBUGS("Voice") << "Region name = \"" << regionName << "\", parcel local ID = " << parcelLocalID << ", cap URI = \"" << capURI << "\"" << LL_ENDL;
1586
1587 // 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.
1589 // If either is empty, wait for the next time around.
1590 if(!regionName.empty())
1591 { 1823 {
1592 if(!capURI.empty()) 1824 S32 parcelLocalID = parcel->getLocalID();
1593 { 1825 std::string regionName = region->getName();
1594 if((parcelLocalID != mCurrentParcelLocalID) || (regionName != mCurrentRegionName)) 1826
1595 { 1827 if((parcelLocalID != mCurrentParcelLocalID) || (regionName != mCurrentRegionName))
1596 // We have changed parcels. Initiate a parcel channel lookup.
1597 mCurrentParcelLocalID = parcelLocalID;
1598 mCurrentRegionName = regionName;
1599
1600 parcelChanged();
1601 }
1602 }
1603 else
1604 { 1828 {
1605 static int count = 0; 1829 // We have changed parcels. Initiate a parcel channel lookup.
1606 static int count2 = 0; 1830 mCurrentParcelLocalID = parcelLocalID;
1607 static int num = 1; 1831 mCurrentRegionName = regionName;
1608 ++count; 1832
1609 if (count % num == 0) 1833 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 } 1834 }
1619 } 1835 }
1620 } 1836 }
@@ -1624,191 +1840,65 @@ void LLVoiceClient::stateMachine()
1624 { 1840 {
1625 //MARK: stateDisableCleanup 1841 //MARK: stateDisableCleanup
1626 case stateDisableCleanup: 1842 case stateDisableCleanup:
1627 // Clean up and reset everything. 1843 // Clean up and reset everything.
1844
1845 mVAPCapResponseID.setNull();
1846 mPIRCapResponseID.setNull();
1847
1848 if(isGatewayRunning())
1849 {
1850 killGateway();
1851 }
1852 logoutSendMessage();
1853 mConnected = false;
1854
1855
1628 closeSocket(); 1856 closeSocket();
1629 deleteAllSessions(); 1857 deleteAllSessions();
1630 deleteAllBuddies(); 1858 deleteAllBuddies();
1631 1859
1632 mConnectorHandle.clear(); 1860 mConnectorHandle.clear();
1633 mAccountHandle.clear(); 1861 mAccountHandle.clear();
1634 mAccountPassword.clear(); 1862 mAccountPassword.clear();
1635 mVoiceAccountServerURI.clear(); 1863 mVoiceAccountServerURI.clear();
1636 1864 mVAPRequested = false;
1637 setState(stateDisabled); 1865 setState(stateDisabled);
1638 break; 1866 break;
1639 1867
1640 //MARK: stateDisabled 1868 //MARK: stateDisabled
1641 case stateDisabled: 1869 case stateDisabled:
1642 if(mTuningMode || (mVoiceEnabled && !mAccountName.empty())) 1870 if(mTuningMode || (mVoiceEnabled && mAccountActive && !mAccountName.empty()))
1643 { 1871 {
1644 setState(stateStart); 1872 setState(stateStart);
1645 } 1873 }
1646 break; 1874 break;
1647 1875
1648 //MARK: stateStart 1876 //MARK: stateStart
1649 case stateStart: 1877 case stateStart:
1650 if(gSavedSettings.getBOOL("CmdLineDisableVoice")) 1878 {
1651 { 1879 LLViewerRegion *region = gAgent.getRegion();
1652 // Voice is locked out, we must not launch the vivox daemon. 1880 bool have_region = (NULL != region && region->capabilitiesReceived());
1653 setState(stateJail); 1881 if(mVoiceEnabled && !mVAPRequested && !mAccountName.empty() && have_region)
1654 }
1655 else if(!isGatewayRunning())
1656 { 1882 {
1657 if(true) 1883 mVAPRequested = true;
1658 { 1884 requestVoiceAccountProvision();
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 } 1885 }
1797 break; 1886 } break;
1798 1887
1799 //MARK: stateDaemonLaunched 1888 //MARK: stateDaemonLaunched
1800 case stateDaemonLaunched: 1889 case stateDaemonLaunched:
1801 if(mUpdateTimer.hasExpired()) 1890 if(mUpdateTimer.hasExpired())
1802 { 1891 {
1803 LL_DEBUGS("Voice") << "Connecting to vivox daemon" << LL_ENDL; 1892
1804
1805 mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS); 1893 mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS);
1806 1894
1807 if(!mSocket) 1895 if(!mSocket)
1808 { 1896 {
1897 LL_DEBUGS("VoiceDaemon") << "Connecting to voice daemon. Protocol: "
1898 << mDaemonScheme << LL_ENDL;
1809 mSocket = LLSocket::create(LLSocket::STREAM_TCP); 1899 mSocket = LLSocket::create(LLSocket::STREAM_TCP);
1810 } 1900 }
1811 1901
1812 mConnected = mSocket->blockingConnect(mDaemonHost); 1902 mConnected = mSocket->blockingConnect(mDaemonHost);
1813 if(mConnected) 1903 if(mConnected)
1814 { 1904 {
@@ -1817,6 +1907,7 @@ void LLVoiceClient::stateMachine()
1817 else 1907 else
1818 { 1908 {
1819 // If the connect failed, the socket may have been put into a bad state. Delete it. 1909 // If the connect failed, the socket may have been put into a bad state. Delete it.
1910 LL_DEBUGS("VoiceDaemon") << "voice daemon not ready yet, retrying" << LL_ENDL;
1820 closeSocket(); 1911 closeSocket();
1821 } 1912 }
1822 } 1913 }
@@ -1842,9 +1933,8 @@ void LLVoiceClient::stateMachine()
1842 1933
1843 setState(stateConnected); 1934 setState(stateConnected);
1844 } 1935 }
1845
1846 break; 1936 break;
1847 1937
1848 //MARK: stateConnected 1938 //MARK: stateConnected
1849 case stateConnected: 1939 case stateConnected:
1850 // Initial devices query 1940 // Initial devices query
@@ -1871,24 +1961,16 @@ void LLVoiceClient::stateMachine()
1871 } 1961 }
1872 else if(!mAccountName.empty() && mVoiceEnabled) 1962 else if(!mAccountName.empty() && mVoiceEnabled)
1873 { 1963 {
1874 LLViewerRegion *region = gAgent.getRegion(); 1964 if ( mAccountPassword.empty() )
1875
1876 if(region)
1877 { 1965 {
1878 if ( region->getCapability("ProvisionVoiceAccountRequest") != "" ) 1966 requestVoiceAccountProvision();
1879 { 1967 }
1880 if ( mAccountPassword.empty() ) 1968 else
1881 { 1969 {
1882 requestVoiceAccountProvision(); 1970 setState(stateConnectorStart);
1883 }
1884 setState(stateConnectorStart);
1885 }
1886 else
1887 {
1888 LL_DEBUGS("Voice") << "region doesn't have ProvisionVoiceAccountRequest capability!" << LL_ENDL;
1889 }
1890 } 1971 }
1891 } 1972 }
1973
1892 break; 1974 break;
1893 1975
1894 //MARK: stateMicTuningStart 1976 //MARK: stateMicTuningStart
@@ -2025,7 +2107,10 @@ void LLVoiceClient::stateMachine()
2025 if(mLoginRetryCount > MAX_LOGIN_RETRIES) 2107 if(mLoginRetryCount > MAX_LOGIN_RETRIES)
2026 { 2108 {
2027 LL_WARNS("Voice") << "too many login retries, giving up." << LL_ENDL; 2109 LL_WARNS("Voice") << "too many login retries, giving up." << LL_ENDL;
2028 setState(stateLoginFailed); 2110 LL_DEBUGS("VoiceSession") << "Cancel Session: too many login retries."
2111 << llendl;
2112 mAccountActive = false;
2113 setState(stateDisableCleanup);
2029 } 2114 }
2030 else 2115 else
2031 { 2116 {
@@ -2385,7 +2470,11 @@ void LLVoiceClient::stateMachine()
2385 2470
2386 //MARK: stateConnectorStopped 2471 //MARK: stateConnectorStopped
2387 case stateConnectorStopped: // connector stop received 2472 case stateConnectorStopped: // connector stop received
2473 {
2474 LL_DEBUGS("VoiceSession") << "Cancel Session: entered stateConnectorStopped."
2475 << llendl;
2388 setState(stateDisableCleanup); 2476 setState(stateDisableCleanup);
2477 }
2389 break; 2478 break;
2390 2479
2391 //MARK: stateConnectorFailed 2480 //MARK: stateConnectorFailed
@@ -2396,6 +2485,8 @@ void LLVoiceClient::stateMachine()
2396 case stateConnectorFailedWaiting: 2485 case stateConnectorFailedWaiting:
2397 if(!mVoiceEnabled) 2486 if(!mVoiceEnabled)
2398 { 2487 {
2488 LL_DEBUGS("VoiceSession") << "Cancel Session: entered stateConnectorFailedWaiting."
2489 << llendl;
2399 setState(stateDisableCleanup); 2490 setState(stateDisableCleanup);
2400 } 2491 }
2401 break; 2492 break;
@@ -2408,6 +2499,8 @@ void LLVoiceClient::stateMachine()
2408 case stateLoginFailedWaiting: 2499 case stateLoginFailedWaiting:
2409 if(!mVoiceEnabled) 2500 if(!mVoiceEnabled)
2410 { 2501 {
2502 LL_DEBUGS("VoiceSession") << "Cancel Session: entered stateLoginFailedWaiting."
2503 << llendl;
2411 setState(stateDisableCleanup); 2504 setState(stateDisableCleanup);
2412 } 2505 }
2413 break; 2506 break;
@@ -2569,7 +2662,7 @@ void LLVoiceClient::sessionGroupCreateSendMessage()
2569 2662
2570void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAudio, bool startText) 2663void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAudio, bool startText)
2571{ 2664{
2572 LL_DEBUGS("Voice") << "requesting create: " << session->mSIPURI << LL_ENDL; 2665 LL_DEBUGS("VoiceSession") << "requesting create: " << session->mSIPURI << LL_ENDL;
2573 2666
2574 session->mCreateInProgress = true; 2667 session->mCreateInProgress = true;
2575 if(startAudio) 2668 if(startAudio)
@@ -2605,7 +2698,7 @@ void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAu
2605 2698
2606void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio, bool startText) 2699void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio, bool startText)
2607{ 2700{
2608 LL_DEBUGS("Voice") << "requesting create: " << session->mSIPURI << LL_ENDL; 2701 LL_DEBUGS("VoiceSession") << "requesting create: " << session->mSIPURI << LL_ENDL;
2609 2702
2610 session->mCreateInProgress = true; 2703 session->mCreateInProgress = true;
2611 if(startAudio) 2704 if(startAudio)
@@ -2642,7 +2735,7 @@ void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, boo
2642 2735
2643void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session) 2736void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session)
2644{ 2737{
2645 LL_DEBUGS("Voice") << "connecting audio to session handle: " << session->mHandle << LL_ENDL; 2738 LL_DEBUGS("VoiceSession") << "connecting audio to session handle: " << session->mHandle << LL_ENDL;
2646 2739
2647 session->mMediaConnectInProgress = true; 2740 session->mMediaConnectInProgress = true;
2648 2741
@@ -2660,7 +2753,7 @@ void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session)
2660 2753
2661void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session) 2754void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session)
2662{ 2755{
2663 LL_DEBUGS("Voice") << "connecting text to session handle: " << session->mHandle << LL_ENDL; 2756 LL_DEBUGS("VoiceSession") << "connecting text to session handle: " << session->mHandle << LL_ENDL;
2664 2757
2665 std::ostringstream stream; 2758 std::ostringstream stream;
2666 2759
@@ -2689,7 +2782,7 @@ void LLVoiceClient::leaveAudioSession()
2689{ 2782{
2690 if(mAudioSession) 2783 if(mAudioSession)
2691 { 2784 {
2692 LL_DEBUGS("Voice") << "leaving session: " << mAudioSession->mSIPURI << LL_ENDL; 2785 LL_DEBUGS("VoiceSession") << "leaving session: " << mAudioSession->mSIPURI << LL_ENDL;
2693 2786
2694 switch(getState()) 2787 switch(getState())
2695 { 2788 {
@@ -2724,7 +2817,7 @@ void LLVoiceClient::leaveAudioSession()
2724 } 2817 }
2725 else 2818 else
2726 { 2819 {
2727 LL_WARNS("Voice") << "called with no session handle" << LL_ENDL; 2820 LL_WARNS("VoiceSession") << "called with no session handle" << LL_ENDL;
2728 setState(stateSessionTerminated); 2821 setState(stateSessionTerminated);
2729 } 2822 }
2730 break; 2823 break;
@@ -2734,13 +2827,13 @@ void LLVoiceClient::leaveAudioSession()
2734 break; 2827 break;
2735 2828
2736 default: 2829 default:
2737 LL_WARNS("Voice") << "called from unknown state" << LL_ENDL; 2830 LL_WARNS("VoiceSession") << "called from unknown state" << LL_ENDL;
2738 break; 2831 break;
2739 } 2832 }
2740 } 2833 }
2741 else 2834 else
2742 { 2835 {
2743 LL_WARNS("Voice") << "called with no active session" << LL_ENDL; 2836 LL_WARNS("VoiceSession") << "called with no active session" << LL_ENDL;
2744 setState(stateSessionTerminated); 2837 setState(stateSessionTerminated);
2745 } 2838 }
2746} 2839}
@@ -2749,7 +2842,7 @@ void LLVoiceClient::sessionTerminateSendMessage(sessionState *session)
2749{ 2842{
2750 std::ostringstream stream; 2843 std::ostringstream stream;
2751 2844
2752 LL_DEBUGS("Voice") << "Sending Session.Terminate with handle " << session->mHandle << LL_ENDL; 2845 LL_DEBUGS("VoiceSession") << "Sending Session.Terminate with handle " << session->mHandle << LL_ENDL;
2753 stream 2846 stream
2754 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Terminate.1\">" 2847 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Terminate.1\">"
2755 << "<SessionHandle>" << session->mHandle << "</SessionHandle>" 2848 << "<SessionHandle>" << session->mHandle << "</SessionHandle>"
@@ -2762,7 +2855,7 @@ void LLVoiceClient::sessionGroupTerminateSendMessage(sessionState *session)
2762{ 2855{
2763 std::ostringstream stream; 2856 std::ostringstream stream;
2764 2857
2765 LL_DEBUGS("Voice") << "Sending SessionGroup.Terminate with handle " << session->mGroupHandle << LL_ENDL; 2858 LL_DEBUGS("VoiceSession") << "Sending SessionGroup.Terminate with handle " << session->mGroupHandle << LL_ENDL;
2766 stream 2859 stream
2767 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.Terminate.1\">" 2860 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.Terminate.1\">"
2768 << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" 2861 << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>"
@@ -2775,7 +2868,7 @@ void LLVoiceClient::sessionMediaDisconnectSendMessage(sessionState *session)
2775{ 2868{
2776 std::ostringstream stream; 2869 std::ostringstream stream;
2777 2870
2778 LL_DEBUGS("Voice") << "Sending Session.MediaDisconnect with handle " << session->mHandle << LL_ENDL; 2871 LL_DEBUGS("VoiceSession") << "Sending Session.MediaDisconnect with handle " << session->mHandle << LL_ENDL;
2779 stream 2872 stream
2780 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.MediaDisconnect.1\">" 2873 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.MediaDisconnect.1\">"
2781 << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" 2874 << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>"
@@ -2791,7 +2884,7 @@ void LLVoiceClient::sessionTextDisconnectSendMessage(sessionState *session)
2791{ 2884{
2792 std::ostringstream stream; 2885 std::ostringstream stream;
2793 2886
2794 LL_DEBUGS("Voice") << "Sending Session.TextDisconnect with handle " << session->mHandle << LL_ENDL; 2887 LL_DEBUGS("VoiceSession") << "Sending Session.TextDisconnect with handle " << session->mHandle << LL_ENDL;
2795 stream 2888 stream
2796 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.TextDisconnect.1\">" 2889 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.TextDisconnect.1\">"
2797 << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" 2890 << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>"
@@ -2823,13 +2916,13 @@ void LLVoiceClient::getRenderDevicesSendMessage()
2823 2916
2824void LLVoiceClient::clearCaptureDevices() 2917void LLVoiceClient::clearCaptureDevices()
2825{ 2918{
2826 LL_DEBUGS("Voice") << "called" << LL_ENDL; 2919 LL_DEBUGS("VoiceDevice") << "called" << LL_ENDL;
2827 mCaptureDevices.clear(); 2920 mCaptureDevices.clear();
2828} 2921}
2829 2922
2830void LLVoiceClient::addCaptureDevice(const std::string& name) 2923void LLVoiceClient::addCaptureDevice(const std::string& name)
2831{ 2924{
2832 LL_DEBUGS("Voice") << name << LL_ENDL; 2925 LL_DEBUGS("VoiceDevice") << name << LL_ENDL;
2833 2926
2834 mCaptureDevices.push_back(name); 2927 mCaptureDevices.push_back(name);
2835} 2928}
@@ -2861,13 +2954,13 @@ void LLVoiceClient::setCaptureDevice(const std::string& name)
2861 2954
2862void LLVoiceClient::clearRenderDevices() 2955void LLVoiceClient::clearRenderDevices()
2863{ 2956{
2864 LL_DEBUGS("Voice") << "called" << LL_ENDL; 2957 LL_DEBUGS("VoiceDevice") << "called" << LL_ENDL;
2865 mRenderDevices.clear(); 2958 mRenderDevices.clear();
2866} 2959}
2867 2960
2868void LLVoiceClient::addRenderDevice(const std::string& name) 2961void LLVoiceClient::addRenderDevice(const std::string& name)
2869{ 2962{
2870 LL_DEBUGS("Voice") << name << LL_ENDL; 2963 LL_DEBUGS("VoiceDevice") << name << LL_ENDL;
2871 mRenderDevices.push_back(name); 2964 mRenderDevices.push_back(name);
2872} 2965}
2873 2966
@@ -2951,7 +3044,7 @@ void LLVoiceClient::tuningRenderStopSendMessage()
2951 3044
2952void LLVoiceClient::tuningCaptureStartSendMessage(int duration) 3045void LLVoiceClient::tuningCaptureStartSendMessage(int duration)
2953{ 3046{
2954 LL_DEBUGS("Voice") << "sending CaptureAudioStart" << LL_ENDL; 3047 LL_DEBUGS("VoiceDevice") << "sending CaptureAudioStart" << LL_ENDL;
2955 3048
2956 std::ostringstream stream; 3049 std::ostringstream stream;
2957 stream 3050 stream
@@ -2964,7 +3057,7 @@ void LLVoiceClient::tuningCaptureStartSendMessage(int duration)
2964 3057
2965void LLVoiceClient::tuningCaptureStopSendMessage() 3058void LLVoiceClient::tuningCaptureStopSendMessage()
2966{ 3059{
2967 LL_DEBUGS("Voice") << "sending CaptureAudioStop" << LL_ENDL; 3060 LL_DEBUGS("VoiceDevice") << "sending CaptureAudioStop" << LL_ENDL;
2968 3061
2969 std::ostringstream stream; 3062 std::ostringstream stream;
2970 stream 3063 stream
@@ -3033,17 +3126,17 @@ void LLVoiceClient::daemonDied()
3033 LL_WARNS("Voice") << "Connection to vivox daemon lost. Resetting state."<< LL_ENDL; 3126 LL_WARNS("Voice") << "Connection to vivox daemon lost. Resetting state."<< LL_ENDL;
3034 3127
3035 // Try to relaunch the daemon 3128 // Try to relaunch the daemon
3129 LL_DEBUGS("VoiceSession") << "Cancel Session: voice daemon died."
3130 << llendl;
3036 setState(stateDisableCleanup); 3131 setState(stateDisableCleanup);
3037} 3132}
3038 3133
3039void LLVoiceClient::giveUp() 3134void LLVoiceClient::giveUp()
3040{ 3135{
3041 // All has failed. Clean up and stop trying. 3136 mAccountActive = false;
3042 closeSocket(); 3137 LL_DEBUGS("VoiceSession") << "Cancel Session: giveUp() called."
3043 deleteAllSessions(); 3138 << llendl;
3044 deleteAllBuddies(); 3139 setState(stateDisableCleanup);
3045
3046 setState(stateJail);
3047} 3140}
3048 3141
3049static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel) 3142static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel)
@@ -3378,7 +3471,7 @@ void LLVoiceClient::buildSetCaptureDevice(std::ostringstream &stream)
3378{ 3471{
3379 if(mCaptureDeviceDirty) 3472 if(mCaptureDeviceDirty)
3380 { 3473 {
3381 LL_DEBUGS("Voice") << "Setting input device = \"" << mCaptureDevice << "\"" << LL_ENDL; 3474 LL_DEBUGS("VoiceDevice") << "Setting input device = \"" << mCaptureDevice << "\"" << LL_ENDL;
3382 3475
3383 stream 3476 stream
3384 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetCaptureDevice.1\">" 3477 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetCaptureDevice.1\">"
@@ -4099,29 +4192,29 @@ void LLVoiceClient::reapSession(sessionState *session)
4099 { 4192 {
4100 if(!session->mHandle.empty()) 4193 if(!session->mHandle.empty())
4101 { 4194 {
4102 LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (non-null session handle)" << LL_ENDL; 4195 LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (non-null session handle)" << LL_ENDL;
4103 } 4196 }
4104 else if(session->mCreateInProgress) 4197 else if(session->mCreateInProgress)
4105 { 4198 {
4106 LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (create in progress)" << LL_ENDL; 4199 LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (create in progress)" << LL_ENDL;
4107 } 4200 }
4108 else if(session->mMediaConnectInProgress) 4201 else if(session->mMediaConnectInProgress)
4109 { 4202 {
4110 LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (connect in progress)" << LL_ENDL; 4203 LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (connect in progress)" << LL_ENDL;
4111 } 4204 }
4112 else if(session == mAudioSession) 4205 else if(session == mAudioSession)
4113 { 4206 {
4114 LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (it's the current session)" << LL_ENDL; 4207 LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (it's the current session)" << LL_ENDL;
4115 } 4208 }
4116 else if(session == mNextAudioSession) 4209 else if(session == mNextAudioSession)
4117 { 4210 {
4118 LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (it's the next session)" << LL_ENDL; 4211 LL_DEBUGS("VoiceSession") << "NOT deleting session " << session->mSIPURI << " (it's the next session)" << LL_ENDL;
4119 } 4212 }
4120 else 4213 else
4121 { 4214 {
4122 // TODO: Question: Should we check for queued text messages here? 4215 // 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. 4216 // 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; 4217 LL_DEBUGS("VoiceSession") << "deleting session " << session->mSIPURI << LL_ENDL;
4125 deleteSession(session); 4218 deleteSession(session);
4126 session = NULL; 4219 session = NULL;
4127 } 4220 }
@@ -4179,17 +4272,17 @@ void LLVoiceClient::leftAudioSession(
4179 case stateJoinSessionFailed: 4272 case stateJoinSessionFailed:
4180 case stateJoinSessionFailedWaiting: 4273 case stateJoinSessionFailedWaiting:
4181 // normal transition 4274 // normal transition
4182 LL_DEBUGS("Voice") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL; 4275 LL_DEBUGS("VoiceSession") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL;
4183 setState(stateSessionTerminated); 4276 setState(stateSessionTerminated);
4184 break; 4277 break;
4185 4278
4186 case stateSessionTerminated: 4279 case stateSessionTerminated:
4187 // this will happen sometimes -- there are cases where we send the terminate and then go straight to this state. 4280 // 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; 4281 LL_WARNS("VoiceSession") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL;
4189 break; 4282 break;
4190 4283
4191 default: 4284 default:
4192 LL_WARNS("Voice") << "unexpected SessionStateChangeEvent (left session) in state " << state2string(getState()) << LL_ENDL; 4285 LL_WARNS("VoiceSession") << "unexpected SessionStateChangeEvent (left session) in state " << state2string(getState()) << LL_ENDL;
4193 setState(stateSessionTerminated); 4286 setState(stateSessionTerminated);
4194 break; 4287 break;
4195 } 4288 }
@@ -4249,7 +4342,7 @@ void LLVoiceClient::mediaStreamUpdatedEvent(
4249{ 4342{
4250 sessionState *session = findSession(sessionHandle); 4343 sessionState *session = findSession(sessionHandle);
4251 4344
4252 LL_DEBUGS("Voice") << "session " << sessionHandle << ", status code " << statusCode << ", string \"" << statusString << "\"" << LL_ENDL; 4345 LL_DEBUGS("VoiceSession") << "session " << sessionHandle << ", status code " << statusCode << ", string \"" << statusString << "\"" << LL_ENDL;
4253 4346
4254 if(session) 4347 if(session)
4255 { 4348 {
@@ -4314,7 +4407,7 @@ void LLVoiceClient::mediaStreamUpdatedEvent(
4314 } 4407 }
4315 else 4408 else
4316 { 4409 {
4317 LL_WARNS("Voice") << "session " << sessionHandle << "not found"<< LL_ENDL; 4410 LL_WARNS("VoiceSession") << "session " << sessionHandle << "not found"<< LL_ENDL;
4318 } 4411 }
4319} 4412}
4320 4413
@@ -4435,7 +4528,7 @@ void LLVoiceClient::participantRemovedEvent(
4435 } 4528 }
4436 else 4529 else
4437 { 4530 {
4438 LL_DEBUGS("Voice") << "unknown session " << sessionHandle << LL_ENDL; 4531 LL_DEBUGS("VoiceSession") << "unknown session " << sessionHandle << LL_ENDL;
4439 } 4532 }
4440} 4533}
4441 4534
@@ -4479,7 +4572,7 @@ void LLVoiceClient::participantUpdatedEvent(
4479 } 4572 }
4480 else 4573 else
4481 { 4574 {
4482 LL_WARNS("Voice") << "unknown session " << sessionHandle << LL_ENDL; 4575 LL_WARNS("VoiceSession") << "unknown session " << sessionHandle << LL_ENDL;
4483 } 4576 }
4484} 4577}
4485 4578
@@ -5058,22 +5151,44 @@ LLVoiceClient::participantState* LLVoiceClient::findParticipantByID(const LLUUID
5058 5151
5059void LLVoiceClient::parcelChanged() 5152void LLVoiceClient::parcelChanged()
5060{ 5153{
5061 if(getState() >= stateNoChannel) 5154 mAccountActive = true;
5155 LLViewerRegion* region = gAgent.getRegion();
5156 if( (getState() >= stateNoChannel) && region && region->capabilitiesReceived())
5062 { 5157 {
5063 // If the user is logged in, start a channel lookup. 5158 // If the user is logged in, start a channel lookup,
5064 LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL; 5159 // but not if already in a private call/conference (then SL regions return an empty cap).
5160 //
5065 5161
5066 std::string url = gAgent.getRegion()->getCapability("ParcelVoiceInfoRequest"); 5162 std::string url = region->getCapability("ParcelVoiceInfoRequest");
5067 LLSD data; 5163 LL_DEBUGS("VoiceCaps") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << " cap url:" << url << LL_ENDL;
5068 LLHTTPClient::post( 5164 if(! url.empty() )
5069 url, 5165 {
5070 data, 5166 mPIRCapResponseID.generate();
5071 new LLVoiceClientCapResponder); 5167 LLSD data;
5168 LLHTTPClient::post(
5169 url,
5170 data,
5171 new LLVoiceClientCapResponder(mPIRCapResponseID));
5172 }
5173 else
5174 {
5175
5176 mAccountActive = false;
5177 LL_DEBUGS("VoiceSession") << "Cancel Session: ParcelVoiceInfoRequest cap empty."
5178 << llendl;
5179 setState(stateDisableCleanup);
5180 }
5181 }
5182 else if (region && !region->capabilitiesReceived())
5183 {
5184 // We don't know yet where to get the cap so requesting it makes no sense
5185 mCurrentRegionName.append("retry");
5186 return;
5072 } 5187 }
5073 else 5188 else
5074 { 5189 {
5075 // The transition to stateNoChannel needs to kick this off again. 5190 // The transition to stateNoChannel needs to kick this off again.
5076 LL_WARNS("Voice") << "not logged in yet, deferring" << LL_ENDL; 5191 LL_DEBUGS("Voice") << "not logged in yet, deferring" << LL_ENDL;
5077 } 5192 }
5078} 5193}
5079 5194
@@ -5086,12 +5201,42 @@ void LLVoiceClient::switchChannel(
5086{ 5201{
5087 bool needsSwitch = false; 5202 bool needsSwitch = false;
5088 5203
5089 LL_DEBUGS("Voice") 5204 LL_DEBUGS("VoiceSession")
5090 << "called in state " << state2string(getState()) 5205 << "Switch channel called in state " << state2string(getState())
5091 << " with uri \"" << uri << "\"" 5206 << " with uri \"" << uri << "\""
5092 << (spatial?", spatial is true":", spatial is false") 5207 << (spatial?", spatial is true":", spatial is false")
5093 << LL_ENDL; 5208 << LL_ENDL;
5094 5209
5210 size_t new_uri_find_sip = std::string::npos;
5211 size_t old_uri_find_sip = std::string::npos;
5212 if(!uri.empty())
5213 {
5214 new_uri_find_sip = uri.find("sip:");
5215 }
5216
5217 if( mNextAudioSession
5218 && !( mNextAudioSession->mSIPURI.empty() )
5219 && (mNextAudioSession->mSIPURI != uri) )
5220 {
5221 old_uri_find_sip = mNextAudioSession->mSIPURI.find("sip:");
5222 }
5223 else
5224 {
5225
5226 // just logged in or voice disabled land in SL,
5227 // anyway right daemon is already up
5228 old_uri_find_sip = new_uri_find_sip;
5229 }
5230
5231 if(old_uri_find_sip != new_uri_find_sip)
5232 {
5233 mAccountActive = true;
5234 LL_DEBUGS("VoiceSession") << "Cancel Session: Session type changed"
5235 << llendl;
5236 setState(stateDisableCleanup);
5237 return;
5238 }
5239
5095 switch(getState()) 5240 switch(getState())
5096 { 5241 {
5097 case stateJoinSessionFailed: 5242 case stateJoinSessionFailed:
@@ -5148,7 +5293,7 @@ void LLVoiceClient::switchChannel(
5148 if(uri.empty()) 5293 if(uri.empty())
5149 { 5294 {
5150 // Leave any channel we may be in 5295 // Leave any channel we may be in
5151 LL_DEBUGS("Voice") << "leaving channel" << LL_ENDL; 5296 LL_DEBUGS("VoiceSession") << "leaving channel" << LL_ENDL;
5152 5297
5153 sessionState *oldSession = mNextAudioSession; 5298 sessionState *oldSession = mNextAudioSession;
5154 mNextAudioSession = NULL; 5299 mNextAudioSession = NULL;
@@ -5160,7 +5305,7 @@ void LLVoiceClient::switchChannel(
5160 } 5305 }
5161 else 5306 else
5162 { 5307 {
5163 LL_DEBUGS("Voice") << "switching to channel " << uri << LL_ENDL; 5308 LL_DEBUGS("VoiceSession") << "switching to channel " << uri << LL_ENDL;
5164 5309
5165 mNextAudioSession = addSession(uri); 5310 mNextAudioSession = addSession(uri);
5166 mNextAudioSession->mHash = hash; 5311 mNextAudioSession->mHash = hash;
@@ -5205,8 +5350,14 @@ void LLVoiceClient::setNonSpatialChannel(
5205 5350
5206void LLVoiceClient::setSpatialChannel( 5351void LLVoiceClient::setSpatialChannel(
5207 const std::string &uri, 5352 const std::string &uri,
5208 const std::string &credentials) 5353 const std::string &credentials,
5354 const LLUUID& response_id)
5209{ 5355{
5356 if (response_id != mPIRCapResponseID)
5357 {
5358 return;
5359 }
5360
5210 mSpatialSessionURI = uri; 5361 mSpatialSessionURI = uri;
5211 mSpatialSessionCredentials = credentials; 5362 mSpatialSessionCredentials = credentials;
5212 mAreaVoiceDisabled = mSpatialSessionURI.empty(); 5363 mAreaVoiceDisabled = mSpatialSessionURI.empty();
@@ -5282,7 +5433,7 @@ bool LLVoiceClient::sendTextMessage(const LLUUID& participant_id, const std::str
5282 } 5433 }
5283 else 5434 else
5284 { 5435 {
5285 LL_DEBUGS("Voice") << "Session not found for participant ID " << participant_id << LL_ENDL; 5436 LL_DEBUGS("VoiceSession") << "Session not found for participant ID " << participant_id << LL_ENDL;
5286 } 5437 }
5287 5438
5288 return result; 5439 return result;
@@ -5331,7 +5482,7 @@ void LLVoiceClient::endUserIMSession(const LLUUID &uuid)
5331 } 5482 }
5332 else 5483 else
5333 { 5484 {
5334 LL_DEBUGS("Voice") << "Session not found for participant ID " << uuid << LL_ENDL; 5485 LL_DEBUGS("VoiceSession") << "Session not found for participant ID " << uuid << LL_ENDL;
5335 } 5486 }
5336} 5487}
5337 5488
@@ -5452,7 +5603,7 @@ void LLVoiceClient::declineInvite(std::string &sessionHandle)
5452 5603
5453void LLVoiceClient::leaveNonSpatialChannel() 5604void LLVoiceClient::leaveNonSpatialChannel()
5454{ 5605{
5455 LL_DEBUGS("Voice") 5606 LL_DEBUGS("VoiceSession")
5456 << "called in state " << state2string(getState()) 5607 << "called in state " << state2string(getState())
5457 << LL_ENDL; 5608 << LL_ENDL;
5458 5609
@@ -5640,7 +5791,9 @@ bool LLVoiceClient::inSpatialChannel(void)
5640 5791
5641 if(mAudioSession) 5792 if(mAudioSession)
5642 result = mAudioSession->mIsSpatial; 5793 result = mAudioSession->mIsSpatial;
5643 5794 if(mNextAudioSession)
5795 result |= !(mNextAudioSession->mIsSpatial);
5796
5644 return result; 5797 return result;
5645} 5798}
5646 5799
@@ -5821,11 +5974,13 @@ void LLVoiceClient::setVoiceEnabled(bool enabled)
5821 mVoiceEnabled = enabled; 5974 mVoiceEnabled = enabled;
5822 if (enabled) 5975 if (enabled)
5823 { 5976 {
5977 mAccountActive = true;
5824 LLVoiceChannel::getCurrentVoiceChannel()->activate(); 5978 LLVoiceChannel::getCurrentVoiceChannel()->activate();
5825 } 5979 }
5826 else 5980 else
5827 { 5981 {
5828 // Turning voice off looses your current channel -- this makes sure the UI isn't out of sync when you re-enable it. 5982 // Turning voice off looses your current channel -- this makes sure the UI isn't out of sync when you re-enable it.
5983 mAccountActive = false;
5829 LLVoiceChannel::getCurrentVoiceChannel()->deactivate(); 5984 LLVoiceChannel::getCurrentVoiceChannel()->deactivate();
5830 } 5985 }
5831 } 5986 }
@@ -6397,7 +6552,7 @@ LLVoiceClient::sessionState *LLVoiceClient::addSession(const std::string &uri, c
6397 { 6552 {
6398 // No existing session found. 6553 // No existing session found.
6399 6554
6400 LL_DEBUGS("Voice") << "adding new session: handle " << handle << " URI " << uri << LL_ENDL; 6555 LL_DEBUGS("VoiceSession") << "adding new session: handle " << handle << " URI " << uri << LL_ENDL;
6401 result = new sessionState(); 6556 result = new sessionState();
6402 result->mSIPURI = uri; 6557 result->mSIPURI = uri;
6403 result->mHandle = handle; 6558 result->mHandle = handle;
@@ -6416,7 +6571,7 @@ LLVoiceClient::sessionState *LLVoiceClient::addSession(const std::string &uri, c
6416 if(uri != result->mSIPURI) 6571 if(uri != result->mSIPURI)
6417 { 6572 {
6418 // TODO: Should this be an internal error? 6573 // TODO: Should this be an internal error?
6419 LL_DEBUGS("Voice") << "changing uri from " << result->mSIPURI << " to " << uri << LL_ENDL; 6574 LL_DEBUGS("VoiceSession") << "changing uri from " << result->mSIPURI << " to " << uri << LL_ENDL;
6420 setSessionURI(result, uri); 6575 setSessionURI(result, uri);
6421 } 6576 }
6422 6577
@@ -6425,17 +6580,17 @@ LLVoiceClient::sessionState *LLVoiceClient::addSession(const std::string &uri, c
6425 if(handle.empty()) 6580 if(handle.empty())
6426 { 6581 {
6427 // There's at least one race condition where where addSession was clearing an existing session handle, which caused things to break. 6582 // 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; 6583 LL_DEBUGS("VoiceSession") << "NOT clearing handle " << result->mHandle << LL_ENDL;
6429 } 6584 }
6430 else 6585 else
6431 { 6586 {
6432 // TODO: Should this be an internal error? 6587 // TODO: Should this be an internal error?
6433 LL_DEBUGS("Voice") << "changing handle from " << result->mHandle << " to " << handle << LL_ENDL; 6588 LL_DEBUGS("VoiceSession") << "changing handle from " << result->mHandle << " to " << handle << LL_ENDL;
6434 setSessionHandle(result, handle); 6589 setSessionHandle(result, handle);
6435 } 6590 }
6436 } 6591 }
6437 6592
6438 LL_DEBUGS("Voice") << "returning existing session: handle " << handle << " URI " << uri << LL_ENDL; 6593 LL_DEBUGS("VoiceSession") << "returning existing session: handle " << handle << " URI " << uri << LL_ENDL;
6439 } 6594 }
6440 6595
6441 verifySessionState(); 6596 verifySessionState();
@@ -6455,14 +6610,14 @@ void LLVoiceClient::setSessionHandle(sessionState *session, const std::string &h
6455 { 6610 {
6456 if(iter->second != session) 6611 if(iter->second != session)
6457 { 6612 {
6458 LL_ERRS("Voice") << "Internal error: session mismatch!" << LL_ENDL; 6613 LL_ERRS("VoiceSession") << "Internal error: session mismatch!" << LL_ENDL;
6459 } 6614 }
6460 6615
6461 mSessionsByHandle.erase(iter); 6616 mSessionsByHandle.erase(iter);
6462 } 6617 }
6463 else 6618 else
6464 { 6619 {
6465 LL_ERRS("Voice") << "Internal error: session handle not found in map!" << LL_ENDL; 6620 LL_ERRS("VoiceSession") << "Internal error: session handle not found in map!" << LL_ENDL;
6466 } 6621 }
6467 } 6622 }
6468 6623
@@ -6494,7 +6649,7 @@ void LLVoiceClient::deleteSession(sessionState *session)
6494 { 6649 {
6495 if(iter->second != session) 6650 if(iter->second != session)
6496 { 6651 {
6497 LL_ERRS("Voice") << "Internal error: session mismatch" << LL_ENDL; 6652 LL_ERRS("VoiceSession") << "Internal error: session mismatch" << LL_ENDL;
6498 } 6653 }
6499 mSessionsByHandle.erase(iter); 6654 mSessionsByHandle.erase(iter);
6500 } 6655 }
@@ -6525,7 +6680,7 @@ void LLVoiceClient::deleteSession(sessionState *session)
6525 6680
6526void LLVoiceClient::deleteAllSessions() 6681void LLVoiceClient::deleteAllSessions()
6527{ 6682{
6528 LL_DEBUGS("Voice") << "called" << LL_ENDL; 6683 LL_DEBUGS("VoiceSession") << "called" << LL_ENDL;
6529 6684
6530 while(!mSessions.empty()) 6685 while(!mSessions.empty())
6531 { 6686 {
@@ -6534,20 +6689,20 @@ void LLVoiceClient::deleteAllSessions()
6534 6689
6535 if(!mSessionsByHandle.empty()) 6690 if(!mSessionsByHandle.empty())
6536 { 6691 {
6537 LL_ERRS("Voice") << "Internal error: empty session map, non-empty handle map" << LL_ENDL; 6692 LL_ERRS("VoiceSession") << "Internal error: empty session map, non-empty handle map" << LL_ENDL;
6538 } 6693 }
6539} 6694}
6540 6695
6541void LLVoiceClient::verifySessionState(void) 6696void LLVoiceClient::verifySessionState(void)
6542{ 6697{
6543 // This is mostly intended for debugging problems with session state management. 6698 // 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; 6699 LL_DEBUGS("VoiceSession") << "Total session count: " << mSessions.size() << " , session handle map size: " << mSessionsByHandle.size() << LL_ENDL;
6545 6700
6546 for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) 6701 for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++)
6547 { 6702 {
6548 sessionState *session = *iter; 6703 sessionState *session = *iter;
6549 6704
6550 LL_DEBUGS("Voice") << "session " << session << ": handle " << session->mHandle << ", URI " << session->mSIPURI << LL_ENDL; 6705 LL_DEBUGS("VoiceSession") << "session " << session << ": handle " << session->mHandle << ", URI " << session->mSIPURI << LL_ENDL;
6551 6706
6552 if(!session->mHandle.empty()) 6707 if(!session->mHandle.empty())
6553 { 6708 {
@@ -6555,13 +6710,13 @@ void LLVoiceClient::verifySessionState(void)
6555 sessionMap::iterator i2 = mSessionsByHandle.find(&(session->mHandle)); 6710 sessionMap::iterator i2 = mSessionsByHandle.find(&(session->mHandle));
6556 if(i2 == mSessionsByHandle.end()) 6711 if(i2 == mSessionsByHandle.end())
6557 { 6712 {
6558 LL_ERRS("Voice") << "internal error (handle " << session->mHandle << " not found in session map)" << LL_ENDL; 6713 LL_ERRS("VoiceSession") << "internal error (handle " << session->mHandle << " not found in session map)" << LL_ENDL;
6559 } 6714 }
6560 else 6715 else
6561 { 6716 {
6562 if(i2->second != session) 6717 if(i2->second != session)
6563 { 6718 {
6564 LL_ERRS("Voice") << "internal error (handle " << session->mHandle << " in session map points to another session)" << LL_ENDL; 6719 LL_ERRS("VoiceSession") << "internal error (handle " << session->mHandle << " in session map points to another session)" << LL_ENDL;
6565 } 6720 }
6566 } 6721 }
6567 } 6722 }
@@ -6574,13 +6729,13 @@ void LLVoiceClient::verifySessionState(void)
6574 sessionIterator i2 = mSessions.find(session); 6729 sessionIterator i2 = mSessions.find(session);
6575 if(i2 == mSessions.end()) 6730 if(i2 == mSessions.end())
6576 { 6731 {
6577 LL_ERRS("Voice") << "internal error (session for handle " << session->mHandle << " not found in session map)" << LL_ENDL; 6732 LL_ERRS("VoiceSession") << "internal error (session for handle " << session->mHandle << " not found in session map)" << LL_ENDL;
6578 } 6733 }
6579 else 6734 else
6580 { 6735 {
6581 if(session->mHandle != (*i2)->mHandle) 6736 if(session->mHandle != (*i2)->mHandle)
6582 { 6737 {
6583 LL_ERRS("Voice") << "internal error (session for handle " << session->mHandle << " points to session with different handle " << (*i2)->mHandle << ")" << LL_ENDL; 6738 LL_ERRS("VoiceSession") << "internal error (session for handle " << session->mHandle << " points to session with different handle " << (*i2)->mHandle << ")" << LL_ENDL;
6584 } 6739 }
6585 } 6740 }
6586 } 6741 }
@@ -7010,6 +7165,8 @@ class LLViewerParcelVoiceInfo : public LLHTTPNode
7010 { 7165 {
7011 LLSD body = input["body"]; 7166 LLSD body = input["body"];
7012 7167
7168 LL_DEBUGS("VoiceCaps") << "ParcelVoiceInfo response: "
7169 << ll_pretty_print_sd(input) << LL_ENDL;
7013 //body has "region_name" (str), "parcel_local_id"(int), 7170 //body has "region_name" (str), "parcel_local_id"(int),
7014 //"voice_credentials" (map). 7171 //"voice_credentials" (map).
7015 7172
@@ -7036,7 +7193,10 @@ class LLViewerParcelVoiceInfo : public LLHTTPNode
7036 voice_credentials["channel_credentials"].asString(); 7193 voice_credentials["channel_credentials"].asString();
7037 } 7194 }
7038 7195
7039 gVoiceClient->setSpatialChannel(uri, credentials); 7196 LLUUID response_id;
7197 response_id.generate();
7198 gVoiceClient->setPIRCapResponseID(response_id);
7199 gVoiceClient->setSpatialChannel(uri, credentials, response_id);
7040 } 7200 }
7041 } 7201 }
7042 } 7202 }
@@ -7050,10 +7210,13 @@ class LLViewerRequiredVoiceVersion : public LLHTTPNode
7050 const LLSD& context, 7210 const LLSD& context,
7051 const LLSD& input) const 7211 const LLSD& input) const
7052 { 7212 {
7213
7053 //You received this messsage (most likely on region cross or 7214 //You received this messsage (most likely on region cross or
7054 //teleport) 7215 //teleport)
7055 if ( input.has("body") && input["body"].has("major_version") ) 7216 if ( input.has("body") && input["body"].has("major_version") )
7056 { 7217 {
7218 LL_DEBUGS("VoiceCaps") << "RequiredVoiceVersion response: "
7219 << ll_pretty_print_sd(input)<< LL_ENDL;
7057 int major_voice_version = 7220 int major_voice_version =
7058 input["body"]["major_version"].asInteger(); 7221 input["body"]["major_version"].asInteger();
7059// int minor_voice_version = 7222// int minor_voice_version =