void ISipPresenceService.Configure(IDataService dataService, Action <DataConfig, Exception> callback) { _dataService = dataService; _dataService.GetData((cfg, error) => { if (error != null) { callback?.Invoke(null, error); return; } ListenIp = cfg.ListenIp; ListenPort = cfg.ListenPort; SipHelper.IsUserOpen = (s) => { foreach (var user in cfg.LastUsers) { if (s.ResourceURI.ToString().Contains(user.Id)) { return(SIPEventPresenceStateEnum.open); } } return(SIPEventPresenceStateEnum.closed); }; var sipChannel = new SIPUDPChannel(new IPEndPoint(IPAddress.Parse(ListenIp), ListenPort)); _sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); _sipTransport.AddSIPChannel(sipChannel); _sipTransport.SIPTransportRequestReceived += SIPTransportRequestReceived; _sipTransport.SIPTransportResponseReceived += SIPTransportResponseReceived; m_sip_notifier = new SipPresenceSubscriptionManager(_sipTransport); m_sip_notifier.InternalEvent += (e, m) => { switch (e) { case SipPresenceSubscriptionManager.SipNotifierEvents.Error: _logger.Error(m); break; case SipPresenceSubscriptionManager.SipNotifierEvents.Info: _logger.Info(m); break; case SipPresenceSubscriptionManager.SipNotifierEvents.Notify: break; case SipPresenceSubscriptionManager.SipNotifierEvents.Subscribe: case SipPresenceSubscriptionManager.SipNotifierEvents.Unsubscribe: SubscribeReceived?.Invoke(m); break; } }; callback?.Invoke(cfg, null); }); }
public void Init() { var port = FreePort.FindNextAvailableUDPPort(15090); transport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); publicIPAddress = STUNClient.GetPublicIPAddress("stun.ekiga.net"); localIPEndPoint = IpAddressLookup.QueryRoutingInterface(asterisk, port); var endpoint = new IPEndPoint(localIPEndPoint.Address, port); var channel = new SIPUDPChannel(endpoint); transport.AddSIPChannel(channel); transport.SIPTransportRequestReceived += Transport_SIPTransportRequestReceived; //var registration = new SIPRegistrationUserAgent( // transport, // null, // new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, port), // new SIPURI("1003", asterisk, null, SIPSchemesEnum.sip, SIPProtocolsEnum.udp), // "1003", // passwords[0], // null, // asterisk, // new SIPURI(SIPSchemesEnum.sip, new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, port)), // 180, // null, // null, // (e) => { logger.Debug($"{ prefix } SIPRegistrationUserAgent; { e.Message }"); } // ); //registration.RegistrationSuccessful += Registration_RegistrationSuccessful; //registration.RegistrationFailed += Registration_RegistrationFailed; //registration.Start(); }
static void Main(string[] args) { try { if (args == null || args.Count() == 0) { Console.WriteLine(USAGE_STRING); } else { bool validArgs = ParseArgs(args); if (validArgs) { Console.WriteLine("XMPP Test Console:"); m_sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); SIPUDPChannel udpChannel = new SIPUDPChannel(new IPEndPoint(m_ipAddress, m_port)); m_sipTransport.AddSIPChannel(udpChannel); m_sipTransport.SIPTransportRequestReceived += SIPTransportRequestReceived; Console.WriteLine("Waiting for SIP INVITE..."); ManualResetEvent mre = new ManualResetEvent(false); mre.WaitOne(); } } } catch (Exception excp) { Console.WriteLine("Exception Main. " + excp.Message); } }
private static Dictionary <string, SIPAccountBinding> _sipRegistrations = new Dictionary <string, SIPAccountBinding>(); // [SIP Username, Binding], tracks SIP clients that have registered with the server. static void Main() { try { Console.WriteLine("SIPSorcery SIP Proxy Demo"); AddConsoleLogger(); // Configure the SIP transport layer. _sipTransport = new SIPTransport(); // Use default options to set up a SIP channel. var sipChannel = new SIPUDPChannel(new IPEndPoint(IPAddress.Any, _listenPort)); _sipTransport.AddSIPChannel(sipChannel); // Wire up the transport layer so SIP requests and responses have somewhere to go. _sipTransport.SIPTransportRequestReceived += SIPTransportRequestReceived; _sipTransport.SIPTransportResponseReceived += SIPTransportResponseReceived; // If you want to see ALL the nitty gritty SIP traffic wire up the events below. //_sipTransport.SIPBadRequestInTraceEvent += SIPBadRequestInTraceEvent; //_sipTransport.SIPBadResponseInTraceEvent += SIPBadResponseInTraceEvent; _sipTransport.SIPRequestInTraceEvent += SIPRequestInTraceEvent; //_sipTransport.SIPRequestOutTraceEvent += SIPRequestOutTraceEvent; //_sipTransport.SIPResponseInTraceEvent += SIPResponseInTraceEvent; _sipTransport.SIPResponseOutTraceEvent += SIPResponseOutTraceEvent; ManualResetEvent mre = new ManualResetEvent(false); mre.WaitOne(); } catch (Exception excp) { Console.WriteLine("Exception Main. " + excp); } }
static void Main() { Console.WriteLine("SIPSorcery Getting Started Demo"); var sipTransport = new SIPTransport(); var sipChannel = new SIPUDPChannel(IPAddress.Loopback, 5060); sipTransport.AddSIPChannel(sipChannel); sipTransport.SIPTransportRequestReceived += (SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest) => { Console.WriteLine($"Request received {localSIPEndPoint.ToString()}<-{remoteEndPoint.ToString()}: {sipRequest.StatusLine}"); if (sipRequest.Method == SIPMethodsEnum.OPTIONS) { SIPResponse optionsResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); sipTransport.SendResponse(optionsResponse); } }; Console.Write("press any key to exit..."); Console.Read(); sipTransport.Shutdown(); }
/// <summary> /// Initialises the SIP transport layer. /// </summary> private void InitialiseSIP() { // Configure the SIP transport layer. m_sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); if (m_sipSocketsNode != null) { // Set up the SIP channels based on the app.config file. List <SIPChannel> sipChannels = SIPTransportConfig.ParseSIPChannelsNode(m_sipSocketsNode); m_sipTransport.AddSIPChannel(sipChannels); } else { // Use default options to set up a SIP channel. int port = FreePort.FindNextAvailableUDPPort(_defaultSIPUdpPort); var sipChannel = new SIPUDPChannel(new IPEndPoint(_defaultLocalAddress, port)); m_sipTransport.AddSIPChannel(sipChannel); } // Wire up the transport layer so incoming SIP requests have somewhere to go. m_sipTransport.SIPTransportRequestReceived += SIPTransportRequestReceived; // Log all SIP packets received to a log file. m_sipTransport.SIPRequestInTraceEvent += (localSIPEndPoint, endPoint, sipRequest) => { _sipTraceLogger.Debug("Request Received : " + localSIPEndPoint + "<-" + endPoint + "\r\n" + sipRequest.ToString()); }; m_sipTransport.SIPRequestOutTraceEvent += (localSIPEndPoint, endPoint, sipRequest) => { _sipTraceLogger.Debug("Request Sent: " + localSIPEndPoint + "->" + endPoint + "\r\n" + sipRequest.ToString()); }; m_sipTransport.SIPResponseInTraceEvent += (localSIPEndPoint, endPoint, sipResponse) => { _sipTraceLogger.Debug("Response Received: " + localSIPEndPoint + "<-" + endPoint + "\r\n" + sipResponse.ToString()); }; m_sipTransport.SIPResponseOutTraceEvent += (localSIPEndPoint, endPoint, sipResponse) => { _sipTraceLogger.Debug("Response Sent: " + localSIPEndPoint + "->" + endPoint + "\r\n" + sipResponse.ToString()); }; }
public void IPv4LoopbackSendReceiveTest() { logger.LogDebug("IPv4LoopbackSendReceiveTest commencing..."); CancellationTokenSource cancelServer = new CancellationTokenSource(); TaskCompletionSource <bool> testComplete = new TaskCompletionSource <bool>(); var serverChannel = new SIPUDPChannel(IPAddress.Loopback, 6060); var clientChannel = new SIPUDPChannel(IPAddress.Loopback, 6061); var serverTask = Task.Run(() => { RunServer(serverChannel, cancelServer); }); var clientTask = Task.Run(async() => { await RunClient(clientChannel, serverChannel.GetContactURI(SIPSchemesEnum.sip, IPAddress.Loopback), testComplete); }); Task.WhenAny(new Task[] { serverTask, clientTask, Task.Delay(TRANSPORT_TEST_TIMEOUT) }).Wait(); if (testComplete.Task.IsCompleted == false) { // The client did not set the completed signal. This means the delay task must have completed and hence the test failed. testComplete.SetResult(false); } Assert.True(testComplete.Task.Result); cancelServer.Cancel(); logger.LogDebug("Test complete."); }
static void Main(string[] args) { try { // Configure the SIP transport layer. _sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); // Use default options to set up a SIP channel. var localIP = LocalIPConfig.GetDefaultIPv4Address(); // Set this manually if needed. int port = FreePort.FindNextAvailableUDPPort(_defaultSIPUdpPort); var sipChannel = new SIPUDPChannel(new IPEndPoint(localIP, port)); _sipTransport.AddSIPChannel(sipChannel); SIPCallDescriptor callDescriptor = new SIPCallDescriptor("test", null, "sip:[email protected]", "sip:[email protected]", null, null, null, null, SIPCallDirection.Out, null, null, null); SIPNonInviteClientUserAgent notifyUac = new SIPNonInviteClientUserAgent(_sipTransport, null, callDescriptor, null, null, (monitorEvent) => { Console.WriteLine("Debug: " + monitorEvent.Message); }); notifyUac.ResponseReceived += (resp) => { Console.WriteLine(resp.ToString()); }; notifyUac.SendRequest(SIPMethodsEnum.NOTIFY); ManualResetEvent mre = new ManualResetEvent(false); mre.WaitOne(); } catch (Exception excp) { Console.WriteLine("Exception Main. " + excp); } finally { Console.WriteLine("Press any key to exit..."); Console.ReadLine(); } }
/// <summary> /// Initialises the SIP transport layer. /// </summary> public async Task InitialiseSIP() { if (_isInitialised == false) { await Task.Run(() => { _isInitialised = true; // Configure the SIP transport layer. SIPTransport = new SIPTransport(); bool sipChannelAdded = false; if (m_sipSocketsNode != null) { // Set up the SIP channels based on the app.config file. List <SIPChannel> sipChannels = SIPTransportConfig.ParseSIPChannelsNode(m_sipSocketsNode); if (sipChannels?.Count > 0) { SIPTransport.AddSIPChannel(sipChannels); sipChannelAdded = true; } } if (sipChannelAdded == false) { // Use default options to set up a SIP channel. SIPUDPChannel udpChannel = null; try { udpChannel = new SIPUDPChannel(new IPEndPoint(IPAddress.Any, SIP_DEFAULT_PORT)); } catch (SocketException bindExcp) { logger.LogWarning($"Socket exception attempting to bind UDP channel to port {SIP_DEFAULT_PORT}, will use random port. {bindExcp.Message}."); udpChannel = new SIPUDPChannel(new IPEndPoint(IPAddress.Any, 0)); } var tcpChannel = new SIPTCPChannel(new IPEndPoint(IPAddress.Any, udpChannel.Port)); SIPTransport.AddSIPChannel(new List <SIPChannel> { udpChannel, tcpChannel }); } }); // Wire up the transport layer so incoming SIP requests have somewhere to go. SIPTransport.SIPTransportRequestReceived += SIPTransportRequestReceived; // Log all SIP packets received to a log file. SIPTransport.SIPRequestInTraceEvent += SIPRequestInTraceEvent; SIPTransport.SIPRequestOutTraceEvent += SIPRequestOutTraceEvent; SIPTransport.SIPResponseInTraceEvent += SIPResponseInTraceEvent; SIPTransport.SIPResponseOutTraceEvent += SIPResponseOutTraceEvent; } }
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 void CreateChannelUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); var udpChan = new SIPUDPChannel(IPAddress.Any, 0); logger.LogDebug($"Listening end point {udpChan.ListeningSIPEndPoint}."); udpChan.Close(); logger.LogDebug("-----------------------------------------"); }
public async void InterChannelCommsUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); var udpChan1 = new SIPUDPChannel(IPAddress.Any, 0); logger.LogDebug($"Listening end point {udpChan1.ListeningSIPEndPoint}."); var udpChan2 = new SIPUDPChannel(IPAddress.Any, 0); logger.LogDebug($"Listening end point {udpChan2.ListeningSIPEndPoint}."); TaskCompletionSource <bool> gotMessage = new TaskCompletionSource <bool>(); SIPEndPoint receivedFromEP = null; SIPEndPoint receivedOnEP = null; udpChan2.SIPMessageReceived = (SIPChannel sipChannel, SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, byte[] buffer) => { logger.LogDebug($"SIP message received from {remoteEndPoint}."); logger.LogDebug($"SIP message received on {localSIPEndPoint}."); logger.LogDebug(Encoding.UTF8.GetString(buffer)); receivedFromEP = remoteEndPoint; receivedOnEP = localSIPEndPoint; gotMessage.SetResult(true); return(Task.CompletedTask); }; var dstEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, IPAddress.Loopback, udpChan2.Port); var optionsReq = SIPRequest.GetRequest(SIPMethodsEnum.OPTIONS, new SIPURI(SIPSchemesEnum.sip, dstEndPoint)); logger.LogDebug($"Attempting to send OPTIONS request to {dstEndPoint}."); // Give sockets a chance to start up. //await Task.Delay(500); await udpChan1.SendAsync(dstEndPoint, Encoding.UTF8.GetBytes(optionsReq.ToString()), null); bool res = gotMessage.Task.Wait(1000); Assert.True(res); Assert.NotNull(receivedFromEP); Assert.NotNull(receivedOnEP); Assert.Equal(IPAddress.Loopback, receivedFromEP.Address); Assert.Equal(IPAddress.Any, receivedOnEP.Address); udpChan1.Close(); udpChan2.Close(); logger.LogDebug("-----------------------------------------"); }
/// <summary> /// Initialises the SIP transport layer. /// </summary> public async Task InitialiseSIP() { if (_isIntialised == false) { await Task.Run(() => { _isIntialised = true; if (String.IsNullOrEmpty(m_DnsServer) == false) { // Use a custom DNS server. m_DnsServer = m_DnsServer.Contains(":") ? m_DnsServer : m_DnsServer + ":53"; DNSManager.SetDNSServers(new List <IPEndPoint> { IPSocket.ParseSocketString(m_DnsServer) }); } // Configure the SIP transport layer. m_sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); bool sipChannelAdded = false; if (m_sipSocketsNode != null) { // Set up the SIP channels based on the app.config file. List <SIPChannel> sipChannels = SIPTransportConfig.ParseSIPChannelsNode(m_sipSocketsNode); if (sipChannels?.Count > 0) { m_sipTransport.AddSIPChannel(sipChannels); sipChannelAdded = true; } } if (sipChannelAdded == false) { // Use default options to set up a SIP channel. int port = FreePort.FindNextAvailableUDPPort(_defaultSIPUdpPort); var sipChannel = new SIPUDPChannel(new IPEndPoint(_defaultLocalAddress, port)); m_sipTransport.AddSIPChannel(sipChannel); } }); // Wire up the transport layer so incoming SIP requests have somewhere to go. m_sipTransport.SIPTransportRequestReceived += SIPTransportRequestReceived; // Log all SIP packets received to a log file. m_sipTransport.SIPRequestInTraceEvent += (localSIPEndPoint, endPoint, sipRequest) => { _sipTraceLogger.Debug("Request Received : " + localSIPEndPoint + "<-" + endPoint + "\r\n" + sipRequest.ToString()); }; m_sipTransport.SIPRequestOutTraceEvent += (localSIPEndPoint, endPoint, sipRequest) => { _sipTraceLogger.Debug("Request Sent: " + localSIPEndPoint + "->" + endPoint + "\r\n" + sipRequest.ToString()); }; m_sipTransport.SIPResponseInTraceEvent += (localSIPEndPoint, endPoint, sipResponse) => { _sipTraceLogger.Debug("Response Received: " + localSIPEndPoint + "<-" + endPoint + "\r\n" + sipResponse.ToString()); }; m_sipTransport.SIPResponseOutTraceEvent += (localSIPEndPoint, endPoint, sipResponse) => { _sipTraceLogger.Debug("Response Sent: " + localSIPEndPoint + "->" + endPoint + "\r\n" + sipResponse.ToString()); }; } }
public void IPv6LoopbackSendReceiveTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); if (!Socket.OSSupportsIPv6) { logger.LogDebug("Test skipped as OS does not support IPv6."); } else { ManualResetEventSlim serverReadyEvent = new ManualResetEventSlim(false); CancellationTokenSource cancelServer = new CancellationTokenSource(); TaskCompletionSource <bool> testComplete = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var serverChannel = new SIPUDPChannel(IPAddress.IPv6Loopback, 0); var clientChannel = new SIPUDPChannel(IPAddress.IPv6Loopback, 0); var serverTask = Task.Run(() => { RunServer(serverChannel, cancelServer, serverReadyEvent); }); var clientTask = Task.Run(async() => { #pragma warning disable RCS1090 // Add call to 'ConfigureAwait' (or vice versa). await RunClient( clientChannel, serverChannel.GetContactURI(SIPSchemesEnum.sip, new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(IPAddress.IPv6Loopback, 0))), testComplete, cancelServer, serverReadyEvent); #pragma warning restore RCS1090 // Add call to 'ConfigureAwait' (or vice versa). }); serverReadyEvent.Wait(); if (!Task.WhenAny(new Task[] { serverTask, clientTask }).Wait(TRANSPORT_TEST_TIMEOUT)) { logger.LogWarning($"Tasks timed out"); } if (testComplete.Task.IsCompleted == false) { // The client did not set the completed signal. This means the delay task must have completed and hence the test failed. testComplete.SetResult(false); } Assert.True(testComplete.Task.Result); cancelServer.Cancel(); } }
private static Dictionary <string, SIPRegistrarBinding> _sipRegistrations = new Dictionary <string, SIPRegistrarBinding>(); // [SIP Username, Contact Address], tracks SIP clients that have registered with the server. static void Main(string[] args) { try { // Configure the SIP transport layer. _sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); if (_sipSocketsNode != null) { // Set up the SIP channels based on the app.config file. List <SIPChannel> sipChannels = SIPTransportConfig.ParseSIPChannelsNode(_sipSocketsNode); _sipTransport.AddSIPChannel(sipChannels); } else { // Use default options to set up a SIP channel. int port = FreePort.FindNextAvailableUDPPort(_defaultSIPUdpPort); var sipChannel = new SIPUDPChannel(new IPEndPoint(_defaultLocalAddress, port)); _sipTransport.AddSIPChannel(sipChannel); } // Wire up the transport layer so SIP requests and responses have somewhere to go. _sipTransport.SIPTransportRequestReceived += SIPTransportRequestReceived; _sipTransport.SIPTransportResponseReceived += SIPTransportResponseReceived; // If you want to see ALL the nitty gritty SIP traffic wire up the events below. //_sipTransport.SIPBadRequestInTraceEvent += SIPBadRequestInTraceEvent; //_sipTransport.SIPBadResponseInTraceEvent += SIPBadResponseInTraceEvent; //_sipTransport.SIPRequestInTraceEvent += SIPRequestInTraceEvent; //_sipTransport.SIPRequestOutTraceEvent += SIPRequestOutTraceEvent; //_sipTransport.SIPResponseInTraceEvent += SIPResponseInTraceEvent; //_sipTransport.SIPResponseOutTraceEvent += SIPResponseOutTraceEvent; ManualResetEvent mre = new ManualResetEvent(false); mre.WaitOne(); } catch (Exception excp) { Console.WriteLine("Exception Main. " + excp); } finally { Console.WriteLine("Press any key to exit..."); Console.ReadLine(); } }
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(); }
private static Dictionary <string, SIPAccountBinding> _sipRegistrations = new Dictionary <string, SIPAccountBinding>(); // [SIP Username, Binding], tracks SIP clients that have registered with the server. static void Main() { try { Console.WriteLine("SIPSorcery SIP Proxy Demo"); logger = SIPSorcery.Sys.Log.Logger; // Configure the SIP transport layer. _sipTransport = new SIPTransport(); if (_sipSocketsNode != null) { // Set up the SIP channels based on the app.config file. List <SIPChannel> sipChannels = SIPTransportConfig.ParseSIPChannelsNode(_sipSocketsNode); _sipTransport.AddSIPChannel(sipChannels); } else { // Use default options to set up a SIP channel. var sipChannel = new SIPUDPChannel(new IPEndPoint(_defaultLocalAddress, _defaultSIPUdpPort)); _sipTransport.AddSIPChannel(sipChannel); } // Wire up the transport layer so SIP requests and responses have somewhere to go. _sipTransport.SIPTransportRequestReceived += SIPTransportRequestReceived; _sipTransport.SIPTransportResponseReceived += SIPTransportResponseReceived; // If you want to see ALL the nitty gritty SIP traffic wire up the events below. //_sipTransport.SIPBadRequestInTraceEvent += SIPBadRequestInTraceEvent; //_sipTransport.SIPBadResponseInTraceEvent += SIPBadResponseInTraceEvent; _sipTransport.SIPRequestInTraceEvent += SIPRequestInTraceEvent; //_sipTransport.SIPRequestOutTraceEvent += SIPRequestOutTraceEvent; //_sipTransport.SIPResponseInTraceEvent += SIPResponseInTraceEvent; _sipTransport.SIPResponseOutTraceEvent += SIPResponseOutTraceEvent; ManualResetEvent mre = new ManualResetEvent(false); mre.WaitOne(); } catch (Exception excp) { Console.WriteLine("Exception Main. " + excp); } }
public void Init() { var port = FreePort.FindNextAvailableUDPPort(15090); transport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine()); publicIPAddress = STUNClient.GetPublicIPAddress("stun.ekiga.net"); localIPEndPoint = IpAddressLookup.QueryRoutingInterface(asterisk, port); var endpoint = new IPEndPoint(localIPEndPoint.Address, port); var channel = new SIPUDPChannel(endpoint); //channel.SIPMessageReceived += (SIPChannel sipChannel, SIPEndPoint remoteEndPoint, byte[] buffer) => { logger.Debug("Channel SIP message received " + channel.SIPChannelEndPoint + "<-" + remoteEndPoint); }; transport.AddSIPChannel(channel); for (var i = 0; i < numbers.Length; i++) { var number = numbers[i]; var password = passwords[i]; var registration = new SIPRegistrationUserAgent( transport, null, new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, port), new SIPURI(number, asterisk, null, SIPSchemesEnum.sip, SIPProtocolsEnum.udp), number, password, null, asterisk, new SIPURI(SIPSchemesEnum.sip, new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, port)), 180, null, null, (e) => { logger.Debug(e.Message); } ); logger.Debug($"{prefix} Registration attempt for {number}@{endpoint.Address}:{endpoint.Port}"); registration.RegistrationSuccessful += Registration_RegistrationSuccessful; registration.RegistrationFailed += Registration_RegistrationFailed; registration.Start(); registrations.Add(registration); } }
public async Task PlaceCallMismatchedCapabilitiesUnitTest() { 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); var serverAudioSession = CreateMockVoIPMediaEndPoint(new List <AudioCodecsEnum> { AudioCodecsEnum.PCMU }); var answerResult = await userAgentServer.Answer(uas, serverAudioSession); logger.LogDebug($"Server agent answer result {answerResult}."); Assert.False(answerResult); }; var dstUri = udpChannel.GetContactURI(SIPSchemesEnum.sip, new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(IPAddress.Loopback, 0))); logger.LogDebug($"Attempting call to {dstUri.ToString()}."); var clientMediaEndPoint = CreateMockVoIPMediaEndPoint(new List <AudioCodecsEnum> { AudioCodecsEnum.G722 }); var callResult = await userAgentClient.Call(dstUri.ToString(), null, null, clientMediaEndPoint); logger.LogDebug($"Client agent answer result {callResult }."); Assert.False(callResult); }
public void GetDefaultContactURIUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); var udpChan = new SIPUDPChannel(IPAddress.Any, 0); logger.LogDebug($"Listening end point {udpChan.ListeningSIPEndPoint}."); var contactURI = udpChan.GetContactURI(SIPSchemesEnum.sip, new SIPEndPoint(udpChan.SIPProtocol, SIPChannel.InternetDefaultAddress, 0)); Assert.NotNull(contactURI); logger.LogDebug($"Contact URI: {contactURI}."); udpChan.Close(); logger.LogDebug("-----------------------------------------"); }
public Dictionary <string, SIPDispatcherJob> Load(SIPTransport sipTransport) { try { Dictionary <string, SIPDispatcherJob> dispatcherJobs = new Dictionary <string, SIPDispatcherJob>(); if (sipTransport == null) { SIPChannel dispatcherChannel = new SIPUDPChannel(new IPEndPoint(IPAddress.Loopback, 0)); sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine(), dispatcherChannel, true); } foreach (XmlNode dispatcherNode in m_configNode.ChildNodes) { string jobType = dispatcherNode.Attributes.GetNamedItem("class").Value; string jobKey = dispatcherNode.Attributes.GetNamedItem("key").Value; if (!jobKey.IsNullOrBlank() && !jobType.IsNullOrBlank()) { SIPDispatcherJob job = SIPDispatcherJobFactory.CreateJob(jobType, dispatcherNode, sipTransport); if (job != null && !dispatcherJobs.ContainsKey(jobKey)) { ThreadPool.QueueUserWorkItem(delegate { job.Start(); }); dispatcherJobs.Add(jobKey, job); } } else { logger.Warn("The job key or class were empty for a SIPDispatcherJob node.\n" + dispatcherNode.OuterXml); } } return(dispatcherJobs); } catch (Exception dispatcherExcp) { logger.Error("Exception StatelessProxyCore Starting Dispatcher. " + dispatcherExcp.Message); return(null); } }
public void IPv4LoopbackSendReceiveTest() { CancellationTokenSource cancelServer = new CancellationTokenSource(); TaskCompletionSource <bool> testComplete = new TaskCompletionSource <bool>(); var serverChannel = new SIPUDPChannel(IPAddress.Loopback, 6060); var clientChannel = new SIPUDPChannel(IPAddress.Loopback, 6061); var serverTask = Task.Run(() => { RunServer(serverChannel, cancelServer); }); var clientTask = Task.Run(async() => { await RunClient(clientChannel, new SIPURI(SIPSchemesEnum.sip, serverChannel.SIPChannelEndPoint), testComplete); }); Task.WhenAny(new Task[] { serverTask, clientTask, Task.Delay(2000) }).Wait(); if (testComplete.Task.IsCompleted == false) { // The client did not set the completed signal. This means the delay task must have completed and hence the test failed. testComplete.SetResult(false); } Assert.IsTrue(testComplete.Task.Result); cancelServer.Cancel(); }
public void IPv4LoopbackSendReceiveTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); ManualResetEventSlim serverReadyEvent = new ManualResetEventSlim(false); CancellationTokenSource cancelServer = new CancellationTokenSource(); TaskCompletionSource <bool> testComplete = new TaskCompletionSource <bool>(); var serverChannel = new SIPUDPChannel(IPAddress.Loopback, 0); var clientChannel = new SIPUDPChannel(IPAddress.Loopback, 0); var serverTask = Task.Run(() => { RunServer(serverChannel, cancelServer, serverReadyEvent); }); var clientTask = Task.Run(async() => { await RunClient( clientChannel, serverChannel.GetContactURI(SIPSchemesEnum.sip, new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(IPAddress.Loopback, 0))), testComplete, cancelServer, serverReadyEvent); }); serverReadyEvent.Wait(); if (!Task.WhenAny(new Task[] { serverTask, clientTask }).Wait(TRANSPORT_TEST_TIMEOUT)) { logger.LogWarning($"Tasks timed out"); } if (testComplete.Task.IsCompleted == false) { // The client did not set the completed signal. This means the delay task must have completed and hence the test failed. testComplete.SetResult(false); } Assert.True(testComplete.Task.Result); cancelServer.Cancel(); logger.LogDebug("Test complete."); }
/// <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(); try { DateTime startTime = DateTime.Now; (var dstEp, var dstUri) = ParseDestination(options.Destination); logger.LogDebug($"Destination IP end point {dstEp} and SIP URI {dstUri}"); IPAddress localAddress = (dstEp.Address.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any; SIPChannel sipChannel = null; switch (dstEp.Protocol) { case SIPProtocolsEnum.tcp: sipChannel = new SIPTCPChannel(new IPEndPoint(localAddress, DEFAULT_SIP_CLIENT_PORT)); (sipChannel as SIPTCPChannel).DisableLocalTCPSocketsCheck = true; // Allow sends to listeners on this host. break; case SIPProtocolsEnum.tls: var certificate = new X509Certificate2(@"localhost.pfx", ""); sipChannel = new SIPTLSChannel(certificate, new IPEndPoint(localAddress, DEFAULT_SIPS_CLIENT_PORT)); break; case SIPProtocolsEnum.udp: sipChannel = new SIPUDPChannel(new IPEndPoint(localAddress, DEFAULT_SIP_CLIENT_PORT)); break; case SIPProtocolsEnum.ws: sipChannel = new SIPClientWebSocketChannel(); break; case SIPProtocolsEnum.wss: sipChannel = new SIPClientWebSocketChannel(); break; default: throw new ApplicationException($"Don't know how to create SIP channel for transport {dstEp.Protocol}."); } sipTransport.AddSIPChannel(sipChannel); Task <bool> task = null; switch (options.Scenario) { case Scenarios.uac: task = InitiateCallTaskAsync(sipTransport, dstUri); 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 {dstEp} did not get a response on task {taskNumber} after {duration.TotalMilliseconds.ToString("0")}ms."); failed = true; } else if (!task.Result) { logger.LogWarning($"=> Request to {dstEp} 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(); } }
/// <summary> /// Executes the command set by the program's command line arguments. /// </summary> /// <param name="options">The options that dictate the SIP command to execute.</param> static async Task RunCommand(Options options) { try { logger.LogDebug($"RunCommand {options.Destination}"); (var dstEp, var dstUri) = ParseDestination(options.Destination); logger.LogDebug($"Destination IP end point {dstEp} and SIP URI {dstUri}"); int sendCount = 0; bool success = true; do { IPAddress localAddress = (dstEp.Address.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any; SIPChannel sipChannel = null; switch (dstEp.Protocol) { case SIPProtocolsEnum.tcp: sipChannel = new SIPTCPChannel(new IPEndPoint(localAddress, DEFAULT_SIP_CLIENT_PORT)); (sipChannel as SIPTCPChannel).DisableLocalTCPSocketsCheck = true; // Allow sends to listeners on this host. break; case SIPProtocolsEnum.tls: var certificate = new X509Certificate2(@"localhost.pfx", ""); sipChannel = new SIPTLSChannel(certificate, new IPEndPoint(localAddress, DEFAULT_SIPS_CLIENT_PORT)); break; case SIPProtocolsEnum.udp: sipChannel = new SIPUDPChannel(new IPEndPoint(localAddress, DEFAULT_SIP_CLIENT_PORT)); break; case SIPProtocolsEnum.ws: sipChannel = new SIPClientWebSocketChannel(); break; case SIPProtocolsEnum.wss: sipChannel = new SIPClientWebSocketChannel(); break; default: throw new ApplicationException($"Don't know how to create SIP channel for transport {dstEp.Protocol}."); } SIPTransport sipTransport = new SIPTransport(); sipTransport.AddSIPChannel(sipChannel); if (sendCount > 0 && options.Period > 0) { await Task.Delay(options.Period * 1000); } sendCount++; DateTime sendTime = DateTime.Now; var sendTask = SendOptionsTaskAsync(sipTransport, dstUri); var result = await Task.WhenAny(sendTask, Task.Delay(options.Timeout * 1000)); TimeSpan duration = DateTime.Now.Subtract(sendTime); if (!sendTask.IsCompleted) { logger.LogWarning($"=> Request to {dstEp} did not get a response on send {sendCount} of {options.Count} after {duration.TotalMilliseconds.ToString("0")}ms."); success = false; } else if (!sendTask.Result) { logger.LogWarning($"=> Request to {dstEp} did not get the expected response on request {sendCount} of {options.Count} after {duration.TotalMilliseconds.ToString("0")}ms."); success = false; } else { logger.LogInformation($"=> Got correct response on send {sendCount} of {options.Count} in {duration.TotalMilliseconds.ToString("0")}ms."); } logger.LogDebug("Shutting down the SIP transport..."); sipTransport.Shutdown(); if (success == false) { break; } }while (sendCount < options.Count); DNSManager.Stop(); // Give the transport half a second to shutdown (puts the log messages in a better sequence). await Task.Delay(500); logger.LogInformation($"=> Command completed {((success) ? "successfully" : "with failure")}."); } catch (Exception excp) { logger.LogError($"Exception RunCommand. {excp.Message}"); } }
static async Task Main(string[] args) { Console.WriteLine("SIPSorcery Video Phone Command Line Demo"); Console.WriteLine("Press ctrl-c to exit."); Log = AddConsoleLogger(); ManualResetEvent exitMRE = new ManualResetEvent(false); ManualResetEvent waitForCallMre = new ManualResetEvent(false); var parseResult = Parser.Default.ParseArguments <Options>(args); _options = (parseResult as Parsed <Options>)?.Value; if (parseResult.Tag != ParserResultType.NotParsed) { if (_options.ListCameras) { #region List webcams. var webcams = await WindowsVideoEndPoint.GetVideoCatpureDevices(); if (webcams == null || webcams.Count == 0) { Console.WriteLine("No webcams were found."); } else { var index = 0; foreach (var webcam in webcams) { Console.WriteLine($"{index}: \"{webcam.Name}\", use --cam={index}."); index++; } } #endregion } else if (_options.ListFormats != null) { #region List webcam formats. var webcams = await WindowsVideoEndPoint.GetVideoCatpureDevices(); if (webcams == null || webcams.Count == 0) { Console.WriteLine("No webcams were found."); } else if (_options.ListFormats >= webcams.Count) { Console.WriteLine($"No webcam available for index {_options.ListFormats}."); } else { string webcamName = webcams[_options.ListFormats.Value].Name; var formats = await WindowsVideoEndPoint.GetDeviceFrameFormats(webcamName); Console.WriteLine($"Video frame formats for {webcamName}."); foreach (var vidFmt in formats) { float vidFps = vidFmt.MediaFrameFormat.FrameRate.Numerator / vidFmt.MediaFrameFormat.FrameRate.Denominator; string pixFmt = vidFmt.MediaFrameFormat.Subtype == WindowsVideoEndPoint.MF_I420_PIXEL_FORMAT ? "I420" : vidFmt.MediaFrameFormat.Subtype; Console.WriteLine($"{vidFmt.Width}x{vidFmt.Height} {vidFps:0.##}fps {pixFmt}"); } } #endregion } else { string webcamName = null; if (_options.WebcamIndex != null) { var webcams = await WindowsVideoEndPoint.GetVideoCatpureDevices(); if (webcams == null || webcams.Count == 0) { Console.WriteLine("No webcams were found."); Application.Exit(); } else if (webcams.Count < _options.WebcamIndex) { Console.WriteLine($"No webcam available for index {_options.WebcamIndex}."); Application.Exit(); } else { webcamName = webcams[_options.WebcamIndex.Value].Name; Console.WriteLine($"Using webcam {webcamName}."); } } _sipTransport = new SIPTransport(); if (string.IsNullOrEmpty(_options.CallDestination)) { // We haven't been asked to place a call so we're listening. IPAddress listenAddress = (System.Net.Sockets.Socket.OSSupportsIPv6) ? IPAddress.IPv6Any : IPAddress.Any; var listenEndPoint = new IPEndPoint(listenAddress, SIP_PORT_DEFAULT); try { SIPUDPChannel udpChannel = new SIPUDPChannel(listenEndPoint, true); _sipTransport.AddSIPChannel(udpChannel); } catch (ApplicationException appExcp) { Console.WriteLine($"Failed to create UDP SIP channel on {listenEndPoint}, error {appExcp.Message}."); SIPUDPChannel udpChannel = new SIPUDPChannel(new IPEndPoint(listenAddress, 0), true); _sipTransport.AddSIPChannel(udpChannel); } var listeningEP = _sipTransport.GetSIPChannels().First().ListeningSIPEndPoint; Console.WriteLine($"Listening for incoming call on {listeningEP}."); } EnableTraceLogs(_sipTransport); // Open a window to display the video feed from the remote SIP party. _form = new Form(); _form.Text = string.IsNullOrEmpty(_options.CallDestination) ? "Listener" : "Caller"; _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); var userAgent = new SIPUserAgent(_sipTransport, null, true); userAgent.OnCallHungup += (dialog) => exitMRE.Set(); WindowsAudioEndPoint windowsAudioEndPoint = null; if (!_options.NoAudio) { windowsAudioEndPoint = new WindowsAudioEndPoint(new AudioEncoder()); windowsAudioEndPoint.RestrictFormats(x => x.Codec == AudioCodecsEnum.G722); } MediaEndPoints mediaEndPoints = null; if (_options.TestPattern && _options.WebcamIndex == null) { var testPattern = new VideoTestPatternSource(new FFmpegVideoEncoder()); var decoderSink = new DecoderVideoSink(new FFmpegVideoEncoder()); //var decoderSink = new DecoderVideoSink(new VpxVideoEncoder()); testPattern.RestrictFormats(format => format.Codec == VIDEO_CODEC); decoderSink.RestrictFormats(format => format.Codec == VIDEO_CODEC); mediaEndPoints = new MediaEndPoints { AudioSink = windowsAudioEndPoint, AudioSource = windowsAudioEndPoint, VideoSink = decoderSink, VideoSource = testPattern, }; } else { WindowsVideoEndPoint windowsVideoEndPoint = webcamName switch { null => new WindowsVideoEndPoint(new FFmpegVideoEncoder()), _ => new WindowsVideoEndPoint(new FFmpegVideoEncoder(), webcamName), }; windowsVideoEndPoint.RestrictFormats(format => format.Codec == VIDEO_CODEC); mediaEndPoints = new MediaEndPoints { AudioSink = windowsAudioEndPoint, AudioSource = windowsAudioEndPoint, VideoSink = windowsVideoEndPoint, VideoSource = windowsVideoEndPoint, }; } mediaEndPoints.VideoSource.OnVideoSourceRawSample += (uint durationMilliseconds, int width, int height, byte[] sample, VideoPixelFormatsEnum pixelFormat) => { if (_isFormActivated) { _form?.BeginInvoke(new Action(() => { if (_form.Handle != IntPtr.Zero) { int stride = width * 3; if (pixelFormat == VideoPixelFormatsEnum.I420) { sample = PixelConverter.I420toBGR(sample, width, height, out stride); } if (_localVideoPicBox.Width != width || _localVideoPicBox.Height != height) { Log.LogDebug($"Adjusting local video display from {_localVideoPicBox.Width}x{_localVideoPicBox.Height} to {width}x{height}."); _localVideoPicBox.Width = width; _localVideoPicBox.Height = height; } unsafe { fixed(byte *s = sample) { System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, (IntPtr)s); _localVideoPicBox.Image = bmpImage; } } } })); } }; Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; Log.LogInformation("Exiting..."); waitForCallMre.Set(); exitMRE.Set(); }; if (string.IsNullOrEmpty(_options.CallDestination)) { ActivateForm(); userAgent.OnIncomingCall += async(ua, req) => { var voipMediaSession = new VoIPMediaSession(mediaEndPoints); voipMediaSession.AcceptRtpFromAny = true; if (voipMediaSession.VideoLocalTrack != null) { voipMediaSession.VideoLocalTrack.MaximumBandwidth = MAXIMUM_VIDEO_BANDWIDTH; } var uas = userAgent.AcceptCall(req); await userAgent.Answer(uas, voipMediaSession); Console.WriteLine("Starting local video source..."); await mediaEndPoints.VideoSource.StartVideo().ConfigureAwait(false); waitForCallMre.Set(); }; Console.WriteLine("Waiting for incoming call..."); waitForCallMre.WaitOne(); } else { var voipMediaSession = new VoIPMediaSession(mediaEndPoints); voipMediaSession.AcceptRtpFromAny = true; if (voipMediaSession.VideoLocalTrack != null) { voipMediaSession.VideoLocalTrack.MaximumBandwidth = MAXIMUM_VIDEO_BANDWIDTH; } ActivateForm(); Console.WriteLine("Starting local video source..."); await mediaEndPoints.VideoSource.StartVideo().ConfigureAwait(false); // Place the call and wait for the result. Task <bool> callTask = userAgent.Call(_options.CallDestination, null, null, voipMediaSession); callTask.Wait(CALL_TIMEOUT_SECONDS * 1000); } if (userAgent.IsCallActive) { Log.LogInformation("Call attempt successful."); mediaEndPoints.VideoSink.OnVideoSinkDecodedSample += (byte[] bmp, uint width, uint height, int stride, VideoPixelFormatsEnum pixelFormat) => { if (_isFormActivated) { _form?.BeginInvoke(new Action(() => { if (_form.Handle != IntPtr.Zero) { unsafe { if (_remoteVideoPicBox.Width != (int)width || _remoteVideoPicBox.Height != (int)height) { Log.LogDebug($"Adjusting remote video display from {_remoteVideoPicBox.Width}x{_remoteVideoPicBox.Height} to {width}x{height}."); _remoteVideoPicBox.Width = (int)width; _remoteVideoPicBox.Height = (int)height; } fixed(byte *s = bmp) { System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap((int)width, (int)height, stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, (IntPtr)s); _remoteVideoPicBox.Image = bmpImage; } } } })); } }; } else { Log.LogWarning("Call attempt failed."); Console.WriteLine("Press ctrl-c to exit."); } exitMRE.WaitOne(); if (userAgent.IsCallActive) { Log.LogInformation("Hanging up."); userAgent.Hangup(); } Task.Delay(1000).Wait(); // Clean up. if (_form.Handle != IntPtr.Zero) { _form.BeginInvoke(new Action(() => _form.Close())); } _sipTransport.Shutdown(); } } }
static void Main() { Console.WriteLine("SIPSorcery registration user agent example."); Console.WriteLine("Press ctrl-c to exit."); AddConsoleLogger(); // Set up a default SIP transport. var sipTransport = new SIPTransport(); var sipChannel = new SIPUDPChannel(IPAddress.Any, 0); sipTransport.AddSIPChannel(sipChannel); EnableTraceLogs(sipTransport); // 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(); }
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 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(); }
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(); } }; }