示例#1
0
        /// <summary>
        /// Converts a generic RtcpPacket into a specific RtcpPacket type and forwards it to the
        /// appropriate method to be processed
        /// </summary>
        /// <param name="packet">Generic RtcpPacket</param>
        /// <param name="ipAddress">IPAddress packet was received from</param>
        private void ProcessPacket(RtcpPacket packet, IPAddress ipAddress)
        {
            switch(packet.PacketType)
            {
                case (byte)Rtcp.PacketType.SR:
                {
                    ProcessSRPacket(new SrPacket(packet), ipAddress);
                    break;
                }

                case (byte)Rtcp.PacketType.RR:
                {
                    ProcessRRPacket(new RrPacket(packet), ipAddress);
                    break;
                }

                case (byte)Rtcp.PacketType.SDES:
                {
                    ProcessSDESPacket(new SdesPacket(packet), ipAddress);
                    break;
                }

                case (byte)Rtcp.PacketType.BYE:
                {
                    ProcessBYEPacket(new ByePacket(packet), ipAddress);
                    break;
                }

                case (byte)Rtcp.PacketType.APP:
                {
                    ProcessAPPPacket(new AppPacket(packet));
                    break;
                }

                default:
                {
                    eventLog.WriteEntry("Received an unhandled Rtcp type, " + packet.ToString(),
                        EventLogEntryType.Warning, (int)RtpEL.ID.UnhandledRtcpType);
                    break;
                }
            }
        }
示例#2
0
 internal void AddPacket(RtcpPacket packet)
 {
     packet.WriteToBuffer(buffer);
 }
示例#3
0
        /// <summary>
        /// Called immediately after the buffer is populated by the network listener
        /// It parses RtcpPackets and rigorously validates them
        /// </summary>
        internal void ParseBuffer()
        {
            // See if the packet ends on a 32 bit boundary as it should
            if(buffer.Length % 4 != 0)
            {
                throw new CompoundPacketException("Compound packets must end on a 32 bit boundary");
            }

            // Parse all data in the buffer
            while(buffer.Length > 0)
            {
                // Retrieve the next packet from the buffer
                // RTCP Version will be validated by RtcpHeader in the generic RtcpPacket
                RtcpPacket packet = new RtcpPacket(buffer);

                // Check a couple of facts if the padding bit is set
                if(packet.Padding == true)
                {
                    // Can't be set on the first packet
                    if(packets.Count == 0)
                    {
                        throw new CompoundPacketException("You can't set the padding bit on the first packet");
                    }
                    else
                    {
                        // There must be as many padding octets as the the last octet claims
                        int octets = 0;
                        byte octet = 0;

                        while(buffer.Length > 0)
                        {
                            octet = buffer.NextByte();
                            octets++;
                        }

                        // Last octet contains the count of padding octets
                        if(octet != octets)
                        {
                            throw new CompoundPacketException(string.Format(
                                "There is a discrepancy between the number of padding bytes - " +
                                "actual: {0}, expected: {1}", octets, octet));
                        }
                    }
                }

                packets.Enqueue(packet);
            }

            // It must be a compound packet
            if(packets.Count <= 1)
            {
                throw new CompoundPacketException(string.Format(
                    "A compound RTCP packet must contain more than 1 packet, actual count: {0}",
                    packets.Count));
            }

            // First packet must be an SR or RR
            byte pt = ((RtcpPacket)packets.Peek()).PacketType;
            if((pt != (byte)Rtcp.PacketType.SR) && (pt != (byte)Rtcp.PacketType.RR))
            {
                throw new CompoundPacketException(string.Format(
                    "The first packet in a compound RTCP packet must be an SR: {0} or RR: {1}, " +
                    "actual: {2}", (byte)Rtcp.PacketType.SR, (byte)Rtcp.PacketType.RR, pt));
            }
        }
示例#4
0
 /// <summary>
 /// Construct a ReceiverReport packet from an existing RtcpPacket
 /// </summary>
 /// <param name="packet">Packet to process</param>
 public RrPacket(RtcpPacket packet) : base(Rtcp.PacketType.RR)
 {
     ProcessPacket(packet);
 }
