HamBook – Blame information for rev 36

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  
36 office 72 public async Task 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();
9 office 109 await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency }, _scanningCancellationToken);
7 office 110 }
5 office 111  
36 office 112 if (bandScanParameters.AutoTune)
23 office 113 {
114 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON }, _scanningCancellationToken);
115  
116 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START }, _scanningCancellationToken);
117  
36 office 118 do
119 {
120 await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);
21 office 121  
36 office 122 try
123 {
124 if (await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _scanningCancellationToken) != TunerState.TUNING_START)
125 {
126 break;
127 }
128 }
129 catch (Exception)
130 {
131 // retry
132 }
133  
134 } while (!_scanningCancellationToken.IsCancellationRequested);
21 office 135 }
136  
36 office 137 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.ON });
21 office 138  
36 office 139 try
140 {
141 using (var memoryStream = new MemoryStream())
142 {
21 office 143  
144 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
36 office 145 Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseTime), _scanningCancellationToken)
146 .ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None);
21 office 147 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
148  
36 office 149 await taskCompletionSource.Task;
21 office 150  
36 office 151 await _serialPort.CopyToAsync(memoryStream, _serialPort.BytesToRead, _scanningCancellationToken);
23 office 152  
36 office 153 memoryStream.Position = 0L;
28 office 154  
36 office 155 var result = Encoding.ASCII.GetString(memoryStream.ToArray());
28 office 156  
36 office 157 Parallel.ForEach(result.Split(Radios.Generic.Constants.EOT), new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, async (split, state) =>
28 office 158 {
36 office 159 if (string.IsNullOrEmpty(split))
160 {
161 state.Stop();
162 }
28 office 163  
164 try
165 {
36 office 166 switch (_catAssemblies.CatParse<BusyState>("BY", new object[] { $"{split}{Radios.Generic.Constants.EOT}" }))
28 office 167 {
36 office 168 case BusyState.ON:
169 if (_configuration.Notifications.TryGetNotificationState(NotificationType.SignalScanDetect, out var notificationState))
170 {
171 state.Stop();
172 }
173  
174 var toastFrom = new ToastForm(
175 $"{Resources.Signal_detected_during_scan}",
176 $"{Resources.Frequency}: {_currentFrequency}Hz",
177 notificationState.LingerTime,
178 Constants.AssemblyIcon);
179  
180 toastFrom.Show();
181  
182 await Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseDetectTime), _scanningCancellationToken);
183 state.Stop();
184 break;
28 office 185 }
186 }
36 office 187 catch (TargetInvocationException exception) when (exception.InnerException is UnmatchedRadioResponseException)
28 office 188 {
36 office 189 // suppress
28 office 190 }
36 office 191 catch (Exception exception)
17 office 192 {
36 office 193 Log.Warning(exception, Resources.Error_encountered_while_scanning_for_signal);
17 office 194 }
36 office 195 });
9 office 196 }
197 }
36 office 198 catch(Exception exception)
199 {
200 Log.Warning(exception, Resources.Error_encountered_while_scanning_for_signal);
201 }
202 finally
203 {
204 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.OFF });
205 }
9 office 206  
36 office 207 _currentFrequency = _currentFrequency + bandScanParameters.StepFrequency;
208 if (_currentFrequency > _maxFrequency)
3 office 209 {
5 office 210 _currentFrequency = _minFrequency;
3 office 211 }
36 office 212 if (_currentFrequency < _minFrequency)
3 office 213 {
5 office 214 _currentFrequency = _minFrequency;
3 office 215 }
216  
36 office 217 } while (!_scanningCancellationToken.IsCancellationRequested);
3 office 218 }
36 office 219 catch (Exception exception)
3 office 220 {
221 Log.Error(exception, Resources.Scanning_aborted);
222 }
9 office 223 finally
224 {
225 if (_serialPort.IsOpen)
226 {
227 _serialPort.Close();
228  
229 _serialPort.DiscardInBuffer();
230 }
231 }
3 office 232 }
233 }
234 }