示例#1
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="rtpSocket">The RTP socket being used for the WebRTC session.</param>
        private static int DoDtlsHandshake(WebRtcSession webRtcSession, Socket rtpSocket, out ProtectRtpPacket protectRtp, out ProtectRtpPacket protectRtcp)
        {
            logger.LogDebug("DoDtlsHandshake started.");

            protectRtp  = null;
            protectRtcp = null;

            if (!File.Exists(DTLS_CERTIFICATE_PATH))
            {
                throw new ApplicationException($"The DTLS certificate file could not be found at {DTLS_CERTIFICATE_PATH}.");
            }
            else if (!File.Exists(DTLS_KEY_PATH))
            {
                throw new ApplicationException($"The DTLS key file could not be found at {DTLS_KEY_PATH}.");
            }

            var dtls = new Dtls(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH);

            webRtcSession.OnClose += (reason) => dtls.Shutdown();

            int res = dtls.DoHandshake((ulong)rtpSocket.Handle);

            logger.LogDebug("DtlsContext initialisation result=" + res);

            if (dtls.GetState() == (int)DtlsState.OK)
            {
                logger.LogDebug("DTLS negotiation complete.");

                var srtpContext = new Srtp(dtls, false);
                protectRtp  = srtpContext.ProtectRTP;
                protectRtcp = srtpContext.ProtectRTCP;
            }

            return(res);
        }
