public async void ChecklistProcessingToFailStateUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); RTPChannel rtpChannel = new RTPChannel(false, null); var iceSession = new IceSession(rtpChannel, RTCIceComponent.rtp, null); iceSession.StartGathering(); Assert.NotNull(iceSession); Assert.NotEmpty(iceSession.Candidates); foreach (var hostCandidate in iceSession.Candidates) { logger.LogDebug($"host candidate: {hostCandidate}"); } var remoteCandidate = RTCIceCandidate.Parse("candidate:408132416 1 udp 2113937151 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999"); await iceSession.AddRemoteCandidate(remoteCandidate); iceSession.SetRemoteCredentials("CI7o", "xxxxxxxxxxxx"); iceSession.StartGathering(); logger.LogDebug($"ICE session retry interval {iceSession.RTO}ms."); // The defaults are 5 STUN requests and for a checklist with one entry they will be 500ms apart. await Task.Delay(4000); Assert.Equal(IceSession.ChecklistEntryState.Failed, iceSession._checklist.Single().State); Assert.Equal(IceSession.ChecklistState.Failed, iceSession._checklistState); Assert.Equal(RTCIceConnectionState.failed, iceSession.ConnectionState); }
public void GetHostCandidatesForRTPBindUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); var localAddress = NetServices.InternetDefaultAddress; RTPSession rtpSession = new RTPSession(true, true, true, localAddress); // Add a track to the session in order to initialise the RTPChannel. MediaStreamTrack dummyTrack = new MediaStreamTrack(null, SDPMediaTypesEnum.audio, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.PCMU) }); rtpSession.addTrack(dummyTrack); RTPChannel rtpChannel = rtpSession.GetRtpChannel(SDPMediaTypesEnum.audio); logger.LogDebug($"RTP channel RTP socket local end point {rtpChannel.RTPLocalEndPoint}."); var iceSession = new IceSession(rtpChannel, RTCIceComponent.rtp, null); iceSession.StartGathering(); Assert.NotNull(iceSession); Assert.NotEmpty(iceSession.Candidates); Assert.True(localAddress.Equals(IPAddress.Parse(iceSession.Candidates.Single().address))); foreach (var hostCandidate in iceSession.Candidates) { logger.LogDebug(hostCandidate.ToString()); } }
public async void ChecklistConstructionUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); RTPChannel rtpChannel = new RTPChannel(false, null); var iceSession = new IceSession(rtpChannel, RTCIceComponent.rtp, null); iceSession.StartGathering(); Assert.NotNull(iceSession); Assert.NotEmpty(iceSession.Candidates); foreach (var hostCandidate in iceSession.Candidates) { logger.LogDebug($"host candidate: {hostCandidate}"); } var remoteCandidate = RTCIceCandidate.Parse("candidate:408132416 1 udp 2113937151 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999"); await iceSession.AddRemoteCandidate(remoteCandidate); var remoteCandidate2 = RTCIceCandidate.Parse("candidate:408132417 1 udp 2113937150 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999"); await iceSession.AddRemoteCandidate(remoteCandidate2); foreach (var entry in iceSession._checklist) { logger.LogDebug($"checklist entry: {entry.LocalCandidate} -> {entry.RemoteCandidate}"); } Assert.Single(iceSession._checklist); }
public async void ChecklistProcessingUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); RTPChannel rtpChannel = new RTPChannel(false, null); var iceSession = new IceSession(rtpChannel, RTCIceComponent.rtp, null); iceSession.StartGathering(); Assert.NotNull(iceSession); Assert.NotEmpty(iceSession.Candidates); foreach (var hostCandidate in iceSession.Candidates) { logger.LogDebug($"host candidate: {hostCandidate}"); } var remoteCandidate = RTCIceCandidate.Parse("candidate:408132416 1 udp 2113937151 192.168.11.50 51268 typ host generation 0 ufrag CI7o network-cost 999"); await iceSession.AddRemoteCandidate(remoteCandidate); iceSession.SetRemoteCredentials("CI7o", "xxxxxxxxxxxx"); iceSession.StartGathering(); await Task.Delay(2000); var checklistEntry = iceSession._checklist.Single(); logger.LogDebug($"Checklist entry state {checklistEntry.State}, last check sent at {checklistEntry.LastCheckSentAt}."); Assert.Equal(IceSession.ChecklistEntryState.InProgress, checklistEntry.State); }
public AudioChannel() { // Set up the device that will play the audio from the RTP received from the remote end of the call. m_waveOut = new WaveOut(); m_waveProvider = new BufferedWaveProvider(_waveFormat); m_waveOut.Init(m_waveProvider); m_waveOut.Play(); // Set up the input device that will provide audio samples that can be encoded, packaged into RTP and sent to // the remote end of the call. m_waveInEvent = new WaveInEvent(); m_waveInEvent.BufferMilliseconds = 20; m_waveInEvent.NumberOfBuffers = 1; m_waveInEvent.DeviceNumber = 0; m_waveInEvent.DataAvailable += RTPChannelSampleAvailable; m_waveInEvent.WaveFormat = _waveFormat; // Create a UDP socket to use for sending and receiving RTP packets. int port = FreePort.FindNextAvailableUDPPort(DEFAULT_START_RTP_PORT); _rtpEndPoint = new IPEndPoint(_defaultLocalAddress, port); m_rtpChannel = new RTPChannel(_rtpEndPoint); m_rtpChannel.OnFrameReady += RTPChannelSampleReceived; _audioLogger.Debug("RTP channel endpoint " + _rtpEndPoint.ToString()); }
/// <summary> /// 确认接收视频请求 /// </summary> /// <param name="response">响应消息</param> /// <returns></returns> public void AckRequest(SIPResponse response) { _rtpChannel = new RTPChannel(_remoteEndPoint.GetIPEndPoint(), _mediaPort[0], _mediaPort[1], FrameTypesEnum.H264); _rtpChannel.OnFrameReady += _rtpChannel_OnFrameReady; _rtpChannel.Start(); SIPURI localUri = new SIPURI(_msgCore.LocalSIPId, _msgCore.LocalEndPoint.ToHost(), ""); SIPURI remoteUri = new SIPURI(_deviceId, _remoteEndPoint.ToHost(), ""); SIPRequest ackReq = _msgCore.Transport.GetRequest(SIPMethodsEnum.ACK, remoteUri); SIPFromHeader from = new SIPFromHeader(null, response.Header.From.FromURI, response.Header.From.FromTag); SIPToHeader to = new SIPToHeader(null, remoteUri, response.Header.To.ToTag); SIPContactHeader contactHeader = new SIPContactHeader(null, localUri); SIPHeader header = new SIPHeader(from, to, response.Header.CSeq, response.Header.CallId); header.CSeqMethod = SIPMethodsEnum.ACK; header.Contact = response.Header.Contact; header.Contact.Clear(); header.Contact.Add(contactHeader); header.Vias = response.Header.Vias; header.MaxForwards = response.Header.MaxForwards; header.ContentLength = response.Header.ContentLength; header.UserAgent = _msgCore.UserAgent; header.Allow = null; ackReq.Header = header; _okTag = response.Header.To.ToTag; _contact = header.Contact.FirstOrDefault(); _via = header.Vias; _msgCore.Transport.SendRequest(_remoteEndPoint, ackReq); }
public void MultipleRtpChannelLoopbackUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); const int PACKET_LENGTH = 100; List <Task> tasks = new List <Task>(); for (int i = 0; i < 3; i++) { var t = Task.Run(async() => { RTPChannel channel1 = new RTPChannel(false, null); bool testResult = false; ManualResetEventSlim testCompleteEvent = new ManualResetEventSlim(false); RTPChannel channel2 = new RTPChannel(false, null); channel2.OnRTPDataReceived += (lep, rep, pkt) => { logger.LogDebug($"RTP data receive packet length {pkt.Length}."); testResult = pkt.Length == PACKET_LENGTH; testCompleteEvent.Set(); }; channel1.Start(); channel2.Start(); // Give the socket receive tasks time to fire up. await Task.Delay(2000); IPAddress channel2Address = (channel2.RTPLocalEndPoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Loopback : IPAddress.Loopback; IPEndPoint channel2Dst = new IPEndPoint(channel2Address, channel2.RTPPort); logger.LogDebug($"Attempting to send packet from {channel1.RTPLocalEndPoint} to {channel2Dst}."); var sendResult = channel1.SendAsync(RTPChannelSocketsEnum.RTP, channel2Dst, new byte[PACKET_LENGTH]); logger.LogDebug($"Send result {sendResult}."); testCompleteEvent.Wait(TimeSpan.FromSeconds(TEST_TIMEOUT_SECONDS)); Assert.True(testResult); channel1.Close("normal"); channel2.Close("normal"); }); tasks.Add(t); } CancellationTokenSource cts = new CancellationTokenSource(); Assert.True(Task.WaitAll(tasks.ToArray(), 10000, cts.Token)); logger.LogDebug($"Test complete."); }
public void Start(string endpoint) { this.endpoint = endpoint; var caller = "1003"; var password = passwords[0]; var port = FreePort.FindNextAvailableUDPPort(15090); rtpChannel = new RTPChannel { DontTimeout = true, RemoteEndPoint = new IPEndPoint(IPAddress.Parse(asterisk), port) }; rtpChannel.SetFrameType(FrameTypesEnum.Audio); rtpChannel.ReservePorts(15000, 15090); rtpChannel.OnFrameReady += RtpChannel_OnFrameReady; uac = new SIPClientUserAgent(transport, null, null, null, null); var uri = SIPURI.ParseSIPURIRelaxed($"{ endpoint }@{ asterisk }"); var from = (new SIPFromHeader(caller, new SIPURI(caller, asterisk, null), null)).ToString(); var random = Crypto.GetRandomInt(5).ToString(); var sdp = new SDP { Version = 2, Username = "******", SessionId = random, Address = localIPEndPoint.Address.ToString(), SessionName = "redfox_" + random, Timing = "0 0", Connection = new SDPConnectionInformation(publicIPAddress.ToString()) }; var announcement = new SDPMediaAnnouncement { Media = SDPMediaTypesEnum.audio, MediaFormats = new List <SDPMediaFormat>() { new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000) }, Port = rtpChannel.RTPPort }; sdp.Media.Add(announcement); var descriptor = new SIPCallDescriptor(caller, password, uri.ToString(), from, null, null, null, null, SIPCallDirection.Out, SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null); uac.CallTrying += Uac_CallTrying; uac.CallRinging += Uac_CallRinging; uac.CallAnswered += Uac_CallAnswered; uac.CallFailed += Uac_CallFailed; uac.Call(descriptor); }
/// <summary> /// rtcp包回调事件处理 /// </summary> /// <param name="buffer"></param> /// <param name="rtcpSocket"></param> private void _rtpChannel_OnControlDataReceived(byte[] buffer, Socket rtcpSocket) { _rtcpSocket = rtcpSocket; DateTime packetTimestamp = DateTime.Now; _rtcpTimestamp = RTPChannel.DateTimeToNptTimestamp90K(DateTime.Now); if (_rtcpRemoteEndPoint != null) { SendRtcpSenderReport(RTPChannel.DateTimeToNptTimestamp(packetTimestamp), _rtcpTimestamp); } }
/// <param name="rtpListenAddress">The local IP address to establish the RTP listener socket on.</param> /// <param name="sdpAdvertiseAddress">The public IP address to put into the SDP sent back to the caller.</param> /// <param name="request">The INVITE request that instigated the RTP diagnostics job.</param> public RTPDiagnosticsJob(IPAddress rtpListenAddress, IPAddress sdpAdvertiseAddress, SIPServerUserAgent uas, SIPRequest request) { m_request = request; m_remoteSDP = SDP.ParseSDPDescription(request.Body); RemoteRTPEndPoint = new IPEndPoint(IPAddress.Parse(m_remoteSDP.Connection.ConnectionAddress), m_remoteSDP.Media[0].Port); UAS = uas; //m_rawSourceStream = new RawSourceWaveStream(m_outStream, WaveFormat.CreateMuLawFormat(8000, 1)); //m_waveFileWriter = new WaveFileWriter("out.wav", new WaveFormat(8000, 16, 1)); m_waveFileWriter = new WaveFileWriter("out.wav", new WaveFormat(8000, 16, 1)); //m_outPCMStream = WaveFormatConversionStream.CreatePcmStream(m_rawSourceStream); //m_rawRTPPayloadWriter = new StreamWriter("out.rtp"); //m_rawRTPPayloadReader = new StreamReader("in.rtp"); //IPEndPoint rtpListenEndPoint = null; IPEndPoint rtpListenEndPoint = null; NetServices.CreateRandomUDPListener(rtpListenAddress, RTP_PORTRANGE_START, RTP_PORTRANGE_END, m_inUsePorts, out rtpListenEndPoint); RTPListenEndPoint = rtpListenEndPoint; m_inUsePorts.Add(rtpListenEndPoint.Port); //RTPListenEndPoint = new IPEndPoint(rtpListenAddress, RTP_PORTRANGE_START); m_rtpChannel = new RTPChannel(RTPListenEndPoint); m_rtpChannel.SampleReceived += SampleReceived; ThreadPool.QueueUserWorkItem(delegate { GetAudioSamples(); }); LocalSDP = new SDP() { SessionId = Crypto.GetRandomString(6), Address = sdpAdvertiseAddress.ToString(), SessionName = "sipsorcery", Timing = "0 0", Connection = new SDPConnectionInformation(sdpAdvertiseAddress.ToString()), Media = new List <SDPMediaAnnouncement>() { new SDPMediaAnnouncement() { Media = SDPMediaTypesEnum.audio, Port = RTPListenEndPoint.Port, MediaFormats = new List <SDPMediaFormat>() { new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU) } } } }; }
public async void RtpChannelLoopbackUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); RTPChannel channel1 = new RTPChannel(false, null); bool testResult = false; ManualResetEventSlim testCompleteEvent = new ManualResetEventSlim(false); RTPChannel channel2 = new RTPChannel(false, null); channel2.OnRTPDataReceived += (lep, rep, pkt) => { logger.LogDebug($"RTP data receive packet length {pkt.Length}."); testResult = true; testCompleteEvent.Set(); }; channel1.Start(); channel2.Start(); // Give the socket receive tasks time to fire up. await Task.Delay(1000); IPAddress channel2Address = (channel2.RTPLocalEndPoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Loopback : IPAddress.Loopback; IPEndPoint channel2Dst = new IPEndPoint(channel2Address, channel2.RTPPort); logger.LogDebug($"Attempting to send packet from {channel1.RTPLocalEndPoint} to {channel2Dst}."); var sendResult = channel1.SendAsync(RTPChannelSocketsEnum.RTP, channel2Dst, new byte[] { 0x00 }); logger.LogDebug($"Send result {sendResult}."); testCompleteEvent.Wait(TimeSpan.FromSeconds(TEST_TIMEOUT_SECONDS)); Assert.True(testResult); channel1.Close("normal"); channel2.Close("normal"); logger.LogDebug($"Test complete."); }
/// <summary> /// sip初始化完成事件 /// </summary> /// <param name="sipRequest">sip请求</param> /// <param name="localEndPoint">本地终结点</param> /// <param name="remoteEndPoint">远程终结点</param> /// <param name="sipAccount">sip账户</param> private void messageCore_SipRequestInited(SIPRequest sipRequest, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, SIPAccount sipAccount) { _sipInited = true; _sipRequest = sipRequest; _localEndPoint = localEndPoint; _remoteEndPoint = remoteEndPoint; _sipAccount = sipAccount; _rtpRemoteEndPoint = new IPEndPoint(remoteEndPoint.Address, remoteEndPoint.Port); _rtpChannel = new RTPChannel(_rtpRemoteEndPoint); _rtpChannel.OnFrameReady += _rtpChannel_OnFrameReady; _rtpChannel.OnControlDataReceived += _rtpChannel_OnControlDataReceived; if (SipStatusHandler != null) { SipStatusHandler(SipServiceStatus.Inited); } _messageCore.SipRequestInited -= messageCore_SipRequestInited; }
public event Action <byte[], int> OnRemoteVideoSampleReady; // Fires when a remote video sample is ready for display. public RTPManager(bool includeAudio, bool includeVideo) { if (includeAudio) { // Create a UDP socket to use for sending and receiving RTP audio packets. _rtpAudioChannel = new RTPChannel(); _rtpAudioChannel.SetFrameType(FrameTypesEnum.Audio); _rtpAudioChannel.ReservePorts(DEFAULT_START_RTP_PORT, DEFAULT_END_RTP_PORT); _rtpAudioChannel.OnFrameReady += AudioFrameReady; } if (includeVideo) { _rtpVideoChannel = new RTPChannel(); _rtpVideoChannel.SetFrameType(FrameTypesEnum.VP8); _rtpVideoChannel.ReservePorts(DEFAULT_START_RTP_PORT, DEFAULT_END_RTP_PORT); _rtpVideoChannel.OnFrameReady += VideoFrameReady; _rtpVideoChannel.OnRTPSocketDisconnected += () => { }; } }
public void RtpChannelCreateManyUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); List <RTPChannel> channels = new List <RTPChannel>(); for (int i = 0; i < 10; i++) { RTPChannel channel = new RTPChannel(true, null); channels.Add(channel); } Assert.Equal(10, channels.Count); foreach (var channel in channels) { channel.Close("normal"); } }
private void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { var endpoint = new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, localSIPEndPoint.Port); if (sipRequest.Method == SIPMethodsEnum.INVITE) { if (transaction != null) { return; } logger.DebugFormat("{0} Incoming call from {1}", prefix, sipRequest.Header.From.FromURI.User); transaction = transport.CreateUASTransaction(sipRequest, remoteEndPoint, endpoint, null); agent = new SIPServerUserAgent( transport, null, sipRequest.Header.From.FromURI.User, null, SIPCallDirection.In, null, null, null, transaction); agent.CallCancelled += Agent_CallCancelled; agent.TransactionComplete += Agent_TransactionComplete; agent.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null); agent.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null); var answer = SDP.ParseSDPDescription(agent.CallRequest.Body); var address = IPAddress.Parse(answer.Connection.ConnectionAddress); var port = answer.Media.FirstOrDefault(m => m.Media == SDPMediaTypesEnum.audio).Port; var random = Crypto.GetRandomInt(5).ToString(); var sdp = new SDP { Version = 2, Username = "******", SessionId = random, Address = localIPEndPoint.Address.ToString(), SessionName = "redfox_" + random, Timing = "0 0", Connection = new SDPConnectionInformation(publicIPAddress.ToString()) }; rtpChannel = new RTPChannel { DontTimeout = true, RemoteEndPoint = new IPEndPoint(address, port) }; rtpChannel.SetFrameType(FrameTypesEnum.Audio); // TODO Fix hardcoded ports rtpChannel.ReservePorts(15000, 15090); rtpChannel.OnFrameReady += Channel_OnFrameReady; rtpChannel.Start(); // Send some setup parameters to punch a hole in the firewall/router rtpChannel.SendRTPRaw(new byte[] { 80, 95, 198, 88, 55, 96, 225, 141, 215, 205, 185, 242, 00 }); rtpChannel.OnControlDataReceived += (b) => { logger.Debug($"{prefix} Control Data Received; {b.Length} bytes"); }; rtpChannel.OnControlSocketDisconnected += () => { logger.Debug($"{prefix} Control Socket Disconnected"); }; var announcement = new SDPMediaAnnouncement { Media = SDPMediaTypesEnum.audio, MediaFormats = new List <SDPMediaFormat>() { new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000) }, Port = rtpChannel.RTPPort }; sdp.Media.Add(announcement); SetState(State.Listening, sipRequest.Header.From.FromURI.User); agent.Progress(SIPResponseStatusCodesEnum.Accepted, null, null, null, null); agent.Answer(SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null, SIPDialogueTransferModesEnum.NotAllowed); SetState(State.Busy, ""); return; } if (sipRequest.Method == SIPMethodsEnum.BYE) { if (State != State.Busy) { return; } logger.DebugFormat("{0} Hangup from {1}", prefix, sipRequest.Header.From.FromURI.User); var noninvite = transport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, endpoint, null); var response = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); noninvite.SendFinalResponse(response); SetState(State.Finished, Endpoint); rtpChannel.OnFrameReady -= Channel_OnFrameReady; rtpChannel.Close(); agent.TransactionComplete -= Agent_TransactionComplete; agent.CallCancelled -= Agent_CallCancelled; agent = null; transaction = null; SetState(State.Ready, Endpoint); return; } if (sipRequest.Method == SIPMethodsEnum.ACK) { } if (sipRequest.Method == SIPMethodsEnum.CANCEL) { } }