WingMan – Blame information for rev 32

Subversion Repositories:
Rev:
Rev Author Line No. Line
32 office 1 using System;
2 using System.Threading;
3 using System.Threading.Tasks;
4 using Open.Nat;
5  
6 namespace WingMan.Discovery
7 {
8 public class Discovery : IDisposable
9 {
10 public delegate void PortMapFailed(object sender, DiscoveryFailedEventArgs args);
11  
12 public Discovery()
13 {
14 NatDiscoverer = new NatDiscoverer();
15 }
16  
17 public Discovery(CancellationTokenSource cancellationTokenSource, TaskScheduler taskScheduler) : this()
18 {
19 CancellationTokenSource = cancellationTokenSource;
20 TaskScheduler = taskScheduler;
21 }
22  
23 private static CancellationTokenSource CancellationTokenSource { get; set; }
24 private static NatDiscoverer NatDiscoverer { get; set; }
25 private static TaskScheduler TaskScheduler { get; set; }
26  
27 private static CancellationTokenSource UPnPCancellationTokenSource { get; set; }
28 private static CancellationTokenSource PMPCancellationTokenSource { get; set; }
29  
30 public void Dispose()
31 {
32 PMPCancellationTokenSource?.Dispose();
33 PMPCancellationTokenSource = null;
34  
35 PMPCancellationTokenSource?.Dispose();
36 PMPCancellationTokenSource = null;
37 }
38  
39 public event PortMapFailed OnPortMapFailed;
40  
41 public async Task<bool> CreateMapping(DiscoveryType type, int port)
42 {
43 switch (type)
44 {
45 case DiscoveryType.UPnP:
46 return await CreateUPnPMapping(port);
47 case DiscoveryType.PMP:
48 return await CreatePMPPortMapping(port);
49 default:
50 throw new ArgumentException("Unknown disocvery type");
51 }
52 }
53  
54 private async Task<bool> CreateUPnPMapping(int port)
55 {
56 try
57 {
58 UPnPCancellationTokenSource = new CancellationTokenSource();
59 var linkedCancellationTokenSource =
60 CancellationTokenSource.CreateLinkedTokenSource(UPnPCancellationTokenSource.Token,
61 CancellationTokenSource.Token);
62 var device = await NatDiscoverer.DiscoverDeviceAsync(PortMapper.Upnp, linkedCancellationTokenSource);
63 await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, "WingMan Host"));
64  
65 return true;
66 }
67 catch (Exception ex)
68 {
69 await Task.Delay(0, CancellationTokenSource.Token).ContinueWith(_ =>
70 OnPortMapFailed?.Invoke(this, new DiscoveryFailedEventArgs(DiscoveryType.UPnP, ex)),
71 CancellationTokenSource.Token, TaskContinuationOptions.None, TaskScheduler);
72  
73 return false;
74 }
75 }
76  
77 private async Task<bool> CreatePMPPortMapping(int port)
78 {
79 try
80 {
81 PMPCancellationTokenSource = new CancellationTokenSource();
82 var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(
83 PMPCancellationTokenSource.Token,
84 CancellationTokenSource.Token);
85 var device = await NatDiscoverer.DiscoverDeviceAsync(PortMapper.Pmp, linkedCancellationTokenSource);
86 await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, "WingMan Host"));
87 return true;
88 }
89 catch (Exception ex)
90 {
91 await Task.Delay(0, CancellationTokenSource.Token).ContinueWith(_ =>
92 OnPortMapFailed?.Invoke(this, new DiscoveryFailedEventArgs(DiscoveryType.PMP, ex)),
93 CancellationTokenSource.Token, TaskContinuationOptions.None, TaskScheduler);
94  
95 return false;
96 }
97 }
98 }
99 }