示例#1
0
 /// <summary>
 /// Attempts to determine which media stream a received RTP packet is for.
 /// </summary>
 /// <param name="header">The header of the received RTP packet.</param>
 /// <returns>The media type for the received packet or null if it could not be determined.</returns>
 private SDPMediaTypesEnum?GetMediaTypeForRtpPacket(RTPHeader header)
 {
     if (m_audioStream != null && m_audioStream.RemoteSsrc == header.SyncSource)
     {
         return(SDPMediaTypesEnum.audio);
     }
     else if (m_videoStream != null && m_videoStream.RemoteSsrc == header.SyncSource)
     {
         return(SDPMediaTypesEnum.video);
     }
     else if (m_audioStream != null && m_videoStream == null)
     {
         if (m_audioStream.RemoteSsrc == null)
         {
             m_audioStream.RemoteSsrc = header.SyncSource;
         }
         return(SDPMediaTypesEnum.audio);
     }
     else if (m_videoStream != null && m_audioStream == null)
     {
         if (m_videoStream.RemoteSsrc == null)
         {
             m_videoStream.RemoteSsrc = header.SyncSource;
         }
         return(SDPMediaTypesEnum.video);
     }
     else if (m_videoStream != null && !m_videoStream.RemoteSsrc.HasValue && m_videoStream.IsRemotePayloadIDMatch(header.PayloadType))
     {
         m_videoStream.RemoteSsrc = header.SyncSource;
         return(SDPMediaTypesEnum.video);
     }
     else if (m_audioStream != null && !m_audioStream.RemoteSsrc.HasValue &&
              (m_audioStream.IsRemotePayloadIDMatch(header.PayloadType) || m_audioStream.RemotePayloadIDs == null))
     {
         // For audio only SIP calls it's likely that setting the payload ID's will be
         // overlooked. Assume that if nothing previous has matched then this is an audio
         // RTP packet from the remote party.
         m_audioStream.RemoteSsrc = header.SyncSource;
         return(SDPMediaTypesEnum.audio);
     }
     else
     {
         logger.LogWarning("An RTP packet was received that could not be matched to an audio or video stream.");
         return(null);
     }
 }
 public RTPPacket(byte[] packet)
 {
     Header  = new RTPHeader(packet);
     Payload = new byte[packet.Length - Header.Length];
     Array.Copy(packet, Header.Length, Payload, 0, Payload.Length);
 }
 public RTPPacket(int payloadSize)
 {
     Header  = new RTPHeader();
     Payload = new byte[payloadSize];
 }
 public RTPPacket()
 {
     Header = new RTPHeader();
 }
示例#5
0
			public void CustomisedHeaderRoundTripTest()
			{
				Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

				RTPHeader src = new RTPHeader();
				src.Version = 3;
				src.PaddingFlag = 1;
				src.HeaderExtensionFlag = 1;
				src.MarkerBit = 1;
				src.CSRCCount = 3;
				src.PayloadType = (int)RTPPayloadTypesEnum.GSM;

				byte[] headerBuffer = src.GetHeader(1, 0, 1);

				RTPHeader dst = new RTPHeader(headerBuffer);

				Console.WriteLine("Versions: " + src.Version + ", " + dst.Version);
				Console.WriteLine("PaddingFlag: " + src.PaddingFlag + ", " + dst.PaddingFlag);
				Console.WriteLine("HeaderExtensionFlag: " + src.HeaderExtensionFlag + ", " + dst.HeaderExtensionFlag);
				Console.WriteLine("CSRCCount: " + src.CSRCCount + ", " + dst.CSRCCount);
				Console.WriteLine("MarkerBit: " + src.MarkerBit + ", " + dst.MarkerBit);
				Console.WriteLine("PayloadType: " + src.PayloadType + ", " + dst.PayloadType);
				Console.WriteLine("SequenceNumber: " + src.SequenceNumber + ", " + dst.SequenceNumber);
				Console.WriteLine("Timestamp: " + src.Timestamp + ", " + dst.Timestamp);
				Console.WriteLine("SyncSource: " + src.SyncSource + ", " + dst.SyncSource);

				string rawHeader = null;
				foreach(byte headerByte in headerBuffer)
				{
					rawHeader += headerByte.ToString("x");
				}

				Console.WriteLine("Raw Header: " + rawHeader);

				Assert.IsTrue(src.Version == dst.Version, "Version was mismatched.");
				Assert.IsTrue(src.PaddingFlag == dst.PaddingFlag, "PaddingFlag was mismatched.");
				Assert.IsTrue(src.HeaderExtensionFlag == dst.HeaderExtensionFlag, "HeaderExtensionFlag was mismatched.");
				Assert.IsTrue(src.CSRCCount == dst.CSRCCount, "CSRCCount was mismatched.");
				Assert.IsTrue(src.MarkerBit == dst.MarkerBit, "MarkerBit was mismatched.");
				Assert.IsTrue(src.SequenceNumber == dst.SequenceNumber, "PayloadType was mismatched.");
				Assert.IsTrue(src.HeaderExtensionFlag == dst.HeaderExtensionFlag, "SequenceNumber was mismatched.");
				Assert.IsTrue(src.Timestamp == dst.Timestamp, "Timestamp was mismatched.");
				Assert.IsTrue(src.SyncSource == dst.SyncSource, "SyncSource was mismatched.");
			}
