Exemple #1
0
        public AudioChannel()
        {
            // Set up the device that will play the audio from the RTP received from the remote end of the call.
            m_waveOut      = new WaveOut();
            m_waveProvider = new BufferedWaveProvider(_waveFormat);
            m_waveOut.Init(m_waveProvider);
            m_waveOut.Play();

            // Set up the input device that will provide audio samples that can be encoded, packaged into RTP and sent to
            // the remote end of the call.
            m_waveInEvent = new WaveInEvent();
            m_waveInEvent.BufferMilliseconds = 20;
            m_waveInEvent.NumberOfBuffers    = 1;
            m_waveInEvent.DeviceNumber       = 0;
            m_waveInEvent.DataAvailable     += RTPChannelSampleAvailable;
            m_waveInEvent.WaveFormat         = _waveFormat;

            // Create a UDP socket to use for sending and receiving RTP packets.
            int port = FreePort.FindNextAvailableUDPPort(DEFAULT_START_RTP_PORT);

            _rtpEndPoint = new IPEndPoint(_defaultLocalAddress, port);
            m_rtpChannel = new RTPChannel(_rtpEndPoint);
            m_rtpChannel.OnFrameReady += RTPChannelSampleReceived;


            _audioLogger.Debug("RTP channel endpoint " + _rtpEndPoint.ToString());
        }
Exemple #2
0
        /// <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()); };
        }
 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();
     }
 }
Exemple #4
0
        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();
        }
Exemple #5
0
        public void Start(string endpoint)
        {
            this.endpoint = endpoint;

            var caller   = "1003";
            var password = passwords[0];
            var port     = FreePort.FindNextAvailableUDPPort(15090);

            rtpChannel = new RTPChannel
            {
                DontTimeout    = true,
                RemoteEndPoint = new IPEndPoint(IPAddress.Parse(asterisk), port)
            };

            rtpChannel.SetFrameType(FrameTypesEnum.Audio);
            rtpChannel.ReservePorts(15000, 15090);
            rtpChannel.OnFrameReady += RtpChannel_OnFrameReady;

            uac = new SIPClientUserAgent(transport, null, null, null, null);

            var uri    = SIPURI.ParseSIPURIRelaxed($"{ endpoint }@{ asterisk }");
            var from   = (new SIPFromHeader(caller, new SIPURI(caller, asterisk, null), null)).ToString();
            var random = Crypto.GetRandomInt(5).ToString();
            var sdp    = new SDP
            {
                Version     = 2,
                Username    = "******",
                SessionId   = random,
                Address     = localIPEndPoint.Address.ToString(),
                SessionName = "redfox_" + random,
                Timing      = "0 0",
                Connection  = new SDPConnectionInformation(publicIPAddress.ToString())
            };

            var announcement = new SDPMediaAnnouncement
            {
                Media        = SDPMediaTypesEnum.audio,
                MediaFormats = new List <SDPMediaFormat>()
                {
                    new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000)
                },
                Port = rtpChannel.RTPPort
            };

            sdp.Media.Add(announcement);

            var descriptor = new SIPCallDescriptor(caller, password, uri.ToString(), from, null, null, null, null, SIPCallDirection.Out, SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null);

            uac.CallTrying   += Uac_CallTrying;
            uac.CallRinging  += Uac_CallRinging;
            uac.CallAnswered += Uac_CallAnswered;
            uac.CallFailed   += Uac_CallFailed;

            uac.Call(descriptor);
        }
Exemple #6
0
        /// <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()); };
            }
        }
Exemple #7
0
        public void Run()
        {
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var port     = FreePort.FindNextAvailableTcpPort(20000);
            var endPoint = new IPEndPoint(IPAddress.Any, port);

            server.Bind(endPoint);
            server.Listen(port);
            var accept = new SocketAsyncEventArgs();

            accept.Completed     += Accept_Completed;
            accept.RemoteEndPoint = endPoint;
            accept.UserToken      = server;
            server.AcceptAsync(accept);
        }
Exemple #8
0
        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();
            }
        }
Exemple #9
0
        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 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);
            }
        }
Exemple #11
0
 public void Start(Action After)
 {
     if (State)
     {
         After?.Invoke();
         return;
     }
     Task.Run(() => {
         ServerEnvironment.Instance.Port = FreePort.FindNextAvailableTCPPort(ServerEnvironment.Instance.Port);
         var line = $@"{ServerEnvironment.Instance.Path}{ServerEnvironment.Instance.WebName}.dll --urls=http://*:{ServerEnvironment.Instance.Port}";
         var psi  = SetProcessInfo(line);
         Process  = Process.Start(psi);
         After?.Invoke();
         Process.OutputDataReceived += new DataReceivedEventHandler(Instance.OnDataReceived);
         Process.BeginOutputReadLine();
         Process.WaitForExit();
         if (Process.ExitCode != 0)
         {
             logger.Info(Process.StandardError.ReadToEnd());
         }
         Process.Close();
         Process = null;
     });
 }
