|
|
|
|
@ -123,14 +123,6 @@ static int scale_mic_volume(float volume)
|
|
|
|
|
return 30 + (int)(volume * 20.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int scale_speaker_volume(float volume)
|
|
|
|
|
{
|
|
|
|
|
// incoming volume has the range [0.0 ... 1.0], with 0.5 as the default.
|
|
|
|
|
// Map it to WebRTC levels as follows: 0.0 -> 30, 0.5 -> 50, 1.0 -> 70
|
|
|
|
|
return 30 + (int)(volume * 40.0f);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
@ -317,7 +309,7 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
|
|
|
|
|
sConnected = false;
|
|
|
|
|
sPump = nullptr;
|
|
|
|
|
|
|
|
|
|
mSpeakerVolume = scale_speaker_volume(0);
|
|
|
|
|
mSpeakerVolume = 0.0;
|
|
|
|
|
|
|
|
|
|
mVoiceVersion.serverVersion = "";
|
|
|
|
|
mVoiceVersion.serverType = VOICE_SERVER_TYPE;
|
|
|
|
|
@ -2220,12 +2212,11 @@ void LLWebRTCVoiceClient::tuningSetMicVolume(float volume)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume)
|
|
|
|
|
{
|
|
|
|
|
int scaled_volume = scale_speaker_volume(volume);
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if(scaled_volume != mTuningSpeakerVolume)
|
|
|
|
|
if (volume != mTuningSpeakerVolume)
|
|
|
|
|
{
|
|
|
|
|
mTuningSpeakerVolume = scaled_volume;
|
|
|
|
|
mTuningSpeakerVolume = volume;
|
|
|
|
|
mTuningSpeakerVolumeDirty = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -2663,7 +2654,7 @@ void LLWebRTCVoiceClient::sendLocalAudioUpdates()
|
|
|
|
|
|
|
|
|
|
if (mSpeakerMuteDirty && !mTuningMode)
|
|
|
|
|
{
|
|
|
|
|
const char *muteval = ((mSpeakerVolume <= scale_speaker_volume(0)) ? "true" : "false");
|
|
|
|
|
const char *muteval = ((mSpeakerVolume <= 0.0) ? "true" : "false");
|
|
|
|
|
|
|
|
|
|
mSpeakerMuteDirty = false;
|
|
|
|
|
|
|
|
|
|
@ -2899,6 +2890,11 @@ void LLWebRTCVoiceClient::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface *
|
|
|
|
|
LL_INFOS("Voice") << "On AudioEstablished." << LL_ENDL;
|
|
|
|
|
mWebRTCAudioInterface = audio_interface;
|
|
|
|
|
audio_interface->setMute(true);
|
|
|
|
|
{
|
|
|
|
|
LLMutexLock lock(&mVoiceStateMutex);
|
|
|
|
|
|
|
|
|
|
audio_interface->setSpeakerVolume(mSpeakerVolume);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LLWebRTCVoiceClient::OnRenegotiationNeeded()
|
|
|
|
|
@ -4901,18 +4897,23 @@ void LLWebRTCVoiceClient::setEarLocation(S32 loc)
|
|
|
|
|
|
|
|
|
|
void LLWebRTCVoiceClient::setVoiceVolume(F32 volume)
|
|
|
|
|
{
|
|
|
|
|
int scaled_volume = scale_speaker_volume(volume);
|
|
|
|
|
|
|
|
|
|
if(scaled_volume != mSpeakerVolume)
|
|
|
|
|
if (volume != mSpeakerVolume)
|
|
|
|
|
{
|
|
|
|
|
int min_volume = scale_speaker_volume(0);
|
|
|
|
|
if((scaled_volume == min_volume) || (mSpeakerVolume == min_volume))
|
|
|
|
|
{
|
|
|
|
|
mSpeakerMuteDirty = true;
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
LLMutexLock lock(&mVoiceStateMutex);
|
|
|
|
|
int min_volume = 0.0;
|
|
|
|
|
if ((volume == min_volume) || (mSpeakerVolume == min_volume))
|
|
|
|
|
{
|
|
|
|
|
mSpeakerMuteDirty = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mSpeakerVolume = scaled_volume;
|
|
|
|
|
mSpeakerVolumeDirty = true;
|
|
|
|
|
mSpeakerVolume = volume;
|
|
|
|
|
mSpeakerVolumeDirty = true;
|
|
|
|
|
}
|
|
|
|
|
if (mWebRTCAudioInterface)
|
|
|
|
|
{
|
|
|
|
|
mWebRTCAudioInterface->setSpeakerVolume(volume);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -6546,755 +6547,7 @@ void LLWebRTCVoiceClient::captureBufferPlayStopSendMessage()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LLWebRTCProtocolParser::LLWebRTCProtocolParser()
|
|
|
|
|
{
|
|
|
|
|
parser = XML_ParserCreate(NULL);
|
|
|
|
|
|
|
|
|
|
reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LLWebRTCProtocolParser::reset()
|
|
|
|
|
{
|
|
|
|
|
responseDepth = 0;
|
|
|
|
|
ignoringTags = false;
|
|
|
|
|
accumulateText = false;
|
|
|
|
|
energy = 0.f;
|
|
|
|
|
hasText = false;
|
|
|
|
|
hasAudio = false;
|
|
|
|
|
hasVideo = false;
|
|
|
|
|
terminated = false;
|
|
|
|
|
ignoreDepth = 0;
|
|
|
|
|
isChannel = false;
|
|
|
|
|
incoming = false;
|
|
|
|
|
enabled = false;
|
|
|
|
|
isEvent = false;
|
|
|
|
|
isLocallyMuted = false;
|
|
|
|
|
isModeratorMuted = false;
|
|
|
|
|
isSpeaking = false;
|
|
|
|
|
participantType = 0;
|
|
|
|
|
returnCode = -1;
|
|
|
|
|
state = 0;
|
|
|
|
|
statusCode = 0;
|
|
|
|
|
volume = 0;
|
|
|
|
|
textBuffer.clear();
|
|
|
|
|
alias.clear();
|
|
|
|
|
numberOfAliases = 0;
|
|
|
|
|
applicationString.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//virtual
|
|
|
|
|
LLWebRTCProtocolParser::~LLWebRTCProtocolParser()
|
|
|
|
|
{
|
|
|
|
|
if (parser)
|
|
|
|
|
XML_ParserFree(parser);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static LLTrace::BlockTimerStatHandle FTM_WebRTC_PROCESS("WebRTC Process");
|
|
|
|
|
|
|
|
|
|
// virtual
|
|
|
|
|
LLIOPipe::EStatus LLWebRTCProtocolParser::process_impl(
|
|
|
|
|
const LLChannelDescriptors& channels,
|
|
|
|
|
buffer_ptr_t& buffer,
|
|
|
|
|
bool& eos,
|
|
|
|
|
LLSD& context,
|
|
|
|
|
LLPumpIO* pump)
|
|
|
|
|
{
|
|
|
|
|
LL_RECORD_BLOCK_TIME(FTM_WebRTC_PROCESS);
|
|
|
|
|
LLBufferStream istr(channels, buffer.get());
|
|
|
|
|
std::ostringstream ostr;
|
|
|
|
|
while (istr.good())
|
|
|
|
|
{
|
|
|
|
|
char buf[1024];
|
|
|
|
|
istr.read(buf, sizeof(buf));
|
|
|
|
|
mInput.append(buf, istr.gcount());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look for input delimiter(s) in the input buffer. If one is found, send the message to the xml parser.
|
|
|
|
|
int start = 0;
|
|
|
|
|
int delim;
|
|
|
|
|
while((delim = mInput.find("\n\n\n", start)) != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// Reset internal state of the LLWebRTCProtocolParser (no effect on the expat parser)
|
|
|
|
|
reset();
|
|
|
|
|
|
|
|
|
|
XML_ParserReset(parser, NULL);
|
|
|
|
|
XML_SetElementHandler(parser, ExpatStartTag, ExpatEndTag);
|
|
|
|
|
XML_SetCharacterDataHandler(parser, ExpatCharHandler);
|
|
|
|
|
XML_SetUserData(parser, this);
|
|
|
|
|
XML_Parse(parser, mInput.data() + start, delim - start, false);
|
|
|
|
|
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << "parsing: " << mInput.substr(start, delim - start) << LL_ENDL;
|
|
|
|
|
start = delim + 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(start != 0)
|
|
|
|
|
mInput = mInput.substr(start);
|
|
|
|
|
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << "at end, mInput is: " << mInput << LL_ENDL;
|
|
|
|
|
|
|
|
|
|
if(!LLWebRTCVoiceClient::sConnected)
|
|
|
|
|
{
|
|
|
|
|
// If voice has been disabled, we just want to close the socket. This does so.
|
|
|
|
|
LL_INFOS("Voice") << "returning STATUS_STOP" << LL_ENDL;
|
|
|
|
|
return STATUS_STOP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return STATUS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLCALL LLWebRTCProtocolParser::ExpatStartTag(void *data, const char *el, const char **attr)
|
|
|
|
|
{
|
|
|
|
|
if (data)
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCProtocolParser *object = (LLWebRTCProtocolParser*)data;
|
|
|
|
|
object->StartTag(el, attr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void XMLCALL LLWebRTCProtocolParser::ExpatEndTag(void *data, const char *el)
|
|
|
|
|
{
|
|
|
|
|
if (data)
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCProtocolParser *object = (LLWebRTCProtocolParser*)data;
|
|
|
|
|
object->EndTag(el);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void XMLCALL LLWebRTCProtocolParser::ExpatCharHandler(void *data, const XML_Char *s, int len)
|
|
|
|
|
{
|
|
|
|
|
if (data)
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCProtocolParser *object = (LLWebRTCProtocolParser*)data;
|
|
|
|
|
object->CharData(s, len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void LLWebRTCProtocolParser::StartTag(const char *tag, const char **attr)
|
|
|
|
|
{
|
|
|
|
|
// Reset the text accumulator. We shouldn't have strings that are inturrupted by new tags
|
|
|
|
|
textBuffer.clear();
|
|
|
|
|
// only accumulate text if we're not ignoring tags.
|
|
|
|
|
accumulateText = !ignoringTags;
|
|
|
|
|
|
|
|
|
|
if (responseDepth == 0)
|
|
|
|
|
{
|
|
|
|
|
isEvent = !stricmp("Event", tag);
|
|
|
|
|
|
|
|
|
|
if (!stricmp("Response", tag) || isEvent)
|
|
|
|
|
{
|
|
|
|
|
// Grab the attributes
|
|
|
|
|
while (*attr)
|
|
|
|
|
{
|
|
|
|
|
const char *key = *attr++;
|
|
|
|
|
const char *value = *attr++;
|
|
|
|
|
|
|
|
|
|
if (!stricmp("requestId", key))
|
|
|
|
|
{
|
|
|
|
|
requestId = value;
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("action", key))
|
|
|
|
|
{
|
|
|
|
|
actionString = value;
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("type", key))
|
|
|
|
|
{
|
|
|
|
|
eventTypeString = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << tag << " (" << responseDepth << ")" << LL_ENDL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (ignoringTags)
|
|
|
|
|
{
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << tag << " (" << responseDepth << ")" << LL_ENDL;
|
|
|
|
|
|
|
|
|
|
// Ignore the InputXml stuff so we don't get confused
|
|
|
|
|
if (!stricmp("InputXml", tag))
|
|
|
|
|
{
|
|
|
|
|
ignoringTags = true;
|
|
|
|
|
ignoreDepth = responseDepth;
|
|
|
|
|
accumulateText = false;
|
|
|
|
|
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << "starting ignore, ignoreDepth is " << ignoreDepth << LL_ENDL;
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("CaptureDevices", tag))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->clearCaptureDevices();
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("RenderDevices", tag))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->clearRenderDevices();
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("CaptureDevice", tag))
|
|
|
|
|
{
|
|
|
|
|
deviceString.clear();
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("RenderDevice", tag))
|
|
|
|
|
{
|
|
|
|
|
deviceString.clear();
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("SessionFont", tag))
|
|
|
|
|
{
|
|
|
|
|
id = 0;
|
|
|
|
|
nameString.clear();
|
|
|
|
|
descriptionString.clear();
|
|
|
|
|
expirationDate = LLDate();
|
|
|
|
|
hasExpired = false;
|
|
|
|
|
fontType = 0;
|
|
|
|
|
fontStatus = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("TemplateFont", tag))
|
|
|
|
|
{
|
|
|
|
|
id = 0;
|
|
|
|
|
nameString.clear();
|
|
|
|
|
descriptionString.clear();
|
|
|
|
|
expirationDate = LLDate();
|
|
|
|
|
hasExpired = false;
|
|
|
|
|
fontType = 0;
|
|
|
|
|
fontStatus = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("MediaCompletionType", tag))
|
|
|
|
|
{
|
|
|
|
|
mediaCompletionType.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
responseDepth++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void LLWebRTCProtocolParser::EndTag(const char *tag)
|
|
|
|
|
{
|
|
|
|
|
const std::string& string = textBuffer;
|
|
|
|
|
|
|
|
|
|
responseDepth--;
|
|
|
|
|
|
|
|
|
|
if (ignoringTags)
|
|
|
|
|
{
|
|
|
|
|
if (ignoreDepth == responseDepth)
|
|
|
|
|
{
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << "end of ignore" << LL_ENDL;
|
|
|
|
|
ignoringTags = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ignoringTags)
|
|
|
|
|
{
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << "processing tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL;
|
|
|
|
|
|
|
|
|
|
// Closing a tag. Finalize the text we've accumulated and reset
|
|
|
|
|
if (!stricmp("ReturnCode", tag))
|
|
|
|
|
returnCode = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
else if (!stricmp("SessionHandle", tag))
|
|
|
|
|
sessionHandle = string;
|
|
|
|
|
else if (!stricmp("SessionGroupHandle", tag))
|
|
|
|
|
sessionGroupHandle = string;
|
|
|
|
|
else if (!stricmp("StatusCode", tag))
|
|
|
|
|
statusCode = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
else if (!stricmp("StatusString", tag))
|
|
|
|
|
statusString = string;
|
|
|
|
|
else if (!stricmp("ParticipantURI", tag))
|
|
|
|
|
uriString = string;
|
|
|
|
|
else if (!stricmp("Volume", tag))
|
|
|
|
|
volume = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
else if (!stricmp("Energy", tag))
|
|
|
|
|
energy = (F32)strtod(string.c_str(), NULL);
|
|
|
|
|
else if (!stricmp("IsModeratorMuted", tag))
|
|
|
|
|
isModeratorMuted = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("IsSpeaking", tag))
|
|
|
|
|
isSpeaking = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("Alias", tag))
|
|
|
|
|
alias = string;
|
|
|
|
|
else if (!stricmp("NumberOfAliases", tag))
|
|
|
|
|
numberOfAliases = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
else if (!stricmp("Application", tag))
|
|
|
|
|
applicationString = string;
|
|
|
|
|
else if (!stricmp("ConnectorHandle", tag))
|
|
|
|
|
connectorHandle = string;
|
|
|
|
|
else if (!stricmp("VersionID", tag))
|
|
|
|
|
versionID = string;
|
|
|
|
|
else if (!stricmp("Version", tag))
|
|
|
|
|
mBuildID = string;
|
|
|
|
|
else if (!stricmp("AccountHandle", tag))
|
|
|
|
|
accountHandle = string;
|
|
|
|
|
else if (!stricmp("State", tag))
|
|
|
|
|
state = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
else if (!stricmp("URI", tag))
|
|
|
|
|
uriString = string;
|
|
|
|
|
else if (!stricmp("IsChannel", tag))
|
|
|
|
|
isChannel = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("Incoming", tag))
|
|
|
|
|
incoming = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("Enabled", tag))
|
|
|
|
|
enabled = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("Name", tag))
|
|
|
|
|
nameString = string;
|
|
|
|
|
else if (!stricmp("AudioMedia", tag))
|
|
|
|
|
audioMediaString = string;
|
|
|
|
|
else if (!stricmp("ChannelName", tag))
|
|
|
|
|
nameString = string;
|
|
|
|
|
else if (!stricmp("DisplayName", tag))
|
|
|
|
|
displayNameString = string;
|
|
|
|
|
else if (!stricmp("Device", tag))
|
|
|
|
|
deviceString = string;
|
|
|
|
|
else if (!stricmp("AccountName", tag))
|
|
|
|
|
nameString = string;
|
|
|
|
|
else if (!stricmp("ParticipantType", tag))
|
|
|
|
|
participantType = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
else if (!stricmp("IsLocallyMuted", tag))
|
|
|
|
|
isLocallyMuted = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("MicEnergy", tag))
|
|
|
|
|
energy = (F32)strtod(string.c_str(), NULL);
|
|
|
|
|
else if (!stricmp("ChannelName", tag))
|
|
|
|
|
nameString = string;
|
|
|
|
|
else if (!stricmp("ChannelURI", tag))
|
|
|
|
|
uriString = string;
|
|
|
|
|
else if (!stricmp("BuddyURI", tag))
|
|
|
|
|
uriString = string;
|
|
|
|
|
else if (!stricmp("Presence", tag))
|
|
|
|
|
statusString = string;
|
|
|
|
|
else if (!stricmp("CaptureDevices", tag))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->setDevicesListUpdated(true);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("RenderDevices", tag))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->setDevicesListUpdated(true);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("CaptureDevice", tag))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->addCaptureDevice(LLVoiceDevice(displayNameString, deviceString));
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("RenderDevice", tag))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->addRenderDevice(LLVoiceDevice(displayNameString, deviceString));
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("BlockMask", tag))
|
|
|
|
|
blockMask = string;
|
|
|
|
|
else if (!stricmp("PresenceOnly", tag))
|
|
|
|
|
presenceOnly = string;
|
|
|
|
|
else if (!stricmp("AutoAcceptMask", tag))
|
|
|
|
|
autoAcceptMask = string;
|
|
|
|
|
else if (!stricmp("AutoAddAsBuddy", tag))
|
|
|
|
|
autoAddAsBuddy = string;
|
|
|
|
|
else if (!stricmp("MessageHeader", tag))
|
|
|
|
|
messageHeader = string;
|
|
|
|
|
else if (!stricmp("MessageBody", tag))
|
|
|
|
|
messageBody = string;
|
|
|
|
|
else if (!stricmp("NotificationType", tag))
|
|
|
|
|
notificationType = string;
|
|
|
|
|
else if (!stricmp("HasText", tag))
|
|
|
|
|
hasText = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("HasAudio", tag))
|
|
|
|
|
hasAudio = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("HasVideo", tag))
|
|
|
|
|
hasVideo = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("Terminated", tag))
|
|
|
|
|
terminated = !stricmp(string.c_str(), "true");
|
|
|
|
|
else if (!stricmp("SubscriptionHandle", tag))
|
|
|
|
|
subscriptionHandle = string;
|
|
|
|
|
else if (!stricmp("SubscriptionType", tag))
|
|
|
|
|
subscriptionType = string;
|
|
|
|
|
else if (!stricmp("SessionFont", tag))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDate, hasExpired, fontType, fontStatus, false);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("TemplateFont", tag))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDate, hasExpired, fontType, fontStatus, true);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("ID", tag))
|
|
|
|
|
{
|
|
|
|
|
id = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("Description", tag))
|
|
|
|
|
{
|
|
|
|
|
descriptionString = string;
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("ExpirationDate", tag))
|
|
|
|
|
{
|
|
|
|
|
expirationDate = expiryTimeStampToLLDate(string);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("Expired", tag))
|
|
|
|
|
{
|
|
|
|
|
hasExpired = !stricmp(string.c_str(), "1");
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("Type", tag))
|
|
|
|
|
{
|
|
|
|
|
fontType = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("Status", tag))
|
|
|
|
|
{
|
|
|
|
|
fontStatus = strtol(string.c_str(), NULL, 10);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp("MediaCompletionType", tag))
|
|
|
|
|
{
|
|
|
|
|
mediaCompletionType = string;;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
textBuffer.clear();
|
|
|
|
|
accumulateText= false;
|
|
|
|
|
|
|
|
|
|
if (responseDepth == 0)
|
|
|
|
|
{
|
|
|
|
|
// We finished all of the XML, process the data
|
|
|
|
|
processResponse(tag);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void LLWebRTCProtocolParser::CharData(const char *buffer, int length)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
This method is called for anything that isn't a tag, which can be text you
|
|
|
|
|
want that lies between tags, and a lot of stuff you don't want like file formatting
|
|
|
|
|
(tabs, spaces, CR/LF, etc).
|
|
|
|
|
|
|
|
|
|
Only copy text if we are in accumulate mode...
|
|
|
|
|
*/
|
|
|
|
|
if (accumulateText)
|
|
|
|
|
textBuffer.append(buffer, length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
LLDate LLWebRTCProtocolParser::expiryTimeStampToLLDate(const std::string& WebRTC_ts)
|
|
|
|
|
{
|
|
|
|
|
// *HACK: WebRTC reports the time incorrectly. LLDate also only parses a
|
|
|
|
|
// subset of valid ISO 8601 dates (only handles Z, not offsets).
|
|
|
|
|
// So just use the date portion and fix the time here.
|
|
|
|
|
std::string time_stamp = WebRTC_ts.substr(0, 10);
|
|
|
|
|
time_stamp += VOICE_FONT_EXPIRY_TIME;
|
|
|
|
|
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << "WebRTC timestamp " << WebRTC_ts << " modified to: " << time_stamp << LL_ENDL;
|
|
|
|
|
|
|
|
|
|
return LLDate(time_stamp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void LLWebRTCProtocolParser::processResponse(std::string tag)
|
|
|
|
|
{
|
|
|
|
|
LL_DEBUGS("WebRTCProtocolParser") << tag << LL_ENDL;
|
|
|
|
|
|
|
|
|
|
// SLIM SDK: the SDK now returns a statusCode of "200" (OK) for success. This is a change vs. previous SDKs.
|
|
|
|
|
// According to Mike S., "The actual API convention is that responses with return codes of 0 are successful, regardless of the status code returned",
|
|
|
|
|
// so I believe this will give correct behavior.
|
|
|
|
|
|
|
|
|
|
if(returnCode == 0)
|
|
|
|
|
statusCode = 0;
|
|
|
|
|
|
|
|
|
|
if (isEvent)
|
|
|
|
|
{
|
|
|
|
|
const char *eventTypeCstr = eventTypeString.c_str();
|
|
|
|
|
LL_DEBUGS("LowVoice") << eventTypeCstr << LL_ENDL;
|
|
|
|
|
|
|
|
|
|
if (!stricmp(eventTypeCstr, "ParticipantUpdatedEvent"))
|
|
|
|
|
{
|
|
|
|
|
// These happen so often that logging them is pretty useless.
|
|
|
|
|
LL_DEBUGS("LowVoice") << "Updated Params: " << sessionHandle << ", " << sessionGroupHandle << ", " << uriString << ", " << alias << ", " << isModeratorMuted << ", " << isSpeaking << ", " << volume << ", " << energy << LL_ENDL;
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->participantUpdatedEvent(sessionHandle, sessionGroupHandle, uriString, alias, isModeratorMuted, isSpeaking, volume, energy);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "AccountLoginStateChangeEvent"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->accountLoginStateChangeEvent(accountHandle, statusCode, statusString, state);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "SessionAddedEvent"))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
<Event type="SessionAddedEvent">
|
|
|
|
|
<SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle>
|
|
|
|
|
<SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==0</SessionHandle>
|
|
|
|
|
<Uri>sip:confctl-1408789@bhr.WebRTC.com</Uri>
|
|
|
|
|
<IsChannel>true</IsChannel>
|
|
|
|
|
<Incoming>false</Incoming>
|
|
|
|
|
<ChannelName />
|
|
|
|
|
</Event>
|
|
|
|
|
*/
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->sessionAddedEvent(uriString, alias, sessionHandle, sessionGroupHandle, isChannel, incoming, nameString, applicationString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "SessionRemovedEvent"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->sessionRemovedEvent(sessionHandle, sessionGroupHandle);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "SessionGroupUpdatedEvent"))
|
|
|
|
|
{
|
|
|
|
|
//nothng useful to process for this event, but we should not WARN that we have received it.
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "SessionGroupAddedEvent"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->sessionGroupAddedEvent(sessionGroupHandle);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "MediaStreamUpdatedEvent"))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
<Event type="MediaStreamUpdatedEvent">
|
|
|
|
|
<SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle>
|
|
|
|
|
<SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==0</SessionHandle>
|
|
|
|
|
<StatusCode>200</StatusCode>
|
|
|
|
|
<StatusString>OK</StatusString>
|
|
|
|
|
<State>2</State>
|
|
|
|
|
<Incoming>false</Incoming>
|
|
|
|
|
</Event>
|
|
|
|
|
*/
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->mediaStreamUpdatedEvent(sessionHandle, sessionGroupHandle, statusCode, statusString, state, incoming);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "MediaCompletionEvent"))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
<Event type="MediaCompletionEvent">
|
|
|
|
|
<SessionGroupHandle />
|
|
|
|
|
<MediaCompletionType>AuxBufferAudioCapture</MediaCompletionType>
|
|
|
|
|
</Event>
|
|
|
|
|
*/
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->mediaCompletionEvent(sessionGroupHandle, mediaCompletionType);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "ParticipantAddedEvent"))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
<Event type="ParticipantAddedEvent">
|
|
|
|
|
<SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg4</SessionGroupHandle>
|
|
|
|
|
<SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==4</SessionHandle>
|
|
|
|
|
<ParticipantUri>sip:xI5auBZ60SJWIk606-1JGRQ==@bhr.WebRTC.com</ParticipantUri>
|
|
|
|
|
<AccountName>xI5auBZ60SJWIk606-1JGRQ==</AccountName>
|
|
|
|
|
<DisplayName />
|
|
|
|
|
<ParticipantType>0</ParticipantType>
|
|
|
|
|
</Event>
|
|
|
|
|
*/
|
|
|
|
|
LL_DEBUGS("LowVoice") << "Added Params: " << sessionHandle << ", " << sessionGroupHandle << ", " << uriString << ", " << alias << ", " << nameString << ", " << displayNameString << ", " << participantType << LL_ENDL;
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->participantAddedEvent(sessionHandle, sessionGroupHandle, uriString, alias, nameString, displayNameString, participantType);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "ParticipantRemovedEvent"))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
<Event type="ParticipantRemovedEvent">
|
|
|
|
|
<SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg4</SessionGroupHandle>
|
|
|
|
|
<SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==4</SessionHandle>
|
|
|
|
|
<ParticipantUri>sip:xtx7YNV-3SGiG7rA1fo5Ndw==@bhr.WebRTC.com</ParticipantUri>
|
|
|
|
|
<AccountName>xtx7YNV-3SGiG7rA1fo5Ndw==</AccountName>
|
|
|
|
|
</Event>
|
|
|
|
|
*/
|
|
|
|
|
LL_DEBUGS("LowVoice") << "Removed params:" << sessionHandle << ", " << sessionGroupHandle << ", " << uriString << ", " << alias << ", " << nameString << LL_ENDL;
|
|
|
|
|
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->participantRemovedEvent(sessionHandle, sessionGroupHandle, uriString, alias, nameString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "AuxAudioPropertiesEvent"))
|
|
|
|
|
{
|
|
|
|
|
// These are really spammy in tuning mode
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->auxAudioPropertiesEvent(energy);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "MessageEvent"))
|
|
|
|
|
{
|
|
|
|
|
//TODO: This probably is not received any more, it was used to support SLim clients
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->messageEvent(sessionHandle, uriString, alias, messageHeader, messageBody, applicationString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "SessionNotificationEvent"))
|
|
|
|
|
{
|
|
|
|
|
//TODO: This probably is not received any more, it was used to support SLim clients
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->sessionNotificationEvent(sessionHandle, uriString, notificationType);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent"))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
<Event type="SessionUpdatedEvent">
|
|
|
|
|
<SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle>
|
|
|
|
|
<SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==0</SessionHandle>
|
|
|
|
|
<Uri>sip:confctl-9@bhd.WebRTC.com</Uri>
|
|
|
|
|
<IsMuted>0</IsMuted>
|
|
|
|
|
<Volume>50</Volume>
|
|
|
|
|
<TransmitEnabled>1</TransmitEnabled>
|
|
|
|
|
<IsFocused>0</IsFocused>
|
|
|
|
|
<SpeakerPosition><Position><X>0</X><Y>0</Y><Z>0</Z></Position></SpeakerPosition>
|
|
|
|
|
<SessionFontID>0</SessionFontID>
|
|
|
|
|
</Event>
|
|
|
|
|
*/
|
|
|
|
|
// We don't need to process this, but we also shouldn't warn on it, since that confuses people.
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "SessionGroupRemovedEvent"))
|
|
|
|
|
{
|
|
|
|
|
// We don't need to process this, but we also shouldn't warn on it, since that confuses people.
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->voiceServiceConnectionStateChangedEvent(statusCode, statusString, mBuildID);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(eventTypeCstr, "AudioDeviceHotSwapEvent"))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
<Event type = "AudioDeviceHotSwapEvent">
|
|
|
|
|
<EventType>RenderDeviceChanged< / EventType>
|
|
|
|
|
<RelevantDevice>
|
|
|
|
|
<Device>Speakers(Turtle Beach P11 Headset)< / Device>
|
|
|
|
|
<DisplayName>Speakers(Turtle Beach P11 Headset)< / DisplayName>
|
|
|
|
|
<Type>SpecificDevice< / Type>
|
|
|
|
|
< / RelevantDevice>
|
|
|
|
|
< / Event>
|
|
|
|
|
*/
|
|
|
|
|
// an audio device was removed or added, fetch and update the local list of audio devices.
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LL_WARNS("WebRTCProtocolParser") << "Unknown event type " << eventTypeString << LL_ENDL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const char *actionCstr = actionString.c_str();
|
|
|
|
|
LL_DEBUGS("LowVoice") << actionCstr << LL_ENDL;
|
|
|
|
|
|
|
|
|
|
if (!stricmp(actionCstr, "Session.Set3DPosition.1"))
|
|
|
|
|
{
|
|
|
|
|
// We don't need to process these
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Connector.Create.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->connectorCreateResponse(statusCode, statusString, connectorHandle, versionID);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.Login.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->loginResponse(statusCode, statusString, accountHandle, numberOfAliases);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Session.Create.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->sessionCreateResponse(requestId, statusCode, statusString, sessionHandle);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "SessionGroup.AddSession.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->sessionGroupAddSessionResponse(requestId, statusCode, statusString, sessionHandle);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Session.Connect.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->sessionConnectResponse(requestId, statusCode, statusString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.Logout.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->logoutResponse(statusCode, statusString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Connector.InitiateShutdown.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->connectorShutdownResponse(statusCode, statusString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.GetSessionFonts.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->accountGetSessionFontsResponse(statusCode, statusString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.GetTemplateFonts.1"))
|
|
|
|
|
{
|
|
|
|
|
LLWebRTCVoiceClient::getInstance()->accountGetTemplateFontsResponse(statusCode, statusString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Aux.SetVadProperties.1"))
|
|
|
|
|
{
|
|
|
|
|
// both values of statusCode (old and more recent) indicate valid requests
|
|
|
|
|
if (statusCode != 0 && statusCode != 200)
|
|
|
|
|
{
|
|
|
|
|
LL_WARNS("Voice") << "Aux.SetVadProperties.1 request failed: "
|
|
|
|
|
<< "statusCode: " << statusCode
|
|
|
|
|
<< " and "
|
|
|
|
|
<< "statusString: " << statusString
|
|
|
|
|
<< LL_ENDL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelGetList.1"))
|
|
|
|
|
{
|
|
|
|
|
LLVoiceClient::getInstance()->channelGetListResponse(statusCode, statusString);
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Connector.AccountCreate.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Connector.MuteLocalMic.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Connector.MuteLocalSpeaker.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Connector.SetLocalMicVolume.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Connector.SetLocalSpeakerVolume.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Session.ListenerSetPosition.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Session.SpeakerSetPosition.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Session.AudioSourceSetPosition.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Session.GetChannelParticipants.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelCreate.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelUpdate.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelDelete.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelCreateAndInvite.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelFolderCreate.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelFolderUpdate.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelFolderDelete.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelAddModerator.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if (!stricmp(actionCstr, "Account.ChannelDeleteModerator.1"))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LLWebRTCSecurity::LLWebRTCSecurity()
|
|
|
|
|
{
|
|
|
|
|
|