HamBook – Blame information for rev 62

Subversion Repositories:
Rev:
Rev Author Line No. Line
54 office 1 using System;
2 using System.IO;
3 using System.Media;
4 using System.Reflection;
3 office 5 using System.Text;
6 using System.Threading;
7 using System.Threading.Tasks;
54 office 8 using Configuration;
3 office 9 using HamBook.Properties;
54 office 10 using HamBook.Radios;
11 using HamBook.Radios.Generic;
9 office 12 using RJCP.IO.Ports;
54 office 13 using Serilog;
12 office 14 using Toasts;
3 office 15  
16 namespace HamBook
17 {
18 public class BandScan
19 {
54 office 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;
25 private int _currentFrequency;
26 private CancellationToken _scanningCancellationToken;
3 office 27 private CancellationTokenSource _scanningCancellationTokenSource;
36 office 28 private Thread _scanThread;
62 office 29 private ToastDisplay _toastDisplay;
3 office 30  
54 office 31 private BandScan()
3 office 32 {
58 office 33  
3 office 34 }
35  
54 office 36 public BandScan(CatAssemblies catAssemblies, int min, int max, SerialPortStream serialPort,
37 Configuration.Configuration configuration) : this()
3 office 38 {
39 _catAssemblies = catAssemblies;
40 _minFrequency = min;
41 _maxFrequency = max;
42 _serialPort = serialPort;
12 office 43 _configuration = configuration;
3 office 44 }
45  
36 office 46 public void Start(int stepFrequency, int pauseTime, int pauseDetectTime, bool autoTune = false)
3 office 47 {
36 office 48 if (_scanThread != null)
21 office 49 {
54 office 50 if (!_scanningCancellationToken.IsCancellationRequested) _scanningCancellationTokenSource.Cancel();
21 office 51  
36 office 52 _scanThread.Join();
53 _scanThread = null;
21 office 54 }
55  
3 office 56 _scanningCancellationTokenSource = new CancellationTokenSource();
57 _scanningCancellationToken = _scanningCancellationTokenSource.Token;
5 office 58  
62 office 59 _toastDisplay = new ToastDisplay(_scanningCancellationToken);
58 office 60  
54 office 61 _scanThread = new Thread(Scan);
36 office 62 _scanThread.Start(new BandScanParameters(stepFrequency, pauseTime, pauseDetectTime, autoTune));
3 office 63 }
64  
39 office 65 public void Stop()
3 office 66 {
36 office 67 if (_scanThread != null)
3 office 68 {
54 office 69 if (!_scanningCancellationToken.IsCancellationRequested) _scanningCancellationTokenSource.Cancel();
21 office 70  
36 office 71 _scanThread.Join();
72 _scanThread = null;
3 office 73 }
58 office 74  
62 office 75 if (_toastDisplay != null)
58 office 76 {
62 office 77 _toastDisplay.Dispose();
78 _toastDisplay = null;
58 office 79 }
21 office 80 }
81  
36 office 82 private async void Scan(object obj)
21 office 83 {
36 office 84 var bandScanParameters = (BandScanParameters)obj;
21 office 85  
54 office 86 if (!_serialPort.IsOpen) _serialPort.Open();
9 office 87  
88 _serialPort.DiscardInBuffer();
89  
3 office 90 try
91 {
5 office 92 _currentFrequency = _minFrequency;
3 office 93  
94 do
95 {
54 office 96 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
97 .GetManifestResourceStream("HamBook.Effects.pot.wav")))
7 office 98 {
99 soundPlayer.Play();
39 office 100  
54 office 101 await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency },
102 _scanningCancellationToken);
7 office 103 }
5 office 104  
36 office 105 if (bandScanParameters.AutoTune)
23 office 106 {
54 office 107 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON },
108 _scanningCancellationToken);
23 office 109  
39 office 110 do
111 {
112 await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);
113  
114 try
115 {
54 office 116 var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { },
117 _scanningCancellationToken);
39 office 118  
54 office 119 if (tuneState != TunerState.TUNER_ON) break;
39 office 120 }
121 catch (Exception)
122 {
123 // retry
124 }
125 } while (!_scanningCancellationToken.IsCancellationRequested);
126  
54 office 127 await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START },
128 _scanningCancellationToken);
23 office 129  
36 office 130 do
131 {
132 await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);
21 office 133  
36 office 134 try
135 {
54 office 136 var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { },
137 _scanningCancellationToken);
39 office 138  
54 office 139 if (tuneState != TunerState.TUNING_START) break;
36 office 140 }
141 catch (Exception)
142 {
143 // retry
144 }
145 } while (!_scanningCancellationToken.IsCancellationRequested);
21 office 146 }
147  
58 office 148 await _catAssemblies.CatWriteAsyncManual<InformationState>("AI", new object[] { InformationState.ON }, _scanningCancellationToken);
21 office 149  
36 office 150 try
151 {
152 using (var memoryStream = new MemoryStream())
153 {
58 office 154 do
155 {
156 var taskCompletionSource = new TaskCompletionSource<bool>();
157  
21 office 158 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
58 office 159 Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseTime), _scanningCancellationToken)
160 .ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None);
21 office 161 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
162  
58 office 163 await taskCompletionSource.Task;
21 office 164  
58 office 165 memoryStream.Position = 0L;
23 office 166  
58 office 167 await _serialPort.CopyToAsync(memoryStream, _serialPort.BytesToRead,
168 _scanningCancellationToken);
28 office 169  
58 office 170 var signal = false;
171 var result = Encoding.ASCII.GetString(memoryStream.ToArray());
172 foreach (var split in result.Split(Radios.Yaesu.FT_891.Constants.Eot))
36 office 173 {
58 office 174 if (!_catAssemblies.CatParse<BusyState>("BY",
175 new object[] { $"{split}{Radios.Yaesu.FT_891.Constants.Eot}" },
176 out var busyState))
177 {
178 continue;
179 }
28 office 180  
58 office 181 if (busyState == BusyState.ON)
28 office 182 {
58 office 183 signal = true;
184 }
185 }
36 office 186  
187  
58 office 188 if (!signal)
189 {
190 break;
191 }
36 office 192  
58 office 193 if (!_configuration.Notifications.TryGetNotificationState(
194 NotificationType.SignalScanDetect, out var notificationState) ||
195 !notificationState.Enabled)
196 {
197 continue;
198 }
199  
200 var toastFrom = new ToastForm(
201 $"{Resources.Signal_detected_during_scan}",
61 office 202 $"{Resources.Frequency}: {_currentFrequency}Hz")
203 {
204 LingerTime = notificationState.LingerTime,
205 Icon = Constants.AssemblyIcon
206 };
58 office 207  
208 System.Windows.Forms.Application.Run(toastFrom);
209  
210 } while (!_scanningCancellationToken.IsCancellationRequested);
9 office 211 }
212 }
54 office 213 catch (Exception exception)
36 office 214 {
215 Log.Warning(exception, Resources.Error_encountered_while_scanning_for_signal);
216 }
217 finally
218 {
58 office 219 await _catAssemblies.CatWriteAsyncManual<InformationState>("AI", new object[] { InformationState.OFF }, _scanningCancellationToken);
36 office 220 }
9 office 221  
36 office 222 _currentFrequency = _currentFrequency + bandScanParameters.StepFrequency;
58 office 223  
54 office 224 if (_currentFrequency > _maxFrequency) _currentFrequency = _minFrequency;
225 if (_currentFrequency < _minFrequency) _currentFrequency = _minFrequency;
58 office 226  
36 office 227 } while (!_scanningCancellationToken.IsCancellationRequested);
3 office 228 }
36 office 229 catch (Exception exception)
3 office 230 {
231 Log.Error(exception, Resources.Scanning_aborted);
232 }
9 office 233 finally
234 {
235 if (_serialPort.IsOpen)
236 {
237 _serialPort.Close();
238  
239 _serialPort.DiscardInBuffer();
240 }
241 }
3 office 242 }
243 }
54 office 244 }