HamBook – Blame information for rev 62
?pathlinks?
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 | } |