示例#2
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        /// <returns>True if the handshake completes successfully. False if not.</returns>
        private static bool DoDtlsHandshake(WebRtcSession webRtcSession)
        {
            Console.WriteLine("DoDtlsHandshake started.");

            var dtls = new DtlsHandshake(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH);

            webRtcSession.OnClose += (reason) => dtls.Shutdown();

            int res = dtls.DoHandshakeAsServer((ulong)webRtcSession.RtpSession.RtpChannel.RtpSocket.Handle);

            Console.WriteLine("DtlsContext initialisation result=" + res);

            if (dtls.IsHandshakeComplete())
            {
                Console.WriteLine("DTLS negotiation complete.");

                // TODO fix race condition!!! First RTP packet is not getting decrypted.
                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                webRtcSession.RtpSession.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#3
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        /// <returns>True if the handshake completed successfully or false otherwise.</returns>
        private static bool DoDtlsHandshake(RTCPeerConnection peerConnection)
        {
            logger.LogDebug("DoDtlsHandshake started.");

            var dtls = new DtlsHandshake(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH);

            int res = dtls.DoHandshakeAsServer((ulong)peerConnection.GetRtpChannel(SDPMediaTypesEnum.audio).RtpSocket.Handle);

            logger.LogDebug("DtlsContext initialisation result=" + res);

            if (dtls.IsHandshakeComplete())
            {
                logger.LogDebug("DTLS negotiation complete.");

                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                peerConnection.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                dtls.Shutdown();
                return(true);
            }
            else
            {
                dtls.Shutdown();
                return(false);
            }
        }
示例#4
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="peerConnection">The WebRTC session to perform the DTLS handshake on.</param>
        /// <returns>True if the handshake completes successfully. False if not.</returns>
        private static async Task <bool> DoDtlsHandshake(RTCPeerConnection peerConnection, DtlsHandshake dtls)
        {
            Console.WriteLine("DoDtlsHandshake started.");

            int res = dtls.DoHandshakeAsServer((ulong)peerConnection.GetRtpChannel(SDPMediaTypesEnum.audio).RtpSocket.Handle);

            Console.WriteLine("DtlsContext initialisation result=" + res);

            if (dtls.IsHandshakeComplete())
            {
                Console.WriteLine("DTLS negotiation complete.");

                // TODO fix race condition!!! First RTP packet is not getting decrypted.
                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                peerConnection.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                await peerConnection.Start();

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#5
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        /// <returns>True if the handshake completed successfully or false otherwise.</returns>
        private static async Task <bool> DoDtlsHandshake(RTCPeerConnection peerConnection, DtlsHandshake dtls)
        {
            logger.LogDebug("DoDtlsHandshake started.");

            int res = dtls.DoHandshakeAsServer((ulong)peerConnection.GetRtpChannel(SDPMediaTypesEnum.audio).RtpSocket.Handle);

            logger.LogDebug("DtlsContext initialisation result=" + res);

            if (dtls.IsHandshakeComplete())
            {
                logger.LogDebug("DTLS negotiation complete.");

                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                peerConnection.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                await peerConnection.Start();

                if (!_isSampling)
                {
                    _ = Task.Run(StartMedia);
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#6
0
        static void Main()
        {
            Console.WriteLine("WebRTC Server Sample Program");
            Console.WriteLine("Press ctrl-c to exit.");

            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream.
            ManualResetEvent        exitMre = new ManualResetEvent(false);

            AddConsoleLogger();

            if (!File.Exists(MP4_FILE_PATH))
            {
                throw new ApplicationException($"The media file at does not exist at {MP4_FILE_PATH}.");
            }

            // Initialise OpenSSL & libsrtp, saves a couple of seconds for the first client connection.
            Console.WriteLine("Initialising OpenSSL and libsrtp...");
            DtlsHandshake.InitialiseOpenSSL();
            Srtp.InitialiseLibSrtp();

            Task.Run(DoDtlsHandshakeLoopbackTest).Wait();

            Console.WriteLine("Test DTLS handshake complete.");

            _mediaSource = new MediaSource();
            _mediaSource.Init(MP4_FILE_PATH, true);
            //_mediaSource.Init(0, 0, VideoSubTypesEnum.I420, 640, 480);

            // Start web socket.
            Console.WriteLine("Starting web socket server...");
            _webSocketServer = new WebSocketServer(IPAddress.Any, WEBSOCKET_PORT, true);
            _webSocketServer.SslConfiguration.ServerCertificate          = new System.Security.Cryptography.X509Certificates.X509Certificate2(WEBSOCKET_CERTIFICATE_PATH);
            _webSocketServer.SslConfiguration.CheckCertificateRevocation = false;
            //_webSocketServer.Log.Level = WebSocketSharp.LogLevel.Debug;
            _webSocketServer.AddWebSocketService <SDPExchange>("/", (sdpExchanger) =>
            {
                sdpExchanger.WebSocketOpened   += SendSDPOffer;
                sdpExchanger.SDPAnswerReceived += SDPAnswerReceived;
            });
            _webSocketServer.Start();

            Console.WriteLine($"Waiting for browser web socket connection to {_webSocketServer.Address}:{_webSocketServer.Port}...");

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitMre.Set();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitMre.WaitOne();

            _mediaSource.Shutdown();
            _webSocketServer.Stop();
        }
示例#7
0
        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogDebug("WebRTCHostedService StartAsync.");

            // Initialise OpenSSL & libsrtp, saves a couple of seconds for the first client connection.
            _logger.LogDebug("Initialising OpenSSL and libsrtp...");
            DtlsHandshake.InitialiseOpenSSL();
            Srtp.InitialiseLibSrtp();

            return(Task.CompletedTask);
        }
示例#8
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        private static bool DoDtlsHandshake(RTCPeerConnection peerConnection)
        {
            Log.LogDebug("DoDtlsHandshake started.");

            if (!File.Exists(DTLS_CERTIFICATE_PATH))
            {
                throw new ApplicationException($"The DTLS certificate file could not be found at {DTLS_CERTIFICATE_PATH}.");
            }
            else if (!File.Exists(DTLS_KEY_PATH))
            {
                throw new ApplicationException($"The DTLS key file could not be found at {DTLS_KEY_PATH}.");
            }

            var dtls = new DtlsHandshake(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH);

            peerConnection.onconnectionstatechange += (state) =>
            {
                if (state == RTCPeerConnectionState.closed)
                {
                    dtls.Shutdown();
                }
            };

            byte[] clientFingerprint = null;
            int    res = dtls.DoHandshakeAsServer((ulong)peerConnection.GetRtpChannel(SDPMediaTypesEnum.audio).RtpSocket.Handle, ref clientFingerprint);

            Log.LogDebug("DtlsContext initialisation result=" + res);

            if (dtls.IsHandshakeComplete())
            {
                // TODO: Check client fingerprint matches one supplied in the SDP.

                Log.LogDebug("DTLS negotiation complete.");

                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                peerConnection.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#9
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        /// <returns>True if the handshake completed successfully or false otherwise.</returns>
        private bool DoDtlsHandshake(WebRtcSession webRtcSession)
        {
            try
            {
                logger.LogDebug("DoDtlsHandshake started.");

                if (!File.Exists(_dtlsCertificatePath))
                {
                    throw new ApplicationException($"The DTLS certificate file could not be found at {_dtlsCertificatePath}.");
                }
                else if (!File.Exists(_dtlsKeyPath))
                {
                    throw new ApplicationException($"The DTLS key file could not be found at {_dtlsKeyPath}.");
                }

                var dtls = new DtlsHandshake(_dtlsCertificatePath, _dtlsKeyPath);
                webRtcSession.OnClose += (reason) => dtls.Shutdown();

                int res = dtls.DoHandshakeAsServer((ulong)webRtcSession.RtpSession.RtpChannel.RtpSocket.Handle);

                logger.LogDebug("DtlsContext initialisation result=" + res);

                if (dtls.IsHandshakeComplete())
                {
                    logger.LogDebug("DTLS negotiation complete.");

                    var srtpSendContext    = new Srtp(dtls, false);
                    var srtpReceiveContext = new Srtp(dtls, true);

                    webRtcSession.RtpSession.SetSecurityContext(
                        srtpSendContext.ProtectRTP,
                        srtpReceiveContext.UnprotectRTP,
                        srtpSendContext.ProtectRTCP,
                        srtpReceiveContext.UnprotectRTCP);

                    webRtcSession.IsDtlsNegotiationComplete = true;

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (Exception excp)
            {
                logger.LogWarning($"Exception DoDtlsHandshake. {excp}");
                return(false);
            }
        }
示例#10
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        private static async Task <bool> DoDtlsHandshake(RTCPeerConnection peerConnection, DtlsHandshake dtls)
        {
            logger.LogDebug("DoDtlsHandshake started.");

            if (!File.Exists(DTLS_CERTIFICATE_PATH))
            {
                throw new ApplicationException($"The DTLS certificate file could not be found at {DTLS_CERTIFICATE_PATH}.");
            }
            else if (!File.Exists(DTLS_KEY_PATH))
            {
                throw new ApplicationException($"The DTLS key file could not be found at {DTLS_KEY_PATH}.");
            }

            byte[] clientFingerprint = null;
            int    res = dtls.DoHandshakeAsServer((ulong)peerConnection.GetRtpChannel(SDPMediaTypesEnum.audio).RtpSocket.Handle, ref clientFingerprint);

            logger.LogDebug("DtlsContext initialisation result=" + res);

            if (dtls.IsHandshakeComplete())
            {
                logger.LogDebug("DTLS negotiation complete.");

                // TODO: Check client fingerprint matches one supplied in the SDP.

                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                peerConnection.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                await peerConnection.Start();

                //dtls.Shutdown();
                if (_sendTestPatternTimer == null)
                {
                    _sendTestPatternTimer = new Timer(SendTestPattern, null, 0, TEST_PATTERN_SPACING_MILLISECONDS);
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#11
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        private static async Task <bool> DoDtlsHandshake(RTCPeerConnection peerConnection)
        {
            logger.LogDebug("DoDtlsHandshake started.");

            if (!File.Exists(DTLS_CERTIFICATE_PATH))
            {
                throw new ApplicationException($"The DTLS certificate file could not be found at {DTLS_CERTIFICATE_PATH}.");
            }
            else if (!File.Exists(DTLS_KEY_PATH))
            {
                throw new ApplicationException($"The DTLS key file could not be found at {DTLS_KEY_PATH}.");
            }

            var dtls = new DtlsHandshake(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH);

            byte[] clientFingerprint = null;
            var    dtlsResult        = await Task.Run(() => dtls.DoHandshakeAsServer((ulong)peerConnection.GetRtpChannel(SDPMediaTypesEnum.audio).RtpSocket.Handle, ref clientFingerprint));

            logger.LogDebug("DtlsContext initialisation result=" + dtlsResult);

            if (dtls.IsHandshakeComplete())
            {
                logger.LogDebug("DTLS handshake succeeded.");

                // TODO: Check client fingerprint matches one supplied in the SDP.

                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                peerConnection.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                return(true);
            }
            else
            {
                logger.LogWarning("DTLS handshake failed.");

                dtls.Shutdown();
                return(false);
            }
        }
示例#12
0
        static void Main()
        {
            Console.WriteLine("WebRTC Server Sample Program");
            Console.WriteLine("Press ctrl-c to exit.");

            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream.
            ManualResetEvent        exitMre = new ManualResetEvent(false);

            AddConsoleLogger();

            // Initialise OpenSSL & libsrtp, saves a couple of seconds for the first client connection.
            Console.WriteLine("Initialising OpenSSL and libsrtp...");
            DtlsHandshake.InitialiseOpenSSL();
            Srtp.InitialiseLibSrtp();

            InitialiseTestPattern();

            // Start web socket.
            Console.WriteLine("Starting web socket server...");
            _webSocketServer = new WebSocketServer(IPAddress.Any, WEBSOCKET_PORT, true);
            _webSocketServer.SslConfiguration.ServerCertificate          = new System.Security.Cryptography.X509Certificates.X509Certificate2(WEBSOCKET_CERTIFICATE_PATH);
            _webSocketServer.SslConfiguration.CheckCertificateRevocation = false;
            //_webSocketServer.Log.Level = WebSocketSharp.LogLevel.Debug;
            _webSocketServer.AddWebSocketService <SDPExchange>("/", (sdpExchanger) =>
            {
                sdpExchanger.WebSocketOpened   += SendSDPOffer;
                sdpExchanger.OnMessageReceived += WebSocketMessageReceived;
            });
            _webSocketServer.Start();

            Console.WriteLine($"Waiting for browser web socket connection to {_webSocketServer.Address}:{_webSocketServer.Port}...");

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                _sendTestPatternTimer?.Dispose();
                exitMre.Set();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitMre.WaitOne();
        }
示例#13
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        private static int DoDtlsHandshake(WebRtcSession webRtcSession)
        {
            logger.LogDebug("DoDtlsHandshake started.");

            if (!File.Exists(DTLS_CERTIFICATE_PATH))
            {
                throw new ApplicationException($"The DTLS certificate file could not be found at {DTLS_CERTIFICATE_PATH}.");
            }
            else if (!File.Exists(DTLS_KEY_PATH))
            {
                throw new ApplicationException($"The DTLS key file could not be found at {DTLS_KEY_PATH}.");
            }

            var dtls = new DtlsHandshake(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH);

            webRtcSession.OnClose += (reason) => dtls.Shutdown();

            int res = dtls.DoHandshakeAsServer((ulong)webRtcSession.RtpSession.RtpChannel.RtpSocket.Handle);

            logger.LogDebug("DtlsContext initialisation result=" + res);

            if (dtls.IsHandshakeComplete())
            {
                logger.LogDebug("DTLS negotiation complete.");

                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                webRtcSession.RtpSession.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                if (!_isSampling)
                {
                    Task.Run(StartMedia);
                }
            }

            return(res);
        }
示例#14
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        private static bool DoDtlsHandshake(RTCPeerConnection peerConnection, DtlsHandshake dtls)
        {
            Log.LogDebug("DoDtlsHandshake started.");

            if (!File.Exists(DTLS_CERTIFICATE_PATH))
            {
                throw new ApplicationException($"The DTLS certificate file could not be found at {DTLS_CERTIFICATE_PATH}.");
            }
            else if (!File.Exists(DTLS_KEY_PATH))
            {
                throw new ApplicationException($"The DTLS key file could not be found at {DTLS_KEY_PATH}.");
            }

            byte[] clientFingerprint = null;
            var    dtlsResult        = dtls.DoHandshakeAsServer((ulong)peerConnection.GetRtpChannel(SDPMediaTypesEnum.audio).RtpSocket.Handle, ref clientFingerprint);

            Log.LogDebug($"DtlsContext initialisation result {dtlsResult}.");

            if (dtls.IsHandshakeComplete())
            {
                Log.LogDebug("DTLS negotiation complete.");

                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                peerConnection.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                return(true);
            }
            else
            {
                Log.LogWarning("DTLS handshake failed.");

                dtls.Shutdown();
                return(false);
            }
        }
示例#15
0
        /// <summary>
        /// Hands the socket handle to the DTLS context and waits for the handshake to complete.
        /// </summary>
        /// <param name="webRtcSession">The WebRTC session to perform the DTLS handshake on.</param>
        private static async Task <bool> DoDtlsHandshake(RTCPeerConnection peerConnection, DtlsHandshake dtls)
        {
            logger.LogDebug("DoDtlsHandshake started.");

            if (!File.Exists(DTLS_CERTIFICATE_PATH))
            {
                throw new ApplicationException($"The DTLS certificate file could not be found at {DTLS_CERTIFICATE_PATH}.");
            }
            else if (!File.Exists(DTLS_KEY_PATH))
            {
                throw new ApplicationException($"The DTLS key file could not be found at {DTLS_KEY_PATH}.");
            }

            int res = dtls.DoHandshakeAsServer((ulong)peerConnection.GetRtpChannel(SDPMediaTypesEnum.audio).RtpSocket.Handle);

            logger.LogDebug("DtlsContext initialisation result=" + res);

            if (dtls.IsHandshakeComplete())
            {
                logger.LogDebug("DTLS negotiation complete.");

                var srtpSendContext    = new Srtp(dtls, false);
                var srtpReceiveContext = new Srtp(dtls, true);

                peerConnection.SetSecurityContext(
                    srtpSendContext.ProtectRTP,
                    srtpReceiveContext.UnprotectRTP,
                    srtpSendContext.ProtectRTCP,
                    srtpReceiveContext.UnprotectRTCP);

                //dtls.Shutdown();

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#16
0
        public async Task Start(CancellationToken ct)
        {
            try
            {
                AddConsoleLogger();

                logger.LogDebug("WebRTCDaemon starting.");

                var wssCertificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(_webSocketCertificatePath, _webSocketCertificatePassword);
                logger.LogDebug("Web Socket Server Certificate: " + wssCertificate.Subject + ", have key " + wssCertificate.HasPrivateKey + ", Expires " + wssCertificate.GetExpirationDateString() + ".");
                logger.LogDebug($"DTLS certificate thumbprint {_dtlsCertificateThumbprint}.");
                logger.LogDebug($"Web socket port {_webSocketPort}.");

                if (!File.Exists(_mediaFilePath))
                {
                    throw new ApplicationException($"The media file at does not exist at {_mediaFilePath}.");
                }

                // Initialise OpenSSL & libsrtp, saves a couple of seconds for the first client connection.
                Console.WriteLine("Initialising OpenSSL and libsrtp...");
                DtlsHandshake.InitialiseOpenSSL();
                Srtp.InitialiseLibSrtp();

                Task.Run(DoDtlsHandshakeLoopbackTest).Wait();

                Console.WriteLine("Test DTLS handshake complete.");

                // Configure the web socket and the different end point handlers.
                int webSocketPort = (!String.IsNullOrEmpty(_webSocketPort)) ? Int32.Parse(_webSocketPort) : DEFAULT_WEB_SOCKET_PORT;
                _webSocketServer = new WebSocketServer(IPAddress.Any, webSocketPort, true);
                _webSocketServer.SslConfiguration.ServerCertificate          = wssCertificate;
                _webSocketServer.SslConfiguration.CheckCertificateRevocation = false;

                // Standard encrypted WebRtc stream.
                _webSocketServer.AddWebSocketService <SDPExchange>("/max", (sdpReceiver) =>
                {
                    sdpReceiver.MediaSource        = MediaSourceEnum.Max;
                    sdpReceiver.WebSocketOpened   += WebRtcStartCall;
                    sdpReceiver.SDPAnswerReceived += WebRtcAnswerReceived;
                });

                if (!String.IsNullOrEmpty(_testPatternImagePath) && File.Exists(_testPatternImagePath))
                {
                    _webSocketServer.AddWebSocketService <SDPExchange>("/testpattern", (sdpReceiver) =>
                    {
                        sdpReceiver.MediaSource        = MediaSourceEnum.TestPattern;
                        sdpReceiver.WebSocketOpened   += WebRtcStartCall;
                        sdpReceiver.SDPAnswerReceived += WebRtcAnswerReceived;
                    });
                }

                _webSocketServer.Start();

                Console.WriteLine($"Waiting for browser web socket connection to {_webSocketServer.Address}:{_webSocketServer.Port}...");

                // Initialise the Media Foundation library that will pull the samples from the mp4 file.
                _mediaSource = new MediaSource();
                _mediaSource.Init(_mediaFilePath, true);

                _ = Task.Run(ExpireConnections);

                while (!ct.IsCancellationRequested)
                {
                    await Task.Delay(1000);
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception WebRTCDaemon.Start. " + excp);
            }
            finally
            {
                Stop();
            }
        }
示例#17
0
        static void Main()
        {
            Console.WriteLine("ICE Console Test Program");
            Console.WriteLine("Press ctrl-c to exit.");

            if (!File.Exists(DTLS_CERTIFICATE_PATH))
            {
                throw new ApplicationException($"The DTLS certificate file could not be found at {DTLS_CERTIFICATE_PATH}.");
            }
            else if (!File.Exists(DTLS_KEY_PATH))
            {
                throw new ApplicationException($"The DTLS key file could not be found at {DTLS_KEY_PATH}.");
            }

            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream.
            ManualResetEvent        exitMre = new ManualResetEvent(false);

            AddConsoleLogger();

            // Initialise OpenSSL & libsrtp, saves a couple of seconds for the first client connection.
            Console.WriteLine("Initialising OpenSSL and libsrtp...");
            DtlsHandshake.InitialiseOpenSSL();
            Srtp.InitialiseLibSrtp();

            Task.Run(DoDtlsHandshakeLoopbackTest).Wait();

            Console.WriteLine("Test DTLS handshake complete.");

            // Start web socket.
            Console.WriteLine("Starting web socket server...");
            _webSocketServer = new WebSocketServer(IPAddress.Any, WEBSOCKET_PORT, true);
            _webSocketServer.SslConfiguration.ServerCertificate          = new System.Security.Cryptography.X509Certificates.X509Certificate2(WEBSOCKET_CERTIFICATE_PATH);
            _webSocketServer.SslConfiguration.CheckCertificateRevocation = false;
            //_webSocketServer.Log.Level = WebSocketSharp.LogLevel.Debug;
            _webSocketServer.AddWebSocketService <WebRtcClient>("/sendoffer", (client) =>
            {
                client.WebSocketOpened   += SendOffer;
                client.OnMessageReceived += WebSocketMessageReceived;
            });
            _webSocketServer.AddWebSocketService <WebRtcClient>("/receiveoffer", (client) =>
            {
                client.WebSocketOpened   += ReceiveOffer;
                client.OnMessageReceived += WebSocketMessageReceived;
            });
            _webSocketServer.Start();

            Console.WriteLine($"Waiting for browser web socket connection to {_webSocketServer.Address}:{_webSocketServer.Port}...");

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitMre.Set();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitMre.WaitOne();

            _webSocketServer.Stop();
        }
示例#18
0
        static void Main()
        {
            Console.WriteLine("WebRTC Server Sample Program");
            Console.WriteLine("Press ctrl-c to exit.");

            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream.
            ManualResetEvent        exitMre = new ManualResetEvent(false);

            AddConsoleLogger();

            if (!File.Exists(MP4_FILE_PATH))
            {
                throw new ApplicationException($"The media file at does not exist at {MP4_FILE_PATH}.");
            }

            // Initialise OpenSSL & libsrtp, saves a couple of seconds for the first client connection.
            Console.WriteLine("Initialising OpenSSL and libsrtp...");
            Dtls.InitialiseOpenSSL();
            Srtp.InitialiseLibSrtp();

            // Initialise the Media Foundation library that will pull the samples from the mp4 file.
            _mfSampleGrabber = new SIPSorceryMedia.MFSampleGrabber();
            _mfSampleGrabber.OnClockStartEvent             += OnClockStartEvent;
            _mfSampleGrabber.OnVideoResolutionChangedEvent += OnVideoResolutionChangedEvent;
            unsafe
            {
                _mfSampleGrabber.OnProcessSampleEvent += OnProcessSampleEvent;
            }
            Task.Run(() => _mfSampleGrabber.Run(MP4_FILE_PATH, true));

            // Hook up event handlers to send the media samples to the network.
            //InitMediaToWebRtcClients();

            // Start web socket.
            Console.WriteLine("Starting web socket server...");
            _webSocketServer = new WebSocketServer(IPAddress.Any, WEBSOCKET_PORT, true);
            _webSocketServer.SslConfiguration.ServerCertificate          = new System.Security.Cryptography.X509Certificates.X509Certificate2(WEBSOCKET_CERTIFICATE_PATH);
            _webSocketServer.SslConfiguration.CheckCertificateRevocation = false;
            //_webSocketServer.Log.Level = WebSocketSharp.LogLevel.Debug;
            _webSocketServer.AddWebSocketService <SDPExchange>("/", (sdpExchanger) =>
            {
                sdpExchanger.WebSocketOpened   += SendSDPOffer;
                sdpExchanger.SDPAnswerReceived += SDPAnswerReceived;
            });
            _webSocketServer.Start();

            Console.WriteLine($"Waiting for browser web socket connection to {_webSocketServer.Address}:{_webSocketServer.Port}...");

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitMre.Set();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitMre.WaitOne();

            _mfSampleGrabber.StopAndExit();
            _webSocketServer.Stop();
        }
示例#19
0
        static async Task Main()
        {
            Console.WriteLine("WebRTC No Signalling Server Sample Program");
            Console.WriteLine("Press ctrl-c to exit.");

            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream.
            ManualResetEvent        exitMre = new ManualResetEvent(false);

            AddConsoleLogger();

            // Initialise OpenSSL & libsrtp, saves a couple of seconds for the first client connection.
            Console.WriteLine("Initialising OpenSSL and libsrtp...");
            DtlsHandshake.InitialiseOpenSSL();
            Srtp.InitialiseLibSrtp();

            InitialiseTestPattern();

            Console.WriteLine($"Starting Peer Connection...");

            var pc = await StartPeerConnection();

            // Start the DTLS task before entering the ICE credentials to avoid DTLS client Hello retransmits.
            // Start the DTLS task immediately so that we are ready to receive the client Hello.
            // If it's missed it can take 10 or more seconds for the peer to retry.
            var dtlsTask = DoDtlsHandshake(pc);

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                _sendTestPatternTimer?.Dispose();
                exitMre.Set();
            };

            Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
            Console.WriteLine("THE SDP OFFER ABOVE NEEDS TO BE PASTED INTO YOUR BROWSER");
            Console.WriteLine();

            Console.WriteLine("Press enter when you the SDP answer is available and then enter the ICE username and password...");
            Console.ReadLine();

            Console.Write("Enter the remote peer ICE User (e.g. for 'a=ice-ufrag:tGXy' enter tGXy) => ");
            var remoteIceUser = Console.ReadLine();

            Console.Write("Enter the remote peer ICE Password (e.g. for 'a=ice-pwd:Icew1/BpwUIJLn2dBMbQyYPB' enter Icew1/BpwUIJLn2dBMbQyYPB) => ");
            var remoteIcePassword = Console.ReadLine();

            pc.SetRemoteCredentials(remoteIceUser, remoteIcePassword);

            var dtlsResult = await dtlsTask;

            logger.LogDebug($"dtls handshake result {dtlsResult}.");

            if (dtlsResult)
            {
                var remoteEP = pc.AudioDestinationEndPoint;
                pc.SetDestination(SDPMediaTypesEnum.audio, remoteEP, remoteEP);
            }
            else
            {
                pc.Close("dtls handshake failed.");
            }

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitMre.WaitOne();

            pc.Close("normal");
        }