HamBook – Blame information for rev 46

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;
36 office 22 using Org.BouncyCastle.Crypto.Engines;
3 office 23  
24 namespace HamBook
25 {
26 public class BandScan
27 {
28 private CancellationTokenSource _scanningCancellationTokenSource;
21 office 29 private CancellationToken _scanningCancellationToken;
36 office 30 private Thread _scanThread;
3 office 31 private CatAssemblies _catAssemblies;
32 private int _minFrequency;
33 private int _maxFrequency;
9 office 34 private SerialPortStream _serialPort;
12 office 35 private Configuration.Configuration _configuration;
5 office 36 private int _currentFrequency;
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  
36 office 52 public void Start(int stepFrequency, int pauseTime, int pauseDetectTime, bool autoTune = false)
3 office 53 {
36 office 54 if (_scanThread != null)
21 office 55 {
56 if (!_scanningCancellationToken.IsCancellationRequested)
57 {
58 _scanningCancellationTokenSource.Cancel();
59 }
60  
36 office 61 _scanThread.Join();
62 _scanThread = null;
21 office 63 }
64  
3 office 65 _scanningCancellationTokenSource = new CancellationTokenSource();
66 _scanningCancellationToken = _scanningCancellationTokenSource.Token;
5 office 67  
36 office 68 _scanThread = new Thread(new ParameterizedThreadStart(Scan));
69 _scanThread.Start(new BandScanParameters(stepFrequency, pauseTime, pauseDetectTime, autoTune));
3 office 70 }
71  
39 office 72 public void Stop()
3 office 73 {
36 office 74 if (_scanThread != null)
3 office 75 {
21 office 76 if (!_scanningCancellationToken.IsCancellationRequested)
77 {
78 _scanningCancellationTokenSource.Cancel();
79 }
80  
36 office 81 _scanThread.Join();
82 _scanThread = null;
3 office 83 }
21 office 84 }
85  
36 office 86 private async void Scan(object obj)
21 office 87 {
36 office 88 var bandScanParameters = (BandScanParameters)obj;
21 office 89  
9 office 90 if (!_serialPort.IsOpen)
91 {
92 _serialPort.Open();
93 }
94  
95 _serialPort.DiscardInBuffer();
96  
3 office 97 try
98 {
99  
5 office 100 _currentFrequency = _minFrequency;
3 office 101  
102 do
103 {
5 office 104 var taskCompletionSource = new TaskCompletionSource<bool>();
3 office 105  
7 office 106 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
107 {
108 soundPlayer.Play();
39 office 109  
9 office 110 await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency }, _scanningCancellationToken);
7 office 111 }
5 office 112  
36 office 113 if (bandScanParameters.AutoTune)
23 office 114 {
115 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON }, _scanningCancellationToken);
116  
39 office 117 do
118 {
119 await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);
120  
121 try
122 {
123 var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _scanningCancellationToken);
124  
125 if (tuneState != TunerState.TUNER_ON)
126 {
127 break;
128 }
129 }
130 catch (Exception)
131 {
132 // retry
133 }
134  
135 } while (!_scanningCancellationToken.IsCancellationRequested);
136  
23 office 137 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START }, _scanningCancellationToken);
138  
36 office 139 do
140 {
141 await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);
21 office 142  
36 office 143 try
144 {
39 office 145 var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _scanningCancellationToken);
146  
147 if (tuneState != TunerState.TUNING_START)
36 office 148 {
149 break;
150 }
151 }
152 catch (Exception)
153 {
154 // retry
155 }
156  
157 } while (!_scanningCancellationToken.IsCancellationRequested);
21 office 158 }
159  
36 office 160 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.ON });
21 office 161  
36 office 162 try
163 {
164 using (var memoryStream = new MemoryStream())
165 {
21 office 166  
167 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
36 office 168 Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseTime), _scanningCancellationToken)
169 .ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None);
21 office 170 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
171  
36 office 172 await taskCompletionSource.Task;
21 office 173  
36 office 174 await _serialPort.CopyToAsync(memoryStream, _serialPort.BytesToRead, _scanningCancellationToken);
23 office 175  
36 office 176 memoryStream.Position = 0L;
28 office 177  
36 office 178 var result = Encoding.ASCII.GetString(memoryStream.ToArray());
28 office 179  
46 office 180 Parallel.ForEach(result.Split(Radios.Yaesu.FT_891.Constants.EOT), new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, async (split, state) =>
28 office 181 {
36 office 182 if (string.IsNullOrEmpty(split))
183 {
184 state.Stop();
185 }
28 office 186  
187 try
188 {
46 office 189 switch (_catAssemblies.CatParse<BusyState>("BY", new object[] { $"{split}{Radios.Yaesu.FT_891.Constants.EOT}" }))
28 office 190 {
36 office 191 case BusyState.ON:
192 if (_configuration.Notifications.TryGetNotificationState(NotificationType.SignalScanDetect, out var notificationState))
193 {
194 state.Stop();
195 }
196  
197 var toastFrom = new ToastForm(
198 $"{Resources.Signal_detected_during_scan}",
199 $"{Resources.Frequency}: {_currentFrequency}Hz",
200 notificationState.LingerTime,
201 Constants.AssemblyIcon);
202  
203 toastFrom.Show();
204  
205 await Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseDetectTime), _scanningCancellationToken);
206 state.Stop();
207 break;
28 office 208 }
209 }
36 office 210 catch (TargetInvocationException exception) when (exception.InnerException is UnmatchedRadioResponseException)
28 office 211 {
36 office 212 // suppress
28 office 213 }
36 office 214 catch (Exception exception)
17 office 215 {
36 office 216 Log.Warning(exception, Resources.Error_encountered_while_scanning_for_signal);
17 office 217 }
36 office 218 });
9 office 219 }
220 }
36 office 221 catch(Exception exception)
222 {
223 Log.Warning(exception, Resources.Error_encountered_while_scanning_for_signal);
224 }
225 finally
226 {
227 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.OFF });
228 }
9 office 229  
36 office 230 _currentFrequency = _currentFrequency + bandScanParameters.StepFrequency;
231 if (_currentFrequency > _maxFrequency)
3 office 232 {
5 office 233 _currentFrequency = _minFrequency;
3 office 234 }
36 office 235 if (_currentFrequency < _minFrequency)
3 office 236 {
5 office 237 _currentFrequency = _minFrequency;
3 office 238 }
239  
36 office 240 } while (!_scanningCancellationToken.IsCancellationRequested);
3 office 241 }
36 office 242 catch (Exception exception)
3 office 243 {
244 Log.Error(exception, Resources.Scanning_aborted);
245 }
9 office 246 finally
247 {
248 if (_serialPort.IsOpen)
249 {
250 _serialPort.Close();
251  
252 _serialPort.DiscardInBuffer();
253 }
254 }
3 office 255 }
256 }
257 }