Exemplo n.º 1
0
 void RtcpListener.IRtpSession.ProcessCompoundPacket(CompoundPacket cp, IPAddress ip)
 {
     foreach(RtcpPacket packet in cp)
     {
         ProcessPacket(packet, ip);
     }
 }
Exemplo n.º 2
0
        public void ListenThread()
        {
            CompoundPacket compoundPacket = new CompoundPacket();
            EndPoint endPoint = null;

            while(!disposed)
            {
                try
                {
                    // Reset the packet for the next round of data
                    compoundPacket.Reset();

                    // Wait for data off the wire
                    rtcpNetworkListener.ReceiveFrom(compoundPacket.Buffer, out endPoint);

                    #region Fault Injection
                    #if FaultInjection
                    // Drop packets
                    if (rtpSession.DropPacketsPercent > 0)
                    {
                        if (rtpSession.Rnd.Next(1, 100) <= rtpSession.DropPacketsPercent)
                        {
                            continue;
                        }
                    }
                    #endif
                    #endregion Fault Injection

                    // Parse the data and rigorously validate it
                    compoundPacket.ParseBuffer();

                    // Pass it on to the rtpSession to analyze and distribute data
                    rtpSession.ProcessCompoundPacket(compoundPacket, ((IPEndPoint)endPoint).Address);
                }
                
                catch (System.Net.Sockets.SocketException e)
                {
                    // No data received before timeout
                    if (e.ErrorCode == 10060)
                    {
                        rtpSession.RaiseNetworkTimeoutEvent("Rtcp");
                    }
                    // We get 10054 socket exceptions in some situations during unicast connections.  Ignore them for now.
                    // Pri2: Find a better solution for the unicast socket exceptions
                    else if(e.ErrorCode == 10054 && !Utility.IsMulticast(rtcpNetworkListener.ExternalInterface) )
                    {
                        continue;
                    }
                    else
                    {
                        Object[] args = new Object[]{this, new RtpEvents.HiddenSocketExceptionEventArgs((RtpSession)rtpSession, e)};
                        EventThrower.QueueUserWorkItem( new RtpEvents.RaiseEvent(RtpEvents.RaiseHiddenSocketExceptionEvent), args );

                        LogEvent(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.Error);
                    }
                }
                catch(RtcpHeader.RtcpHeaderException e)
                {
                    // TODO - this is a pretty serious error - what should we do - exit thread, squelch? JVE
                    LogEvent(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.RtcpHeaderException);
                }
                catch(CompoundPacket.CompoundPacketException e)
                {
                    // TODO - this is a pretty serious error - what should we do - exit thread, squelch? JVE
                    LogEvent(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.CompoundPacketException);
                }
                catch (ThreadAbortException) {}
                catch (Exception e)
                {
                    LogEvent(e.ToString(), EventLogEntryType.Error, (int)RtpEL.ID.Error);
                }
            }
        }
Exemplo n.º 3
0
        private void AddAppPackets(CompoundPacket cp)
        {
            while(!cpComplete && appPackets.Count > 0)
            {
                AppPacket app = (AppPacket)appPackets.Peek();
        
                if(space >= app.Size)
                {
                    int start = cp.Buffer.Length;
                    cp.AddPacket(app);
                    int end = cp.Buffer.Length;

                    space -= app.Size;
                    appPackets.Dequeue();

                    Debug.Assert( (end-start) == app.Size ); // math check
                }
                else
                {
                    cpComplete = true;
                }
            }
        }
Exemplo n.º 4
0
        private void AddByeReports(CompoundPacket cp)
        {
            while(!cpComplete && byeReports.Count > 0)
            {
                bool byepComplete = false;
                bool addedReport = false;

                ByePacket byep = new ByePacket();
        
                // Remove the size of the header + ssrc
                if(space >= byep.Size)
                {
                    space -= byep.Size;

                    // Add the rest
                    while(space >= Rtp.SSRC_SIZE && byeReports.Count > 0)
                    {
                        try
                        {
                            uint ssrc = (uint)byeReports.Peek();
                            byep.AddSSRC(ssrc);
                            byeReports.Dequeue();
                            
                            space -= Rtp.SSRC_SIZE;
                            addedReport = true;
                        }
                        catch(RtcpPacket.InsufficientItemSpaceException)
                        {
                            // No more room in bp for reports
                            byepComplete = true;
                            break;
                        }
                    }
                }

                // We broke out of the loop for one of 3 reasons
                // 1. There were no more byeReports
                // 2. There was no more room in bp
                // 3. There was no more room in cp (cpComplete)

                // If we added a report to bp, add bp to cp
                if(addedReport)
                {
                    int start = cp.Buffer.Length;
                    cp.AddPacket(byep);
                    int end = cp.Buffer.Length;

                    Debug.Assert( (end-start) == byep.Size ); // math check
                }

                // Figure out if we exited because cp is complete
                if(byeReports.Count > 0 && byepComplete == false)
                {
                    cpComplete = true;
                }
            }
        }
