Esempio n. 1
0
        public void ByeEncode()
        {
            // Define variables
            ByePacket p1            = new ByePacket();
            string    encodedString = p1.Encode(true);

            // Check result
            Assert.AreEqual("b", encodedString, "Bye message didn't encode correctly");
        }
Esempio n. 2
0
        public void ByeDecode()
        {
            // Define variables
            ByePacket p1            = new ByePacket();
            string    encodedString = p1.Encode(true);

            // Try to decode packet
            try
            {
                ByePacket p2 = ByePacket.Decode(encodedString);
            }
            catch (System.Exception e)
            {
                Assert.Fail("Bye packet exception: " + e.Message);
            }
        }
Esempio n. 3
0
        // This function is meant to be run in its own thread
        // Is writes and reads Packets to/from the UdpClient
        private void _networkRun()
        {
            if (!_running.Value)
            {
                return;
            }

            Console.WriteLine("[Server] Waiting for UDP datagrams on port {0}", Port);

            while (_running.Value)
            {
                bool canRead         = _udpClient.Available > 0;
                int  numToWrite      = _outgoingMessages.Count;
                int  numToDisconnect = _sendByePacketTo.Count;

                // Get data if there is some
                if (canRead)
                {
                    // Read in one datagram
                    IPEndPoint ep   = new IPEndPoint(IPAddress.Any, 0);
                    byte[]     data = _udpClient.Receive(ref ep); // Blocks

                    // Enque a new message
                    NetworkMessage nm = new NetworkMessage();
                    nm.Sender      = ep;
                    nm.Packet      = new Packet(data);
                    nm.ReceiveTime = DateTime.Now;

                    _incomingMessages.Enqueue(nm);

                    //Console.WriteLine("RCVD: {0}", nm.Packet);
                }

                // Write out queued
                for (int i = 0; i < numToWrite; i++)
                {
                    // Send some data
                    Tuple <Packet, IPEndPoint> msg;
                    bool have = _outgoingMessages.TryDequeue(out msg);
                    if (have)
                    {
                        msg.Item1.Send(_udpClient, msg.Item2);
                    }

                    //Console.WriteLine("SENT: {0}", msg.Item1);
                }

                // Notify clients of Bye
                for (int i = 0; i < numToDisconnect; i++)
                {
                    IPEndPoint to;
                    bool       have = _sendByePacketTo.TryDequeue(out to);
                    if (have)
                    {
                        ByePacket bp = new ByePacket();
                        bp.Send(_udpClient, to);
                    }
                }

                // If Nothing happened, take a nap
                if (!canRead && (numToWrite == 0) && (numToDisconnect == 0))
                {
                    Thread.Sleep(1);
                }
            }

            Console.WriteLine("[Server] Done listening for UDP datagrams");

            // Wait for all arena's thread to join
            Queue <Arena> arenas = new Queue <Arena>(_activeArenas.Keys);

            if (arenas.Count > 0)
            {
                Console.WriteLine("[Server] Waiting for active Areans to finish...");
                foreach (Arena arena in arenas)
                {
                    arena.JoinThread();
                }
            }

            // See which clients are left to notify of Bye
            if (_sendByePacketTo.Count > 0)
            {
                Console.WriteLine("[Server] Notifying remaining clients of shutdown...");

                // run in a loop until we've told everyone else
                IPEndPoint to;
                bool       have = _sendByePacketTo.TryDequeue(out to);
                while (have)
                {
                    ByePacket bp = new ByePacket();
                    bp.Send(_udpClient, to);
                    have = _sendByePacketTo.TryDequeue(out to);
                }
            }
        }
