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."); }
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); } }