示例#6
0
			public void HeaderRoundTripTest()
			{
				Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

				RTPHeader src = new RTPHeader();
				byte[] headerBuffer = src.GetHeader(1, 0, 1);
				RTPHeader dst = new RTPHeader(headerBuffer);

				Console.WriteLine("Versions: " + src.Version + ", " + dst.Version);
				Console.WriteLine("PaddingFlag: " + src.PaddingFlag + ", " + dst.PaddingFlag);
				Console.WriteLine("HeaderExtensionFlag: " + src.HeaderExtensionFlag + ", " + dst.HeaderExtensionFlag);
				Console.WriteLine("CSRCCount: " + src.CSRCCount + ", " + dst.CSRCCount);
				Console.WriteLine("MarkerBit: " + src.MarkerBit + ", " + dst.MarkerBit);
				Console.WriteLine("PayloadType: " + src.PayloadType + ", " + dst.PayloadType);
				Console.WriteLine("SequenceNumber: " + src.SequenceNumber + ", " + dst.SequenceNumber);
				Console.WriteLine("Timestamp: " + src.Timestamp + ", " + dst.Timestamp);
				Console.WriteLine("SyncSource: " + src.SyncSource + ", " + dst.SyncSource);

				Console.WriteLine("Raw Header: " + System.Text.Encoding.ASCII.GetString(headerBuffer, 0, headerBuffer.Length));

				Assert.IsTrue(src.Version == dst.Version, "Version was mismatched.");
				Assert.IsTrue(src.PaddingFlag == dst.PaddingFlag, "PaddingFlag was mismatched.");
				Assert.IsTrue(src.HeaderExtensionFlag == dst.HeaderExtensionFlag, "HeaderExtensionFlag was mismatched.");
				Assert.IsTrue(src.CSRCCount == dst.CSRCCount, "CSRCCount was mismatched.");
				Assert.IsTrue(src.MarkerBit == dst.MarkerBit, "MarkerBit was mismatched.");
				Assert.IsTrue(src.SequenceNumber == dst.SequenceNumber, "PayloadType was mismatched.");
				Assert.IsTrue(src.HeaderExtensionFlag == dst.HeaderExtensionFlag, "SequenceNumber was mismatched.");
				Assert.IsTrue(src.Timestamp == dst.Timestamp, "Timestamp was mismatched.");
				Assert.IsTrue(src.SyncSource == dst.SyncSource, "SyncSource was mismatched.");
			}
示例#7
0
			public void GetHeaderTest()
			{
				Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

				RTPHeader rtpHeader = new RTPHeader();
				byte[] headerBuffer = rtpHeader.GetHeader(1, 0, 1);

				int byteNum = 1;
				foreach(byte headerByte in headerBuffer)
				{
					Console.WriteLine(byteNum + ": " + headerByte.ToString("x"));
					byteNum++;
				}
			}
