corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) 2006-2014, openmetaverse.org
3 * All rights reserved.
4 *
5 * - Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * - Neither the name of the openmetaverse.org nor the names
11 * of its contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26  
27 using System;
28 using System.Collections.Generic;
29 using System.Net.Sockets;
30 using System.Text;
31 using System.IO;
32 using System.Xml;
33 using System.Threading;
34 using OpenMetaverse;
35 using OpenMetaverse.StructuredData;
36 using OpenMetaverse.Http;
37 using OpenMetaverse.Interfaces;
38 using OpenMetaverse.Messages.Linden;
39  
40 namespace OpenMetaverse.Utilities
41 {
42 public enum VoiceStatus
43 {
44 StatusLoginRetry,
45 StatusLoggedIn,
46 StatusJoining,
47 StatusJoined,
48 StatusLeftChannel,
49 BeginErrorStatus,
50 ErrorChannelFull,
51 ErrorChannelLocked,
52 ErrorNotAvailable,
53 ErrorUnknown
54 }
55  
56 public enum VoiceServiceType
57 {
58 /// <summary>Unknown voice service level</summary>
59 Unknown,
60 /// <summary>Spatialized local chat</summary>
61 TypeA,
62 /// <summary>Remote multi-party chat</summary>
63 TypeB,
64 /// <summary>One-to-one and small group chat</summary>
65 TypeC
66 }
67  
68 public partial class VoiceManager
69 {
70 public const int VOICE_MAJOR_VERSION = 1;
71 public const string DAEMON_ARGS = " -p tcp -h -c -ll ";
72 public const int DAEMON_LOG_LEVEL = 1;
73 public const int DAEMON_PORT = 44124;
74 public const string VOICE_RELEASE_SERVER = "bhr.vivox.com";
75 public const string VOICE_DEBUG_SERVER = "bhd.vivox.com";
76 public const string REQUEST_TERMINATOR = "\n\n\n";
77  
78 public delegate void LoginStateChangeCallback(int cookie, string accountHandle, int statusCode, string statusString, int state);
79 public delegate void NewSessionCallback(int cookie, string accountHandle, string eventSessionHandle, int state, string nameString, string uriString);
80 public delegate void SessionStateChangeCallback(int cookie, string uriString, int statusCode, string statusString, string eventSessionHandle, int state, bool isChannel, string nameString);
81 public delegate void ParticipantStateChangeCallback(int cookie, string uriString, int statusCode, string statusString, int state, string nameString, string displayNameString, int participantType);
82 public delegate void ParticipantPropertiesCallback(int cookie, string uriString, int statusCode, string statusString, bool isLocallyMuted, bool isModeratorMuted, bool isSpeaking, int volume, float energy);
83 public delegate void AuxAudioPropertiesCallback(int cookie, float energy);
84 public delegate void BasicActionCallback(int cookie, int statusCode, string statusString);
85 public delegate void ConnectorCreatedCallback(int cookie, int statusCode, string statusString, string connectorHandle);
86 public delegate void LoginCallback(int cookie, int statusCode, string statusString, string accountHandle);
87 public delegate void SessionCreatedCallback(int cookie, int statusCode, string statusString, string sessionHandle);
88 public delegate void DevicesCallback(int cookie, int statusCode, string statusString, string currentDevice);
89 public delegate void ProvisionAccountCallback(string username, string password);
90 public delegate void ParcelVoiceInfoCallback(string regionName, int localID, string channelURI);
91  
92 public event LoginStateChangeCallback OnLoginStateChange;
93 public event NewSessionCallback OnNewSession;
94 public event SessionStateChangeCallback OnSessionStateChange;
95 public event ParticipantStateChangeCallback OnParticipantStateChange;
96 public event ParticipantPropertiesCallback OnParticipantProperties;
97 public event AuxAudioPropertiesCallback OnAuxAudioProperties;
98 public event ConnectorCreatedCallback OnConnectorCreated;
99 public event LoginCallback OnLogin;
100 public event SessionCreatedCallback OnSessionCreated;
101 public event BasicActionCallback OnSessionConnected;
102 public event BasicActionCallback OnAccountLogout;
103 public event BasicActionCallback OnConnectorInitiateShutdown;
104 public event BasicActionCallback OnAccountChannelGetList;
105 public event BasicActionCallback OnSessionTerminated;
106 public event DevicesCallback OnCaptureDevices;
107 public event DevicesCallback OnRenderDevices;
108 public event ProvisionAccountCallback OnProvisionAccount;
109 public event ParcelVoiceInfoCallback OnParcelVoiceInfo;
110  
111 public GridClient Client;
112 public string VoiceServer = VOICE_RELEASE_SERVER;
113 public bool Enabled;
114  
115 protected Voice.TCPPipe _DaemonPipe;
116 protected VoiceStatus _Status;
117 protected int _CommandCookie = 0;
118 protected string _TuningSoundFile = String.Empty;
119 protected Dictionary<string, string> _ChannelMap = new Dictionary<string, string>();
120 protected List<string> _CaptureDevices = new List<string>();
121 protected List<string> _RenderDevices = new List<string>();
122  
123 #region Response Processing Variables
124  
125 private bool isEvent = false;
126 private bool isChannel = false;
127 private bool isLocallyMuted = false;
128 private bool isModeratorMuted = false;
129 private bool isSpeaking = false;
130 private int cookie = 0;
131 //private int returnCode = 0;
132 private int statusCode = 0;
133 private int volume = 0;
134 private int state = 0;
135 private int participantType = 0;
136 private float energy = 0f;
137 private string statusString = String.Empty;
138 //private string uuidString = String.Empty;
139 private string actionString = String.Empty;
140 private string connectorHandle = String.Empty;
141 private string accountHandle = String.Empty;
142 private string sessionHandle = String.Empty;
143 private string eventSessionHandle = String.Empty;
144 private string eventTypeString = String.Empty;
145 private string uriString = String.Empty;
146 private string nameString = String.Empty;
147 //private string audioMediaString = String.Empty;
148 private string displayNameString = String.Empty;
149  
150 #endregion Response Processing Variables
151  
152 public VoiceManager(GridClient client)
153 {
154 Client = client;
155 Client.Network.RegisterEventCallback("RequiredVoiceVersion", new Caps.EventQueueCallback(RequiredVoiceVersionEventHandler));
156  
157 // Register callback handlers for the blocking functions
158 RegisterCallbacks();
159  
160 Enabled = true;
161 }
162  
163 public bool IsDaemonRunning()
164 {
165 throw new NotImplementedException();
166 }
167  
168 public bool StartDaemon()
169 {
170 throw new NotImplementedException();
171 }
172  
173 public void StopDaemon()
174 {
175 throw new NotImplementedException();
176 }
177  
178 public bool ConnectToDaemon()
179 {
180 if (!Enabled) return false;
181  
182 return ConnectToDaemon("127.0.0.1", DAEMON_PORT);
183 }
184  
185 public bool ConnectToDaemon(string address, int port)
186 {
187 if (!Enabled) return false;
188  
189 _DaemonPipe = new Voice.TCPPipe();
190 _DaemonPipe.OnDisconnected += new Voice.TCPPipe.OnDisconnectedCallback(_DaemonPipe_OnDisconnected);
191 _DaemonPipe.OnReceiveLine += new Voice.TCPPipe.OnReceiveLineCallback(_DaemonPipe_OnReceiveLine);
192  
193 SocketException se = _DaemonPipe.Connect(address, port);
194  
195 if (se == null)
196 {
197 return true;
198 }
199 else
200 {
201 Console.WriteLine("Connection failed: " + se.Message);
202 return false;
203 }
204 }
205  
206 public Dictionary<string, string> GetChannelMap()
207 {
208 return new Dictionary<string, string>(_ChannelMap);
209 }
210  
211 public List<string> CurrentCaptureDevices()
212 {
213 return new List<string>(_CaptureDevices);
214 }
215  
216 public List<string> CurrentRenderDevices()
217 {
218 return new List<string>(_RenderDevices);
219 }
220  
221 public string VoiceAccountFromUUID(UUID id)
222 {
223 string result = "x" + Convert.ToBase64String(id.GetBytes());
224 return result.Replace('+', '-').Replace('/', '_');
225 }
226  
227 public UUID UUIDFromVoiceAccount(string accountName)
228 {
229 if (accountName.Length == 25 && accountName[0] == 'x' && accountName[23] == '=' && accountName[24] == '=')
230 {
231 accountName = accountName.Replace('/', '_').Replace('+', '-');
232 byte[] idBytes = Convert.FromBase64String(accountName);
233  
234 if (idBytes.Length == 16)
235 return new UUID(idBytes, 0);
236 else
237 return UUID.Zero;
238 }
239 else
240 {
241 return UUID.Zero;
242 }
243 }
244  
245 public string SIPURIFromVoiceAccount(string account)
246 {
247 return String.Format("sip:{0}@{1}", account, VoiceServer);
248 }
249  
250 public int RequestCaptureDevices()
251 {
252 if (_DaemonPipe.Connected)
253 {
254 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
255 "<Request requestId=\"{0}\" action=\"Aux.GetCaptureDevices.1\"></Request>{1}",
256 _CommandCookie++,
257 REQUEST_TERMINATOR)));
258  
259 return _CommandCookie - 1;
260 }
261 else
262 {
263 Logger.Log("VoiceManager.RequestCaptureDevices() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
264 return -1;
265 }
266 }
267  
268 public int RequestRenderDevices()
269 {
270 if (_DaemonPipe.Connected)
271 {
272 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
273 "<Request requestId=\"{0}\" action=\"Aux.GetRenderDevices.1\"></Request>{1}",
274 _CommandCookie++,
275 REQUEST_TERMINATOR)));
276  
277 return _CommandCookie - 1;
278 }
279 else
280 {
281 Logger.Log("VoiceManager.RequestRenderDevices() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
282 return -1;
283 }
284 }
285  
286 public int RequestCreateConnector()
287 {
288 return RequestCreateConnector(VoiceServer);
289 }
290  
291 public int RequestCreateConnector(string voiceServer)
292 {
293 if (_DaemonPipe.Connected)
294 {
295 VoiceServer = voiceServer;
296  
297 string accountServer = String.Format("https://www.{0}/api2/", VoiceServer);
298 string logPath = ".";
299  
300 StringBuilder request = new StringBuilder();
301 request.Append(String.Format("<Request requestId=\"{0}\" action=\"Connector.Create.1\">", _CommandCookie++));
302 request.Append("<ClientName>V2 SDK</ClientName>");
303 request.Append(String.Format("<AccountManagementServer>{0}</AccountManagementServer>", accountServer));
304 request.Append("<Logging>");
305 request.Append("<Enabled>false</Enabled>");
306 request.Append(String.Format("<Folder>{0}</Folder>", logPath));
307 request.Append("<FileNamePrefix>vivox-gateway</FileNamePrefix>");
308 request.Append("<FileNameSuffix>.log</FileNameSuffix>");
309 request.Append("<LogLevel>0</LogLevel>");
310 request.Append("</Logging>");
311 request.Append("</Request>");
312 request.Append(REQUEST_TERMINATOR);
313  
314 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(request.ToString()));
315  
316 return _CommandCookie - 1;
317 }
318 else
319 {
320 Logger.Log("VoiceManager.CreateConnector() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
321 return -1;
322 }
323 }
324  
325 private bool RequestVoiceInternal(string me, CapsClient.CompleteCallback callback, string capsName)
326 {
327 if (Enabled && Client.Network.Connected)
328 {
329 if (Client.Network.CurrentSim != null && Client.Network.CurrentSim.Caps != null)
330 {
331 Uri url = Client.Network.CurrentSim.Caps.CapabilityURI(capsName);
332  
333 if (url != null)
334 {
335 CapsClient request = new CapsClient(url);
336 OSDMap body = new OSDMap();
337 request.OnComplete += new CapsClient.CompleteCallback(callback);
338 request.BeginGetResponse(body, OSDFormat.Xml, Client.Settings.CAPS_TIMEOUT);
339  
340 return true;
341 }
342 else
343 {
344 Logger.Log("VoiceManager." + me + "(): " + capsName + " capability is missing",
345 Helpers.LogLevel.Info, Client);
346 return false;
347 }
348 }
349 }
350  
351 Logger.Log("VoiceManager.RequestVoiceInternal(): Voice system is currently disabled",
352 Helpers.LogLevel.Info, Client);
353 return false;
354  
355 }
356  
357 public bool RequestProvisionAccount()
358 {
359 return RequestVoiceInternal("RequestProvisionAccount", ProvisionCapsResponse, "ProvisionVoiceAccountRequest");
360 }
361  
362 public bool RequestParcelVoiceInfo()
363 {
364 return RequestVoiceInternal("RequestParcelVoiceInfo", ParcelVoiceInfoResponse, "ParcelVoiceInfoRequest");
365 }
366  
367 public int RequestLogin(string accountName, string password, string connectorHandle)
368 {
369 if (_DaemonPipe.Connected)
370 {
371 StringBuilder request = new StringBuilder();
372 request.Append(String.Format("<Request requestId=\"{0}\" action=\"Account.Login.1\">", _CommandCookie++));
373 request.Append(String.Format("<ConnectorHandle>{0}</ConnectorHandle>", connectorHandle));
374 request.Append(String.Format("<AccountName>{0}</AccountName>", accountName));
375 request.Append(String.Format("<AccountPassword>{0}</AccountPassword>", password));
376 request.Append("<AudioSessionAnswerMode>VerifyAnswer</AudioSessionAnswerMode>");
377 request.Append("<AccountURI />");
378 request.Append("<ParticipantPropertyFrequency>10</ParticipantPropertyFrequency>");
379 request.Append("<EnableBuddiesAndPresence>false</EnableBuddiesAndPresence>");
380 request.Append("</Request>");
381 request.Append(REQUEST_TERMINATOR);
382  
383 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(request.ToString()));
384  
385 return _CommandCookie - 1;
386 }
387 else
388 {
389 Logger.Log("VoiceManager.Login() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
390 return -1;
391 }
392 }
393  
394 public int RequestSetRenderDevice(string deviceName)
395 {
396 if (_DaemonPipe.Connected)
397 {
398 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
399 "<Request requestId=\"{0}\" action=\"Aux.SetRenderDevice.1\"><RenderDeviceSpecifier>{1}</RenderDeviceSpecifier></Request>{2}",
400 _CommandCookie, deviceName, REQUEST_TERMINATOR)));
401  
402 return _CommandCookie - 1;
403 }
404 else
405 {
406 Logger.Log("VoiceManager.RequestSetRenderDevice() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
407 return -1;
408 }
409 }
410  
411 public int RequestStartTuningMode(int duration)
412 {
413 if (_DaemonPipe.Connected)
414 {
415 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
416 "<Request requestId=\"{0}\" action=\"Aux.CaptureAudioStart.1\"><Duration>{1}</Duration></Request>{2}",
417 _CommandCookie, duration, REQUEST_TERMINATOR)));
418  
419 return _CommandCookie - 1;
420 }
421 else
422 {
423 Logger.Log("VoiceManager.RequestStartTuningMode() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
424 return -1;
425 }
426 }
427  
428 public int RequestStopTuningMode()
429 {
430 if (_DaemonPipe.Connected)
431 {
432 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
433 "<Request requestId=\"{0}\" action=\"Aux.CaptureAudioStop.1\"></Request>{1}",
434 _CommandCookie, REQUEST_TERMINATOR)));
435  
436 return _CommandCookie - 1;
437 }
438 else
439 {
440 Logger.Log("VoiceManager.RequestStopTuningMode() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
441 return _CommandCookie - 1;
442 }
443 }
444  
445 public int RequestSetSpeakerVolume(int volume)
446 {
447 if (volume < 0 || volume > 100)
448 throw new ArgumentException("volume must be between 0 and 100", "volume");
449  
450 if (_DaemonPipe.Connected)
451 {
452 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
453 "<Request requestId=\"{0}\" action=\"Aux.SetSpeakerLevel.1\"><Level>{1}</Level></Request>{2}",
454 _CommandCookie, volume, REQUEST_TERMINATOR)));
455  
456 return _CommandCookie - 1;
457 }
458 else
459 {
460 Logger.Log("VoiceManager.RequestSetSpeakerVolume() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
461 return -1;
462 }
463 }
464  
465 public int RequestSetCaptureVolume(int volume)
466 {
467 if (volume < 0 || volume > 100)
468 throw new ArgumentException("volume must be between 0 and 100", "volume");
469  
470 if (_DaemonPipe.Connected)
471 {
472 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
473 "<Request requestId=\"{0}\" action=\"Aux.SetMicLevel.1\"><Level>{1}</Level></Request>{2}",
474 _CommandCookie, volume, REQUEST_TERMINATOR)));
475  
476 return _CommandCookie - 1;
477 }
478 else
479 {
480 Logger.Log("VoiceManager.RequestSetCaptureVolume() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
481 return -1;
482 }
483 }
484  
485 /// <summary>
486 /// Does not appear to be working
487 /// </summary>
488 /// <param name="fileName"></param>
489 /// <param name="loop"></param>
490 public int RequestRenderAudioStart(string fileName, bool loop)
491 {
492 if (_DaemonPipe.Connected)
493 {
494 _TuningSoundFile = fileName;
495  
496 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
497 "<Request requestId=\"{0}\" action=\"Aux.RenderAudioStart.1\"><SoundFilePath>{1}</SoundFilePath><Loop>{2}</Loop></Request>{3}",
498 _CommandCookie++, _TuningSoundFile, (loop ? "1" : "0"), REQUEST_TERMINATOR)));
499  
500 return _CommandCookie - 1;
501 }
502 else
503 {
504 Logger.Log("VoiceManager.RequestRenderAudioStart() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
505 return -1;
506 }
507 }
508  
509 public int RequestRenderAudioStop()
510 {
511 if (_DaemonPipe.Connected)
512 {
513 _DaemonPipe.SendData(Encoding.ASCII.GetBytes(String.Format(
514 "<Request requestId=\"{0}\" action=\"Aux.RenderAudioStop.1\"><SoundFilePath>{1}</SoundFilePath></Request>{2}",
515 _CommandCookie++, _TuningSoundFile, REQUEST_TERMINATOR)));
516  
517 return _CommandCookie - 1;
518 }
519 else
520 {
521 Logger.Log("VoiceManager.RequestRenderAudioStop() called when the daemon pipe is disconnected", Helpers.LogLevel.Error, Client);
522 return -1;
523 }
524 }
525  
526 #region Callbacks
527  
528 private void RequiredVoiceVersionEventHandler(string capsKey, IMessage message, Simulator simulator)
529 {
530 RequiredVoiceVersionMessage msg = (RequiredVoiceVersionMessage)message;
531  
532 if (VOICE_MAJOR_VERSION != msg.MajorVersion)
533 {
534 Logger.Log(String.Format("Voice version mismatch! Got {0}, expecting {1}. Disabling the voice manager",
535 msg.MajorVersion, VOICE_MAJOR_VERSION), Helpers.LogLevel.Error, Client);
536 Enabled = false;
537 }
538 else
539 {
540 Logger.DebugLog("Voice version " + msg.MajorVersion + " verified", Client);
541 }
542 }
543  
544 private void ProvisionCapsResponse(CapsClient client, OSD response, Exception error)
545 {
546 if (response is OSDMap)
547 {
548 OSDMap respTable = (OSDMap)response;
549  
550 if (OnProvisionAccount != null)
551 {
552 try { OnProvisionAccount(respTable["username"].AsString(), respTable["password"].AsString()); }
553 catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
554 }
555 }
556 }
557  
558 private void ParcelVoiceInfoResponse(CapsClient client, OSD response, Exception error)
559 {
560 if (response is OSDMap)
561 {
562 OSDMap respTable = (OSDMap)response;
563  
564 string regionName = respTable["region_name"].AsString();
565 int localID = (int)respTable["parcel_local_id"].AsInteger();
566  
567 string channelURI = null;
568 if (respTable["voice_credentials"] is OSDMap)
569 {
570 OSDMap creds = (OSDMap)respTable["voice_credentials"];
571 channelURI = creds["channel_uri"].AsString();
572 }
573  
574 if (OnParcelVoiceInfo != null) OnParcelVoiceInfo(regionName, localID, channelURI);
575 }
576 }
577  
578 private void _DaemonPipe_OnDisconnected(SocketException se)
579 {
580 if (se != null) Console.WriteLine("Disconnected! " + se.Message);
581 else Console.WriteLine("Disconnected!");
582 }
583  
584 private void _DaemonPipe_OnReceiveLine(string line)
585 {
586 XmlTextReader reader = new XmlTextReader(new StringReader(line));
587  
588 while (reader.Read())
589 {
590 switch (reader.NodeType)
591 {
592 case XmlNodeType.Element:
593 {
594 if (reader.Depth == 0)
595 {
596 isEvent = (reader.Name == "Event");
597  
598 if (isEvent || reader.Name == "Response")
599 {
600 for (int i = 0; i < reader.AttributeCount; i++)
601 {
602 reader.MoveToAttribute(i);
603  
604 switch (reader.Name)
605 {
606 // case "requestId":
607 // uuidString = reader.Value;
608 // break;
609 case "action":
610 actionString = reader.Value;
611 break;
612 case "type":
613 eventTypeString = reader.Value;
614 break;
615 }
616 }
617 }
618 }
619 else
620 {
621 switch (reader.Name)
622 {
623 case "InputXml":
624 cookie = -1;
625  
626 // Parse through here to get the cookie value
627 reader.Read();
628 if (reader.Name == "Request")
629 {
630 for (int i = 0; i < reader.AttributeCount; i++)
631 {
632 reader.MoveToAttribute(i);
633  
634 if (reader.Name == "requestId")
635 {
636 Int32.TryParse(reader.Value, out cookie);
637 break;
638 }
639 }
640 }
641  
642 if (cookie == -1)
643 {
644 Logger.Log("VoiceManager._DaemonPipe_OnReceiveLine(): Failed to parse InputXml for the cookie",
645 Helpers.LogLevel.Warning, Client);
646 }
647 break;
648 case "CaptureDevices":
649 _CaptureDevices.Clear();
650 break;
651 case "RenderDevices":
652 _RenderDevices.Clear();
653 break;
654 // case "ReturnCode":
655 // returnCode = reader.ReadElementContentAsInt();
656 // break;
657 case "StatusCode":
658 statusCode = reader.ReadElementContentAsInt();
659 break;
660 case "StatusString":
661 statusString = reader.ReadElementContentAsString();
662 break;
663 case "State":
664 state = reader.ReadElementContentAsInt();
665 break;
666 case "ConnectorHandle":
667 connectorHandle = reader.ReadElementContentAsString();
668 break;
669 case "AccountHandle":
670 accountHandle = reader.ReadElementContentAsString();
671 break;
672 case "SessionHandle":
673 sessionHandle = reader.ReadElementContentAsString();
674 break;
675 case "URI":
676 uriString = reader.ReadElementContentAsString();
677 break;
678 case "IsChannel":
679 isChannel = reader.ReadElementContentAsBoolean();
680 break;
681 case "Name":
682 nameString = reader.ReadElementContentAsString();
683 break;
684 // case "AudioMedia":
685 // audioMediaString = reader.ReadElementContentAsString();
686 // break;
687 case "ChannelName":
688 nameString = reader.ReadElementContentAsString();
689 break;
690 case "ParticipantURI":
691 uriString = reader.ReadElementContentAsString();
692 break;
693 case "DisplayName":
694 displayNameString = reader.ReadElementContentAsString();
695 break;
696 case "AccountName":
697 nameString = reader.ReadElementContentAsString();
698 break;
699 case "ParticipantType":
700 participantType = reader.ReadElementContentAsInt();
701 break;
702 case "IsLocallyMuted":
703 isLocallyMuted = reader.ReadElementContentAsBoolean();
704 break;
705 case "IsModeratorMuted":
706 isModeratorMuted = reader.ReadElementContentAsBoolean();
707 break;
708 case "IsSpeaking":
709 isSpeaking = reader.ReadElementContentAsBoolean();
710 break;
711 case "Volume":
712 volume = reader.ReadElementContentAsInt();
713 break;
714 case "Energy":
715 energy = reader.ReadElementContentAsFloat();
716 break;
717 case "MicEnergy":
718 energy = reader.ReadElementContentAsFloat();
719 break;
720 case "ChannelURI":
721 uriString = reader.ReadElementContentAsString();
722 break;
723 case "ChannelListResult":
724 _ChannelMap[nameString] = uriString;
725 break;
726 case "CaptureDevice":
727 reader.Read();
728 _CaptureDevices.Add(reader.ReadElementContentAsString());
729 break;
730 case "CurrentCaptureDevice":
731 reader.Read();
732 nameString = reader.ReadElementContentAsString();
733 break;
734 case "RenderDevice":
735 reader.Read();
736 _RenderDevices.Add(reader.ReadElementContentAsString());
737 break;
738 case "CurrentRenderDevice":
739 reader.Read();
740 nameString = reader.ReadElementContentAsString();
741 break;
742 }
743 }
744  
745 break;
746 }
747 case XmlNodeType.EndElement:
748 if (reader.Depth == 0)
749 ProcessEvent();
750 break;
751 }
752 }
753  
754 if (isEvent)
755 {
756 }
757  
758 //Client.DebugLog("VOICE: " + line);
759 }
760  
761 private void ProcessEvent()
762 {
763 if (isEvent)
764 {
765 switch (eventTypeString)
766 {
767 case "LoginStateChangeEvent":
768 if (OnLoginStateChange != null) OnLoginStateChange(cookie, accountHandle, statusCode, statusString, state);
769 break;
770 case "SessionNewEvent":
771 if (OnNewSession != null) OnNewSession(cookie, accountHandle, eventSessionHandle, state, nameString, uriString);
772 break;
773 case "SessionStateChangeEvent":
774 if (OnSessionStateChange != null) OnSessionStateChange(cookie, uriString, statusCode, statusString, eventSessionHandle, state, isChannel, nameString);
775 break;
776 case "ParticipantStateChangeEvent":
777 if (OnParticipantStateChange != null) OnParticipantStateChange(cookie, uriString, statusCode, statusString, state, nameString, displayNameString, participantType);
778 break;
779 case "ParticipantPropertiesEvent":
780 if (OnParticipantProperties != null) OnParticipantProperties(cookie, uriString, statusCode, statusString, isLocallyMuted, isModeratorMuted, isSpeaking, volume, energy);
781 break;
782 case "AuxAudioPropertiesEvent":
783 if (OnAuxAudioProperties != null) OnAuxAudioProperties(cookie, energy);
784 break;
785 }
786 }
787 else
788 {
789 switch (actionString)
790 {
791 case "Connector.Create.1":
792 if (OnConnectorCreated != null) OnConnectorCreated(cookie, statusCode, statusString, connectorHandle);
793 break;
794 case "Account.Login.1":
795 if (OnLogin != null) OnLogin(cookie, statusCode, statusString, accountHandle);
796 break;
797 case "Session.Create.1":
798 if (OnSessionCreated != null) OnSessionCreated(cookie, statusCode, statusString, sessionHandle);
799 break;
800 case "Session.Connect.1":
801 if (OnSessionConnected != null) OnSessionConnected(cookie, statusCode, statusString);
802 break;
803 case "Session.Terminate.1":
804 if (OnSessionTerminated != null) OnSessionTerminated(cookie, statusCode, statusString);
805 break;
806 case "Account.Logout.1":
807 if (OnAccountLogout != null) OnAccountLogout(cookie, statusCode, statusString);
808 break;
809 case "Connector.InitiateShutdown.1":
810 if (OnConnectorInitiateShutdown != null) OnConnectorInitiateShutdown(cookie, statusCode, statusString);
811 break;
812 case "Account.ChannelGetList.1":
813 if (OnAccountChannelGetList != null) OnAccountChannelGetList(cookie, statusCode, statusString);
814 break;
815 case "Aux.GetCaptureDevices.1":
816 if (OnCaptureDevices != null) OnCaptureDevices(cookie, statusCode, statusString, nameString);
817 break;
818 case "Aux.GetRenderDevices.1":
819 if (OnRenderDevices != null) OnRenderDevices(cookie, statusCode, statusString, nameString);
820 break;
821 }
822 }
823 }
824  
825 #endregion Callbacks
826 }
827 }