Esempio n. 4
0
        private void Start()
        {
            //BufferChunk chunk = new BufferChunk(2048);
            CompoundPacket compoundPacket = new CompoundPacket();
            EndPoint       endPoint       = null;

            while (isRunning)
            {
                try
                {
                    compoundPacket.Reset();
                    udpListener.ReceiveFrom(compoundPacket.Buffer, out endPoint);

                    compoundPacket.ParseBuffer();
                    //IPAddress ipAddress = ((IPEndPoint)endPoint).Address;
                    IPEndPoint ipEndpoint = (IPEndPoint)endPoint;

                    // The compound packet enumerator destroys its list during enumeration,
                    // so we keep track of packets that have yet to be processed
                    IList <RtcpPacket> yetToBeProcessed = new List <RtcpPacket>();


                    String venueName = null;
                    //uint ssrc = 0;
                    long when = 0; // in units of "ticks"

                    // scan through the compound packet, looking for key pieces of meta-data
                    // first, look for the app packet that specifies the venue
                    // also, obtain the ssrc and the time stamp

                    foreach (RtcpPacket packet in compoundPacket)
                    {
                        if (packet.PacketType == (byte)Rtcp.PacketType.APP)
                        {
                            AppPacket appPacket = new AppPacket(packet);
                            if (appPacket.Name.Equals(Rtcp.APP_PACKET_NAME) &&
                                appPacket.Subtype == Rtcp.VENUE_APP_PACKET_SUBTYPE)
                            {
                                BufferChunk chunk = new BufferChunk(appPacket.Data);
                                when      = chunk.NextInt64();
                                venueName = chunk.NextUtf8String(chunk.Length);
                                int padIndex = venueName.IndexOf((char)0);
                                if (padIndex > 0)
                                {
                                    venueName = venueName.Substring(0, padIndex);
                                }
                            }
                        }
                        else
                        {
                            yetToBeProcessed.Add(packet);
                        }
                    }

                    if (venueName == null)
                    {
                        continue; // can't do anything if we don't know the venue for this packet
                    }
                    if (when == 0)
                    {
                        continue; // need a timestamp
                    }
                    VenueState venueState = null;

                    // compound operations must always be locked...
                    lock (venueStateMap)
                    {
                        if (!venueStateMap.ContainsKey(venueName))
                        {
                            venueState = new VenueState(venueName);
                        }
                        else
                        {
                            venueState = venueStateMap[venueName];
                        }
                    }


                    // scan again, this time processing the RTCP packets
                    foreach (RtcpPacket packet in yetToBeProcessed)
                    {
                        switch (packet.PacketType)
                        {
                        case (byte)Rtcp.PacketType.SR:
                        {
                            SrPacket sr = new SrPacket(packet);

                            SenderData senderData = venueState.GetSenderState(sr.SSRC);
                            senderData.Source = ipEndpoint;

                            senderData.updateSenderState(sr.SenderReport, when);

                            // this "refreshes" the host state (so that it won't expire)
                            venueState.SenderData[sr.SSRC] = senderData;
                            break;
                        }

                        case (byte)Rtcp.PacketType.RR:
                        {
                            RrPacket     rr           = new RrPacket(packet);
                            ReceiverData receiverData = venueState.GetReceiverData(ipEndpoint);

                            // currently, we replace all receiver summaries with the data
                            // from a single RR packet
                            receiverData.updateReceiverState(rr.ReceiverReports, when, venueState);


                            // this "refreshes" the host state (so that it won't expire)
                            venueState.ReceiverData[ipEndpoint] = receiverData;
                            break;
                        }

                        case (byte)Rtcp.PacketType.SDES:
                        {
                            SdesPacket sdp = new SdesPacket(packet);

                            foreach (SdesReport report in sdp.Reports())
                            {
                                SenderData senderData = venueState.GetSenderState(report.SSRC);
                                senderData.CName  = report.SdesData.CName;
                                senderData.Source = ipEndpoint;

                                // this "refreshes" the host state (so that it won't expire)
                                venueState.SenderData[report.SSRC] = senderData;

                                ReceiverData receiverData =
                                    venueState.GetReceiverDataWithoutCreating(ipEndpoint);

                                if (receiverData != null)
                                {
                                    receiverData.CName = report.SdesData.CName;
                                }
                            }
                            break;
                        }

                        case (byte)Rtcp.PacketType.BYE:
                        {
                            //BYE packets occur when capabilities stop.  Clean out sender data only for the
                            //ssrc's affected.  We leave receiver reports alone for now.
                            ByePacket byePacket = new ByePacket(packet);
                            foreach (uint ssrc in byePacket.SSRCs)
                            {
                                venueState.SenderData.Remove(ssrc);
                            }
                            //Set a flag to cause the matrix for this venue to be rebuilt on the next request.
                            venueState.ParticipantChange = true;
                            continue;
                        }

                        case (byte)Rtcp.PacketType.APP:
                        {
                            // ignored

                            break;
                        }
                        }
                    }   // foreach packet...

                    // refresh the venue state
                    venueStateMap[venueName] = venueState;
                }
                catch (Exception e)
                {
                    Console.Out.WriteLine("Exception : " + e.ToString());

                    writeEventLog("Exception in receive thread: " + e.ToString(), EventLogEntryType.Warning);
                }
            } // loop forever...
        }
Esempio n. 5
0
 /// <summary>
 /// A ByePacket can contain multiple SSRCs so we need to process them in a loop
 /// </summary>
 /// <param name="packet">ByePacket</param>
 /// <param name="ipAddress">IPAddress packet was received from</param>
 private void ProcessBYEPacket(ByePacket packet, IPAddress ipAddress)
 {
     // Remove stream does a special form of AddSsrcToIp
     // to try and prevent mischievous programming
     foreach(uint ssrc in packet.SSRCs)
     {
         RemoveSSRC(ssrc, ipAddress);
     }
 }