Exemplo n.º 5
0
        private void AddSdesReports(CompoundPacket cp)
        {
            while(!cpComplete && sdesReports.Count > 0)
            {
                bool sdespComplete = false;
                bool addedReport = false;

                SdesPacket sdesp = new SdesPacket();
        
                if(space >= sdesp.Size)
                {
                    space -= sdesp.Size;

                    while(sdesReports.Count > 0)
                    {
                        SdesReport report = (SdesReport)sdesReports.Peek();

                        if( space >= report.Size )
                        {
                            try
                            {
                                sdesp.AddReport(report);
                                sdesReports.Pop();

                                space -= report.Size;
                                addedReport = true;
                            }
                            catch(RtcpPacket.InsufficientItemSpaceException)
                            {
                                // No more room in rrp for reports
                                sdespComplete = true;
                                break;
                            }
                        }
                        else
                        {
                            break; // while loop
                        }
                    }
                }

                // We broke out of the loop for one of 3 reasons
                // 1. There were no more sdesReports
                // 2. There was no more room in sdesp
                // 3. There was no more room in cp (cpComplete)

                // If we added a report to sdesp, add sdesp to cp
                if(addedReport)
                {
                    int start = cp.Buffer.Length;
                    cp.AddPacket(sdesp);
                    int end = cp.Buffer.Length;

                    Debug.Assert( (end-start) == sdesp.Size ); // math check
                }

                // Figure out if we exited because cp is complete
                if(sdesReports.Count > 0 && sdespComplete == false)
                {
                    cpComplete = true;
                }
            }
        }
Exemplo n.º 6
0
        private void AddReceiverReports(CompoundPacket cp)
        {
            while(!cpComplete && receiverReports.Count > 0)
            {
                bool rrpComplete = false;
                bool addedReport = false;

                RrPacket rrp = new RrPacket();
                rrp.SSRC = participant.SSRC;
        
                // Remove the size of the header + ssrc
                if(space >= rrp.Size)
                {
                    space -= rrp.Size;

                    // Add the rest
                    while(space >= ReceiverReport.SIZE && receiverReports.Count > 0)
                    {
                        try
                        {
                            ReceiverReport rr = (ReceiverReport)receiverReports.Peek();
                            rrp.AddReceiverReport(rr);
                            receiverReports.Dequeue();
                            
                            space -= ReceiverReport.SIZE;
                            addedReport = true;
                        }
                        catch(RtcpPacket.InsufficientItemSpaceException)
                        {
                            // No more room in rrp for reports
                            rrpComplete = true;
                            break;
                        }
                    }
                }

                // We broke out of the loop for one of 3 reasons
                // 1. There were no more ReceiverReports
                // 2. There was no more room in rrp
                // 3. There was no more room in cp (cpComplete)

                // If we added a report to rrp, add rrp to cp
                if(addedReport)
                {
                    int start = cp.Buffer.Length;
                    cp.AddPacket(rrp);
                    int end = cp.Buffer.Length;

                    Debug.Assert( (end - start) == rrp.Size ); // math check
                }

                // Figure out if we exited because cp is complete
                if(receiverReports.Count > 0 && rrpComplete == false)
                {
                    cpComplete = true;
                }
            }
        }
Exemplo n.º 7
0
        private void AddSenderReportPackets(CompoundPacket cp)
        {
            while(!cpComplete && senderReportPackets.Count > 0)
            {
                SrPacket sr = (SrPacket)senderReportPackets.Peek();
        
                if(space >= sr.Size)
                {
                    int start = cp.Buffer.Length;
                    cp.AddPacket(sr);
                    int end = cp.Buffer.Length;

                    space -= sr.Size;
                    senderReportPackets.Dequeue();

                    Debug.Assert( (end - start) == sr.Size ); // math check
                }
                else
                {
                    cpComplete = true;
                }
            }
        }
Exemplo n.º 8
0
        private void AddEmptyReceiverReportPacket(CompoundPacket cp)
        {
            RrPacket rr = new RrPacket();
            rr.SSRC = participant.SSRC;

            int start = cp.Buffer.Length;
            cp.AddPacket(rr);
            int end = cp.Buffer.Length;

            space -= rr.Size;

            Debug.Assert( (end - start) == rr.Size ); // math check
        }
Exemplo n.º 9
0
        internal void BuildCompoundPackets()
        {
            // Add the local participant / session info
            sdesReports.Push(new SdesReport(participant.SSRC, participant));

            while(DataRemains())
            {
                CompoundPacket cp = new CompoundPacket();
                space = cp.Size;
                cpComplete = false;

                // All compound packets must start with a SenderReportPacket or a
                // ReceiverReportPacket.  If we don't have real ones, add an empty 
                // ReceiverReportPacket.
                if(senderReportPackets.Count == 0 && receiverReports.Count == 0)
                {
                    AddEmptyReceiverReportPacket(cp);
                }
                else
                {
                    AddSenderReportPackets(cp);
                    AddReceiverReports(cp);
                }

                AddSdesReports(cp);
                AddAppPackets(cp);
                AddByeReports(cp);

                compoundPackets.Enqueue(cp);
            }
        }