/// <summary> /// Example of how to create a basic RTP session object and hook up the event handlers. /// </summary> /// <param name="ua">The user agent the RTP session is being created for.</param> /// <param name="dst">THe destination specified on an incoming call. Can be used to /// set the audio source.</param> /// <returns>A new RTP session object.</returns> private static RtpAudioSession CreateRtpSession() { List <SDPMediaFormatsEnum> codecs = new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU, SDPMediaFormatsEnum.PCMA, SDPMediaFormatsEnum.G722 }; var audioOptions = new AudioSourceOptions { AudioSource = AudioSourcesEnum.Silence }; var rtpAudioSession = new RtpAudioSession(audioOptions, codecs); // Wire up the event handler for RTP packets received from the remote party. //rtpAudioSession.OnRtpPacketReceived += (type, rtp) => OnRtpPacketReceived(type, rtp); rtpAudioSession.OnRtcpBye += (reason) => Log.LogDebug($"RTCP BYE received."); rtpAudioSession.OnRtpClosed += (reason) => Log.LogDebug("RTP session closed."); rtpAudioSession.OnReceiveReport += RtpSession_OnReceiveReport; rtpAudioSession.OnSendReport += RtpSession_OnSendReport; //rtpAudioSession.OnTimeout += (mediaType) => //{ // if (ua?.Dialogue != null) // { // Log.LogWarning($"RTP timeout on call with {ua.Dialogue.RemoteTarget}, hanging up."); // } // else // { // Log.LogWarning($"RTP timeout on incomplete call, closing RTP session."); // } // ua.Hangup(); //}; return(rtpAudioSession); }
/// <summary> /// Example of how to create a basic RTP session object and hook up the event handlers. /// </summary> /// <param name="ua">The suer agent the RTP session is being created for.</param> /// <returns>A new RTP session object.</returns> private static RtpAudioSession CreateRtpSession(SIPUserAgent ua) { var rtpAudioSession = new RtpAudioSession(AddressFamily.InterNetwork); // Add the required audio capabilities to the RTP session. These will // automatically get used when creating SDP offers/answers. var pcma = new SDPMediaFormat(SDPMediaFormatsEnum.PCMA); // RTP event support. int clockRate = pcma.GetClockRate(); SDPMediaFormat rtpEventFormat = new SDPMediaFormat(DTMF_EVENT_PAYLOAD_ID); rtpEventFormat.SetFormatAttribute($"{RTPSession.TELEPHONE_EVENT_ATTRIBUTE}/{clockRate}"); rtpEventFormat.SetFormatParameterAttribute("0-16"); var audioCapabilities = new List <SDPMediaFormat> { pcma, rtpEventFormat }; MediaStreamTrack audioTrack = new MediaStreamTrack(null, SDPMediaTypesEnum.audio, false, audioCapabilities); rtpAudioSession.addTrack(audioTrack); // Wire up the event handler for RTP packets received from the remote party. rtpAudioSession.OnRtpPacketReceived += (type, rtp) => OnRtpPacketReceived(ua, type, rtp); if (_sendSilenceTimer == null) { _sendSilenceTimer = new Timer(SendSilence, null, 0, SEND_SILENCE_PERIOD_MS); } return(rtpAudioSession); }
/// <summary> /// Example of how to create a basic RTP session object and hook up the event handlers. /// </summary> /// <param name="ua">The user agent the RTP session is being created for.</param> /// <param name="dst">THe destination specified on an incoming call. Can be used to /// set the audio source.</param> /// <returns>A new RTP session object.</returns> private static RtpAudioSession CreateRtpSession(SIPUserAgent ua) { List <SDPMediaFormatsEnum> codecs = new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU, SDPMediaFormatsEnum.PCMA, SDPMediaFormatsEnum.G722 }; var audioOptions = new AudioSourceOptions { AudioSource = AudioSourcesEnum.Silence }; var rtpAudioSession = new RtpAudioSession(audioOptions, codecs); // Wire up the event handler for RTP packets received from the remote party. rtpAudioSession.OnRtpPacketReceived += (ep, type, rtp) => OnRtpPacketReceived(ua, type, rtp); rtpAudioSession.OnTimeout += (mediaType) => { if (ua?.Dialogue != null) { Log.LogWarning($"RTP timeout on call with {ua.Dialogue.RemoteTarget}, hanging up."); } else { Log.LogWarning($"RTP timeout on incomplete call, closing RTP session."); } ua.Hangup(); }; return(rtpAudioSession); }
/// <summary> /// Example of how to create a basic RTP session object and hook up the event handlers. /// </summary> /// <param name="ua">The user agent the RTP session is being created for.</param> /// <param name="dst">THe destination specified on an incoming call. Can be used to /// set the audio source.</param> /// <returns>A new RTP session object.</returns> private static RtpAudioSession CreateRtpSession(SIPUserAgent ua, string dst) { List <SDPMediaFormatsEnum> codecs = new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU, SDPMediaFormatsEnum.PCMA, SDPMediaFormatsEnum.G722 }; var audioSource = AudioSourcesEnum.SineWave; if (string.IsNullOrEmpty(dst) || !Enum.TryParse <AudioSourcesEnum>(dst, out audioSource)) { audioSource = AudioSourcesEnum.Silence; } var audioOptions = new AudioSourceOptions { AudioSource = audioSource }; if (audioSource == AudioSourcesEnum.Music) { audioOptions.SourceFiles = new Dictionary <SDPMediaFormatsEnum, string>(); if (codecs.Contains(SDPMediaFormatsEnum.PCMA)) { audioOptions.SourceFiles.Add(SDPMediaFormatsEnum.PCMA, MUSIC_FILE_PCMA); } if (codecs.Contains(SDPMediaFormatsEnum.PCMU)) { audioOptions.SourceFiles.Add(SDPMediaFormatsEnum.PCMU, MUSIC_FILE_PCMU); } if (codecs.Contains(SDPMediaFormatsEnum.G722)) { audioOptions.SourceFiles.Add(SDPMediaFormatsEnum.G722, MUSIC_FILE_G722); } } ; Log.LogInformation($"RTP audio session source set to {audioSource}."); var rtpAudioSession = new RtpAudioSession(audioOptions, codecs); // Wire up the event handler for RTP packets received from the remote party. rtpAudioSession.OnRtpPacketReceived += (type, rtp) => OnRtpPacketReceived(ua, type, rtp); rtpAudioSession.OnTimeout += (mediaType) => { if (ua?.Dialogue != null) { Log.LogWarning($"RTP timeout on call with {ua.Dialogue.RemoteTarget}, hanging up."); } else { Log.LogWarning($"RTP timeout on incomplete call, closing RTP session."); } ua.Hangup(); }; return(rtpAudioSession); }
/// <summary> /// An asynchronous task that attempts to initiate a new call to a listening UAS. /// </summary> /// <param name="sipTransport">The transport object to use for the send.</param> /// <param name="dst">The destination end point to send the request to.</param> /// <returns>True if the expected response was received, false otherwise.</returns> private static async Task <bool> InitiateCallTaskAsync(SIPTransport sipTransport, SIPURI dst) { //UdpClient hepClient = new UdpClient(0, AddressFamily.InterNetwork); try { //sipTransport.SIPRequestOutTraceEvent += (localEP, remoteEP, req) => //{ // logger.LogDebug($"Request sent: {localEP}->{remoteEP}"); // logger.LogDebug(req.ToString()); // //var hepBuffer = HepPacket.GetBytes(localEP, remoteEP, DateTimeOffset.Now, 333, "myHep", req.ToString()); // //hepClient.SendAsync(hepBuffer, hepBuffer.Length, "192.168.11.49", 9060); //}; //sipTransport.SIPResponseInTraceEvent += (localEP, remoteEP, resp) => //{ // logger.LogDebug($"Response received: {localEP}<-{remoteEP}"); // logger.LogDebug(resp.ToString()); // //var hepBuffer = HepPacket.GetBytes(remoteEP, localEP, DateTimeOffset.Now, 333, "myHep", resp.ToString()); // //hepClient.SendAsync(hepBuffer, hepBuffer.Length, "192.168.11.49", 9060); //}; var ua = new SIPUserAgent(sipTransport, null); ua.ClientCallTrying += (uac, resp) => logger.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}."); ua.ClientCallRinging += (uac, resp) => logger.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}."); ua.ClientCallFailed += (uac, err) => logger.LogWarning($"{uac.CallDescriptor.To} Failed: {err}"); ua.ClientCallAnswered += (uac, resp) => logger.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}."); var audioOptions = new DummyAudioOptions { AudioSource = DummyAudioSourcesEnum.Silence }; var rtpAudioSession = new RtpAudioSession(audioOptions, new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU }); var result = await ua.Call(dst.ToString(), null, null, rtpAudioSession); await rtpAudioSession.Start(); ua.Hangup(); await Task.Delay(200); return(result); } catch (Exception excp) { logger.LogError($"Exception InitiateCallTaskAsync. {excp.Message}"); return(false); } }
public async Task PlaceCallUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); SIPTransport serverTransport = new SIPTransport(); SIPUDPChannel udpChannel = new SIPUDPChannel(IPAddress.Loopback, 0); serverTransport.AddSIPChannel(udpChannel); // Set up two user agents: one to answer the test call and one to place it. SIPUserAgent userAgentServer = new SIPUserAgent(serverTransport, null); SIPUserAgent userAgentClient = new SIPUserAgent(new SIPTransport(), null); serverTransport.SIPTransportRequestReceived += async(lep, rep, req) => { logger.LogDebug("Request received: " + req.StatusLine); var uas = userAgentServer.AcceptCall(req); RtpAudioSession serverAudioSession = new RtpAudioSession( new AudioSourceOptions { AudioSource = AudioSourcesEnum.None }, new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU }); var answerResult = await userAgentServer.Answer(uas, serverAudioSession); logger.LogDebug($"Server agent answer result {answerResult}."); Assert.True(answerResult); }; var dstUri = udpChannel.GetContactURI(SIPSchemesEnum.sip, new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(IPAddress.Loopback, 0))); logger.LogDebug($"Attempting call to {dstUri.ToString()}."); RtpAudioSession clientAudioSession = new RtpAudioSession( new AudioSourceOptions { AudioSource = AudioSourcesEnum.None }, new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU }); var callResult = await userAgentClient.Call(dstUri.ToString(), null, null, clientAudioSession); logger.LogDebug($"Client agent answer result {callResult }."); Assert.True(callResult); Assert.Equal(SIPDialogueStateEnum.Confirmed, userAgentClient.Dialogue.DialogueState); Assert.Equal(SIPDialogueStateEnum.Confirmed, userAgentServer.Dialogue.DialogueState); }
static async Task Main() { Console.WriteLine("SIPSorcery Convert Audio"); AddConsoleLogger(); //WaveFormatConversionStream converter = new WaveFormatConversionStream(_format_s16le48k, ) _waveFile = new WaveFileWriter("output_s16le48k.mp3", _format_s16le48k); var sipTransport = new SIPTransport(); var userAgent = new SIPUserAgent(sipTransport, null); userAgent.OnCallHungup += (dialog) => { Console.WriteLine("Call hungup."); _waveFile?.Close(); }; //EnableTraceLogs(sipTransport); var audioOptions = new AudioSourceOptions { AudioSource = AudioSourcesEnum.Silence }; var audioFormats = new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU }; var rtpSession = new RtpAudioSession(audioOptions, audioFormats); rtpSession.OnRtpPacketReceived += RtpSession_OnRtpPacketReceived; // Place the call and wait for the result. bool callResult = await userAgent.Call(DESTINATION, null, null, rtpSession); Console.WriteLine($"Call result {((callResult) ? "success" : "failure")}."); Console.WriteLine("press any key to exit..."); Console.Read(); if (userAgent.IsCallActive) { Console.WriteLine("Hanging up."); userAgent.Hangup(); } // Clean up. sipTransport.Shutdown(); SIPSorcery.Net.DNSManager.Stop(); }
/// <summary> /// Example of how to create a basic RTP session object and hook up the event handlers. /// </summary> /// <param name="ua">The suer agent the RTP session is being created for.</param> /// <returns>A new RTP session object.</returns> private static RtpAudioSession CreateRtpSession(SIPUserAgent ua, string dst) { List <SDPMediaFormatsEnum> codecs = new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU, SDPMediaFormatsEnum.PCMA, SDPMediaFormatsEnum.G722 }; var audioSource = DummyAudioSourcesEnum.SineWave; if (!Enum.TryParse <DummyAudioSourcesEnum>(dst, out audioSource)) { audioSource = DummyAudioSourcesEnum.Silence; } var audioOptions = new DummyAudioOptions { AudioSource = audioSource }; if (audioSource == DummyAudioSourcesEnum.Music) { audioOptions.SourceFiles = new Dictionary <SDPMediaFormatsEnum, string>(); if (codecs.Contains(SDPMediaFormatsEnum.PCMA)) { audioOptions.SourceFiles.Add(SDPMediaFormatsEnum.PCMA, MUSIC_FILE_PCMA); } if (codecs.Contains(SDPMediaFormatsEnum.PCMU)) { audioOptions.SourceFiles.Add(SDPMediaFormatsEnum.PCMU, MUSIC_FILE_PCMU); } if (codecs.Contains(SDPMediaFormatsEnum.G722)) { audioOptions.SourceFiles.Add(SDPMediaFormatsEnum.G722, MUSIC_FILE_G722); } } ; Log.LogInformation($"RTP audio session source set to {audioSource}."); var rtpAudioSession = new RtpAudioSession(audioOptions, codecs); // Wire up the event handler for RTP packets received from the remote party. rtpAudioSession.OnRtpPacketReceived += (type, rtp) => OnRtpPacketReceived(ua, type, rtp); return(rtpAudioSession); }
static void Main() { Console.WriteLine("SIPSorcery Blind Transfer Demo: Transferee"); Console.WriteLine("Waiting for incoming call from Transferor."); Console.WriteLine("Press 'q' or ctrl-c to exit."); // Plumbing code to facilitate a graceful exit. CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream. AddConsoleLogger(); // Set up a default SIP transport. _sipTransport = new SIPTransport(); _sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.Any, SIP_LISTEN_PORT))); EnableTraceLogs(_sipTransport); var userAgent = new SIPUserAgent(_sipTransport, null); userAgent.ServerCallCancelled += (uas) => Log.LogDebug("Incoming call cancelled by remote party."); userAgent.OnCallHungup += (dialog) => Log.LogDebug("Call hungup by remote party."); userAgent.OnIncomingCall += async(ua, req) => { List <SDPMediaFormatsEnum> codecs = new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU, SDPMediaFormatsEnum.PCMA, SDPMediaFormatsEnum.G722 }; var audioOptions = new AudioSourceOptions { AudioSource = AudioSourcesEnum.Silence }; var rtpAudioSession = new RtpAudioSession(audioOptions, codecs); var uas = ua.AcceptCall(req); bool answerResult = await ua.Answer(uas, rtpAudioSession); Log.LogDebug($"Answer incoming call result {answerResult}."); _ = Task.Run(async() => { await Task.Delay(1000); Log.LogDebug($"Sending DTMF sequence {string.Join("", DTMF_SEQUENCEFOR_TRANSFEROR.Select(x => x))}."); foreach (byte dtmf in DTMF_SEQUENCEFOR_TRANSFEROR) { Log.LogDebug($"Sending DTMF tone to transferor {dtmf}."); await ua.SendDtmf(dtmf); } }); }; userAgent.OnTransferRequested += (referredTo, referredBy) => true; userAgent.OnTransferToTargetSuccessful += (dst) => { Task.Run(async() => { await Task.Delay(1000); Log.LogDebug($"Sending DTMF sequence {string.Join("", DTMF_SEQUENCEFOR_TRANSFEROR.Select(x => x))}."); foreach (byte dtmf in DTMF_SEQUENCEFOR_TRANSFEROR) { Log.LogDebug($"Sending DTMF tone to target {dtmf}."); await userAgent.SendDtmf(dtmf); } }); }; Task.Run(() => OnKeyPress(userAgent, exitCts)); exitCts.Token.WaitHandle.WaitOne(); #region Cleanup. Log.LogInformation("Exiting..."); //userAgent?.Hangup(); // Give any BYE or CANCEL requests time to be transmitted. Log.LogInformation("Waiting 1s for calls to be cleaned up..."); Task.Delay(1000).Wait(); SIPSorcery.Net.DNSManager.Stop(); if (_sipTransport != null) { Log.LogInformation("Shutting down SIP transport..."); _sipTransport.Shutdown(); } #endregion }