示例#5
0
 /// <summary>
 /// Construct a SenderReport packet from an existing RtcpPacket
 /// </summary>
 /// <param name="packet">Packet to process</param>
 public SrPacket(RtcpPacket packet) : base(Rtcp.PacketType.SR)
 {
     sr = new SenderReport();
     ProcessPacket(packet);
 }
示例#6
0
 /// <summary>
 /// Construct an APP packet from an existing RtcpPacket
 /// </summary>
 /// <param name="packet">Packet to process</param>
 public AppPacket(RtcpPacket packet) : base(Rtcp.PacketType.APP)
 {
     ProcessPacket(packet);
 }
示例#7
0
 /// <summary>
 /// Constructor used to process an existing BYE packet
 /// </summary>
 public ByePacket(RtcpPacket packet) : base(Rtcp.PacketType.BYE)
 {
     ProcessPacket(packet);
 }
示例#8
0
 /// <summary>
 /// Construct an SDES packet from an existing RtcpPacket
 /// </summary>
 public SdesPacket(RtcpPacket packet) : base(Rtcp.PacketType.SDES)
 {
     ProcessPacket(packet);
 }
示例#9
0
        /// <summary>
        /// Converts packet's data into derived class member data
        /// </summary>
        /// <param name="packet"></param>
        protected void ProcessPacket(RtcpPacket packet)
        {
            ValidatePacketType(Header.PacketType, packet.Header.PacketType);

            // Store the header
            header = packet.Header;

            // Do the real work
            ReadDataFromBuffer(packet.buffer);

            // Leave the buffer 32 bit aligned
            RemovePadding(packet.buffer);
        }
示例#10
0
        /// <summary>
        /// Called immediately after the buffer is populated by the network listener
        /// It parses RtcpPackets and rigorously validates them
        /// </summary>
        public void ParseBuffer()
        {
            // See if the packet ends on a 32 bit boundary as it should
            if(buffer.Length % 4 != 0)
            {
                throw new CompoundPacketException(Strings.CompoundPacketsMustEndOnBoundary);
            }

            // Parse all data in the buffer
            while(buffer.Length > 0)
            {
                // Retrieve the next packet from the buffer
                // RTCP Version will be validated by RtcpHeader in the generic RtcpPacket
                RtcpPacket packet = new RtcpPacket(buffer);

                // Check a couple of facts if the padding bit is set
                if(packet.Padding == true)
                {
                    // Can't be set on the first packet
                    if(packets.Count == 0)
                    {
                        throw new CompoundPacketException(Strings.YouCantSetThePaddingBit);
                    }
                    else
                    {
                        // There must be as many padding octets as the the last octet claims
                        int octets = 0;
                        byte octet = 0;

                        while(buffer.Length > 0)
                        {
                            octet = buffer.NextByte();
                            octets++;
                        }

                        // Last octet contains the count of padding octets
                        if(octet != octets)
                        {
                            throw new CompoundPacketException(string.Format(CultureInfo.CurrentCulture, 
                                Strings.PaddingBytesDiscrepancy, octets, octet));
                        }
                    }
                }

                packets.Enqueue(packet);
            }

            // It must be a compound packet
            if(packets.Count <= 1)
            {
                throw new CompoundPacketException(string.Format(CultureInfo.CurrentCulture, 
                    Strings.MustContainMoreThan1Packet, packets.Count));
            }

            // First packet must be an SR or RR
            byte pt = ((RtcpPacket)packets.Peek()).PacketType;
            if((pt != (byte)Rtcp.PacketType.SR) && (pt != (byte)Rtcp.PacketType.RR))
            {
                throw new CompoundPacketException(string.Format(CultureInfo.CurrentCulture, 
                    Strings.FirstPacketMustBeSROrRR, (byte)Rtcp.PacketType.SR, (byte)Rtcp.PacketType.RR, pt));
            }
        }