예제 #1
0
        public void Run(String driverdir, Action <string> driverfoundcallback = null)
        {
            drivers           = new Dictionary <string, BonDriverWithPrivilege>();
            listeners         = new Dictionary <string, TSListener>();
            TunerThreads      = new Dictionary <string, Thread>();
            TunerListenerList = new Dictionary <string, List <TSListener> >();

            var driverfilenames = from filename in System.IO.Directory.EnumerateFiles(driverdir)
                                  where filename.Substring(filename.Length - 4) == ".dll" && filename.IndexOf("BonDriver_File") == -1
                                  select filename;

            foreach (string e in driverfilenames)
            {
                try
                {
                    BonDriverWithPrivilege d = new BonDriverWithPrivilege(e);
                    string dname             = e.Substring(e.LastIndexOf(@"\") + 1);
                    Console.WriteLine(string.Format("Path: {0}, Name: {1}", e, dname));

                    if (!d.OpenTuner())
                    {
                        System.Threading.Thread.Sleep(500);
                        if (!d.OpenTuner())
                        {
                            d.Release();
                            Console.WriteLine(string.Format("Failed: {0}", dname));
                            continue;
                        }
                    }
                    drivers[dname]           = d;
                    TunerListenerList[dname] = new List <TSListener>();
                    Thread tt = new Thread(TunerThread);
                    TunerThreads.Add(dname, tt);
                    tt.Start(new Context(this, dname));
                    driverfoundcallback?.Invoke(dname);
                }
                catch (Exception ex)
                {
                }
            }

            // BonDriver 読み込み完了
            ControlTcpListener      = new TcpListener(IPAddress.Any, cport);
            ControlConnectionThread = new Thread(ControlConnectionAccept);
            ControlConnectionThread.Start(new Context(this, ControlTcpListener));
            VideoTcpListener      = new TcpListener(IPAddress.Any, vport);
            VideoConnectionThread = new Thread(VideoConnectionAccept);
            VideoConnectionThread.Start(new Context(this, VideoTcpListener));

            Console.WriteLine("Running.");
        }
예제 #2
0
        static void ConnectionProc(object ctx)
        {
            Context  c = (Context)ctx;
            TSServer s = c.cls;

            var guid = System.Guid.NewGuid().ToString();

            s.Log(guid, "Control connection has established.");

            var tc = (TcpClient)c.obj;
            var ns = tc.GetStream();
            var sr = new System.IO.StreamReader(ns);
            var sw = new System.IO.StreamWriter(ns);

            sw.AutoFlush = true;
            var listener = new TSListener()
            {
                ControlConnection = tc, GUID = guid, ControlConnectionStreamReader = sr
            };

            s.listeners[guid] = listener;
            sw.WriteLine(guid);

            s.Log(guid, "Send GUID to client.");

            var begin = DateTime.Now;

            while (listener.VideoConnection == null)
            {
                if (DateTime.Now - begin > new TimeSpan(0, 0, 5))
                {
                    tc.Close();
                    s.listeners.Remove(guid);
                    s.Log(guid, "Waiting Video connection timed out.");
                    return;
                }
                System.Threading.Thread.Sleep(1);
            }
            listener.VideoConnection.SendTimeout = 500;
            s.Log(guid, "Video connection has been established.");

            BonDriverWithPrivilege driver = null;
            string lasttunername          = null;
            bool   hasPrivilege           = false;

            try
            {
                while (true)
                {
                    var msg = ReadToMessageEnd(sr);
                    if (String.IsNullOrEmpty(msg))
                    {
                        break;
                    }
                    //s.Log(guid, String.Format("Message has been arrived:\n{0}", msg));

                    var    xdoc = System.Xml.Linq.XDocument.Parse(msg);
                    string cmd  = xdoc.XPathSelectElement("/command/name").Value;
                    var    args = from e in xdoc.XPathSelectElements("/command/args/arg") select e;

                    switch (cmd)
                    {
                    case "OpenTuner":
                    {
                        var name = xdoc.XPathSelectElement("/command/args/arg[@name=\"Name\"]");
                        if (name == null)
                        {
                            SendInvalidParameters(sw);
                        }
                        else
                        {
                            if (s.drivers.ContainsKey(name.Value))
                            {
                                driver = s.drivers[name.Value];
                                //TunerListenerList[name.Value].Add(listener);
                                lasttunername = name.Value;

                                var hostname    = xdoc.XPathSelectElement("/command/args/arg[@name=\"HostName\"]");
                                var processname = xdoc.XPathSelectElement("/command/args/arg[@name=\"ProcessName\"]");
                                var processid   = xdoc.XPathSelectElement("/command/args/arg[@name=\"ProcessID\"]");

                                listener.HostName    = hostname == null ? null : hostname.Value;
                                listener.ProcessName = processname == null ? null : processname.Value;
                                if (processid != null)
                                {
                                    int pid;
                                    if (int.TryParse(processid.Value, out pid))
                                    {
                                        listener.ProcessID = pid;
                                    }
                                }

                                sw.WriteLine("<response status=\"200\" />\r\n");
                                var priv = xdoc.XPathSelectElement("/command/args/arg[@name=\"Privilege\"]");
                                if (priv != null)
                                {
                                    hasPrivilege = priv.Value == "True";
                                    if (hasPrivilege)
                                    {
                                        driver.AddPrivilegeClient(guid);
                                    }
                                }
                                s.Log(guid, String.Format("Open tuner {0}{1} from {2}:{3}({4}).", name.Value, hasPrivilege ? " with privilege" : "", listener.HostName, listener.ProcessName, listener.ProcessID));
                            }
                            else
                            {
                                sw.WriteLine("<response status=\"402\">Invalid tuner name.</response>\r\n");
                            }
                        }
                        break;
                    }

                    case "SetChannel":
                    {
                        UInt32 space, channel;
                        var    success = true;

                        var e_space   = xdoc.XPathSelectElement("/command/args/arg[@name=\"Space\"]");
                        var e_channel = xdoc.XPathSelectElement("/command/args/arg[@name=\"Channel\"]");
                        if (e_space == null || e_channel == null)
                        {
                            SendInvalidParameters(sw);
                            break;
                        }

                        success |= UInt32.TryParse(e_space.Value, out space);
                        success |= UInt32.TryParse(e_channel.Value, out channel);
                        if (!success)
                        {
                            SendInvalidParameters(sw); break;
                        }

                        if (driver == null)
                        {
                            SendTunerIsNotOpened(sw); break;
                        }

                        s.Log(guid, String.Format("Set channel. (space: {0}, channel: {1})", space, channel));

                        var cursp = driver.GetCurSpace();
                        var curch = driver.GetCurChannel();

                        if (space == cursp && channel == curch)
                        {
                            sw.WriteLine(String.Format("<response status=\"200\">{0}</response>\r\n", true));
                        }
                        else
                        {
                            if (!hasPrivilege && driver.IsPrivilegeClientAvailable)
                            {
                                s.Log(guid, "\"Set channel\" is denied because privilege client is available.");
                                sw.WriteLine(String.Format("<response status=\"405\">Privilege client is available.</response>\r\n"));
                            }
                            else
                            {
                                var result = driver.SetChannel(space, channel);
                                sw.WriteLine(String.Format("<response status=\"200\">{0}</response>\r\n", result));
                            }
                        }

                        if (!s.TunerListenerList[lasttunername].Contains(listener))
                        {
                            s.TunerListenerList[lasttunername].Add(listener);
                            s.Log(guid, "Add Listener to TLL.");
                        }

                        break;
                    }

                    case "CloseTuner":
                        // nothing to do
                        // you haven't to do anything.
                        break;

                    case "GetSignalLevel":
                    {
                        if (driver == null)
                        {
                            SendTunerIsNotOpened(sw); break;
                        }

                        var siglevel = driver.GetSignalLevel();
                        sw.WriteLine(String.Format("<response status=\"200\">{0}</response>\r\n", siglevel));
                        s.Log(guid, String.Format("GetSignalLevel: {0}", siglevel));
                        break;
                    }

                    case "EnumTuningSpace":
                    {
                        var e_space = xdoc.XPathSelectElement("/command/args/arg[@name=\"Space\"]");
                        if (e_space == null)
                        {
                            SendInvalidParameters(sw); break;
                        }

                        UInt32 space;
                        if (!UInt32.TryParse(e_space.Value, out space))
                        {
                            SendInvalidParameters(sw); break;
                        }

                        if (driver == null)
                        {
                            SendTunerIsNotOpened(sw); break;
                        }

                        s.Log(guid, String.Format("EnumTuningSpace. (space: {0})", space));
                        var result = driver.EnumTuningSpace(space);
                        sw.WriteLine(String.Format("<response status=\"{0}\">{1}</response>\r\n", result == null ? 404 : 200, result));
                        break;
                    }

                    case "EnumChannelName":
                    {
                        UInt32 space, channel;
                        var    success = true;

                        var e_space   = xdoc.XPathSelectElement("/command/args/arg[@name=\"Space\"]");
                        var e_channel = xdoc.XPathSelectElement("/command/args/arg[@name=\"Channel\"]");
                        if (e_space == null || e_channel == null)
                        {
                            SendInvalidParameters(sw); break;
                        }

                        success |= UInt32.TryParse(e_space.Value, out space);
                        success |= UInt32.TryParse(e_channel.Value, out channel);
                        if (!success)
                        {
                            SendInvalidParameters(sw); break;
                        }

                        if (driver == null)
                        {
                            SendTunerIsNotOpened(sw); break;
                        }

                        s.Log(guid, String.Format("EnumChannelName. (space: {0}, channel: {1})", space, channel));

                        var result = driver.EnumChannelName(space, channel);
                        sw.WriteLine(String.Format("<response status=\"{0}\">{1}</response>\r\n", result == null ? 404 : 200, result));
                        break;
                    }

                    case "GetCurSpace":
                    {
                        if (driver == null)
                        {
                            SendTunerIsNotOpened(sw); break;
                        }

                        var csp = driver.GetCurSpace();
                        sw.WriteLine(String.Format("<response status=\"200\">{0}</response>\r\n", csp));
                        s.Log(guid, String.Format("GetCurSpace: {0}", csp));
                        break;
                    }

                    case "GetCurChannel":
                    {
                        if (driver == null)
                        {
                            SendTunerIsNotOpened(sw); break;
                        }

                        var cch = driver.GetCurChannel();
                        sw.WriteLine(String.Format("<response status=\"200\">{0}</response>\r\n", cch));
                        s.Log(guid, String.Format("GetCurChannel: {0}", cch));
                        break;
                    }

                    default:
                        // invalid command
                        sw.WriteLine(String.Format("<response status=\"499\">Invalid command.</response>\r\n"));
                        s.Log(guid, "Invalid command.");
                        break;
                    }
                }
            }
            catch (System.IO.IOException)
            {
            }
            catch (System.ObjectDisposedException)
            {
            }
            finally
            {
                s.Log(guid, "Control connection has been disconnected.");

                if (listener.VideoConnection != null)
                {
                    s.Log(guid, "Video connection has been disconnected.");
                    listener.VideoConnection.Close();
                    listener.VideoConnection = null;
                }
                if (driver != null)
                {
                    if (hasPrivilege)
                    {
                        driver.RemovePrivilegeClient(guid);
                    }
                    if (s.TunerListenerList[lasttunername].Contains(listener))
                    {
                        s.TunerListenerList[lasttunername].Remove(listener);
                        s.Log(guid, "Remove Listener from TLL.");
                    }
                }
                s.listeners.Remove(guid);
            }
        }