/// <summary> /// Adds a console logger. Can be omitted if internal SIPSorcery debug and warning messages are not required. /// </summary> private static void AddConsoleLogger() { var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; }
/// <summary> /// Wires up the dotnet logging infrastructure to STDOUT. /// </summary> private static void EnableConsoleLogger() { // Logging configuration. Can be omitted if internal SIPSorcery debug and warning messages are not required. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; }
/// <summary> /// Creates a LoggerFactory from the given log filename /// </summary> /// <param name="logFileName"></param> /// <returns></returns> private static LoggerFactory CreateLoggerFactory(string logFileName) { Log.Logger = new LoggerConfiguration() .WriteTo.File(logFileName, rollingInterval: RollingInterval.Month, outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}{NewLine}", restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Warning) .WriteTo.Console(outputTemplate: "{Message:lj}{NewLine}") .CreateLogger(); var factory = new LoggerFactory(); factory.AddSerilog(Log.Logger); return(factory); }
//private static Microsoft.Extensions.Logging.ILogger logger = SIPSorcery.Sys.Log.Logger; public static void InitTestLogger(ITestOutputHelper output) { var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(output, Serilog.Events.LogEventLevel.Verbose) .WriteTo.Console(Serilog.Events.LogEventLevel.Verbose) .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; //logger = SIPSorcery.Sys.Log.Logger; }
public DefaultLoggerFactory(IConfigAccessor configAccessor) { _loggingConfig = configAccessor.Get <LoggingConfig>(); _loggerFactory = new MSLoggerFactory(); var instrumentationConfig = configAccessor.Get <InstrumentationConfig>(); var level = EventLevel(_loggingConfig.Level); _loggerFactory.AddSerilog(new LoggerConfiguration().MinimumLevel.Verbose().Enrich .WithProperty("SourceContext", null).Enrich .WithProperty(nameof(instrumentationConfig.ServiceName), instrumentationConfig.ServiceName ?? instrumentationConfig.ApplicationCode).Enrich .FromLogContext().WriteTo.RollingFile(_loggingConfig.FilePath, level, outputTemplate, null, 1073741824, 31, null, false, false, TimeSpan.FromMilliseconds(500)).CreateLogger()); }
static void Main(string[] args) { var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() //.Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console(theme: AnsiConsoleTheme.Code) .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; logger = SIPSorcery.Sys.Log.Logger; var result = Parser.Default.ParseArguments <Options>(args) .WithParsed <Options>(opts => RunCommand(opts).Wait()); }
/// <summary> /// Enable detailed SIP log messages. /// </summary> private static void EnableTraceLogs(SIPTransport sipTransport) { // Logging configuration. Can be ommitted if internal SIPSorcery debug and warning messages are not required. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; sipTransport.SIPRequestInTraceEvent += (localEP, remoteEP, req) => { Log.LogDebug($"Request received: {localEP}<-{remoteEP}"); Log.LogDebug(req.ToString()); }; sipTransport.SIPRequestOutTraceEvent += (localEP, remoteEP, req) => { Log.LogDebug($"Request sent: {localEP}->{remoteEP}"); Log.LogDebug(req.ToString()); }; sipTransport.SIPResponseInTraceEvent += (localEP, remoteEP, resp) => { Log.LogDebug($"Response received: {localEP}<-{remoteEP}"); Log.LogDebug(resp.ToString()); }; sipTransport.SIPResponseOutTraceEvent += (localEP, remoteEP, resp) => { Log.LogDebug($"Response sent: {localEP}->{remoteEP}"); Log.LogDebug(resp.ToString()); }; sipTransport.SIPRequestRetransmitTraceEvent += (tx, req, count) => { Log.LogDebug($"Request retransmit {count} for request {req.StatusLine}, initial transmit {DateTime.Now.Subtract(tx.InitialTransmit).TotalSeconds.ToString("0.###")}s ago."); }; sipTransport.SIPResponseRetransmitTraceEvent += (tx, resp, count) => { Log.LogDebug($"Response retransmit {count} for response {resp.ShortDescription}, initial transmit {DateTime.Now.Subtract(tx.InitialTransmit).TotalSeconds.ToString("0.###")}s ago."); }; }
private void ThisAddIn_Startup(object sender, System.EventArgs e) { // attempt to make a global exception handler to avoid crashes // https://social.msdn.microsoft.com/Forums/vstudio/en-US/c37599d9-21e8-4c32-b00e-926f97c8f639/global-exception-handler-for-vs-2008-excel-addin?forum=vsto // https://stackoverflow.com/questions/12115030/catch-c-sharp-wpf-unhandled-exception-in-word-add-in-before-microsoft-displays-e // https://exceptionalcode.wordpress.com/2010/02/17/centralizing-vsto-add-in-exception-management-with-postsharp/ // https://www.add-in-express.com/forum/read.php?FID=5&TID=12667 RegisterToExceptionEvents(); var myUserControl1 = new ucApiCredentials(); apiCredentialsTaskPane = this.CustomTaskPanes.Add(myUserControl1, "API Credentials"); apiCredentialsTaskPane.VisibleChanged += new EventHandler(myCustomTaskPane_VisibleChanged); // instantiate and configure logging. Using serilog here, to log to console and a text-file. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() #pragma warning disable S1075 // URIs should not be hardcoded .WriteTo.File("c:\\temp\\logs\\myapp.txt", rollingInterval: RollingInterval.Day) #pragma warning restore S1075 // URIs should not be hardcoded .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); // create logger and put it to work. var logProvider = loggerFactory.CreateLogger <ThisAddIn>(); logProvider.LogDebug("debiggung"); Logger = logProvider; // Configure PostSharp Logging to use Serilog LoggingServices.DefaultBackend = new MicrosoftLoggingBackend(loggerFactory); Globals.ThisAddIn.ApiUrl = Settings.Default?.ApiUrl; Globals.ThisAddIn.ApiUsername = Settings.Default?.ApiUsername; Globals.ThisAddIn.OWAUrl = Settings.Default?.OWAUrl; Globals.ThisAddIn.OWAUsername = Settings.Default?.OWAUsername; this.Application.WorkbookActivate += Application_WorkbookActivate; this.Application.WorkbookOpen += Application_WorkbookOpen; }
static void Main(string[] args) { Console.WriteLine("SIPSorcery registration user agent example."); Console.WriteLine("Press ctrl-c to exit."); // Logging configuration. Can be ommitted if internal SIPSorcery debug and warning messages are not required. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; // If your default DNS server supports SRV records there is no need to set a specific DNS server. DNSManager.SetDNSServers(new List <IPEndPoint> { IPEndPoint.Parse("8.8.8.8:53") }); // Set up a default SIP transport. var sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); int port = FreePort.FindNextAvailableUDPPort(SIPConstants.DEFAULT_SIP_PORT); var sipChannel = new SIPUDPChannel(new IPEndPoint(LocalIPConfig.GetDefaultIPv4Address(), port)); sipTransport.AddSIPChannel(sipChannel); // Create a client user agent to maintain a periodic registration with a SIP server. var regUserAgent = new SIPRegistrationUserAgent( sipTransport, "softphonesample", "password", "sipsorcery.com"); // Event handlers for the different stages of the registration. regUserAgent.RegistrationFailed += (uri, err) => SIPSorcery.Sys.Log.Logger.LogError($"{uri.ToString()}: {err}"); regUserAgent.RegistrationTemporaryFailure += (uri, msg) => SIPSorcery.Sys.Log.Logger.LogWarning($"{uri.ToString()}: {msg}"); regUserAgent.RegistrationRemoved += (uri) => SIPSorcery.Sys.Log.Logger.LogError($"{uri.ToString()} registration failed."); regUserAgent.RegistrationSuccessful += (uri) => SIPSorcery.Sys.Log.Logger.LogInformation($"{uri.ToString()} registration succeeded."); // Start the thread to perform the initial registration and then periodically resend it. regUserAgent.Start(); }
public static IUnityContainer ConfigureLogging(this IUnityContainer container) { // instantiate and configure logging. Using serilog here, to log to console and a text-file. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .WriteTo.Console() //.WriteTo.File("logs\\myapp.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); // create logger and put it to work. var logProvider = loggerFactory.CreateLogger("DotNetCoreWCF.Host"); container.RegisterInstance <ILoggerFactory>(loggerFactory); container.RegisterInstance <Microsoft.Extensions.Logging.ILogger>(logProvider); return(container); }
public static IServiceCollection ConfigureLogging(this IServiceCollection services) { // instantiate and configure logging. Using serilog here, to log to console and a text-file. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .WriteTo.Console() //.WriteTo.File("logs\\myapp.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); // create logger and put it to work. var logProvider = loggerFactory.CreateLogger("DotNetCoreWCF.Client"); services.AddSingleton <ILoggerFactory>(loggerFactory); services.AddSingleton <Microsoft.Extensions.Logging.ILogger>(logProvider); return(services); }
protected void Application_Start() { var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); Log.Logger = new Serilog.LoggerConfiguration() .Enrich.WithHttpRequestId() .Enrich.WithHttpRequestType() .Enrich.WithHttpRequestRawUrl() .Enrich.WithMachineName() .Enrich.WithProperty("CPU", Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER")) .WriteTo.File(Server.MapPath("~/App_Data/logs.txt")) .WriteTo.Seq("http://localhost:5341") .MinimumLevel.Debug() .CreateLogger(); loggerFactory.AddSerilog(Log.Logger); // create logger and put it to work. var logProvider = loggerFactory.CreateLogger <MvcApplication>(); logProvider.LogInformation("Hi Serilog!"); var container = new Container { Options = { DefaultScopedLifestyle = new WebRequestLifestyle() } }; container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); // register logger factory and generic logger container.RegisterInstance <ILoggerFactory>(loggerFactory); container.RegisterSingleton(typeof(ILogger <>), typeof(Logger <>)); container.Verify(); DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
private const int SUCCESS_REGISTRATION_COUNT = 3; // Number of successful registrations to attempt before exiting process. static void Main(string[] args) { Console.WriteLine("SIPSorcery registration user agent example."); Console.WriteLine("Press ctrl-c to exit."); // Logging configuration. Can be ommitted if internal SIPSorcery debug and warning messages are not required. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; // Set up a default SIP transport. var sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); int port = FreePort.FindNextAvailableUDPPort(SIPConstants.DEFAULT_SIP_PORT); var sipChannel = new SIPUDPChannel(new IPEndPoint(LocalIPConfig.GetDefaultIPv4Address(), port)); sipTransport.AddSIPChannel(sipChannel); // Create a client user agent to maintain a periodic registration with a SIP server. var regUserAgent = new SIPRegistrationUserAgent( sipTransport, "softphonesample", "password", "sipsorcery.com", 120); int successCounter = 0; ManualResetEvent taskCompleteMre = new ManualResetEvent(false); // Event handlers for the different stages of the registration. regUserAgent.RegistrationFailed += (uri, err) => SIPSorcery.Sys.Log.Logger.LogError($"{uri.ToString()}: {err}"); regUserAgent.RegistrationTemporaryFailure += (uri, msg) => SIPSorcery.Sys.Log.Logger.LogWarning($"{uri.ToString()}: {msg}"); regUserAgent.RegistrationRemoved += (uri) => SIPSorcery.Sys.Log.Logger.LogError($"{uri.ToString()} registration failed."); regUserAgent.RegistrationSuccessful += (uri) => { SIPSorcery.Sys.Log.Logger.LogInformation($"{uri.ToString()} registration succeeded."); Interlocked.Increment(ref successCounter); SIPSorcery.Sys.Log.Logger.LogInformation($"Successful registrations {successCounter} of {SUCCESS_REGISTRATION_COUNT}."); if (successCounter == SUCCESS_REGISTRATION_COUNT) { taskCompleteMre.Set(); } }; Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; SIPSorcery.Sys.Log.Logger.LogInformation("Exiting..."); taskCompleteMre.Set(); }; // Start the thread to perform the initial registration and then periodically resend it. regUserAgent.Start(); taskCompleteMre.WaitOne(); regUserAgent.Stop(); if (sipTransport != null) { SIPSorcery.Sys.Log.Logger.LogInformation("Shutting down SIP transport..."); sipTransport.Shutdown(); } SIPSorcery.Net.DNSManager.Stop(); }
static void Main() { Console.WriteLine("SIPSorcery client user agent server example."); Console.WriteLine("Press ctrl-c to exit."); // Logging configuration. Can be ommitted if internal SIPSorcery debug and warning messages are not required. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; // Set up a default SIP transport. var sipTransport = new SIPTransport(); sipTransport.ContactHost = Dns.GetHostName(); 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))); //sipTransport.AddSIPChannel(new SIPTCPChannel(new IPEndPoint(IPAddress.IPv6Any, SIP_LISTEN_PORT))); //if (File.Exists("localhost.pfx")) //{ // var certificate = new X509Certificate2(@"localhost.pfx", ""); // sipTransport.AddSIPChannel(new SIPTLSChannel(certificate, new IPEndPoint(IPAddress.Any, SIPS_LISTEN_PORT))); // sipTransport.AddSIPChannel(new SIPTLSChannel(certificate, new IPEndPoint(IPAddress.IPv6Any, SIPS_LISTEN_PORT))); //} //EnableTraceLogs(sipTransport); // To keep things a bit simpler this example only supports a single call at a time and the SIP server user agent // acts as a singleton SIPServerUserAgent uas = null; CancellationTokenSource rtpCts = null; // Cancellation token to stop the RTP stream. // Because this is a server user agent the SIP transport must start listening for client user agents. sipTransport.SIPTransportRequestReceived += async(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { if (sipRequest.Method == SIPMethodsEnum.INVITE) { SIPSorcery.Sys.Log.Logger.LogInformation("Incoming call request: " + localSIPEndPoint + "<-" + remoteEndPoint + " " + sipRequest.URI.ToString() + "."); //SIPSorcery.Sys.Log.Logger.LogDebug(sipRequest.ToString()); // If there's already a call in progress hang it up. Of course this is not ideal for a real softphone or server but it // means this example can be kept simpler. if (uas?.IsHungup == false) { uas?.Hangup(false); } rtpCts?.Cancel(); UASInviteTransaction uasTransaction = sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); uas = new SIPServerUserAgent(sipTransport, null, null, null, SIPCallDirection.In, null, null, null, uasTransaction); rtpCts = new CancellationTokenSource(); // In practice there could be a number of reasons to reject the call. Unsupported extensions, mo matching codecs etc. etc. if (sipRequest.Header.HasUnknownRequireExtension) { // The caller requires an extension that we don't support. SIPSorcery.Sys.Log.Logger.LogWarning($"Rejecting incoming call due to one or more required exensions not being supported, required extensions: {sipRequest.Header.Require}."); uas.Reject(SIPResponseStatusCodesEnum.NotImplemented, "Unsupported Require Extension", null); } else { uas.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null); uas.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null); // Simulating answer delay to test provisional response retransmits. await Task.Delay(2000); // Initialise an RTP session to receive the RTP packets from the remote SIP server. Socket rtpSocket = null; Socket controlSocket = null; NetServices.CreateRtpSocket(localSIPEndPoint.Address, 49000, 49100, false, out rtpSocket, out controlSocket); IPEndPoint rtpEndPoint = rtpSocket.LocalEndPoint as IPEndPoint; IPEndPoint dstRtpEndPoint = SDP.GetSDPRTPEndPoint(sipRequest.Body); var rtpSession = new RTPSession((int)RTPPayloadTypesEnum.PCMU, null, null); var rtpTask = Task.Run(() => SendRecvRtp(rtpSocket, rtpSession, dstRtpEndPoint, AUDIO_FILE, rtpCts)) .ContinueWith(_ => { if (uas?.IsHungup == false) { uas?.Hangup(false); } }); uas.Answer(SDP.SDP_MIME_CONTENTTYPE, GetSDP(rtpEndPoint).ToString(), null, SIPDialogueTransferModesEnum.NotAllowed); } } else if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPSorcery.Sys.Log.Logger.LogInformation("Call hungup."); SIPNonInviteTransaction byeTransaction = sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse byeResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendFinalResponse(byeResponse); uas?.Hangup(true); rtpCts?.Cancel(); } else if (sipRequest.Method == SIPMethodsEnum.OPTIONS) { try { SIPSorcery.Sys.Log.Logger.LogInformation($"{localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipRequest.StatusLine}"); //SIPSorcery.Sys.Log.Logger.LogDebug(sipRequest.ToString()); SIPResponse optionsResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); sipTransport.SendResponse(optionsResponse); } catch (Exception optionsExcp) { SIPSorcery.Sys.Log.Logger.LogWarning($"Failed to send SIP OPTIONS response. {optionsExcp.Message}"); } } }; Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; SIPSorcery.Sys.Log.Logger.LogInformation("Exiting..."); rtpCts?.Cancel(); if (uas?.IsHungup == false) { uas?.Hangup(false); // Give the BYE or CANCEL request time to be transmitted. SIPSorcery.Sys.Log.Logger.LogInformation("Waiting 1s for call to hangup..."); Task.Delay(1000).Wait(); } if (sipTransport != null) { SIPSorcery.Sys.Log.Logger.LogInformation("Shutting down 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. CancellationTokenSource rtpCts = new CancellationTokenSource(); // Cancellation token to stop the RTP stream. bool isCallHungup = false; bool hasCallFailed = false; // Logging configuration. Can be ommitted if internal SIPSorcery debug and warning messages are not required. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; SIPURI callUri = SIPURI.ParseSIPURI(DEFAULT_DESTINATION_SIP_URI); if (args != null && args.Length > 0) { if (!SIPURI.TryParse(args[0])) { Log.LogWarning($"Command line argument could not be parsed as a SIP URI {args[0]}"); } else { callUri = SIPURI.ParseSIPURIRelaxed(args[0]); } } Log.LogInformation($"Call destination {callUri}."); // Set up a default SIP transport. var sipTransport = new SIPTransport(); int port = SIPConstants.DEFAULT_SIP_PORT + 1000; IPAddress localAddress = sipTransport.GetLocalAddress(IPAddress.Parse("8.8.8.8")); sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(localAddress, port))); //sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.Any, port))); //sipTransport.AddSIPChannel(new SIPUDPChannel(new IPEndPoint(IPAddress.IPv6Any, port))); //EnableTraceLogs(sipTransport); // Select the IP address to use for RTP based on the destination SIP URI. var endPointForCall = callUri.ToSIPEndPoint() == null?sipTransport.GetDefaultSIPEndPoint(callUri.Protocol) : sipTransport.GetDefaultSIPEndPoint(callUri.ToSIPEndPoint()); // Initialise an RTP session to receive the RTP packets from the remote SIP server. Socket rtpSocket = null; Socket controlSocket = null; // TODO (find something better): If the SIP endpoint is using 0.0.0.0 for SIP use loopback for RTP. IPAddress rtpAddress = localAddress; NetServices.CreateRtpSocket(rtpAddress, 49000, 49100, false, out rtpSocket, out controlSocket); var rtpSendSession = new RTPSession((int)RTPPayloadTypesEnum.PCMU, null, null); // 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 += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}."); uac.CallFailed += (uac, err) => { Log.LogWarning($"{uac.CallDescriptor.To} Failed: {err}"); hasCallFailed = true; }; uac.CallAnswered += (uac, resp) => { if (resp.Status == SIPResponseStatusCodesEnum.Ok) { Log.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}."); IPEndPoint remoteRtpEndPoint = SDP.GetSDPRTPEndPoint(resp.Body); Log.LogDebug($"Sending initial RTP packet to remote RTP socket {remoteRtpEndPoint}."); // Send a dummy packet to open the NAT session on the RTP path. rtpSendSession.SendAudioFrame(rtpSocket, remoteRtpEndPoint, 0, new byte[] { 0x00 }); } 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 += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPNonInviteTransaction byeTransaction = sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse byeResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendFinalResponse(byeResponse); if (uac.IsUACAnswered) { Log.LogInformation("Call was hungup by remote server."); isCallHungup = true; rtpCts.Cancel(); } } }; // It's a good idea to start the RTP receiving socket before the call request is sent. // A SIP server will generally start sending RTP as soon as it has processed the incoming call request and // being ready to receive will stop any ICMP error response being generated. Task.Run(() => SendRecvRtp(rtpSocket, rtpSendSession, rtpCts)); // Start the thread that places the call. SIPCallDescriptor callDescriptor = new SIPCallDescriptor( SIPConstants.SIP_DEFAULT_USERNAME, null, callUri.ToString(), SIPConstants.SIP_DEFAULT_FROMURI, null, null, null, null, SIPCallDirection.Out, SDP.SDP_MIME_CONTENTTYPE, GetSDP(rtpSocket.LocalEndPoint as IPEndPoint).ToString(), null); uac.Call(callDescriptor); // Ctrl-c will gracefully exit the call at any point. Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; rtpCts.Cancel(); }; // At this point the call has been initiated and everything will be handled in an event handler or on the RTP // receive task. The code below is to gracefully exit. // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed. rtpCts.Token.WaitHandle.WaitOne(); Log.LogInformation("Exiting..."); rtpSocket?.Close(); controlSocket?.Close(); 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(); } SIPSorcery.Net.DNSManager.Stop(); if (sipTransport != null) { Log.LogInformation("Shutting down SIP transport..."); sipTransport.Shutdown(); } }
private static readonly int RTP_REPORTING_PERIOD_SECONDS = 5; // Period at which to write RTP stats. static void Main() { Console.WriteLine("SIPSorcery client user agent example."); Console.WriteLine("Press ctrl-c to exit."); // Plumbing code to facilitate a graceful exit. CancellationTokenSource cts = new CancellationTokenSource(); bool isCallHungup = false; bool hasCallFailed = false; // Logging configuration. Can be ommitted if internal SIPSorcery debug and warning messages are not required. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; // Set up a default SIP transport. IPAddress defaultAddr = LocalIPConfig.GetDefaultIPv4Address(); var sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); int port = FreePort.FindNextAvailableUDPPort(SIPConstants.DEFAULT_SIP_PORT + 2); var sipChannel = new SIPUDPChannel(new IPEndPoint(defaultAddr, port)); sipTransport.AddSIPChannel(sipChannel); // Initialise an RTP session to receive the RTP packets from the remote SIP server. Socket rtpSocket = null; Socket controlSocket = null; NetServices.CreateRtpSocket(defaultAddr, 49000, 49100, false, out rtpSocket, out controlSocket); var rtpSendSession = new RTPSession((int)RTPPayloadTypesEnum.PCMU, null, null); // 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) => SIPSorcery.Sys.Log.Logger.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}."); uac.CallRinging += (uac, resp) => SIPSorcery.Sys.Log.Logger.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}."); uac.CallFailed += (uac, err) => { SIPSorcery.Sys.Log.Logger.LogWarning($"{uac.CallDescriptor.To} Failed: {err}"); hasCallFailed = true; }; uac.CallAnswered += (uac, resp) => { if (resp.Status == SIPResponseStatusCodesEnum.Ok) { SIPSorcery.Sys.Log.Logger.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}."); IPEndPoint remoteRtpEndPoint = SDP.GetSDPRTPEndPoint(resp.Body); SIPSorcery.Sys.Log.Logger.LogDebug($"Sending initial RTP packet to remote RTP socket {remoteRtpEndPoint}."); // Send a dummy packet to open the NAT session on the RTP path. rtpSendSession.SendAudioFrame(rtpSocket, remoteRtpEndPoint, 0, new byte[] { 0x00 }); } else { SIPSorcery.Sys.Log.Logger.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 += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPNonInviteTransaction byeTransaction = sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse byeResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendFinalResponse(byeResponse); if (uac.IsUACAnswered) { SIPSorcery.Sys.Log.Logger.LogInformation("Call was hungup by remote server."); isCallHungup = true; cts.Cancel(); } } }; // It's a good idea to start the RTP receiving socket before the call request is sent. // A SIP server will generally start sending RTP as soon as it has processed the incoming call request and // being ready to receive will stop any ICMP error response being generated. Task.Run(() => SendRecvRtp(rtpSocket, rtpSendSession, cts)); // Start the thread that places the call. SIPCallDescriptor callDescriptor = new SIPCallDescriptor( SIPConstants.SIP_DEFAULT_USERNAME, null, DESTINATION_SIP_URI, SIPConstants.SIP_DEFAULT_FROMURI, null, null, null, null, SIPCallDirection.Out, SDP.SDP_MIME_CONTENTTYPE, GetSDP(rtpSocket.LocalEndPoint as IPEndPoint).ToString(), null); uac.Call(callDescriptor); // At this point the call has been initiated and everything will be handled in an event handler or on the RTP // receive task. The code below is to gracefully exit. // Ctrl-c will gracefully exit the call at any point. Console.CancelKeyPress += async delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; cts.Cancel(); SIPSorcery.Sys.Log.Logger.LogInformation("Exiting..."); rtpSocket?.Close(); controlSocket?.Close(); if (!isCallHungup && uac != null) { if (uac.IsUACAnswered) { SIPSorcery.Sys.Log.Logger.LogInformation($"Hanging up call to {uac.CallDescriptor.To}."); uac.Hangup(); } else if (!hasCallFailed) { SIPSorcery.Sys.Log.Logger.LogInformation($"Cancelling call to {uac.CallDescriptor.To}."); uac.Cancel(); } // Give the BYE or CANCEL request time to be transmitted. SIPSorcery.Sys.Log.Logger.LogInformation("Waiting 1s for call to clean up..."); await Task.Delay(1000); } SIPSorcery.Net.DNSManager.Stop(); if (sipTransport != null) { SIPSorcery.Sys.Log.Logger.LogInformation("Shutting down SIP transport..."); sipTransport.Shutdown(); } }; }
private static readonly int RTP_REPORTING_PERIOD_SECONDS = 5; // Period at which to write RTP stats. static void Main() { Console.WriteLine("SIPSorcery client user agent server example."); Console.WriteLine("Press ctrl-c to exit."); // Logging configuration. Can be ommitted if internal SIPSorcery debug and warning messages are not required. var loggerFactory = new Microsoft.Extensions.Logging.LoggerFactory(); var loggerConfig = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); loggerFactory.AddSerilog(loggerConfig); SIPSorcery.Sys.Log.LoggerFactory = loggerFactory; // Set up a default SIP transport. IPAddress defaultAddr = LocalIPConfig.GetDefaultIPv4Address(); var sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); int port = FreePort.FindNextAvailableUDPPort(SIPConstants.DEFAULT_SIP_PORT); var sipChannel = new SIPUDPChannel(new IPEndPoint(defaultAddr, port)); sipTransport.AddSIPChannel(sipChannel); // To keep things a bit simpler this example only supports a single call at a time and the SIP server user agent // acts as a singleton SIPServerUserAgent uas = null; CancellationTokenSource uasCts = null; // Because this is a server user agent the SIP transport must start listening for client user agents. sipTransport.SIPTransportRequestReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { if (sipRequest.Method == SIPMethodsEnum.INVITE) { SIPSorcery.Sys.Log.Logger.LogInformation("Incoming call request: " + localSIPEndPoint + "<-" + remoteEndPoint + " " + sipRequest.URI.ToString() + "."); // If there's already a call in progress hang it up. Of course this is not ideal for a real softphone or server but it // means this example can be kept a little it simpler. uas?.Hangup(); UASInviteTransaction uasTransaction = sipTransport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); uas = new SIPServerUserAgent(sipTransport, null, null, null, SIPCallDirection.In, null, null, null, uasTransaction); uasCts = new CancellationTokenSource(); uas.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null); uas.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null); // Initialise an RTP session to receive the RTP packets from the remote SIP server. Socket rtpSocket = null; Socket controlSocket = null; NetServices.CreateRtpSocket(defaultAddr, 49000, 49100, false, out rtpSocket, out controlSocket); IPEndPoint rtpEndPoint = rtpSocket.LocalEndPoint as IPEndPoint; IPEndPoint dstRtpEndPoint = SDP.GetSDPRTPEndPoint(sipRequest.Body); var rtpSession = new RTPSession((int)RTPPayloadTypesEnum.PCMU, null, null); var rtpTask = Task.Run(() => SendRecvRtp(rtpSocket, rtpSession, dstRtpEndPoint, AUDIO_FILE, uasCts)) .ContinueWith(_ => { if (uas?.IsHungup == false) { uas?.Hangup(); } }); uas.Answer(SDP.SDP_MIME_CONTENTTYPE, GetSDP(rtpEndPoint).ToString(), null, SIPDialogueTransferModesEnum.NotAllowed); } else if (sipRequest.Method == SIPMethodsEnum.BYE) { SIPSorcery.Sys.Log.Logger.LogInformation("Call hungup."); SIPNonInviteTransaction byeTransaction = sipTransport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null); SIPResponse byeResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); byeTransaction.SendFinalResponse(byeResponse); uas?.Hangup(); uasCts?.Cancel(); } }; Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; SIPSorcery.Sys.Log.Logger.LogInformation("Exiting..."); if (uas?.IsHungup == false) { uas?.Hangup(); } uasCts?.Cancel(); if (sipTransport != null) { SIPSorcery.Sys.Log.Logger.LogInformation("Shutting down SIP transport..."); sipTransport.Shutdown(); } }; }