HamBook – Diff between revs 46 and 54
?pathlinks?
Rev 46 | Rev 54 | |||
---|---|---|---|---|
Line 1... | Line -... | |||
1 | using HamBook.Radios.Generic; |
- | ||
2 | using HamBook.Radios; |
- | ||
3 | using System; |
1 | using System; |
|
4 | using System.Collections.Generic; |
2 | using System.IO; |
|
5 | using System.IO.Ports; |
3 | using System.Media; |
|
6 | using System.Linq; |
4 | using System.Reflection; |
|
7 | using System.Text; |
5 | using System.Text; |
|
8 | using System.Threading; |
6 | using System.Threading; |
|
9 | using System.Threading.Tasks; |
7 | using System.Threading.Tasks; |
|
10 | using Serilog; |
8 | using Configuration; |
|
11 | using HamBook.Properties; |
9 | using HamBook.Properties; |
|
12 | using Serilog.Events; |
10 | using HamBook.Radios; |
|
13 | using System.Media; |
- | ||
14 | using System.Reflection; |
11 | using HamBook.Radios.Generic; |
|
15 | using RJCP.IO.Ports; |
12 | using RJCP.IO.Ports; |
|
16 | using System.Diagnostics; |
- | ||
17 | using System.IO; |
13 | using Serilog; |
|
18 | using Toasts; |
14 | using Toasts; |
|
19 | using System.Drawing; |
- | ||
20 | using Configuration; |
- | ||
21 | using System.Security.Cryptography; |
- | ||
22 | using Org.BouncyCastle.Crypto.Engines; |
- | ||
Line 23... | Line 15... | |||
23 | |
15 | |
|
24 | namespace HamBook |
16 | namespace HamBook |
|
25 | { |
17 | { |
|
26 | public class BandScan |
18 | public class BandScan |
|
- | 19 | { |
||
27 | { |
20 | private readonly CatAssemblies _catAssemblies; |
|
- | 21 | private readonly Configuration.Configuration _configuration; |
||
- | 22 | private readonly int _maxFrequency; |
||
- | 23 | private readonly int _minFrequency; |
||
- | 24 | private readonly SerialPortStream _serialPort; |
||
28 | private CancellationTokenSource _scanningCancellationTokenSource; |
25 | private int _currentFrequency; |
|
- | 26 | private CancellationToken _scanningCancellationToken; |
||
29 | private CancellationToken _scanningCancellationToken; |
27 | private CancellationTokenSource _scanningCancellationTokenSource; |
|
30 | private Thread _scanThread; |
- | ||
31 | private CatAssemblies _catAssemblies; |
- | ||
32 | private int _minFrequency; |
- | ||
33 | private int _maxFrequency; |
- | ||
34 | private SerialPortStream _serialPort; |
- | ||
35 | private Configuration.Configuration _configuration; |
- | ||
Line 36... | Line 28... | |||
36 | private int _currentFrequency; |
28 | private Thread _scanThread; |
|
37 | |
29 | |
|
38 | private BandScan() |
30 | private BandScan() |
|
Line 39... | Line 31... | |||
39 | { |
31 | { |
|
- | 32 | } |
||
40 | } |
33 | |
|
41 | |
34 | public BandScan(CatAssemblies catAssemblies, int min, int max, SerialPortStream serialPort, |
|
42 | public BandScan(CatAssemblies catAssemblies, int min, int max, SerialPortStream serialPort, Configuration.Configuration configuration) : this() |
35 | Configuration.Configuration configuration) : this() |
|
43 | { |
36 | { |
|
44 | _catAssemblies = catAssemblies; |
37 | _catAssemblies = catAssemblies; |
|
45 | _minFrequency = min; |
38 | _minFrequency = min; |
|
46 | _maxFrequency = max; |
- | ||
47 | _serialPort = serialPort; |
39 | _maxFrequency = max; |
|
Line 48... | Line 40... | |||
48 | _configuration = configuration; |
40 | _serialPort = serialPort; |
|
49 | |
41 | _configuration = configuration; |
|
50 | } |
42 | } |
|
51 | |
43 | |
|
52 | public void Start(int stepFrequency, int pauseTime, int pauseDetectTime, bool autoTune = false) |
44 | public void Start(int stepFrequency, int pauseTime, int pauseDetectTime, bool autoTune = false) |
|
53 | { |
- | ||
54 | if (_scanThread != null) |
- | ||
55 | { |
- | ||
Line 56... | Line 45... | |||
56 | if (!_scanningCancellationToken.IsCancellationRequested) |
45 | { |
|
57 | { |
46 | if (_scanThread != null) |
|
58 | _scanningCancellationTokenSource.Cancel(); |
47 | { |
|
Line 59... | Line 48... | |||
59 | } |
48 | if (!_scanningCancellationToken.IsCancellationRequested) _scanningCancellationTokenSource.Cancel(); |
|
60 | |
49 | |
|
Line 61... | Line 50... | |||
61 | _scanThread.Join(); |
50 | _scanThread.Join(); |
|
62 | _scanThread = null; |
51 | _scanThread = null; |
|
63 | } |
52 | } |
|
Line 64... | Line 53... | |||
64 | |
53 | |
|
65 | _scanningCancellationTokenSource = new CancellationTokenSource(); |
54 | _scanningCancellationTokenSource = new CancellationTokenSource(); |
|
66 | _scanningCancellationToken = _scanningCancellationTokenSource.Token; |
55 | _scanningCancellationToken = _scanningCancellationTokenSource.Token; |
|
67 | |
56 | |
|
68 | _scanThread = new Thread(new ParameterizedThreadStart(Scan)); |
57 | _scanThread = new Thread(Scan); |
|
69 | _scanThread.Start(new BandScanParameters(stepFrequency, pauseTime, pauseDetectTime, autoTune)); |
- | ||
70 | } |
- | ||
71 | |
- | ||
Line 72... | Line 58... | |||
72 | public void Stop() |
58 | _scanThread.Start(new BandScanParameters(stepFrequency, pauseTime, pauseDetectTime, autoTune)); |
|
73 | { |
59 | } |
|
74 | if (_scanThread != null) |
60 | |
|
75 | { |
61 | public void Stop() |
|
Line 76... | Line 62... | |||
76 | if (!_scanningCancellationToken.IsCancellationRequested) |
62 | { |
|
77 | { |
63 | if (_scanThread != null) |
|
78 | _scanningCancellationTokenSource.Cancel(); |
64 | { |
|
Line 79... | Line 65... | |||
79 | } |
65 | if (!_scanningCancellationToken.IsCancellationRequested) _scanningCancellationTokenSource.Cancel(); |
|
80 | |
- | ||
81 | _scanThread.Join(); |
- | ||
82 | _scanThread = null; |
- | ||
Line 83... | Line 66... | |||
83 | } |
66 | |
|
Line 84... | Line 67... | |||
84 | } |
67 | _scanThread.Join(); |
|
85 | |
68 | _scanThread = null; |
|
86 | private async void Scan(object obj) |
- | ||
87 | { |
69 | } |
|
Line 88... | Line 70... | |||
88 | var bandScanParameters = (BandScanParameters)obj; |
70 | } |
|
89 | |
71 | |
|
90 | if (!_serialPort.IsOpen) |
72 | private async void Scan(object obj) |
|
Line 91... | Line 73... | |||
91 | { |
73 | { |
|
- | 74 | var bandScanParameters = (BandScanParameters)obj; |
||
92 | _serialPort.Open(); |
75 | |
|
93 | } |
76 | if (!_serialPort.IsOpen) _serialPort.Open(); |
|
Line 94... | Line 77... | |||
94 | |
77 | |
|
- | 78 | _serialPort.DiscardInBuffer(); |
||
95 | _serialPort.DiscardInBuffer(); |
79 | |
|
Line 96... | Line 80... | |||
96 | |
80 | try |
|
97 | try |
81 | { |
|
98 | { |
82 | _currentFrequency = _minFrequency; |
|
- | 83 | |
||
Line 99... | Line 84... | |||
99 | |
84 | do |
|
100 | _currentFrequency = _minFrequency; |
85 | { |
|
101 | |
86 | var taskCompletionSource = new TaskCompletionSource<bool>(); |
|
Line 102... | Line 87... | |||
102 | do |
87 | |
|
103 | { |
88 | using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly() |
|
104 | var taskCompletionSource = new TaskCompletionSource<bool>(); |
89 | .GetManifestResourceStream("HamBook.Effects.pot.wav"))) |
|
- | 90 | { |
||
Line 105... | Line 91... | |||
105 | |
91 | soundPlayer.Play(); |
|
106 | using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav"))) |
- | ||
107 | { |
- | ||
108 | soundPlayer.Play(); |
- | ||
109 | |
92 | |
|
110 | await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency }, _scanningCancellationToken); |
93 | await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency }, |
|
111 | } |
94 | _scanningCancellationToken); |
|
112 | |
95 | } |
|
113 | if (bandScanParameters.AutoTune) |
96 | |
|
114 | { |
- | ||
115 | await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON }, _scanningCancellationToken); |
97 | if (bandScanParameters.AutoTune) |
|
Line 116... | Line 98... | |||
116 | |
98 | { |
|
- | 99 | await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON }, |
||
Line 117... | Line 100... | |||
117 | do |
100 | _scanningCancellationToken); |
|
118 | { |
101 | |
|
119 | await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken); |
102 | do |
|
Line 120... | Line 103... | |||
120 | |
103 | { |
|
121 | try |
104 | await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken); |
|
122 | { |
105 | |
|
- | 106 | try |
||
Line 123... | Line 107... | |||
123 | var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _scanningCancellationToken); |
107 | { |
|
124 | |
- | ||
125 | if (tuneState != TunerState.TUNER_ON) |
- | ||
126 | { |
- | ||
127 | break; |
108 | var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, |
|
128 | } |
109 | _scanningCancellationToken); |
|
129 | } |
110 | |
|
130 | catch (Exception) |
111 | if (tuneState != TunerState.TUNER_ON) break; |
|
131 | { |
112 | } |
|
132 | // retry |
- | ||
133 | } |
113 | catch (Exception) |
|
134 | |
114 | { |
|
Line 135... | Line 115... | |||
135 | } while (!_scanningCancellationToken.IsCancellationRequested); |
115 | // retry |
|
Line 136... | Line 116... | |||
136 | |
116 | } |
|
137 | await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START }, _scanningCancellationToken); |
117 | } while (!_scanningCancellationToken.IsCancellationRequested); |
|
138 | |
118 | |
|
139 | do |
119 | await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START }, |
|
140 | { |
- | ||
141 | await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken); |
120 | _scanningCancellationToken); |
|
142 | |
121 | |
|
143 | try |
122 | do |
|
144 | { |
123 | { |
|
Line 145... | Line 124... | |||
145 | var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _scanningCancellationToken); |
124 | await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken); |
|
Line 146... | Line 125... | |||
146 | |
125 | |
|
- | 126 | try |
||
Line 147... | Line 127... | |||
147 | if (tuneState != TunerState.TUNING_START) |
127 | { |
|
Line 148... | Line 128... | |||
148 | { |
128 | var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, |
|
Line 149... | Line 129... | |||
149 | break; |
129 | _scanningCancellationToken); |
|
150 | } |
130 | |
|
151 | } |
131 | if (tuneState != TunerState.TUNING_START) break; |
|
152 | catch (Exception) |
132 | } |
|
153 | { |
133 | catch (Exception) |
|
154 | // retry |
- | ||
Line 155... | Line 134... | |||
155 | } |
134 | { |
|
156 | |
- | ||
157 | } while (!_scanningCancellationToken.IsCancellationRequested); |
- | ||
158 | } |
135 | // retry |
|
- | 136 | } |
||
- | 137 | } while (!_scanningCancellationToken.IsCancellationRequested); |
||
- | 138 | } |
||
159 | |
139 | |
|
- | 140 | _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.ON }); |
||
160 | _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.ON }); |
141 | |
|
- | 142 | try |
||
- | 143 | { |
||
- | 144 | using (var memoryStream = new MemoryStream()) |
||
- | 145 | { |
||
- | 146 | #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed |
||
- | 147 | Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseTime), _scanningCancellationToken) |
||
- | 148 | .ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None); |
||
- | 149 | #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed |
||
- | 150 | |
||
- | 151 | await taskCompletionSource.Task; |
||
161 | |
152 | |
|
- | 153 | await _serialPort.CopyToAsync(memoryStream, _serialPort.BytesToRead, |
||
- | 154 | _scanningCancellationToken); |
||
162 | try |
155 | |
|
163 | { |
156 | memoryStream.Position = 0L; |
|
164 | using (var memoryStream = new MemoryStream()) |
- | ||
165 | { |
- | ||
166 | |
- | ||
167 | #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed |
- | ||
168 | Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseTime), _scanningCancellationToken) |
- | ||
169 | .ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None); |
- | ||
170 | #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed |
- | ||
171 | |
- | ||
172 | await taskCompletionSource.Task; |
- | ||
173 | |
- | ||
174 | await _serialPort.CopyToAsync(memoryStream, _serialPort.BytesToRead, _scanningCancellationToken); |
- | ||
175 | |
157 | |
|
176 | memoryStream.Position = 0L; |
158 | var result = Encoding.ASCII.GetString(memoryStream.ToArray()); |
|
177 | |
159 | |
|
178 | var result = Encoding.ASCII.GetString(memoryStream.ToArray()); |
160 | Parallel.ForEach(result.Split(Radios.Yaesu.FT_891.Constants.Eot), |
|
179 | |
161 | new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, |
|
180 | Parallel.ForEach(result.Split(Radios.Yaesu.FT_891.Constants.EOT), new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, async (split, state) => |
162 | async (split, state) => |
|
181 | { |
163 | { |
|
182 | if (string.IsNullOrEmpty(split)) |
164 | if (string.IsNullOrEmpty(split)) state.Stop(); |
|
183 | { |
165 | |
|
184 | state.Stop(); |
166 | try |
|
185 | } |
167 | { |
|
186 | |
168 | switch (_catAssemblies.CatParse<BusyState>("BY", |
|
187 | try |
169 | new object[] { $"{split}{Radios.Yaesu.FT_891.Constants.Eot}" })) |
|
188 | { |
170 | { |
|
189 | switch (_catAssemblies.CatParse<BusyState>("BY", new object[] { $"{split}{Radios.Yaesu.FT_891.Constants.EOT}" })) |
171 | case BusyState.ON: |
|
190 | { |
172 | if (_configuration.Notifications.TryGetNotificationState( |
|
191 | case BusyState.ON: |
173 | NotificationType.SignalScanDetect, out var notificationState)) |
|
192 | if (_configuration.Notifications.TryGetNotificationState(NotificationType.SignalScanDetect, out var notificationState)) |
174 | state.Stop(); |
|
193 | { |
175 | |
|
194 | state.Stop(); |
176 | var toastFrom = new ToastForm( |
|
195 | } |
177 | $"{Resources.Signal_detected_during_scan}", |
|
196 | |
178 | $"{Resources.Frequency}: {_currentFrequency}Hz", |
|
Line 197... | Line 179... | |||
197 | var toastFrom = new ToastForm( |
179 | notificationState.LingerTime, |
|
198 | $"{Resources.Signal_detected_during_scan}", |
- | ||
199 | $"{Resources.Frequency}: {_currentFrequency}Hz", |
- | ||
200 | notificationState.LingerTime, |
180 | Constants.AssemblyIcon); |
|
201 | Constants.AssemblyIcon); |
- | ||
202 | |
- | ||
203 | toastFrom.Show(); |
- | ||
204 | |
181 | |
|
205 | await Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseDetectTime), _scanningCancellationToken); |
- | ||
206 | state.Stop(); |
- | ||
207 | break; |
182 | toastFrom.Show(); |
|
208 | } |
183 | |
|
209 | } |
184 | await Task.Delay( |
|
210 | catch (TargetInvocationException exception) when (exception.InnerException is UnmatchedRadioResponseException) |
185 | TimeSpan.FromSeconds(bandScanParameters.PauseDetectTime), |
|
211 | { |
186 | _scanningCancellationToken); |
|
Line 252... | Line 227... | |||
252 | _serialPort.DiscardInBuffer(); |
227 | _serialPort.DiscardInBuffer(); |
|
253 | } |
228 | } |
|
254 | } |
229 | } |
|
255 | } |
230 | } |
|
256 | } |
231 | } |
|
257 | } |
232 | } |
|
258 | |
233 | |