public RtspStatusCode Options()
        {
            if ((_rtspSocket == null))
            {
                Connect();
            }
            RtspRequest  request = null;
            RtspResponse response;

            if (string.IsNullOrEmpty(_rtspSessionId))
            {
                request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
            }
            else
            {
                request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
                request.Headers.Add("Session", _rtspSessionId);
            }
            SendRequest(request);
            ReceiveResponse(out response);
            string sessionHeader;

            if (!response.Headers.TryGetValue("Session", out sessionHeader))
            {
                Logger.Error(string.Format("Failed to tune, not able to locate session header in RTSP Options response"));
            }
            ProcessSessionHeader(sessionHeader, "Options");
            string optionsHeader;

            if (!response.Headers.TryGetValue("Public", out optionsHeader))
            {
                Logger.Error(string.Format("Failed to tune, not able to Options header in RTSP Options response"));
            }
            return(response.StatusCode);
        }
        public RtspStatusCode TearDown()
        {
            if ((_rtspSocket == null))
            {
                Connect();
            }
            RtspResponse response;
            var          request = new RtspRequest(RtspMethod.Teardown, string.Format("rtsp://{0}:{1}/stream={2}", _address, 554, _rtspStreamId), 1, 0);

            request.Headers.Add("Session", _rtspSessionId);
            SendRequest(request);
            ReceiveResponse(out response);
            if (_rtpListener != null)
            {
                _rtpListener.Dispose();
                _rtpListener.PacketReceived -= new RtpListener.PacketReceivedHandler(RtpPacketReceived);
                _rtpListener = null;
            }
            if (_rtcpListener != null)
            {
                _rtcpListener.Dispose();
                _rtcpListener.PacketReceived -= new RtcpListener.PacketReceivedHandler(RtcpPacketReceived);
                _rtcpListener = null;
            }
            StopKeepAliveThread();
            //Disconnect();
            _rtspSessionId = string.Empty;
            return(response.StatusCode);
        }
        public RtspStatusCode Describe()
        {
            if ((_rtspSocket == null))
            {
                Connect();
            }
            RtspRequest  request = null;
            RtspResponse response;
            var          locked  = false;
            var          level   = 0;
            var          quality = 0;

            if (string.IsNullOrEmpty(_rtspSessionId))
            {
                request = new RtspRequest(RtspMethod.Describe, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
                request.Headers.Add("Accept", "application/sdp");
            }
            else
            {
                request = new RtspRequest(RtspMethod.Describe, string.Format("rtsp://{0}:{1}/stream={2}", _address, 554, _rtspStreamId), 1, 0);
                request.Headers.Add("Accept", "application/sdp");
                request.Headers.Add("Session", _rtspSessionId);
            }
            SendRequest(request);
            ReceiveResponse(out response);
            string sessionHeader;

            if (!response.Headers.TryGetValue("Session", out sessionHeader))
            {
                Logger.Error(string.Format("Failed to tune, not able to locate session header in RTSP Describe response"));
            }
            ProcessSessionHeader(sessionHeader, "Describe");
            var m = RegexDescribeResponseSignalInfo.Match(response.Body);

            if (m.Success)
            {
                locked  = m.Groups[2].Captures[0].Value.Equals("1");
                level   = int.Parse(m.Groups[1].Captures[0].Value) * 100 / 255;  // level: 0..255 => 0..100
                quality = int.Parse(m.Groups[3].Captures[0].Value) * 100 / 15;   // quality: 0..15 => 0..100
            }
            OnSignalInfo(new SignalInfoArgs(locked, level, quality));

            /*
             *  v=0
             *  o=- 1378633020884883 1 IN IP4 192.168.2.108
             *  s=SatIPServer:1 4
             *  t=0 0
             *  a=tool:idl4k
             *  m=video 52780 RTP/AVP 33
             *  c=IN IP4 0.0.0.0
             *  b=AS:5000
             *  a=control:stream=4
             *  a=fmtp:33 ver=1.0;tuner=1,0,0,0,12344,h,dvbs2,,off,,22000,34;pids=0,100,101,102,103,106
             *  =sendonly
             */
            return(response.StatusCode);
        }
        public RtspStatusCode Play(string query)
        {
            if ((_rtspSocket == null))
            {
                Connect();
            }
            RtspResponse response;
            string       data = string.Empty;

            if (string.IsNullOrEmpty(query))
            {
                data = string.Format("rtsp://{0}:{1}/stream={2}", _address,
                                     554, _rtspStreamId);
            }
            else
            {
                data = string.Format("rtsp://{0}:{1}/stream={2}?{3}", _address,
                                     554, _rtspStreamId, query);
            }
            var request = new RtspRequest(RtspMethod.Play, data, 1, 0);

            request.Headers.Add("Session", _rtspSessionId);
            SendRequest(request);
            ReceiveResponse(out response);
            string sessionHeader;

            if (!response.Headers.TryGetValue("Session", out sessionHeader))
            {
                Logger.Error(string.Format("Failed to tune, not able to locate Session header in RTSP Play response"));
            }
            ProcessSessionHeader(sessionHeader, "Play");
            string rtpinfoHeader;

            if (!response.Headers.TryGetValue("RTP-Info", out rtpinfoHeader))
            {
                Logger.Error(string.Format("Failed to tune, not able to locate Rtp-Info header in RTSP Play response"));
            }
            return(response.StatusCode);
        }
 private void KeepAlive()
 {
     try
     {
         while (!_keepAliveThreadStopEvent.WaitOne(RtspSessionTimeToLive))    // -5 seconds to avoid timeout
         {
             if ((_rtspSocket == null))
             {
                 Connect();
             }
             RtspRequest request = null;
             if (string.IsNullOrEmpty(_rtspSessionId))
             {
                 request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
             }
             else
             {
                 request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
                 request.Headers.Add("Session", _rtspSessionId);
             }
             RtspResponse response;
             SendRequest(request);
             ReceiveResponse(out response);
             if (response.StatusCode != RtspStatusCode.Ok)
             {
                 Logger.Critical("SAT>IP : keep-alive request/response failed, non-OK RTSP OPTIONS status code {0} {1}", response.StatusCode, response.ReasonPhrase);
             }
         }
     }
     catch (ThreadAbortException)
     {
     }
     catch (Exception ex)
     {
         Logger.Error(ex.ToString(), "SAT>IP : keep-alive thread exception");
         return;
     }
     Logger.Info("SAT>IP : keep-alive thread stopping");
 }
 private void SendRequest(RtspRequest request)
 {
     if (_rtspSocket == null)
     {
         Connect();
     }
     try
     {
         request.Headers.Add("CSeq", _rtspSequenceNum.ToString());
         _rtspSequenceNum++;
         byte[] requestBytes = request.Serialise();
         if (_rtspSocket != null)
         {
             var requestBytesCount = _rtspSocket.Send(requestBytes, requestBytes.Length, SocketFlags.None);
             if (requestBytesCount < 1)
             {
             }
         }
     }
     catch (Exception e)
     {
         Logger.Error(e.Message);
     }
 }
        public RtspStatusCode Setup(string query, TransmissionMode transmissionmode)
        {
            RtspRequest  request = null;
            RtspResponse response;

            if ((_rtspSocket == null))
            {
                Connect();
            }
            if (string.IsNullOrEmpty(_rtspSessionId))
            {
                request = new RtspRequest(RtspMethod.Setup, string.Format("rtsp://{0}:{1}/?{2}", _address, 554, query), 1, 0);
                switch (transmissionmode)
                {
                case TransmissionMode.Multicast:
                    request.Headers.Add("Transport", string.Format("RTP/AVP;{0}", transmissionmode.ToString().ToLower()));
                    break;

                case TransmissionMode.Unicast:
                    var activeTcpConnections = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections();
                    var usedPorts            = new HashSet <int>();
                    foreach (var connection in activeTcpConnections)
                    {
                        usedPorts.Add(connection.LocalEndPoint.Port);
                    }
                    for (var port = 40000; port <= 65534; port += 2)
                    {
                        if (!usedPorts.Contains(port) && !usedPorts.Contains(port + 1))
                        {
                            _rtpPort  = port;
                            _rtcpPort = port + 1;
                            break;
                        }
                    }
                    request.Headers.Add("Transport", string.Format("RTP/AVP;{0};client_port={1}-{2}", transmissionmode.ToString().ToLower(), _rtpPort, _rtcpPort));
                    break;
                }
            }
            else
            {
                request = new RtspRequest(RtspMethod.Setup, string.Format("rtsp://{0}:{1}/?{2}", _address, 554, query), 1, 0);
                switch (transmissionmode)
                {
                case TransmissionMode.Multicast:
                    request.Headers.Add("Session", _rtspSessionId);
                    request.Headers.Add("Transport", string.Format("RTP/AVP;{0}", transmissionmode.ToString().ToLower()));
                    break;

                case TransmissionMode.Unicast:
                    request.Headers.Add("Session", _rtspSessionId);
                    request.Headers.Add("Transport", string.Format("RTP/AVP;{0};client_port={1}-{2}", transmissionmode.ToString().ToLower(), _rtpPort, _rtcpPort));
                    break;
                }
            }
            SendRequest(request);
            ReceiveResponse(out response);
            if (response.StatusCode == RtspStatusCode.Ok)
            {
                if (!response.Headers.TryGetValue("com.ses.streamID", out _rtspStreamId))
                {
                    Logger.Error(string.Format("Failed to tune, not able to locate Stream ID header in RTSP SETUP response"));
                }
                string sessionHeader;
                if (!response.Headers.TryGetValue("Session", out sessionHeader))
                {
                    Logger.Error(string.Format("Failed to tune, not able to locate Session header in RTSP SETUP response"));
                }
                ProcessSessionHeader(sessionHeader, "Setup");
                string transportHeader;
                if (!response.Headers.TryGetValue("Transport", out transportHeader))
                {
                    Logger.Error(string.Format("Failed to tune, not able to locate Transport header in RTSP SETUP response"));
                }
                ProcessTransportHeader(transportHeader);

                StartKeepAliveThread();
                //if (_rtpListener == null)
                //{
                //    _rtpListener = new RtpListener(_destination, _rtpPort, transmissionmode);
                //    _rtpListener.PacketReceived += new RtpListener.PacketReceivedHandler(RtpPacketReceived);
                //    _rtpListener.StartRtpListenerThread();
                //}
                if (_rtcpListener == null)
                {
                    _rtcpListener = new RtcpListener(Destination, _rtcpPort, transmissionmode);
                    _rtcpListener.PacketReceived += new RtcpListener.PacketReceivedHandler(RtcpPacketReceived);
                    _rtcpListener.StartRtcpListenerThread();
                }
            }
            return(response.StatusCode);
        }