aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/VoiceChat
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/VoiceChat')
-rw-r--r--OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs370
-rw-r--r--OpenSim/Region/Environment/Modules/VoiceChat/VoiceClient.cs196
-rw-r--r--OpenSim/Region/Environment/Modules/VoiceChat/VoicePacket.cs85
-rw-r--r--OpenSim/Region/Environment/Modules/VoiceChat/VoicePacketHeader.cs65
4 files changed, 0 insertions, 716 deletions
diff --git a/OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs b/OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs
deleted file mode 100644
index aa8764d..0000000
--- a/OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs
+++ /dev/null
@@ -1,370 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
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 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using System.Threading;
32using System.Net.Sockets;
33using System.Net;
34using OpenSim.Region.Environment.Scenes;
35using OpenSim.Framework;
36using OpenSim.Region.Environment.Modules;
37using OpenSim.Region.Environment.Interfaces;
38using Nini;
39using libsecondlife;
40
41namespace OpenSim.Region.Environment.Modules.VoiceChat
42{
43 public class VoiceChatServer : IRegionModule
44 {
45 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
46
47 int m_dummySocketPort = 53134;
48
49 Thread m_listenerThread;
50 Thread m_mainThread;
51 List<Scene> m_scenes = new List<Scene>();
52 Socket m_server;
53 Socket m_selectCancel;
54 bool m_enabled = false;
55
56 Dictionary<Socket, VoiceClient> m_clients = new Dictionary<Socket,VoiceClient>();
57 Dictionary<LLUUID, VoiceClient> m_uuidToClient = new Dictionary<LLUUID,VoiceClient>();
58
59
60 #region IRegionModule Members
61
62 public void Initialise(Scene scene, Nini.Config.IConfigSource source)
63 {
64 try
65 {
66 m_enabled = source.Configs["Voice"].GetBoolean("enabled", m_enabled);
67 }
68 catch (Exception)
69 { }
70
71 if (m_enabled)
72 {
73 if (!m_scenes.Contains(scene))
74 m_scenes.Add(scene);
75
76 scene.EventManager.OnNewClient += NewClient;
77 scene.EventManager.OnRemovePresence += RemovePresence;
78 }
79 }
80
81 public void PostInitialise()
82 {
83 if (m_enabled != true)
84 return;
85
86 try
87 {
88 CreateListeningSocket();
89 }
90 catch (Exception)
91 {
92 m_log.Error("[VOICECHAT]: Unable to start listening");
93 return;
94 }
95
96 m_listenerThread = new Thread(new ThreadStart(ListenIncomingConnections));
97 m_listenerThread.IsBackground = true;
98 m_listenerThread.Start();
99
100 m_mainThread = new Thread(new ThreadStart(RunVoiceChat));
101 m_mainThread.IsBackground = true;
102 m_mainThread.Start();
103
104 Thread.Sleep(500);
105 m_selectCancel = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
106 m_selectCancel.Connect("localhost", m_dummySocketPort);
107 }
108
109 public void Close()
110 {
111 throw new NotImplementedException();
112 }
113
114 public string Name
115 {
116 get { return "VoiceChatModule"; }
117 }
118
119 public bool IsSharedModule
120 {
121 get { return true; } // I think we can share this one.
122 }
123
124 #endregion
125
126 public void NewClient(IClientAPI client)
127 {
128 m_log.Info("[VOICECHAT]: New client: " + client.AgentId);
129 lock (m_uuidToClient)
130 {
131 m_uuidToClient[client.AgentId] = null;
132 }
133 }
134
135 public void RemovePresence(LLUUID uuid)
136 {
137 lock (m_uuidToClient)
138 {
139 if (m_uuidToClient.ContainsKey(uuid))
140 {
141 if (m_uuidToClient[uuid] != null)
142 {
143 RemoveClient(m_uuidToClient[uuid].m_socket);
144 }
145 m_uuidToClient.Remove(uuid);
146 }
147 else
148 {
149 m_log.Error("[VOICECHAT]: Presence not found on RemovePresence: " + uuid);
150 }
151 }
152 }
153
154 public bool AddClient(VoiceClient client, LLUUID uuid)
155 {
156 lock (m_uuidToClient)
157 {
158 if (m_uuidToClient.ContainsKey(uuid))
159 {
160 if (m_uuidToClient[uuid] != null) {
161 m_log.Warn("[VOICECHAT]: Multiple login attempts for " + uuid);
162 return false;
163 }
164 m_uuidToClient[uuid] = client;
165 return true;
166 }
167 }
168 return false;
169 }
170
171 public void RemoveClient(Socket socket)
172 {
173 m_log.Info("[VOICECHAT]: Removing client");
174 lock(m_clients)
175 {
176 VoiceClient client = m_clients[socket];
177
178 lock(m_uuidToClient)
179 {
180 if (m_uuidToClient.ContainsKey(client.m_clientId))
181 {
182 m_uuidToClient[client.m_clientId] = null;
183 }
184 }
185
186 m_clients.Remove(socket);
187 client.m_socket.Close();
188 }
189 }
190
191 protected void CreateListeningSocket()
192 {
193 IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 12000);
194 m_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
195 m_server.Bind(listenEndPoint);
196 m_server.Listen(50);
197 }
198
199 void ListenIncomingConnections()
200 {
201 m_log.Info("[VOICECHAT]: Listening connections...");
202 //ServerStatus.ReportThreadName("VoiceChat: Connection listener");
203
204 byte[] dummyBuffer = new byte[1];
205
206 while (true)
207 {
208 try
209 {
210 Socket connection = m_server.Accept();
211 lock (m_clients)
212 {
213 m_clients[connection] = new VoiceClient(connection, this);
214 m_selectCancel.Send(dummyBuffer);
215 m_log.Info("[VOICECHAT]: Voicechat connection from " + connection.RemoteEndPoint.ToString());
216 }
217 }
218 catch (SocketException e)
219 {
220 m_log.Error("[VOICECHAT]: During accept: " + e.ToString());
221 }
222 }
223 }
224
225 Socket ListenLoopbackSocket()
226 {
227 IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), m_dummySocketPort);
228 Socket dummyListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
229 dummyListener.Bind(listenEndPoint);
230 dummyListener.Listen(1);
231 Socket socket = dummyListener.Accept();
232 dummyListener.Close();
233 return socket;
234 }
235
236 void RunVoiceChat()
237 {
238 m_log.Info("[VOICECHAT]: Connection handler started...");
239 //ServerStatus.ReportThreadName("VoiceChat: Connection handler");
240
241 //Listen a loopback socket for aborting select call
242 Socket dummySocket = ListenLoopbackSocket();
243
244 List<Socket> sockets = new List<Socket>();
245 byte[] buffer = new byte[65536];
246
247 while (true)
248 {
249 if (m_clients.Count == 0)
250 {
251 Thread.Sleep(100);
252 continue;
253 }
254
255 lock (m_clients)
256 {
257 foreach (Socket s in m_clients.Keys)
258 {
259 sockets.Add(s);
260 }
261 }
262 sockets.Add(dummySocket);
263
264 try
265 {
266 Socket.Select(sockets, null, null, 200000);
267 }
268 catch (SocketException e)
269 {
270 m_log.Warn("[VOICECHAT]: " + e.Message);
271 }
272
273 foreach (Socket s in sockets)
274 {
275 try
276 {
277 if (s.RemoteEndPoint != dummySocket.RemoteEndPoint)
278 {
279 ReceiveFromSocket(s, buffer);
280 }
281 else
282 {
283 //Receive data and check if there was an error with select abort socket
284 if (s.Receive(buffer) <= 0)
285 {
286 //Just give a warning for now
287 m_log.Error("[VOICECHAT]: Select abort socket was closed");
288 }
289 }
290 }
291 catch(ObjectDisposedException)
292 {
293 m_log.Warn("[VOICECHAT]: Connection has been already closed");
294 }
295 catch (Exception e)
296 {
297 m_log.Error("[VOICECHAT]: Exception: " + e.Message);
298
299 RemoveClient(s);
300 }
301 }
302
303 sockets.Clear();
304 }
305 }
306
307 private void ReceiveFromSocket( Socket s, byte[] buffer )
308 {
309 int byteCount = s.Receive(buffer);
310 if (byteCount <= 0)
311 {
312 m_log.Info("[VOICECHAT]: Connection lost to " + s.RemoteEndPoint);
313 lock (m_clients)
314 {
315 RemoveClient(s);
316 }
317 }
318 else
319 {
320 //ServerStatus.ReportInPacketTcp(byteCount);
321 lock (m_clients)
322 {
323 if (m_clients.ContainsKey(s))
324 {
325 m_clients[s].OnDataReceived(buffer, byteCount);
326 }
327 else
328 {
329 m_log.Warn("[VOICECHAT]: Got data from " + s.RemoteEndPoint +
330 ", but source is not a valid voice client");
331 }
332 }
333 }
334 }
335
336 public LLVector3 getScenePresencePosition(LLUUID clientID)
337 {
338 foreach (Scene scene in m_scenes)
339 {
340 ScenePresence x;
341 if ((x = scene.GetScenePresence(clientID)) != null)
342 {
343 return x.AbsolutePosition + new LLVector3(Constants.RegionSize * scene.RegionInfo.RegionLocX,
344 Constants.RegionSize * scene.RegionInfo.RegionLocY, 0);
345 }
346 }
347 return LLVector3.Zero;
348 }
349
350 public void BroadcastVoice(VoicePacket packet)
351 {
352 libsecondlife.LLVector3 origPos = getScenePresencePosition(packet.m_clientId);
353
354 byte[] bytes = packet.GetBytes();
355 foreach (VoiceClient client in m_clients.Values)
356 {
357 if (client.IsEnabled() && client.m_clientId != packet.m_clientId &&
358 client.m_authenticated && client.IsCodecSupported(packet.m_codec))
359 {
360 LLVector3 presenceLoc = getScenePresencePosition(client.m_clientId);
361
362 if (presenceLoc != LLVector3.Zero && Util.GetDistanceTo(presenceLoc, origPos) < 20)
363 {
364 client.SendTo(bytes);
365 }
366 }
367 }
368 }
369 }
370}
diff --git a/OpenSim/Region/Environment/Modules/VoiceChat/VoiceClient.cs b/OpenSim/Region/Environment/Modules/VoiceChat/VoiceClient.cs
deleted file mode 100644
index 4a0b130..0000000
--- a/OpenSim/Region/Environment/Modules/VoiceChat/VoiceClient.cs
+++ /dev/null
@@ -1,196 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
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 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Collections.Generic;
31using System.Text;
32using System.Net.Sockets;
33using OpenSim.Region.Environment.Scenes;
34using libsecondlife;
35
36namespace OpenSim.Region.Environment.Modules.VoiceChat
37{
38 /**
39 * Represents a single voiceclient instance
40 **/
41 public class VoiceClient
42 {
43 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
44
45 public Socket m_socket;
46 public LLUUID m_clientId;
47 public bool m_authenticated = false;
48
49 protected VoicePacketHeader m_header = null;
50 protected int m_headerBytesReceived = 0;
51
52 protected int m_offset = 0;
53 protected int m_supportedCodecs = 0;
54
55 protected byte[] m_buffer = null;
56 protected byte[] m_headerBytes = new byte[5];
57
58 protected bool m_enabled = true;
59
60 protected VoiceChatServer m_server;
61
62 public VoiceClient(Socket socket, VoiceChatServer server)
63 {
64 m_socket = socket;
65 m_server = server;
66 }
67
68 public void OnDataReceived(byte[] data, int byteCount)
69 {
70 int offset = 0;
71 while (offset < byteCount)
72 {
73 if (m_header == null)
74 {
75 if (m_headerBytesReceived < 5)
76 {
77 m_headerBytes[m_headerBytesReceived++] = data[offset++];
78 }
79 else if (m_headerBytesReceived == 5)
80 {
81 m_header = new VoicePacketHeader();
82 m_header.Parse(m_headerBytes);
83 if (m_header.length > 65535)
84 {
85 throw new Exception("Packet size " + m_header.length + " > 65535");
86 }
87
88 m_buffer = new byte[m_header.length];
89 m_offset = 0;
90 m_headerBytesReceived = 0;
91 }
92 }
93 else
94 {
95 int bytesToCopy = m_header.length-m_offset;
96 if (bytesToCopy > byteCount - offset)
97 bytesToCopy = byteCount - offset;
98
99 Buffer.BlockCopy(data, offset, m_buffer, m_offset, bytesToCopy);
100
101 offset += bytesToCopy;
102 m_offset += bytesToCopy;
103
104 if (m_offset == m_header.length)
105 {
106 ParsePacket(m_header.type, m_buffer);
107 m_header = null;
108 }
109 }
110 }
111 }
112
113 void ParsePacket(byte type, byte[] data)
114 {
115 switch (type)
116 {
117 case 0: //LOGIN
118 ParseLogin(data);
119 break;
120
121 case 1: //AUDIODATA
122 if (m_authenticated)
123 {
124 VoicePacket packet = new VoicePacket(data);
125 packet.m_clientId = m_clientId;
126 m_server.BroadcastVoice(packet);
127 }
128 else
129 {
130 m_log.Warn("[VOICECHAT]: Got unauthorized audio data from " +
131 m_socket.RemoteEndPoint.ToString());
132 m_socket.Close();
133 }
134 break;
135
136 case 3: //ENABLEVOIP
137 if (data[0] == 0)
138 {
139 m_log.Warn("[VOICECHAT]: VoiceChat has been disabled for " + m_clientId);
140 m_enabled = false;
141 }
142 else
143 {
144 m_log.Warn("[VOICECHAT]: VoiceChat has been enabled for " + m_clientId);
145 m_enabled = true;
146 }
147 break;
148
149
150 default:
151 throw new Exception("Invalid packet received");
152 }
153 }
154
155 void ParseLogin(byte[] data)
156 {
157 m_clientId = new LLUUID(data, 0);
158
159 m_supportedCodecs = data[16];
160 m_supportedCodecs |= data[17] << 8;
161 m_supportedCodecs |= data[18] << 16;
162 m_supportedCodecs |= data[19] << 24;
163
164 if (m_server.AddClient(this, m_clientId))
165 {
166 m_log.Info("[VOICECHAT]: Client authenticated succesfully: " + m_clientId);
167 m_authenticated = true;
168 }
169 else
170 {
171 throw new Exception("Unable to authenticate with id " + m_clientId);
172 }
173 }
174
175 public bool IsEnabled()
176 {
177 return m_enabled;
178 }
179
180 public bool IsCodecSupported(int codec)
181 {
182 if ((m_supportedCodecs & codec) != 0)
183 return true;
184
185 return false;
186 }
187
188 public void SendTo(byte[] data)
189 {
190 if (m_authenticated)
191 {
192 //ServerStatus.ReportOutPacketTcp(m_socket.Send(data));
193 }
194 }
195 }
196}
diff --git a/OpenSim/Region/Environment/Modules/VoiceChat/VoicePacket.cs b/OpenSim/Region/Environment/Modules/VoiceChat/VoicePacket.cs
deleted file mode 100644
index 241d156..0000000
--- a/OpenSim/Region/Environment/Modules/VoiceChat/VoicePacket.cs
+++ /dev/null
@@ -1,85 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
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 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using libsecondlife;
32
33namespace OpenSim.Region.Environment.Modules.VoiceChat
34{
35 public enum VoiceCodec
36 {
37 None = 0,
38 PCM8 = 1 << 0,
39 PCM16 = 1 << 1,
40 PCM32 = 1 << 2,
41 Speex = 1 << 3,
42 }
43
44 public class VoicePacket
45 {
46 public LLUUID m_clientId;
47 byte[] m_audioData;
48 public int m_codec;
49
50 public VoicePacket(byte[] data)
51 {
52 int pos = 0;
53 m_codec = data[pos++];
54 m_codec |= data[pos++] << 8;
55 m_codec |= data[pos++] << 16;
56 m_codec |= data[pos++] << 24;
57
58 m_audioData = new byte[data.Length - pos];
59 Buffer.BlockCopy(data, pos, m_audioData, 0, data.Length - pos);
60 }
61
62 public byte[] GetBytes()
63 {
64 VoicePacketHeader header = new VoicePacketHeader();
65 byte[] bytes = new byte[5+16+4+m_audioData.Length];
66
67 header.length = bytes.Length-5;
68
69 //ToClient packets are type 2
70 header.type = 2;
71
72 int pos = 0;
73 header.CopyTo(bytes, pos); pos += 5;
74 m_clientId.GetBytes().CopyTo(bytes, pos); pos += 16;
75
76 bytes[pos++] = (byte)((m_codec) % 256);
77 bytes[pos++] = (byte)((m_codec << 8) % 256);
78 bytes[pos++] = (byte)((m_codec << 16) % 256);
79 bytes[pos++] = (byte)((m_codec << 24) % 256);
80
81 m_audioData.CopyTo(bytes, pos);
82 return bytes;
83 }
84 }
85}
diff --git a/OpenSim/Region/Environment/Modules/VoiceChat/VoicePacketHeader.cs b/OpenSim/Region/Environment/Modules/VoiceChat/VoicePacketHeader.cs
deleted file mode 100644
index 3645bcd..0000000
--- a/OpenSim/Region/Environment/Modules/VoiceChat/VoicePacketHeader.cs
+++ /dev/null
@@ -1,65 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
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 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31
32namespace OpenSim.Region.Environment.Modules.VoiceChat
33{
34 public class VoicePacketHeader
35 {
36 public byte type;
37 public int length;
38
39 public void Parse(byte[] data)
40 {
41 int offset = 0;
42 type = data[offset++];
43
44 length = data[offset++];
45 length |= data[offset++] << 8;
46 length |= data[offset++] << 16;
47 length |= data[offset++] << 24;
48 }
49
50 public void CopyTo(byte[] data, int offset)
51 {
52 data[offset + 0] = type;
53
54 data[offset + 1] = (byte)(length & 0x000000FF);
55 data[offset + 2] = (byte)((length & 0x0000FF00) >> 8);
56 data[offset + 3] = (byte)((length & 0x00FF0000) >> 16);
57 data[offset + 4] = (byte)((length & 0xFF000000) >> 24);
58 }
59
60 public int GetLength()
61 {
62 return 5;
63 }
64 }
65}