HamBook – Blame information for rev 28

Subversion Repositories:
Rev:
Rev Author Line No. Line
3 office 1 using HamBook.Radios.Generic;
2 using HamBook.Radios;
3 using System;
4 using System.Collections.Generic;
5 using System.IO.Ports;
6 using System.Linq;
7 using System.Text;
8 using System.Threading;
9 using System.Threading.Tasks;
10 using Serilog;
11 using HamBook.Properties;
12 using Serilog.Events;
7 office 13 using System.Media;
14 using System.Reflection;
9 office 15 using RJCP.IO.Ports;
16 using System.Diagnostics;
17 using System.IO;
12 office 18 using Toasts;
19 using System.Drawing;
20 using Configuration;
21 office 21 using System.Security.Cryptography;
3 office 22  
23 namespace HamBook
24 {
25 public class BandScan
26 {
27 private CancellationTokenSource _scanningCancellationTokenSource;
21 office 28 private CancellationToken _scanningCancellationToken;
3 office 29  
30 private CatAssemblies _catAssemblies;
31 private int _minFrequency;
32 private int _maxFrequency;
9 office 33 private SerialPortStream _serialPort;
12 office 34 private Configuration.Configuration _configuration;
5 office 35 private int _currentFrequency;
9 office 36 private Task _scanTask;
3 office 37  
38 private BandScan()
39 {
40 }
41  
12 office 42 public BandScan(CatAssemblies catAssemblies, int min, int max, SerialPortStream serialPort, Configuration.Configuration configuration) : this()
3 office 43 {
44 _catAssemblies = catAssemblies;
45 _minFrequency = min;
46 _maxFrequency = max;
47 _serialPort = serialPort;
12 office 48 _configuration = configuration;
3 office 49  
50 }
51  
23 office 52 public async void Start(int stepFrequency, int pauseTime, bool autoTune = false)
3 office 53 {
21 office 54 if(_scanTask != null)
55 {
56 if (!_scanningCancellationToken.IsCancellationRequested)
57 {
58 _scanningCancellationTokenSource.Cancel();
59 }
60  
61 await _scanTask;
62 _scanTask = null;
63 }
64  
3 office 65 _scanningCancellationTokenSource = new CancellationTokenSource();
66 _scanningCancellationToken = _scanningCancellationTokenSource.Token;
5 office 67  
23 office 68 _scanTask = Scan(stepFrequency, pauseTime, autoTune);
3 office 69 }
70  
23 office 71 public async void Start(int stepFrequency, int pauseTime, int pauseDetectTime, bool autoTune = false)
3 office 72 {
21 office 73 if (_scanTask != null)
3 office 74 {
21 office 75 if (!_scanningCancellationToken.IsCancellationRequested)
76 {
77 _scanningCancellationTokenSource.Cancel();
78 }
79  
80 await _scanTask;
81 _scanTask = null;
3 office 82 }
9 office 83  
21 office 84 _scanningCancellationTokenSource = new CancellationTokenSource();
85 _scanningCancellationToken = _scanningCancellationTokenSource.Token;
86  
23 office 87 _scanTask = Scan(stepFrequency, pauseTime, pauseDetectTime, autoTune);
21 office 88 }
89  
90 public async Task Stop()
91 {
92 if (_scanTask != null)
9 office 93 {
21 office 94 if (!_scanningCancellationToken.IsCancellationRequested)
95 {
96 _scanningCancellationTokenSource.Cancel();
97 }
98  
9 office 99 await _scanTask;
100 _scanTask = null;
101 }
3 office 102 }
103  
23 office 104 private async Task Scan(int stepFrequency, int pauseTime, bool autoTune)
3 office 105 {
9 office 106 if (!_serialPort.IsOpen)
107 {
108 _serialPort.Open();
109 }
110  
111 _serialPort.DiscardInBuffer();
112  
113 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.ON });
114  
3 office 115 try
116 {
117  
5 office 118 _currentFrequency = _minFrequency;
3 office 119  
120 do
121 {
5 office 122 var taskCompletionSource = new TaskCompletionSource<bool>();
3 office 123  
5 office 124 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
21 office 125 Task.Delay(TimeSpan.FromSeconds(pauseTime), _scanningCancellationToken)
9 office 126 .ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None);
5 office 127 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
3 office 128  
7 office 129 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
130 {
131 soundPlayer.Play();
9 office 132 await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency }, _scanningCancellationToken);
7 office 133 }
5 office 134  
23 office 135 if (autoTune)
136 {
137 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON }, _scanningCancellationToken);
138  
139 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START }, _scanningCancellationToken);
140 }
141  
21 office 142 await taskCompletionSource.Task;
143  
144 _currentFrequency = _currentFrequency + stepFrequency;
145 if (_currentFrequency > _maxFrequency)
146 {
147 _currentFrequency = _minFrequency;
148 }
149 if (_currentFrequency < _minFrequency)
150 {
151 _currentFrequency = _minFrequency;
152 }
153  
154 } while (!_scanningCancellationToken.IsCancellationRequested);
155 }
156 catch (Exception exception)
157 {
158 Log.Error(exception, Resources.Scanning_aborted);
159 }
160 finally
161 {
162 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.OFF });
163  
164 if (_serialPort.IsOpen)
165 {
166 _serialPort.Close();
167  
168 _serialPort.DiscardInBuffer();
169 }
170 }
171 }
172  
23 office 173 private async Task Scan(int stepFrequency, int pauseTime, int pauseDetectTime, bool autoTune)
21 office 174 {
175 if (!_serialPort.IsOpen)
176 {
177 _serialPort.Open();
178 }
179  
180 _serialPort.DiscardInBuffer();
181  
182 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.ON });
183  
184 try
185 {
186  
187 _currentFrequency = _minFrequency;
188  
189 do
190 {
191 var taskCompletionSource = new TaskCompletionSource<bool>();
192  
193 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
194 Task.Delay(TimeSpan.FromSeconds(pauseTime), _scanningCancellationToken)
195 .ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None);
196 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
197  
198 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
199 {
200 soundPlayer.Play();
201 await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency }, _scanningCancellationToken);
202 }
203  
23 office 204 if(autoTune)
205 {
28 office 206 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.OFF });
23 office 207  
28 office 208 try
209 {
210 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON }, _scanningCancellationToken);
211  
212 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START }, _scanningCancellationToken);
213  
214 do
215 {
216 await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);
217  
218 try
219 {
220 if(await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _scanningCancellationToken) != TunerState.TUNING_START)
221 {
222 break;
223 }
224 }
225 catch(Exception)
226 {
227 // retry
228 }
229  
230 } while (!_scanningCancellationToken.IsCancellationRequested);
231 }
232 finally
233 {
234 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.ON });
235 }
23 office 236 }
237  
9 office 238 using (var memoryStream = new MemoryStream())
239 {
240 _serialPort.DiscardInBuffer();
5 office 241  
9 office 242 await taskCompletionSource.Task;
243  
21 office 244 var count = _serialPort.BaudRate / sizeof(byte) * pauseTime;
9 office 245 await _serialPort.CopyToAsync(memoryStream, count, _scanningCancellationToken);
246  
247 memoryStream.Position = 0L;
248  
11 office 249 // TODO: radios
9 office 250 var result = Encoding.ASCII.GetString(memoryStream.ToArray());
11 office 251 foreach (var split in result.Split(Radios.Generic.Constants.EOT))
9 office 252 {
17 office 253 if(string.IsNullOrEmpty(split))
254 {
255 continue;
256 }
257  
258 try
9 office 259 {
18 office 260 switch (_catAssemblies.CatParse<BusyState>("BY", new object[] { $"{split}{Radios.Generic.Constants.EOT}" }))
17 office 261 {
262 case BusyState.ON:
21 office 263 if (_configuration.Notifications.TryGetNotificationState(NotificationType.SignalScanDetect, out var notificationState))
17 office 264 {
21 office 265 continue;
266 }
12 office 267  
21 office 268 var toastFrom = new ToastForm(
269 $"{Resources.Signal_detected_during_scan}",
270 $"{Resources.Frequency}: {_currentFrequency}Hz",
271 notificationState.LingerTime,
272 Constants.AssemblyIcon);
12 office 273  
21 office 274 toastFrom.Show();
275  
276 await Task.Delay(TimeSpan.FromSeconds(pauseDetectTime), _scanningCancellationToken);
17 office 277 continue;
278 }
9 office 279 }
18 office 280 catch (TargetInvocationException exception) when (exception.InnerException is UnmatchedRadioResponseException)
17 office 281 {
282 // suppress
283 }
18 office 284 catch (Exception exception)
17 office 285 {
18 office 286 Log.Warning(exception, Resources.Unexpected_failure_while_scanning);
17 office 287 }
9 office 288 }
289 }
290  
21 office 291 _currentFrequency = _currentFrequency + stepFrequency;
5 office 292 if(_currentFrequency > _maxFrequency)
3 office 293 {
5 office 294 _currentFrequency = _minFrequency;
3 office 295 }
5 office 296 if(_currentFrequency < _minFrequency)
3 office 297 {
5 office 298 _currentFrequency = _minFrequency;
3 office 299 }
300  
5 office 301 } while(!_scanningCancellationToken.IsCancellationRequested);
3 office 302 }
303 catch(Exception exception)
304 {
305 Log.Error(exception, Resources.Scanning_aborted);
306 }
9 office 307 finally
308 {
309 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.OFF });
310  
311 if (_serialPort.IsOpen)
312 {
313 _serialPort.Close();
314  
315 _serialPort.DiscardInBuffer();
316 }
317 }
3 office 318 }
319 }
320 }