示例#8
0
		public RTPPacket(byte[] packet)
		{
			Header = new RTPHeader(packet);	
		}
示例#9
0
		public RTPPacket(int payloadSize)
		{
			Header = new RTPHeader();
			Payload = new byte[payloadSize]; //GetNullPayload(payloadSize);
		}
示例#10
0
		public RTPPacket()
		{
			Header = new RTPHeader();
		}
示例#11
0
 public RTPPacket(byte[] packet)
 {
     Header = new RTPHeader(packet);
     Payload = new byte[packet.Length - Header.Length];
     Array.Copy(packet, Header.Length, Payload, 0, Payload.Length);
 }
示例#12
0
 public RTPPacket(int payloadSize)
 {
     Header = new RTPHeader();
     Payload = new byte[payloadSize];
 }
示例#13
0
        private void Send()
        {
            try
            {
                int       payloadSize = RTPPacketSendSize;
                RTPPacket rtpPacket   = new RTPPacket(RTPPacketSendSize);
                byte[]    rtpBytes    = rtpPacket.GetBytes();

                RTPHeader rtpHeader = new RTPHeader();
                rtpHeader.SequenceNumber = (UInt16)65000;  //Convert.ToUInt16(Crypto.GetRandomInt(0, UInt16.MaxValue));
                uint   sendTimestamp     = uint.MaxValue - 5000;
                uint   lastSendTimestamp = sendTimestamp;
                UInt16 lastSeqNum        = 0;

                logger.Debug("RTP send stream starting to " + IPSocket.GetSocketString(m_streamEndPoint) + " with payload size " + payloadSize + " bytes.");

                Sending            = true;
                m_startRTPSendTime = DateTime.MinValue;
                m_lastRTPSentTime  = DateTime.MinValue;
                m_sampleStartSeqNo = rtpHeader.SequenceNumber;

                DateTime lastRTPSendAttempt = DateTime.Now;

                while (m_udpListener != null && !StopListening)
                {
                    // This may be changed by the listener so it needs to be set each iteration.
                    IPEndPoint dstEndPoint = m_streamEndPoint;

                    //logger.Info("Sending RTP packet to " + dstEndPoint.Address + ":"  + dstEndPoint.Port);

                    if (payloadSize != m_rtpPacketSendSize)
                    {
                        payloadSize = m_rtpPacketSendSize;
                        logger.Info("Changing RTP payload to " + payloadSize);
                        rtpPacket = new RTPPacket(RTP_HEADER_SIZE + m_rtpPacketSendSize);
                        rtpBytes  = rtpPacket.GetBytes();
                    }

                    try
                    {
                        if (m_startRTPSendTime == DateTime.MinValue)
                        {
                            m_startRTPSendTime  = DateTime.Now;
                            rtpHeader.MarkerBit = 0;

                            logger.Debug("RTPSink Send SyncSource=" + rtpPacket.Header.SyncSource + ".");
                        }
                        else
                        {
                            lastSendTimestamp = sendTimestamp;
                            double milliSinceLastSend = DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds;
                            sendTimestamp = Convert.ToUInt32((lastSendTimestamp + (milliSinceLastSend * TIMESTAMP_FACTOR)) % uint.MaxValue);

                            if (lastSendTimestamp > sendTimestamp)
                            {
                                logger.Error("RTP Sender previous timestamp (" + lastSendTimestamp + ") > timestamp (" + sendTimestamp + ") ms since last send=" + milliSinceLastSend + ", lastseqnum=" + lastSeqNum + ", seqnum=" + rtpHeader.SequenceNumber + ".");
                            }

                            if (DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds > 75)
                            {
                                logger.Debug("delayed send: " + rtpHeader.SequenceNumber + ", time since last send " + DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds + "ms.");
                            }
                        }

                        rtpHeader.Timestamp = sendTimestamp;
                        byte[] rtpHeaderBytes = rtpHeader.GetBytes();
                        Array.Copy(rtpHeaderBytes, 0, rtpBytes, 0, rtpHeaderBytes.Length);

                        // Send RTP packets and any extra channels required to emulate mutliple calls.
                        for (int channelCount = 0; channelCount < m_channels; channelCount++)
                        {
                            //logger.Debug("Send rtp getting wallclock timestamp for " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss:fff"));
                            //DateTime sendTime = DateTime.Now;
                            //rtpHeader.Timestamp = RTPHeader.GetWallclockUTCStamp(sendTime);
                            //logger.Debug(rtpHeader.SequenceNumber + "," + rtpHeader.Timestamp);

                            m_udpListener.Send(rtpBytes, rtpBytes.Length, dstEndPoint);
                            m_lastRTPSentTime = DateTime.Now;

                            m_packetsSent++;
                            m_bytesSent += rtpBytes.Length;

                            if (m_packetsSent % 500 == 0)
                            {
                                logger.Debug("Total packets sent to " + dstEndPoint.ToString() + " " + m_packetsSent + ", bytes " + NumberFormatter.ToSIByteFormat(m_bytesSent, 2) + ".");
                            }

                            //sendLogger.Info(m_lastRTPSentTime.ToString("dd MMM yyyy HH:mm:ss:fff") + "," + m_lastRTPSentTime.Subtract(m_startRTPSendTime).TotalMilliseconds.ToString("0") + "," + rtpHeader.SequenceNumber + "," + rtpBytes.Length);

                            //sendLogger.Info(rtpHeader.SequenceNumber + "," + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss:fff"));

                            if (DataSent != null)
                            {
                                try
                                {
                                    DataSent(m_streamId, rtpBytes, dstEndPoint);
                                }
                                catch (Exception excp)
                                {
                                    logger.Error("Exception RTPSink DataSent. " + excp.Message);
                                }
                            }

                            lastSeqNum = rtpHeader.SequenceNumber;
                            if (rtpHeader.SequenceNumber == UInt16.MaxValue)
                            {
                                //logger.Debug("RTPSink looping  the sequence number in sample.");
                                rtpHeader.SequenceNumber = 0;
                            }
                            else
                            {
                                rtpHeader.SequenceNumber++;
                            }
                        }
                    }
                    catch (Exception excp)
                    {
                        logger.Error("Exception RTP Send. " + excp.GetType() + ". " + excp.Message);

                        if (excp.GetType() == typeof(SocketException))
                        {
                            logger.Error("socket exception errorcode=" + ((SocketException)excp).ErrorCode + ".");
                        }

                        logger.Warn("Remote socket closed on send. Last RTP recevied " + m_lastRTPReceivedTime.ToString("dd MMM yyyy HH:mm:ss") + ", last RTP successfull send " + m_lastRTPSentTime.ToString("dd MMM yyyy HH:mm:ss") + ".");
                    }

                    Thread.Sleep(RTPFrameSize);

                    #region Check for whether the stream has timed out on a send or receive and if so shut down the stream.

                    double noRTPRcvdDuration = (m_lastRTPReceivedTime != DateTime.MinValue) ? DateTime.Now.Subtract(m_lastRTPReceivedTime).TotalSeconds : 0;
                    double noRTPSentDuration = (m_lastRTPSentTime != DateTime.MinValue) ? DateTime.Now.Subtract(m_lastRTPSentTime).TotalSeconds : 0;
                    double testDuration      = DateTime.Now.Subtract(m_startRTPSendTime).TotalSeconds;

                    if ((
                            noRTPRcvdDuration > NO_RTP_TIMEOUT ||
                            noRTPSentDuration > NO_RTP_TIMEOUT ||
                            (m_lastRTPReceivedTime == DateTime.MinValue && testDuration > NO_RTP_TIMEOUT)) && // If the test request comes from a private or unreachable IP address then no RTP will ever be received.
                        StopIfNoData)
                    {
                        logger.Warn("Disconnecting RTP stream on " + m_localEndPoint.Address.ToString() + ":" + m_localEndPoint.Port + " due to not being able to send any RTP for " + NO_RTP_TIMEOUT + "s.");
                        StopListening = true;
                    }

                    // Shutdown the socket even if there is still RTP but the stay alive limit has been exceeded.
                    if (RTPMaxStayAlive > 0 && DateTime.Now.Subtract(m_startRTPSendTime).TotalSeconds > RTPMaxStayAlive)
                    {
                        logger.Warn("Shutting down RTPSink due to passing RTPMaxStayAlive time.");
                        Shutdown();
                        StopListening = true;
                    }

                    #endregion
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception Send RTPSink: " + excp.Message);
            }
            finally
            {
                #region Shut down socket.

                Shutdown();

                if (SenderClosed != null)
                {
                    try
                    {
                        SenderClosed(m_streamId, m_callDescriptorId);
                    }
                    catch (Exception excp)
                    {
                        logger.Error("Exception RTPSink SenderClosed. " + excp.Message);
                    }
                }

                #endregion
            }
        }
示例#14
0
        private void RTPPacketReceived(UDPListener listener, IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, byte[] buffer)
        {
            if ((buffer[0] == 0x0 || buffer[0] == 0x1) && buffer.Length >= 20)
            {
                // Probably a STUN request.
                STUNMessage stunMessage = STUNMessage.ParseSTUNMessage(buffer, buffer.Length);

                if (stunMessage != null)
                {
                    logger.Debug("STUN message received on RTP channel " + stunMessage.Header.MessageType + ".");

                    if (stunMessage.Header.MessageType == STUNMessageTypesEnum.BindingRequest)
                    {
                        logger.Debug("RTP channel sending STUN response to " + remoteEndPoint + ".");
                        STUNMessage stunResponse = new STUNMessage();
                        stunResponse.Header.MessageType = STUNMessageTypesEnum.BindingResponse;
                        stunResponse.Header.TransactionId = stunMessage.Header.TransactionId;
                        stunResponse.AddUsernameAttribute(Encoding.UTF8.GetString(stunMessage.Attributes[0].Value));
                        byte[] stunRespBytes = stunResponse.ToByteBuffer();
                        SendRaw(remoteEndPoint, stunRespBytes, stunRespBytes.Length);
                    }
                }
            }
            else
            {
                logger.Debug("RTP packet received from " + remoteEndPoint + ".");

                if (SampleReceived != null)
                {
                    var rtpHeader = new RTPHeader(buffer);

                    SampleReceived(buffer, rtpHeader.Length);
                }
            }
        }
示例#15
0
		private void Send()
		{
            try
            {
                int payloadSize = RTPPacketSendSize;
                RTPPacket rtpPacket = new RTPPacket(RTPPacketSendSize);
                byte[] rtpBytes = rtpPacket.GetBytes();

                RTPHeader rtpHeader = new RTPHeader();
                rtpHeader.SequenceNumber = (UInt16)65000;  //Convert.ToUInt16(Crypto.GetRandomInt(0, UInt16.MaxValue));
                uint sendTimestamp = uint.MaxValue - 5000;
                uint lastSendTimestamp = sendTimestamp;
                UInt16 lastSeqNum = 0;

                logger.Debug("RTP send stream starting to " + IPSocket.GetSocketString(m_streamEndPoint) + " with payload size " + payloadSize + " bytes.");

                Sending = true;
                m_startRTPSendTime = DateTime.MinValue;
                m_lastRTPSentTime = DateTime.MinValue;
                m_sampleStartSeqNo = rtpHeader.SequenceNumber;

                DateTime lastRTPSendAttempt = DateTime.Now;

                while (m_udpListener != null && !StopListening)
                {
                    // This may be changed by the listener so it needs to be set each iteration.
                    IPEndPoint dstEndPoint = m_streamEndPoint;

                    //logger.Info("Sending RTP packet to " + dstEndPoint.Address + ":"  + dstEndPoint.Port);

                    if (payloadSize != m_rtpPacketSendSize)
                    {
                        payloadSize = m_rtpPacketSendSize;
                        logger.Info("Changing RTP payload to " + payloadSize);
                        rtpPacket = new RTPPacket(RTP_HEADER_SIZE + m_rtpPacketSendSize);
                        rtpBytes = rtpPacket.GetBytes();
                    }

                    try
                    {
                        if (m_startRTPSendTime == DateTime.MinValue)
                        {
                            m_startRTPSendTime = DateTime.Now;
                            rtpHeader.MarkerBit = 0;

                            logger.Debug("RTPSink Send SyncSource=" + rtpPacket.Header.SyncSource + ".");
                        }
                        else
                        {
                            lastSendTimestamp = sendTimestamp;
                            double milliSinceLastSend = DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds;
                            sendTimestamp = Convert.ToUInt32((lastSendTimestamp + (milliSinceLastSend * TIMESTAMP_FACTOR)) % uint.MaxValue);

                            if (lastSendTimestamp > sendTimestamp)
                            {
                                logger.Error("RTP Sender previous timestamp (" + lastSendTimestamp + ") > timestamp (" + sendTimestamp + ") ms since last send=" + milliSinceLastSend  + ", lastseqnum=" + lastSeqNum + ", seqnum=" + rtpHeader.SequenceNumber + ".");
                            }

                            if (DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds > 75)
                            {
                                logger.Debug("delayed send: " + rtpHeader.SequenceNumber + ", time since last send " + DateTime.Now.Subtract(m_lastRTPSentTime).TotalMilliseconds + "ms.");
                            }
                        }

                        rtpHeader.Timestamp = sendTimestamp;
                        byte[] rtpHeaderBytes = rtpHeader.GetBytes();
                        Array.Copy(rtpHeaderBytes, 0, rtpBytes, 0, rtpHeaderBytes.Length);

                        // Send RTP packets and any extra channels required to emulate mutliple calls.
                        for (int channelCount = 0; channelCount < m_channels; channelCount++)
                        {
                            //logger.Debug("Send rtp getting wallclock timestamp for " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss:fff"));
                            //DateTime sendTime = DateTime.Now;
                            //rtpHeader.Timestamp = RTPHeader.GetWallclockUTCStamp(sendTime);
                            //logger.Debug(rtpHeader.SequenceNumber + "," + rtpHeader.Timestamp);

                            m_udpListener.Send(rtpBytes, rtpBytes.Length, dstEndPoint);
                            m_lastRTPSentTime = DateTime.Now;

                            m_packetsSent++;
                            m_bytesSent += rtpBytes.Length;

                            if (m_packetsSent % 500 == 0)
                            {
                                logger.Debug("Total packets sent to " + dstEndPoint.ToString() + " " + m_packetsSent + ", bytes " + NumberFormatter.ToSIByteFormat(m_bytesSent, 2) + ".");
                            }

                            //sendLogger.Info(m_lastRTPSentTime.ToString("dd MMM yyyy HH:mm:ss:fff") + "," + m_lastRTPSentTime.Subtract(m_startRTPSendTime).TotalMilliseconds.ToString("0") + "," + rtpHeader.SequenceNumber + "," + rtpBytes.Length);

                            //sendLogger.Info(rtpHeader.SequenceNumber + "," + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss:fff"));

                            if (DataSent != null)
                            {
                                try
                                {
                                    DataSent(m_streamId, rtpBytes, dstEndPoint);
                                }
                                catch (Exception excp)
                                {
                                    logger.Error("Exception RTPSink DataSent. " + excp.Message);
                                }
                            }

                            lastSeqNum = rtpHeader.SequenceNumber;
                            if (rtpHeader.SequenceNumber == UInt16.MaxValue)
                            {
                                //logger.Debug("RTPSink looping  the sequence number in sample.");
                                rtpHeader.SequenceNumber = 0;
                            }
                            else
                            {
                                rtpHeader.SequenceNumber++;
                            }
                        }
                    }
                    catch (Exception excp)
                    {
                        logger.Error("Exception RTP Send. " + excp.GetType() + ". " + excp.Message);

                        if (excp.GetType() == typeof(SocketException))
                        {
                            logger.Error("socket exception errorcode=" + ((SocketException)excp).ErrorCode + ".");
                        }

                        logger.Warn("Remote socket closed on send. Last RTP recevied " + m_lastRTPReceivedTime.ToString("dd MMM yyyy HH:mm:ss") + ", last RTP successfull send " + m_lastRTPSentTime.ToString("dd MMM yyyy HH:mm:ss") + ".");
                    }

                    Thread.Sleep(RTPFrameSize);

                    #region Check for whether the stream has timed out on a send or receive and if so shut down the stream.

                    double noRTPRcvdDuration = (m_lastRTPReceivedTime != DateTime.MinValue) ? DateTime.Now.Subtract(m_lastRTPReceivedTime).TotalSeconds : 0;
                    double noRTPSentDuration = (m_lastRTPSentTime != DateTime.MinValue) ? DateTime.Now.Subtract(m_lastRTPSentTime).TotalSeconds : 0;
                    double testDuration = DateTime.Now.Subtract(m_startRTPSendTime).TotalSeconds;

                    if ((
                        noRTPRcvdDuration > NO_RTP_TIMEOUT || 
                        noRTPSentDuration > NO_RTP_TIMEOUT || 
                        (m_lastRTPReceivedTime == DateTime.MinValue && testDuration > NO_RTP_TIMEOUT)) // If the test request comes from a private or unreachable IP address then no RTP will ever be received. 
                        && StopIfNoData)
                    {
                        logger.Warn("Disconnecting RTP stream on " + m_localEndPoint.Address.ToString() + ":" + m_localEndPoint.Port + " due to not being able to send any RTP for " + NO_RTP_TIMEOUT + "s.");
                        StopListening = true;
                    }

                    // Shutdown the socket even if there is still RTP but the stay alive limit has been exceeded.
                    if (RTPMaxStayAlive > 0 && DateTime.Now.Subtract(m_startRTPSendTime).TotalSeconds > RTPMaxStayAlive)
                    {
                        logger.Warn("Shutting down RTPSink due to passing RTPMaxStayAlive time.");
                        Shutdown();
                        StopListening = true;
                    }

                    #endregion
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception Send RTPSink: " + excp.Message);
            }
            finally
            {
                #region Shut down socket.

                Shutdown();

                if (SenderClosed != null)
                {
                    try
                    {
                        SenderClosed(m_streamId, m_callDescriptorId);
                    }
                    catch (Exception excp)
                    {
                        logger.Error("Exception RTPSink SenderClosed. " + excp.Message);
                    }
                }

                #endregion
            }
		}
示例#16
0
        private void SocketRead_Completed(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                if (e.SocketError == SocketError.Success)
                {
                    if (e.Buffer == null || e.Buffer.Length == 0)
                    {
                        // No need to care about zero byte packets.
                        //string remoteEndPoint = (inEndPoint != null) ? inEndPoint.ToString() : "could not determine";
                        //logger.Error("Zero bytes received on SIPUDPChannel " + m_localSIPEndPoint.ToString() + ".");
                    }
                    else
                    {
                        Debug.WriteLine("RTP packet received from " + e.RemoteEndPoint + ".");
                        logger.Debug("RTP packet received from " + e.RemoteEndPoint + ".");

                        if (SampleReceived != null)
                        {
                            try
                            {
                                var rtpBytes = e.Buffer.Take(e.BytesTransferred).ToArray();
                                var rtpHeader = new RTPHeader(rtpBytes);
                                SampleReceived(rtpBytes, rtpHeader.Length);
                            }
                            catch (Exception rtpParseExcp)
                            {
                                logger.Error("Exception WPRTPChannel parsing RTP. " + rtpParseExcp.Message);
                            }
                        }
                    }
                }
                else
                {
                    Debug.WriteLine("Error listening on WPRTPChannel. " + e.SocketError.ToString());
                    logger.Error("Error listening on WPRTPChannel. " + e.SocketError.ToString());
                }

                if (!m_isClosed)
                {
                    SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs();
                    receiveArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                    receiveArgs.SetBuffer(new Byte[MaxRTPMessageSize], 0, MaxRTPMessageSize);
                    receiveArgs.Completed += SocketRead_Completed;
                    m_rtpListener.ReceiveAsync(receiveArgs);
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception WPRTPChannel SocketRead_Completed. " + excp.Message);
                throw;
            }
        }