static void Main() { Console.WriteLine("SIPSorcery Notification Client Demo"); // Use verbose to get display the full SIP messages. AddConsoleLogger(LogEventLevel.Verbose); var sipTransport = new SIPTransport(); sipTransport.EnableTraceLogs(); var mwiURI = SIPURI.ParseSIPURIRelaxed($"{USERNAME}@{SERVER}"); int expiry = 180; SIPNotifierClient mwiSubscriber = new SIPNotifierClient(sipTransport, null, SIPEventPackagesEnum.MessageSummary, mwiURI, USERNAME, null, PASSWORD, expiry, null); mwiSubscriber.SubscriptionFailed += (uri, failureStatus, errorMessage) => Console.WriteLine($"MWI failed for {uri}, {errorMessage}"); mwiSubscriber.SubscriptionSuccessful += (uri) => Console.WriteLine($"MWI subscription successful for {uri}"); mwiSubscriber.NotificationReceived += (evt, msg) => Console.WriteLine($"MWI notification, type {evt}, message {msg}."); mwiSubscriber.Start(); Console.WriteLine("press any key to exit..."); Console.ReadLine(); Console.WriteLine("Exiting..."); // Clean up. mwiSubscriber.Stop(); Thread.Sleep(1000); sipTransport.Shutdown(); }
static async Task Main() { Console.WriteLine("SIPSorcery SIP Call Server example."); Console.WriteLine("Press 'c' to place a call to the default destination."); Console.WriteLine("Press 'd' to send a random DTMF tone to the newest call."); Console.WriteLine("Press 'h' to hangup the oldest call."); Console.WriteLine("Press 'H' to hangup all calls."); Console.WriteLine("Press 'l' to list current calls."); Console.WriteLine("Press 'r' to list current registrations."); Console.WriteLine("Press 't' to transfer the newest call to the default destination."); Console.WriteLine("Press 'q' to quit."); Log = AddConsoleLogger(); // Set up a default SIP transport. _sipTransport = new SIPTransport(); _sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.Any, SIP_LISTEN_PORT))); _sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.IPv6Any, SIP_LISTEN_PORT))); _sipTransport.AddSIPChannel(new SIPTCPChannel(new IPEndPoint(IPAddress.Any, SIP_LISTEN_PORT))); var localhostCertificate = new X509Certificate2(SIPS_CERTIFICATE_PATH); _sipTransport.AddSIPChannel(new SIPTLSChannel(localhostCertificate, new IPEndPoint(IPAddress.Any, SIPS_LISTEN_PORT))); // If it's desired to listen on a single IP address use the equivalent of: //_sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.Parse("192.168.11.50"), SIP_LISTEN_PORT))); _sipTransport.EnableTraceLogs(); _sipTransport.SIPTransportRequestReceived += OnRequest; // Uncomment to enable registrations. //StartRegistrations(_sipTransport, _sipAccounts); CancellationTokenSource exitCts = new CancellationTokenSource(); await Task.Run(() => OnKeyPress(exitCts.Token)); Log.LogInformation("Exiting..."); if (_sipTransport != null) { Log.LogInformation("Shutting down SIP transport..."); _sipTransport.Shutdown(); } }
static void Main() { Console.WriteLine("SIPSorcery registration user agent example."); Console.WriteLine("Press ctrl-c to exit."); Log = AddConsoleLogger(LogEventLevel.Verbose); // Set up a default SIP transport. var sipTransport = new SIPTransport(); sipTransport.EnableTraceLogs(); // Create a client user agent to maintain a periodic registration with a SIP server. var regUserAgent = new SIPRegistrationUserAgent(sipTransport, USERNAME, PASSWORD, DOMAIN, EXPIRY); // Event handlers for the different stages of the registration. regUserAgent.RegistrationFailed += (uri, err) => Log.LogWarning($"{uri}: {err}"); regUserAgent.RegistrationTemporaryFailure += (uri, msg) => Log.LogWarning($"{uri}: {msg}"); regUserAgent.RegistrationRemoved += (uri) => Log.LogWarning($"{uri} registration failed."); regUserAgent.RegistrationSuccessful += (uri) => Log.LogInformation($"{uri} registration succeeded."); // Start the thread to perform the initial registration and then periodically resend it. regUserAgent.Start(); ManualResetEvent exitMRE = new ManualResetEvent(false); Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { e.Cancel = true; Log.LogInformation("Exiting..."); exitMRE.Set(); }; exitMRE.WaitOne(); regUserAgent.Stop(); sipTransport.Shutdown(); }
static async Task Main() { Console.WriteLine("SIPSorcery Getting Started Video Call Demo"); Console.WriteLine("Press ctrl-c to exit."); Log = AddConsoleLogger(); ManualResetEvent exitMRE = new ManualResetEvent(false); var sipTransport = new SIPTransport(); sipTransport.EnableTraceLogs(); var userAgent = new SIPUserAgent(sipTransport, null, true); #region Set up a simple Windows Form with two picture boxes. _form = new Form(); _form.AutoSize = true; _form.BackgroundImageLayout = ImageLayout.Center; _localVideoPicBox = new PictureBox { Size = new Size(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT), Location = new Point(0, 0), Visible = true }; _remoteVideoPicBox = new PictureBox { Size = new Size(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT), Location = new Point(0, VIDEO_FRAME_HEIGHT), Visible = true }; _form.Controls.Add(_localVideoPicBox); _form.Controls.Add(_remoteVideoPicBox); #endregion Application.EnableVisualStyles(); ThreadPool.QueueUserWorkItem(delegate { Application.Run(_form); }); _form.FormClosing += (sender, e) => _isFormActivated = false; _form.Activated += (sender, e) => _isFormActivated = true; _form.FormClosed += (sender, e) => userAgent.Hangup(); userAgent.OnCallHungup += (dialog) => { if (_isFormActivated) { _form.Close(); } }; // Video sink and source to generate and consume VP8 video streams. var testPattern = new VideoTestPatternSource(new VpxVideoEncoder()); var vp8VideoSink = new VideoEncoderEndPoint(); // Add the video sink and source to the media session. MediaEndPoints mediaEndPoints = new MediaEndPoints { VideoSink = vp8VideoSink, VideoSource = testPattern, }; var voipMediaSession = new VoIPMediaSession(mediaEndPoints); voipMediaSession.AcceptRtpFromAny = true; #region Connect the video frames generate from the sink and source to the Windows form. testPattern.OnVideoSourceRawSample += (uint durationMilliseconds, int width, int height, byte[] sample, VideoPixelFormatsEnum pixelFormat) => { if (_isFormActivated) { _form?.BeginInvoke(new Action(() => { if (_form.Handle != IntPtr.Zero) { unsafe { fixed(byte *s = sample) { var bmpImage = new Bitmap(width, height, width * 3, System.Drawing.Imaging.PixelFormat.Format24bppRgb, (IntPtr)s); _localVideoPicBox.Image = bmpImage; } } } })); } }; vp8VideoSink.OnVideoSinkDecodedSample += (byte[] bmp, uint width, uint height, int stride, VideoPixelFormatsEnum pixelFormat) => { if (_isFormActivated) { _form?.BeginInvoke(new Action(() => { if (_form.Handle != IntPtr.Zero) { unsafe { fixed(byte *s = bmp) { var bmpImage = new Bitmap((int)width, (int)height, stride, PixelFormat.Format24bppRgb, (IntPtr)s); _remoteVideoPicBox.Image = bmpImage; } } } })); } }; #endregion // Place the call. var callResult = await userAgent.Call(DESTINATION, null, null, voipMediaSession).ConfigureAwait(false); Console.WriteLine($"Call result {((callResult) ? "success" : "failure")}."); Console.WriteLine("Press any key to hangup and exit."); Console.ReadLine(); if (userAgent.IsCallActive) { _isFormActivated = false; userAgent.Hangup(); await Task.Delay(1000).ConfigureAwait(false); } sipTransport.Shutdown(); }
static async Task Main() { Console.WriteLine("SIPSorcery Play Sounds Demo"); AddConsoleLogger(); CancellationTokenSource exitCts = new CancellationTokenSource(); var sipTransport = new SIPTransport(); sipTransport.EnableTraceLogs(); var userAgent = new SIPUserAgent(sipTransport, OUTBOUND_PROXY); userAgent.ClientCallFailed += (uac, error, sipResponse) => Console.WriteLine($"Call failed {error}."); userAgent.ClientCallFailed += (uac, error, sipResponse) => exitCts.Cancel(); userAgent.OnCallHungup += (dialog) => exitCts.Cancel(); var windowsAudio = new WindowsAudioEndPoint(new AudioEncoder()); //windowsAudio.RestrictFormats(format => format.Codec == AudioCodecsEnum.G722); var voipMediaSession = new VoIPMediaSession(windowsAudio.ToMediaEndPoints()); voipMediaSession.AcceptRtpFromAny = true; //voipMediaSession.AudioExtrasSource.AudioSamplePeriodMilliseconds = 20; //voipMediaSession.AudioLocalTrack.Capabilities.Clear(); //voipMediaSession.AudioLocalTrack.Capabilities.Add( // new SDPAudioVideoMediaFormat(new AudioFormat(AudioCodecsEnum.L16, 118, 8000))); Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; if (userAgent != null) { if (userAgent.IsCalling || userAgent.IsRinging) { Console.WriteLine("Cancelling in progress call."); userAgent.Cancel(); } else if (userAgent.IsCallActive) { Console.WriteLine("Hanging up established call."); userAgent.Hangup(); } } ; exitCts.Cancel(); }; // Place the call and wait for the result. var callTask = userAgent.Call(DESTINATION, null, null, voipMediaSession); Console.WriteLine("press ctrl-c to exit..."); bool callResult = await callTask; if (callResult) { Console.WriteLine($"Call to {DESTINATION} succeeded."); await windowsAudio.PauseAudio(); try { await voipMediaSession.AudioExtrasSource.StartAudio(); //Console.WriteLine("Sending welcome message from 8KHz sample."); await voipMediaSession.AudioExtrasSource.SendAudioFromStream(new FileStream(WELCOME_8K, FileMode.Open), AudioSamplingRatesEnum.Rate8KHz); await Task.Delay(200, exitCts.Token); Console.WriteLine("Sending sine wave."); voipMediaSession.AudioExtrasSource.SetSource(AudioSourcesEnum.SineWave); await Task.Delay(5000, exitCts.Token); Console.WriteLine("Sending white noise signal."); voipMediaSession.AudioExtrasSource.SetSource(AudioSourcesEnum.WhiteNoise); await Task.Delay(2000, exitCts.Token); Console.WriteLine("Sending pink noise signal."); voipMediaSession.AudioExtrasSource.SetSource(AudioSourcesEnum.PinkNoise); await Task.Delay(2000, exitCts.Token); Console.WriteLine("Sending silence."); voipMediaSession.AudioExtrasSource.SetSource(AudioSourcesEnum.Silence); await Task.Delay(2000, exitCts.Token); Console.WriteLine("Playing music."); voipMediaSession.AudioExtrasSource.SetSource(AudioSourcesEnum.Music); await Task.Delay(5000, exitCts.Token); Console.WriteLine("Sending goodbye message from 16KHz sample."); await voipMediaSession.AudioExtrasSource.SendAudioFromStream(new FileStream(GOODBYE_16K, FileMode.Open), AudioSamplingRatesEnum.Rate16KHz); voipMediaSession.AudioExtrasSource.SetSource(AudioSourcesEnum.None); await voipMediaSession.AudioExtrasSource.PauseAudio(); await Task.Delay(200, exitCts.Token); } catch (TaskCanceledException) { } // Switch to the external microphone input source. await windowsAudio.ResumeAudio(); exitCts.Token.WaitHandle.WaitOne(); } else { Console.WriteLine($"Call to {DESTINATION} failed."); } Console.WriteLine("Exiting..."); if (userAgent?.IsHangingUp == true) { Console.WriteLine("Waiting 1s for the call hangup or cancel to complete..."); await Task.Delay(1000); } // Clean up. sipTransport.Shutdown(); }
static void Main(string[] args) { Console.WriteLine("SIPSorcery registration user agent example."); Console.WriteLine("Press ctrl-c to exit."); Log = AddConsoleLogger(LogEventLevel.Verbose); string server = DEFAULT_SERVER; string username = DEFAULT_USERNAME; string password = DEFAULT_PASSWORD; int expiry = DEFAULT_EXPIRY; int posn = 0; while (posn < args?.Length && posn <= 3) { switch (posn) { case 0: server = args[posn++].Trim(); break; case 1: username = args[posn++].Trim(); break; case 2: password = args[posn++].Trim(); break; case 3: int.TryParse(args[posn++], out expiry); break; } } Console.WriteLine("Attempting registration with:"); Console.WriteLine($" server: {server}"); Console.WriteLine($" username: {username}"); Console.WriteLine($" expiry: {expiry}"); // Set up a default SIP transport. var sipTransport = new SIPTransport(); sipTransport.EnableTraceLogs(); // Create a client user agent to maintain a periodic registration with a SIP server. var regUserAgent = new SIPRegistrationUserAgent(sipTransport, username, password, server, expiry); // Event handlers for the different stages of the registration. regUserAgent.RegistrationFailed += (uri, err) => Log.LogWarning($"{uri}: {err}"); regUserAgent.RegistrationTemporaryFailure += (uri, msg) => Log.LogWarning($"{uri}: {msg}"); regUserAgent.RegistrationRemoved += (uri) => Log.LogWarning($"{uri} registration failed."); regUserAgent.RegistrationSuccessful += (uri) => Log.LogInformation($"{uri} registration succeeded."); // Start the thread to perform the initial registration and then periodically resend it. regUserAgent.Start(); ManualResetEvent exitMRE = new ManualResetEvent(false); Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { e.Cancel = true; Log.LogInformation("Exiting..."); exitMRE.Set(); }; exitMRE.WaitOne(); regUserAgent.Stop(); // Allow for unregister request to be sent (REGISTER with 0 expiry) Task.Delay(1500).Wait(); sipTransport.Shutdown(); }
/// <summary> /// Runs a single task as part of the overall job. /// </summary> /// <param name="options">The options that dictate the type of task to run.</param> /// <param name="taskNumber">The number assigned to this task.</param> /// <returns>A boolean indicating whether this single task succeeded or not.</returns> private static async Task <bool> RunTask(Options options, int taskNumber) { SIPTransport sipTransport = new SIPTransport(); sipTransport.PreferIPv6NameResolution = options.PreferIPv6; if (options.Verbose) { sipTransport.EnableTraceLogs(); } try { DateTime startTime = DateTime.Now; var dstUri = ParseDestination(options.Destination); logger.LogDebug($"Destination SIP URI {dstUri}"); if (options.SourcePort != 0) { var sipChannel = sipTransport.CreateChannel(dstUri.Protocol, options.PreferIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, options.SourcePort); sipTransport.AddSIPChannel(sipChannel); } Task <bool> task = null; switch (options.Scenario) { case Scenarios.reg: task = InitiateRegisterTaskAsync(sipTransport, dstUri); break; case Scenarios.uac: case Scenarios.uacw: task = InitiateCallTaskAsync(sipTransport, dstUri, options.Scenario); break; case Scenarios.opt: default: task = SendOptionsTaskAsync(sipTransport, dstUri); break; } var result = await Task.WhenAny(task, Task.Delay(options.Timeout * 1000)); TimeSpan duration = DateTime.Now.Subtract(startTime); bool failed = false; if (!task.IsCompleted) { logger.LogWarning($"=> Request to {dstUri} did not get a response on task {taskNumber} after {duration.TotalMilliseconds.ToString("0")}ms."); failed = true; } else if (!task.Result) { logger.LogWarning($"=> Request to {dstUri} did not get the expected response on task {taskNumber} after {duration.TotalMilliseconds.ToString("0")}ms."); failed = true; } else { logger.LogInformation($"=> Got correct response on send {taskNumber} in {duration.TotalMilliseconds.ToString("0")}ms."); } return(!failed); } finally { logger.LogDebug("Shutting down the SIP transport..."); sipTransport.Shutdown(); } }
static void Main(string[] args) { Console.WriteLine("SIPSorcery client user agent example."); Console.WriteLine("Press ctrl-c to exit."); // Plumbing code to facilitate a graceful exit. ManualResetEvent exitMre = new ManualResetEvent(false); bool preferIPv6 = false; bool isCallHungup = false; bool hasCallFailed = false; Log = AddConsoleLogger(LogEventLevel.Verbose); SIPURI callUri = SIPURI.ParseSIPURI(DEFAULT_DESTINATION_SIP_URI); if (args?.Length > 0) { if (!SIPURI.TryParse(args[0], out callUri)) { Log.LogWarning($"Command line argument could not be parsed as a SIP URI {args[0]}"); } } if (args?.Length > 1 && args[1] == "ipv6") { preferIPv6 = true; } if (preferIPv6) { Log.LogInformation($"Call destination {callUri}, preferencing IPv6."); } else { Log.LogInformation($"Call destination {callUri}."); } // Set up a default SIP transport. var sipTransport = new SIPTransport(); sipTransport.PreferIPv6NameResolution = preferIPv6; sipTransport.EnableTraceLogs(); var audioSession = new WindowsAudioEndPoint(new AudioEncoder()); audioSession.RestrictFormats(x => x.Codec == AudioCodecsEnum.PCMA || x.Codec == AudioCodecsEnum.PCMU); //audioSession.RestrictFormats(x => x.Codec == AudioCodecsEnum.G722); var rtpSession = new VoIPMediaSession(audioSession.ToMediaEndPoints()); var offerSDP = rtpSession.CreateOffer(preferIPv6 ? IPAddress.IPv6Any : IPAddress.Any); // Create a client user agent to place a call to a remote SIP server along with event handlers for the different stages of the call. var uac = new SIPClientUserAgent(sipTransport); uac.CallTrying += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}."); uac.CallRinging += async(uac, resp) => { Log.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}."); if (resp.Status == SIPResponseStatusCodesEnum.SessionProgress) { if (resp.Body != null) { var result = rtpSession.SetRemoteDescription(SdpType.answer, SDP.ParseSDPDescription(resp.Body)); if (result == SetDescriptionResultEnum.OK) { await rtpSession.Start(); Log.LogInformation($"Remote SDP set from in progress response. RTP session started."); } } } }; uac.CallFailed += (uac, err, resp) => { Log.LogWarning($"Call attempt to {uac.CallDescriptor.To} Failed: {err}"); hasCallFailed = true; }; uac.CallAnswered += async(iuac, resp) => { if (resp.Status == SIPResponseStatusCodesEnum.Ok) { Log.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}."); if (resp.Body != null) { var result = rtpSession.SetRemoteDescription(SdpType.answer, SDP.ParseSDPDescription(resp.Body)); if (result == SetDescriptionResultEnum.OK) { await rtpSession.Start(); } else { Log.LogWarning($"Failed to set remote description {result}."); uac.Hangup(); } } else if (!rtpSession.IsStarted) { Log.LogWarning($"Failed to set get remote description in session progress or final response."); uac.Hangup(); } } else { Log.LogWarning($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}."); } }; // The only incoming request that needs to be explicitly handled for this example is if the remote end hangs up the call. sipTransport.SIPTransportRequestReceived += async(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPResponse okResponse = SIPResponse.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); await sipTransport.SendResponseAsync(okResponse); if (uac.IsUACAnswered) { Log.LogInformation("Call was hungup by remote server."); isCallHungup = true; exitMre.Set(); } } }; // Start the thread that places the call. SIPCallDescriptor callDescriptor = new SIPCallDescriptor( SIPConstants.SIP_DEFAULT_USERNAME, null, callUri.ToString(), SIPConstants.SIP_DEFAULT_FROMURI, callUri.CanonicalAddress, null, null, null, SIPCallDirection.Out, SDP.SDP_MIME_CONTENTTYPE, offerSDP.ToString(), null); uac.Call(callDescriptor, null); // Ctrl-c will gracefully exit the call at any point. Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; exitMre.Set(); }; // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed. exitMre.WaitOne(); Log.LogInformation("Exiting..."); rtpSession.Close(null); if (!isCallHungup && uac != null) { if (uac.IsUACAnswered) { Log.LogInformation($"Hanging up call to {uac.CallDescriptor.To}."); uac.Hangup(); } else if (!hasCallFailed) { Log.LogInformation($"Cancelling call to {uac.CallDescriptor.To}."); uac.Cancel(); } // Give the BYE or CANCEL request time to be transmitted. Log.LogInformation("Waiting 1s for call to clean up..."); Task.Delay(1000).Wait(); } if (sipTransport != null) { Log.LogInformation("Shutting down SIP transport..."); sipTransport.Shutdown(); } }