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