Exemple #12
0
        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();
                }
            };
        }
Exemple #14
0
        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();
                }
            };
        }
Exemple #15
0
        ///<summary>Processes a received query.</summary>
        ///<param name="Query">The query to process.</param>
        private async Task ProcessQuery(byte[] Query)
        {
            try
            {
                Request request = null;
                Request.ParseRequest(Query, out request);
                switch (request.Command)
                {
                case Command.Connect:     //CONNECT
                    IPAddress RemoteIP   = request.DstAddr;
                    int       RemotePort = 0;
                    if (Query[3] == 1)
                    {
                        RemoteIP   = IPAddress.Parse(Query[4].ToString() + "." + Query[5].ToString() + "." + Query[6].ToString() + "." + Query[7].ToString());
                        RemotePort = Query[8] * 256 + Query[9];
                    }
                    else if (Query[3] == 3)
                    {
                        if (RemoteIP == null)
                        {
                            RemoteIP = Dns.GetHostAddressesAsync(Encoding.ASCII.GetString(Query, 5, Query[4])).Result[0];
                        }
                        RemotePort = Query[4] + 5;
                        RemotePort = Query[RemotePort] * 256 + Query[RemotePort + 1];
                    }
                    RemoteConnection = new TcpSocket(RemoteIP.AddressFamily, false);
                    try
                    {
                        await RemoteConnection.ConnectAsync(new IPEndPoint(RemoteIP, RemotePort));
                        await OnConnected(null);
                    }
                    catch (SocketException ex)
                    {
                        Console.WriteLine("[WARN] SocketError=" + ex.SocketErrorCode + "\r\n");
                        await OnConnected(ex);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("[WARN] " + ex.Message + "\r\n" + ex.StackTrace);
                        await OnConnected(ex);
                    }
                    break;

                case Command.Bind:     //BIND
                    byte[] Reply   = new byte[10];
                    long   LocalIP = BitConverter.ToInt64(Listener.GetLocalExternalIP().Result.GetAddressBytes(), 0);
                    AcceptSocket = new TcpSocket(IPAddress.Any.AddressFamily, false);
                    AcceptSocket.Bind(new IPEndPoint(IPAddress.Any, 0));
                    AcceptSocket.Listen(50);
                    Reply[0] = 5;                                                                         //Version 5
                    Reply[1] = 0;                                                                         //Everything is ok :)
                    Reply[2] = 0;                                                                         //Reserved
                    Reply[3] = 1;                                                                         //We're going to send a IPv4 address
                    Reply[4] = (byte)((LocalIP % 256));                                                   //IP Address/1
                    Reply[5] = (byte)((LocalIP % 65536) / 256);                                           //IP Address/2
                    Reply[6] = (byte)((LocalIP % 16777216) / 65536);                                      //IP Address/3
                    Reply[7] = (byte)(Math.Floor(LocalIP / 16777216.0));                                  //IP Address/4
                    Reply[8] = (byte)(Math.Floor(((IPEndPoint)AcceptSocket.LocalEndPoint).Port / 256.0)); //Port/1
                    Reply[9] = (byte)(((IPEndPoint)AcceptSocket.LocalEndPoint).Port % 256);               //Port/2
                    await Connection.SendAsync(Reply, async (int x) => { await this.OnStartAccept(); });

                    break;

                case Command.UdpAssociate:     //UDP ASSOCIATE

                    if (request.DstAddr.Equals(IPAddress.Any) && request.DstPort == 0)
                    {
                        request.DstPort = FreePort.FindNextAvailableUDPPort(4200);
                        if (request.DstPort == 0)
                        {
                            await Dispose(ReplyCode.SocksFailure);

                            return;
                        }
                    }
                    if (request.DstAddr.Equals(IPAddress.Any))
                    {
                        request.DstAddr = ((IPEndPoint)Connection.LocalEndPoint).Address;
                    }
                    UdpClientEndPoint = new IPEndPoint(request.DstAddr, request.DstPort);
                    LocalBindEndPoint = new IPEndPoint(((IPEndPoint)(Connection.LocalEndPoint)).Address, request.DstPort);
                    var reply = request.CreateReply(LocalBindEndPoint.Address, LocalBindEndPoint.Port);
                    await Connection.SendAsync(reply.ToBytes(), async (int x) => { await this.StartUdpReceive(); });

                    break;

                default:
                    await Dispose(ReplyCode.UnsupportedCommand);

                    break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("[WARN] " + ex.Message + "\r\n" + ex.StackTrace);
                await Dispose(ReplyCode.SocksFailure);
            }
        }