|
1 | | -using System; |
2 | | -using System.Collections.Generic; |
3 | | -using System.Linq; |
4 | | -using System.Text; |
5 | | -using System.Threading; |
6 | | -using System.Net; |
7 | | -using System.Net.Sockets; |
8 | | -//using System.Threading.Tasks; |
9 | | -using LabNation.DeviceInterface.Net; |
10 | | - |
11 | | -namespace LabNation.DeviceInterface.Hardware |
12 | | -{ |
13 | | - //class that provides raw HW access to the device |
14 | | - internal class InterfaceManagerZeroConf : InterfaceManager<InterfaceManagerZeroConf, SmartScopeInterfaceEthernet> |
15 | | - { |
16 | | - object pollLock = new object(); |
17 | | - bool pollThreadRunning; |
18 | | - Thread pollThread; |
19 | | - const int POLL_INTERVAL = 5000; |
20 | | - List<ServiceLocation> detectedServices = new List<ServiceLocation>(); |
21 | | - |
22 | | - class ServiceLocation |
23 | | - { |
24 | | - public IPAddress ip; |
25 | | - public int port; |
26 | | - public string name; |
27 | | - public ServiceLocation(IPAddress ip, int port, string name) |
28 | | - { |
29 | | - this.ip = ip; |
30 | | - this.port = port; |
31 | | - this.name = name; |
32 | | - } |
33 | | - public override bool Equals(object s) |
34 | | - { |
35 | | - if (!(s is ServiceLocation)) |
36 | | - return false; |
37 | | - ServiceLocation sl = (ServiceLocation)s; |
38 | | - return |
39 | | - this.ip.Equals(sl.ip) && |
40 | | - this.port == sl.port && |
41 | | - this.name == sl.name; |
42 | | - } |
43 | | - } |
44 | | - |
45 | | - Dictionary<ServiceLocation, SmartScopeInterfaceEthernet> createdInterfaces = new Dictionary<ServiceLocation, SmartScopeInterfaceEthernet>(); |
46 | | - |
47 | | - protected override void Initialize() |
48 | | - { |
49 | | - startPollThread(); |
50 | | - } |
51 | | - |
52 | | - private void startPollThread() |
53 | | - { |
54 | | - pollThread = new Thread(new ThreadStart(pollThreadStart)); |
55 | | - pollThread.Name = "ZeroConf poll thread"; |
56 | | - pollThreadRunning = true; |
57 | | - pollThread.Start(); |
58 | | - } |
59 | | - |
60 | | - private void pollThreadStart() |
61 | | - { |
62 | | - while (pollThreadRunning) |
63 | | - { |
64 | | - PollDevice(); //PollDevice contains the Thread.Sleep |
65 | | - } |
66 | | - } |
67 | | - |
68 | | - /*private async Task<IReadOnlyList<IZeroconfHost>> FindZeroConf() |
69 | | - { |
70 | | - IReadOnlyList<IZeroconfHost> results = await |
71 | | - ZeroconfResolver.ResolveAsync("_sss._tcp.local."); |
72 | | - return results; |
73 | | - } |
74 | | -
|
75 | | - async Task<List<ServiceLocation>> EnumerateAllServicesFromAllHosts() |
76 | | - { |
77 | | - ILookup<string, string> domains = await ZeroconfResolver.BrowseDomainsAsync(); |
78 | | - var responses = await ZeroconfResolver.ResolveAsync(domains.Select(g => g.Key)); |
79 | | - List<ServiceLocation> l = new List<ServiceLocation>(); |
80 | | - foreach (var resp in responses) |
81 | | - foreach (IService s in resp.Services.Values) |
82 | | - l.Add(new ServiceLocation(IPAddress.Parse(resp.IPAddress), s.Port, s.Name)); |
83 | | - return l; |
84 | | - }*/ |
85 | | - |
86 | | - Func<ServiceLocation, bool> nameFilter = new Func<ServiceLocation, bool>(x => x.name == Constants.SERVICE_TYPE + "." + Constants.REPLY_DOMAIN); |
87 | | - public override void PollDevice() |
88 | | - { |
89 | | - Common.Logger.Info("Polling ZeroConf"); |
90 | | - |
91 | | - throw new Exception("Need to implement a Linux-buildable ZeroConf solution"); |
92 | | - /*Task<List<ServiceLocation>> hostsTask = EnumerateAllServicesFromAllHosts(); |
93 | | -
|
94 | | - hostsTask.Wait(); |
95 | | - List<ServiceLocation> detectedServices = hostsTask.Result.Where(nameFilter).ToList(); |
96 | | -
|
97 | | - foreach (var kvp in createdInterfaces) |
98 | | - { |
99 | | - if (!kvp.Value.Connected) |
100 | | - { |
101 | | - LabNation.Common.Logger.Info("An ethernet interface was removed"); |
102 | | - onConnect(kvp.Value, false); |
103 | | - createdInterfaces.Remove(kvp.Key); |
104 | | - } |
105 | | - } |
106 | | -
|
107 | | - //handle connects |
108 | | - List<ServiceLocation> newInterfaces = detectedServices.Where(x => !createdInterfaces.ContainsKey(x)).ToList(); |
109 | | - foreach (ServiceLocation loc in detectedServices) |
110 | | - { |
111 | | - if (createdInterfaces.Where(x => x.Key.ip.Equals(loc.ip) && x.Key.port == loc.port).Count() == 0) |
112 | | - { |
113 | | - // A new interface |
114 | | - LabNation.Common.Logger.Info("A new SmartScopeServer was detected at "+loc.ip.ToString()+":"+loc.port.ToString()); |
115 | | - SmartScopeInterfaceEthernet ethif = new SmartScopeInterfaceEthernet(loc.ip, loc.port, OnInterfaceDisconnect); |
116 | | - if (ethif.Connected) |
117 | | - { |
118 | | - createdInterfaces.Add(loc, ethif); |
119 | | - if (onConnect != null) |
120 | | - onConnect(ethif, true); |
121 | | - } |
122 | | - else |
123 | | - { |
124 | | - LabNation.Common.Logger.Info("... failed connecting to SmartScopeServer at " + loc.ip.ToString() + ":" + loc.port.ToString()); |
125 | | - } |
126 | | - } |
127 | | - }*/ |
128 | | - } |
129 | | - |
130 | | - public void Destroy() |
131 | | - { |
132 | | - pollThreadRunning = false; |
133 | | - if(pollThread != null) |
134 | | - pollThread.Join(1000); |
135 | | - |
136 | | - } |
137 | | - |
138 | | - private void OnInterfaceDisconnect(SmartScopeInterfaceEthernet hardwareInterface) |
139 | | - { |
140 | | - //remove from list |
141 | | - if (createdInterfaces.ContainsValue(hardwareInterface)) |
142 | | - createdInterfaces.Remove(createdInterfaces.Single(x => x.Value == hardwareInterface).Key); |
143 | | - |
144 | | - //propage upwards (to DeviceManager) |
145 | | - onConnect(hardwareInterface, false); |
146 | | - |
147 | | - //send DISCONNECT command to server |
148 | | - hardwareInterface.Destroy(); |
149 | | - } |
150 | | - } |
151 | | -} |
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.Linq; |
| 4 | +using System.Text; |
| 5 | +using System.Threading; |
| 6 | +using System.Net; |
| 7 | +using System.Net.Sockets; |
| 8 | +using Mono.Zeroconf; |
| 9 | +using System.Threading.Tasks; |
| 10 | +using LabNation.DeviceInterface.Net; |
| 11 | + |
| 12 | +namespace LabNation.DeviceInterface.Hardware |
| 13 | +{ |
| 14 | + //class that provides raw HW access to the device |
| 15 | + internal class InterfaceManagerZeroConf : InterfaceManager<InterfaceManagerZeroConf, SmartScopeInterfaceEthernet> |
| 16 | + { |
| 17 | + object pollLock = new object(); |
| 18 | + bool pollThreadRunning; |
| 19 | + int polling = 0; |
| 20 | + Thread pollThread; |
| 21 | + const int POLL_INTERVAL = 5000; |
| 22 | + List<ServiceLocation> detectedServices = new List<ServiceLocation>(); |
| 23 | + |
| 24 | + class ServiceLocation |
| 25 | + { |
| 26 | + public IPAddress ip; |
| 27 | + public int port; |
| 28 | + public string name; |
| 29 | + public ServiceLocation(IPAddress ip, int port, string name) |
| 30 | + { |
| 31 | + this.ip = ip; |
| 32 | + this.port = port; |
| 33 | + this.name = name; |
| 34 | + } |
| 35 | + public override bool Equals(object s) |
| 36 | + { |
| 37 | + if (!(s is ServiceLocation)) |
| 38 | + return false; |
| 39 | + ServiceLocation sl = (ServiceLocation)s; |
| 40 | + return |
| 41 | + this.ip.Equals(sl.ip) && |
| 42 | + this.port == sl.port && |
| 43 | + this.name == sl.name; |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + Dictionary<ServiceLocation, SmartScopeInterfaceEthernet> createdInterfaces = new Dictionary<ServiceLocation, SmartScopeInterfaceEthernet>(); |
| 48 | + |
| 49 | + protected override void Initialize() |
| 50 | + { |
| 51 | + startPollThread(); |
| 52 | + } |
| 53 | + |
| 54 | + private void startPollThread() |
| 55 | + { |
| 56 | + pollThread = new Thread(new ThreadStart(pollThreadStart)); |
| 57 | + pollThread.Name = "ZeroConf poll thread"; |
| 58 | + pollThreadRunning = true; |
| 59 | + pollThread.Start(); |
| 60 | + } |
| 61 | + |
| 62 | + private void pollThreadStart() |
| 63 | + { |
| 64 | + while (pollThreadRunning) |
| 65 | + { |
| 66 | + System.Threading.Thread.Sleep(POLL_INTERVAL); |
| 67 | + if (polling == 0 && createdInterfaces.Count == 0) |
| 68 | + PollDevice(); |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + public override void PollDevice() |
| 73 | + { |
| 74 | + //browser needs to be renewed each time, as it's being disposed after Browse |
| 75 | + ServiceBrowser browser = new ServiceBrowser(); |
| 76 | + browser.ServiceAdded += delegate(object o, ServiceBrowseEventArgs args) |
| 77 | + { |
| 78 | + Console.WriteLine("Found Service: {0}", args.Service.Name); |
| 79 | + args.Service.Resolved += delegate(object o2, ServiceResolvedEventArgs args2) |
| 80 | + { |
| 81 | + polling++; |
| 82 | + IResolvableService s = (IResolvableService)args2.Service; |
| 83 | + |
| 84 | + ServiceLocation loc = new ServiceLocation(s.HostEntry.AddressList[0], s.Port, s.FullName); |
| 85 | + LabNation.Common.Logger.Info("A new ethernet interface was found"); |
| 86 | + SmartScopeInterfaceEthernet ethif = new SmartScopeInterfaceEthernet(loc.ip, loc.port, OnInterfaceDisconnect); |
| 87 | + if (ethif.Connected) |
| 88 | + { |
| 89 | + createdInterfaces.Add(loc, ethif); |
| 90 | + if (onConnect != null) |
| 91 | + onConnect(ethif, true); |
| 92 | + } |
| 93 | + else |
| 94 | + { |
| 95 | + LabNation.Common.Logger.Info("... but could not connect to ethernet interface"); |
| 96 | + } |
| 97 | + polling--; |
| 98 | + }; |
| 99 | + args.Service.Resolve(); |
| 100 | + }; |
| 101 | + |
| 102 | + //go for it! |
| 103 | + Common.Logger.Info("Polling ZeroConf"); |
| 104 | + browser.Browse("_sss._tcp", "local"); |
| 105 | + } |
| 106 | + |
| 107 | + public void Destroy() |
| 108 | + { |
| 109 | + foreach (var hw in createdInterfaces) |
| 110 | + hw.Value.Destroy(); |
| 111 | + |
| 112 | + pollThreadRunning = false; |
| 113 | + pollThread.Join(POLL_INTERVAL); |
| 114 | + } |
| 115 | + |
| 116 | + private void OnInterfaceDisconnect(SmartScopeInterfaceEthernet hardwareInterface) |
| 117 | + { |
| 118 | + //remove from list |
| 119 | + if (createdInterfaces.ContainsValue(hardwareInterface)) |
| 120 | + createdInterfaces.Remove(createdInterfaces.Single(x => x.Value == hardwareInterface).Key); |
| 121 | + |
| 122 | + //propage upwards (to DeviceManager) |
| 123 | + onConnect(hardwareInterface, false); |
| 124 | + |
| 125 | + //send DISCONNECT command to server |
| 126 | + hardwareInterface.Destroy(); |
| 127 | + } |
| 128 | + } |
| 129 | +} |
0 commit comments