static void Main() { Console.WriteLine("SIPSorcery Getting Started Demo"); Log = AddConsoleLogger(); _waveFile = new WaveFileWriter("output.mp3", _waveFormat); _sipTransport = new SIPTransport(); _sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.Any, SIP_LISTEN_PORT))); var userAgent = new SIPUserAgent(_sipTransport, null, true); userAgent.ServerCallCancelled += (uas) => Log.LogDebug("Incoming call cancelled by remote party."); userAgent.OnCallHungup += (dialog) => _waveFile?.Close(); userAgent.OnIncomingCall += async(ua, req) => { WindowsAudioEndPoint winAudioEP = new WindowsAudioEndPoint(new AudioEncoder()); VoIPMediaSession voipMediaSession = new VoIPMediaSession(winAudioEP.ToMediaEndPoints()); voipMediaSession.AcceptRtpFromAny = true; voipMediaSession.OnRtpPacketReceived += OnRtpPacketReceived; var uas = userAgent.AcceptCall(req); await userAgent.Answer(uas, voipMediaSession); }; Console.WriteLine("press any key to exit..."); Console.Read(); // Clean up. _sipTransport.Shutdown(); }
static async Task Main() { Console.WriteLine("SIPSorcery Getting Started Demo"); AddConsoleLogger(); var sipTransport = new SIPTransport(); var userAgent = new SIPUserAgent(sipTransport, null); var winAudio = new WindowsAudioEndPoint(new AudioEncoder()); var voipMediaSession = new VoIPMediaSession(new MediaEndPoints { AudioSink = winAudio, AudioSource = winAudio }); // Place the call and wait for the result. bool callResult = await userAgent.Call(DESTINATION, null, null, voipMediaSession); 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(); }
static async Task Main() { Console.WriteLine("SIPSorcery Getting Started Demo"); AddConsoleLogger(); var sipTransport = new SIPTransport(); EnableTraceLogs(sipTransport); var userAgent = new SIPUserAgent(sipTransport, null); var rtpSession = new WindowsAudioRtpSession(); // 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(); Task.Delay(1000).Wait(); } // Clean up. sipTransport.Shutdown(); }
static async Task Main() { Console.WriteLine("SIPSorcery Getting Started PortAudio Demo (YMMV)"); AddConsoleLogger(); var userAgent = new SIPUserAgent(); var portAudioEndPoint = new PortAudioEndPoint(new AudioEncoder()); var voipMediaSession = new VoIPMediaSession(portAudioEndPoint.ToMediaEndPoints()); voipMediaSession.AcceptRtpFromAny = true; // Place the call and wait for the result. bool callResult = await userAgent.Call(DESTINATION, null, null, voipMediaSession); 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(); await Task.Delay(1000); } }
public async Task IncomingCallNoSdpUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); SIPTransport transport = new SIPTransport(); transport.AddSIPChannel(new MockSIPChannel(new System.Net.IPEndPoint(IPAddress.Any, 0))); SIPUserAgent userAgent = new SIPUserAgent(transport, null); string inviteReqStr = "INVITE sip:192.168.11.50:5060 SIP/2.0" + m_CRLF + "Via: SIP/2.0/UDP 192.168.11.50:60163;rport;branch=z9hG4bKPj869f70960bdd4204b1352eaf242a3691" + m_CRLF + "To: <sip:[email protected]>;tag=ZUJSXRRGXQ" + m_CRLF + "From: <sip:[email protected]>;tag=4a60ce364b774258873ff199e5e39938" + m_CRLF + "Call-ID: 17324d6df8744d978008c8997bfd208d" + m_CRLF + "CSeq: 3532 INVITE" + m_CRLF + "Contact: <sip:[email protected]:60163;ob>" + m_CRLF + "Max-Forwards: 70" + m_CRLF + "Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS" + m_CRLF + "Supported: replaces, 100rel, timer, norefersub" + m_CRLF + "Content-Length: 0" + m_CRLF + "Content-Type: application/sdp" + m_CRLF + "Session-Expires: 1800" + m_CRLF + m_CRLF; SIPEndPoint dummySipEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Loopback, 0)); SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(inviteReqStr, dummySipEndPoint, dummySipEndPoint); SIPRequest inviteReq = SIPRequest.ParseSIPRequest(sipMessageBuffer); var uas = userAgent.AcceptCall(inviteReq); await userAgent.Answer(uas, CreateMockVoIPMediaEndPoint()); // The call attempt should timeout while waiting for the ACK request with the SDP answer. Assert.False(userAgent.IsCallActive); }
/// <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); }
static async Task Main() { Console.WriteLine("SIPSorcery Getting Started Demo"); AddConsoleLogger(); var sipTransport = new SIPTransport(); var userAgent = new SIPUserAgent(sipTransport, null); var rtpSession = new RtpAVSession(new AudioOptions { AudioSource = AudioSourcesEnum.Microphone }, null); // 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 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); }
public async Task CancelCallUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); SIPTransport aliceTransport = new SIPTransport(); aliceTransport.AddSIPChannel(new SIPUDPChannel(IPAddress.Loopback, 0)); var alice = new SIPUserAgent(aliceTransport, null, true); SIPServerUserAgent uas = null; // Auto accept but NOT answering. alice.OnIncomingCall += (ua, req) => uas = ua.AcceptCall(req); SIPTransport bobTransport = new SIPTransport(); bobTransport.AddSIPChannel(new SIPUDPChannel(IPAddress.Loopback, 0)); var bob = new SIPUserAgent(bobTransport, null, true); var callTask = bob.Call(alice.ContactURI.ToString(), null, null, CreateMediaSession()); await Task.Delay(500); Assert.True(bob.IsRinging); Assert.NotNull(uas); Assert.False(uas.IsCancelled); bob.Cancel(); await Task.Delay(500); Assert.False(alice.IsCallActive); Assert.False(bob.IsCallActive); Assert.True(uas.IsCancelled); }
/// <summary> /// Because this is a server user agent the SIP transport must start listening for client user agents. /// </summary> private static async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { if (sipRequest.Header.From != null && sipRequest.Header.From.FromTag != null && sipRequest.Header.To != null && sipRequest.Header.To.ToTag != null) { // This is an in-dialog request that will be handled directly by a user agent instance. } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { Log.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}."); var userAgent = new SIPUserAgent(_sipTransport, null); userAgent.ServerCallCancelled += (uas) => Log.LogDebug("Incoming call cancelled by remote party."); userAgent.OnCallHungup += (dialog) => _waveFile?.Close(); var rtpSession = new RtpAVSession( new AudioOptions { AudioSource = AudioSourcesEnum.CaptureDevice, AudioCodecs = new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU, SDPMediaFormatsEnum.PCMA } }, null); rtpSession.OnRtpPacketReceived += OnRtpPacketReceived; var uas = userAgent.AcceptCall(sipRequest); await userAgent.Answer(uas, rtpSession); if (userAgent.IsCallActive) { await rtpSession.Start(); } } else if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPResponse byeResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); await _sipTransport.SendResponseAsync(byeResponse); } else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE) { SIPResponse notAllowededResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); await _sipTransport.SendResponseAsync(notAllowededResponse); } else if (sipRequest.Method == SIPMethodsEnum.OPTIONS || sipRequest.Method == SIPMethodsEnum.REGISTER) { SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); await _sipTransport.SendResponseAsync(optionsResponse); } } catch (Exception reqExcp) { Log.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}"); } }
/// <summary> /// Because this is a server user agent the SIP transport must start listening for client user agents. /// </summary> private static async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { if (sipRequest.Header.From != null && sipRequest.Header.From.FromTag != null && sipRequest.Header.To != null && sipRequest.Header.To.ToTag != null) { // This is an in-dialog request that will be handled directly by a user agent instance. } else if (sipRequest.Method == SIPMethodsEnum.INVITE) { Log.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}."); SIPUserAgent ua = new SIPUserAgent(_sipTransport, null); ua.OnCallHungup += OnHangup; ua.ServerCallCancelled += (uas) => Log.LogDebug("Incoming call cancelled by remote party."); ua.OnDtmfTone += (key, duration) => OnDtmfTone(ua, key, duration); ua.OnRtpEvent += (evt, hdr) => Log.LogDebug($"rtp event {evt.EventID}, duration {evt.Duration}, end of event {evt.EndOfEvent}, timestamp {hdr.Timestamp}, marker {hdr.MarkerBit}."); ua.OnTransactionTraceMessage += (tx, msg) => Log.LogDebug($"uas tx {tx.TransactionId}: {msg}"); ua.ServerCallRingTimeout += (uas) => { Log.LogWarning($"Incoming call timed out in {uas.ClientTransaction.TransactionState} state waiting for client ACK, terminating."); ua.Hangup(); }; var uas = ua.AcceptCall(sipRequest); var rtpSession = CreateRtpSession(ua, sipRequest.URI.User); await ua.Answer(uas, rtpSession); if (ua.IsCallActive) { await rtpSession.Start(); _calls.TryAdd(ua.Dialogue.CallId, ua); } } else if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPResponse byeResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); await _sipTransport.SendResponseAsync(byeResponse); } else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE) { SIPResponse notAllowededResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); await _sipTransport.SendResponseAsync(notAllowededResponse); } else if (sipRequest.Method == SIPMethodsEnum.OPTIONS || sipRequest.Method == SIPMethodsEnum.REGISTER) { SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); await _sipTransport.SendResponseAsync(optionsResponse); } } catch (Exception reqExcp) { Log.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}"); } }
static async Task Main() { Console.WriteLine("SIPSorcery Getting Started Demo"); AddConsoleLogger(); _waveFile = new WaveFileWriter("output.mp3", _waveFormat); var sipTransport = new SIPTransport(); var userAgent = new SIPUserAgent(sipTransport, null); userAgent.ClientCallFailed += (uac, err, resp) => { Console.WriteLine($"Call failed {err}"); _waveFile?.Close(); }; userAgent.OnCallHungup += (dialog) => _waveFile?.Close(); WindowsAudioEndPoint winAudioEP = new WindowsAudioEndPoint(new AudioEncoder()); VoIPMediaSession voipSession = new VoIPMediaSession(winAudioEP.ToMediaEndPoints()); voipSession.OnRtpPacketReceived += OnRtpPacketReceived; // Ctrl-c will gracefully exit the call at any point. Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; if (userAgent.IsCallActive) { Console.WriteLine("Hanging up."); userAgent.Hangup(); } else { Console.WriteLine("Cancelling call"); userAgent.Cancel(); } }; // Place the call and wait for the result. bool callResult = await userAgent.Call(DESTINATION, null, null, voipSession); 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(); }
/// <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); }
static void Main() { Console.WriteLine("SIPSorcery sip.js Demo"); Log = AddConsoleLogger(); var sipTransport = new SIPTransport(); EnableTraceLogs(sipTransport); var sipChannel = new SIPWebSocketChannel(IPAddress.Loopback, 8081); sipTransport.AddSIPChannel(sipChannel); var userAgent = new SIPUserAgent(sipTransport, null, true); userAgent.OnIncomingCall += async(ua, req) => { Log.LogDebug($"Auto-answering incoming call from {req.Header.From}."); var uas = userAgent.AcceptCall(req); var peerConnection = new RTCPeerConnection(null); peerConnection.onconnectionstatechange += (state) => { Log.LogDebug($"Peer connection state change to {state}."); if (state == RTCPeerConnectionState.failed) { peerConnection.Close("ice disconnection"); } else if (state == RTCPeerConnectionState.connected) { peerConnection.OnRtpPacketReceived += OnRtpPacketReceived; } else if (state == RTCPeerConnectionState.closed) { peerConnection.OnRtpPacketReceived -= OnRtpPacketReceived; } }; MediaStreamTrack audioTrack = new MediaStreamTrack(new List <AudioFormat> { new AudioFormat(SDPWellKnownMediaFormatsEnum.PCMU) }, MediaStreamStatusEnum.SendRecv); peerConnection.addTrack(audioTrack); //MediaStreamTrack videoTrack = new MediaStreamTrack("1", SDPMediaTypesEnum.video, false, new List<SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }, MediaStreamStatusEnum.Inactive); //peerConnection.addTrack(videoTrack); var answerResult = await userAgent.Answer(uas, peerConnection); }; Console.Write("press any key to exit..."); Console.Read(); sipTransport.Shutdown(); }
/// <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, resp) => logger.LogWarning($"{uac.CallDescriptor.To} Failed: {err}"); ua.ClientCallAnswered += (uac, resp) => logger.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}."); var audioOptions = new AudioSourceOptions { AudioSource = AudioSourcesEnum.Silence }; var audioExtrasSource = new AudioExtrasSource(new AudioEncoder(), audioOptions); audioExtrasSource.RestrictCodecs(new List <AudioCodecsEnum> { AudioCodecsEnum.PCMU }); var voipMediaSession = new VoIPMediaSession(new MediaEndPoints { AudioSource = audioExtrasSource }); var result = await ua.Call(dst.ToString(), null, null, voipMediaSession); ua.Hangup(); await Task.Delay(200); return(result); } catch (Exception excp) { logger.LogError($"Exception InitiateCallTaskAsync. {excp.Message}"); return(false); } }
public async Task BlindTransferCancelUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); SIPTransport transport = new SIPTransport(); transport.AddSIPChannel(new MockSIPChannel(new System.Net.IPEndPoint(IPAddress.Any, 0))); SIPUserAgent userAgent = new SIPUserAgent(transport, null); string inviteReqStr = "INVITE sip:192.168.11.50:5060 SIP/2.0" + m_CRLF + "Via: SIP/2.0/UDP 192.168.11.50:60163;rport;branch=z9hG4bKPj869f70960bdd4204b1352eaf242a3691" + m_CRLF + "To: <sip:[email protected]>;tag=ZUJSXRRGXQ" + m_CRLF + "From: <sip:[email protected]>;tag=4a60ce364b774258873ff199e5e39938" + m_CRLF + "Call-ID: 17324d6df8744d978008c8997bfd208d" + m_CRLF + "CSeq: 3532 INVITE" + m_CRLF + "Contact: <sip:[email protected]:60163;ob>" + m_CRLF + "Max-Forwards: 70" + m_CRLF + "User-Agent: MicroSIP/3.19.22" + m_CRLF + "Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS" + m_CRLF + "Supported: replaces, 100rel, timer, norefersub" + m_CRLF + "Content-Length: 343" + m_CRLF + "Content-Type: application/sdp" + m_CRLF + "Session-Expires: 1800" + m_CRLF + "Min-SE: 90" + m_CRLF + "" + m_CRLF + "v=0" + m_CRLF + "o=- 3785527268 3785527269 IN IP4 192.168.11.50" + m_CRLF + "s=pjmedia" + m_CRLF + "t=0 0" + m_CRLF + "m=audio 4032 RTP/AVP 0 101" + m_CRLF + "c=IN IP4 192.168.11.50" + m_CRLF + "a=rtpmap:0 PCMU/8000" + m_CRLF + "a=rtpmap:101 telephone-event/8000" + m_CRLF + "a=fmtp:101 0-16" + m_CRLF + "a=sendrecv"; SIPEndPoint dummySipEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Any, 0)); SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(inviteReqStr, dummySipEndPoint, dummySipEndPoint); SIPRequest inviteReq = SIPRequest.ParseSIPRequest(sipMessageBuffer); UASInviteTransaction uasTx = new UASInviteTransaction(transport, inviteReq, null); SIPServerUserAgent mockUas = new SIPServerUserAgent(transport, null, null, null, SIPCallDirection.In, null, null, null, uasTx); await userAgent.Answer(mockUas, CreateMediaSession()); CancellationTokenSource cts = new CancellationTokenSource(); var blindTransferTask = userAgent.BlindTransfer(SIPURI.ParseSIPURIRelaxed("127.0.0.1"), TimeSpan.FromSeconds(2), cts.Token); cts.Cancel(); Assert.False(await blindTransferTask); //await Assert.ThrowsAnyAsync<TaskCanceledException>(async () => { bool result = ; }); }
static async Task Main() { Console.WriteLine("SIPSorcery Convert Audio"); Log = 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 }; AudioExtrasSource audioExtrasSource = new AudioExtrasSource(new AudioEncoder(), audioOptions); audioExtrasSource.RestrictFormats((format) => format.Codec == AudioCodecsEnum.PCMU); var rtpSession = new VoIPMediaSession(new MediaEndPoints { AudioSource = audioExtrasSource }); rtpSession.OnAudioFormatsNegotiated += (formats) => { _ratio = (double)(OUT_SAMPLE_RATE / formats.First().RtpClockRate); }; 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(); }
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); }
public SIPClient(SIPTransport sipTransport, RTPMediaSessionManager rtpMediaSessionManager) { m_sipTransport = sipTransport; m_rtpMediaSessionManager = rtpMediaSessionManager; m_userAgent = new SIPUserAgent(m_sipTransport, null); m_userAgent.ClientCallTrying += CallTrying; m_userAgent.ClientCallRinging += CallRinging; m_userAgent.ClientCallAnswered += CallAnswered; m_userAgent.ClientCallFailed += CallFailed; m_userAgent.OnCallHungup += CallFinished; m_userAgent.ServerCallCancelled += IncomingCallCancelled; m_userAgent.OnTransferNotify += OnTransferNotify; }
static async Task DialNumber() { string fromHeader = (new SIPFromHeader(USERNAME, new SIPURI(USERNAME, DOMAIN, null), null)).ToString(); SIPCallDescriptor callDescriptor = new SIPCallDescriptor(USERNAME, PASSWORD, DEFAULT_CALL_DESTINATION, fromHeader, null, null, null, null, SIPCallDirection.Out, SDP.SDP_MIME_CONTENTTYPE, null, null); callDescriptor.CallId = "12028883999"; userAgent = new SIPUserAgent(sipTransport, null); userAgent.ClientCallTrying += (uac, resp) => Console.WriteLine($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}."); userAgent.ClientCallRinging += (uac, resp) => Console.WriteLine($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}."); userAgent.ClientCallFailed += (uac, err, resp) => Console.WriteLine($"{uac.CallDescriptor.To} Failed: {err}, Status code: {resp?.StatusCode}"); userAgent.ClientCallAnswered += (uac, resp) => Console.WriteLine($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}."); userAgent.OnDtmfTone += (key, duration) => OnDtmfTone(userAgent, key, duration); userAgent.OnRtpEvent += (evt, hdr) => Console.WriteLine($"rtp event {evt.EventID}, duration {evt.Duration}, end of event {evt.EndOfEvent}, timestamp {hdr.Timestamp}, marker {hdr.MarkerBit}."); userAgent.OnCallHungup += OnHangup; var rtpSession = new RtpAVSession( new AudioOptions { AudioSource = AudioSourcesEnum.CaptureDevice, AudioCodecs = new List <SDPMediaFormatsEnum> { SDPMediaFormatsEnum.PCMU, SDPMediaFormatsEnum.PCMA } }, null); rtpSession.OnRtpPacketReceived += OnRtpPacketReceived; var callResult = await userAgent.Call(callDescriptor, rtpSession); Console.WriteLine($"Call result {((callResult) ? "success" : "failure")}."); if (callResult) { Console.WriteLine("Enter digits one after another"); for (int i = 0; i < 11; i++) { var p = Console.ReadLine(); await userAgent.SendDtmf(byte.Parse(p)); } } Console.WriteLine("Enter ?"); Console.ReadLine(); await userAgent.SendDtmf(35); Thread.Sleep(60000); userAgent.Hangup(); _waveFile.Dispose(); Console.WriteLine("Hangup"); }
public SIPClient(SIPTransport sipTransport) { m_sipTransport = sipTransport; m_userAgent = new SIPUserAgent(m_sipTransport, null); m_userAgent.ClientCallTrying += CallTrying; m_userAgent.ClientCallRinging += CallRinging; m_userAgent.ClientCallAnswered += CallAnswered; m_userAgent.ClientCallFailed += CallFailed; m_userAgent.OnCallHungup += CallFinished; m_userAgent.ServerCallCancelled += IncomingCallCancelled; m_userAgent.OnTransferNotify += OnTransferNotify; m_userAgent.OnDtmfTone += OnDtmfTone; }
public override void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. Action <string> logDelegate = (str) => { InvokeOnMainThread(() => { LogTextView.Text += str; }); }; SIPSorcery.LogFactory.Set(new TextViewLoggerFactory(logDelegate)); _userAgent = new SIPUserAgent(); }
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(); }
public async Task HandleInvalidSdpPortOnAnswerUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); SIPTransport transport = new SIPTransport(); SIPUserAgent userAgent = new SIPUserAgent(transport, null); string inviteReqStr = @"INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 0.0.0.0;branch=z9hG4bK57441c4980b94e1686a06ae080be2935;rport To: <sip:[email protected]> From: <sip:0.0.0.0:0>;tag=MYILIYPHQD Call-ID: ddf0e5a9687b4745925438da9000445d CSeq: 1 INVITE Max-Forwards: 70 Allow: ACK, BYE, CANCEL, INFO, INVITE, NOTIFY, OPTIONS, PRACK, REFER, REGISTER, SUBSCRIBE Content-Length: 0 v=0 o=- 1838015445 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0 m=audio 79762 RTP/AVP 0 a=rtpmap:0 PCMU/8000 a=sendrecv"; SIPEndPoint dummySipEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Any, 0)); SIPMessageBuffer sipMessageBuffer = SIPMessageBuffer.ParseSIPMessage(inviteReqStr, dummySipEndPoint, dummySipEndPoint); SIPRequest inviteReq = SIPRequest.ParseSIPRequest(sipMessageBuffer); var uas = userAgent.AcceptCall(inviteReq); RTPSession rtpSession = new RTPSession(false, false, false); MediaStreamTrack audioTrack = new MediaStreamTrack(SDPMediaTypesEnum.audio, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.PCMU) }); rtpSession.addTrack(audioTrack); var result = await userAgent.Answer(uas, rtpSession); Assert.False(result); rtpSession.Close("normal"); }
static async Task Main() { Console.WriteLine("SIPSorcery Play Sounds Demo"); AddConsoleLogger(); var sipTransport = new SIPTransport(); EnableTraceLogs(sipTransport); var userAgent = new SIPUserAgent(sipTransport, null); var rtpSession = new WindowsAudioRtpSession(); // Place the call and wait for the result. bool callResult = await userAgent.Call(DESTINATION, null, null, rtpSession); Console.WriteLine($"Call result {((callResult) ? "success" : "failure")}."); if (callResult) { await Task.Delay(1000); await rtpSession.SendAudioFromStream(new FileStream(WELCOME_16K, FileMode.Open), AudioSamplingRatesEnum.SampleRate16KHz); await Task.Delay(1000); await rtpSession.SendAudioFromStream(new FileStream(GOODBYE_16K, FileMode.Open), AudioSamplingRatesEnum.SampleRate16KHz); } Console.WriteLine("press any key to exit..."); Console.Read(); if (userAgent.IsCallActive) { Console.WriteLine("Hanging up."); userAgent.Hangup(); } // Give the hangup a chance to complete. await Task.Delay(1000); // Clean up. sipTransport.Shutdown(); SIPSorcery.Net.DNSManager.Stop(); }
static async Task Main() { Console.WriteLine("SIP Get Started"); var userAgent = new SIPUserAgent(); var winAudio = new WindowsAudioEndPoint(new AudioEncoder()); var voipMediaSession = new VoIPMediaSession(winAudio.ToMediaEndPoints()); voipMediaSession.AcceptRtpFromAny = true; // Place the call and wait for the result. bool callResult = await userAgent.Call(DESTINATION, null, null, voipMediaSession); Console.WriteLine($"Call result {((callResult) ? "success" : "failure")}."); Console.WriteLine("Press any key to hangup and exit."); Console.ReadLine(); }
/// <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); }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); SetContentView(Resource.Layout.activity_main); var callButton = FindViewById <Button>(Resource.Id.callButton); var cancelButton = FindViewById <Button>(Resource.Id.cancelButton); var destination = FindViewById <TextView>(Resource.Id.callDestination); var statusScroll = FindViewById <ScrollView>(Resource.Id.statusScroll); var statusText = FindViewById <TextView>(Resource.Id.statusTextView); Action <string> logDelegate = (str) => { this.RunOnUiThread(() => { statusText.Append(str); statusScroll.FullScroll(FocusSearchDirection.Down); }); }; SIPSorcery.LogFactory.Set(new TextViewLoggerFactory(logDelegate)); var userAgent = new SIPUserAgent(); callButton.Click += async(sender, e) => { callButton.Enabled = false; cancelButton.Enabled = true; logDelegate($"Calling {destination.Text}...\n"); var callResult = await userAgent.Call(destination.Text, null, null, new AudioSendOnlyMediaSession()); logDelegate($"Call result {callResult}...\n"); }; cancelButton.Click += (sender, e) => { cancelButton.Enabled = false; callButton.Enabled = true; logDelegate("Cancelled.\n"); }; }
/// <summary> /// Because this is a server user agent the SIP transport must start listening for client user agents. /// </summary> private static async Task OnRequest(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) { try { if (sipRequest.Method == SIPMethodsEnum.INVITE) { Log.LogInformation($"Incoming call request: {localSIPEndPoint}<-{remoteEndPoint} {sipRequest.URI}."); SIPUserAgent ua = new SIPUserAgent(_sipTransport, null); ua.OnCallHungup += OnHangup; ua.ServerCallCancelled += (uas) => Log.LogDebug("Incoming call cancelled by remote party."); ua.OnDtmfTone += (key, duration) => OnDtmfTone(ua, key, duration); var uas = ua.AcceptCall(sipRequest); var rtpSession = CreateRtpSession(ua); await ua.Answer(uas, rtpSession); if (ua.IsCallActive) { _calls.TryAdd(ua.Dialogue.CallId, ua); Timer sendSilenceTimer = new Timer(SendSilence, ua, 0, SEND_SILENCE_PERIOD_MS); } } else if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPResponse byeResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.CallLegTransactionDoesNotExist, null); await _sipTransport.SendResponseAsync(byeResponse); } else if (sipRequest.Method == SIPMethodsEnum.SUBSCRIBE) { SIPResponse notAllowededResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.MethodNotAllowed, null); await _sipTransport.SendResponseAsync(notAllowededResponse); } else if (sipRequest.Method == SIPMethodsEnum.OPTIONS || sipRequest.Method == SIPMethodsEnum.REGISTER) { SIPResponse optionsResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); await _sipTransport.SendResponseAsync(optionsResponse); } } catch (Exception reqExcp) { Log.LogWarning($"Exception handling {sipRequest.Method}. {reqExcp.Message}"); } }
/// <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 VoIPMediaSession CreateRtpSession(SIPUserAgent ua, string dst) { List <AudioCodecsEnum> codecs = new List <AudioCodecsEnum> { AudioCodecsEnum.PCMU, AudioCodecsEnum.PCMA, AudioCodecsEnum.G722 }; var audioSource = AudioSourcesEnum.SineWave; if (string.IsNullOrEmpty(dst) || !Enum.IsDefined(typeof(AudioSourcesEnum), dst) || !Enum.TryParse(dst, out audioSource)) { audioSource = AudioSourcesEnum.Music; } Log.LogInformation($"RTP audio session source set to {audioSource}."); AudioExtrasSource audioExtrasSource = new AudioExtrasSource(new AudioEncoder(), new AudioSourceOptions { AudioSource = audioSource }); audioExtrasSource.RestrictFormats(formats => codecs.Contains(formats.Codec)); var rtpAudioSession = new VoIPMediaSession(new MediaEndPoints { AudioSource = audioExtrasSource }); rtpAudioSession.AcceptRtpFromAny = true; // 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); }