HamBook – Blame information for rev 18

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;
3 office 21  
22 namespace HamBook
23 {
24 public class BandScan
25 {
26 private CancellationTokenSource _scanningCancellationTokenSource;
27  
28 private CancellationToken _scanningCancellationToken;
29 private CatAssemblies _catAssemblies;
30 private int _minFrequency;
31 private int _maxFrequency;
9 office 32 private SerialPortStream _serialPort;
12 office 33 private Configuration.Configuration _configuration;
5 office 34 private int _currentFrequency;
9 office 35 private Task _scanTask;
3 office 36  
37 private BandScan()
38 {
39 }
40  
12 office 41 public BandScan(CatAssemblies catAssemblies, int min, int max, SerialPortStream serialPort, Configuration.Configuration configuration) : this()
3 office 42 {
43 _catAssemblies = catAssemblies;
44 _minFrequency = min;
45 _maxFrequency = max;
46 _serialPort = serialPort;
12 office 47 _configuration = configuration;
3 office 48  
49 }
50  
9 office 51 public void Start(int step, int pause, int detect)
3 office 52 {
53 _scanningCancellationTokenSource = new CancellationTokenSource();
54 _scanningCancellationToken = _scanningCancellationTokenSource.Token;
5 office 55  
9 office 56 _scanTask = Scan(step, pause, detect);
3 office 57 }
58  
9 office 59 public async Task Stop()
3 office 60 {
61 if (_scanningCancellationTokenSource != null)
62 {
63 _scanningCancellationTokenSource.Cancel();
64 }
9 office 65  
66 if(_scanTask != null)
67 {
68 await _scanTask;
69 _scanTask = null;
70 }
3 office 71 }
72  
9 office 73 private async Task Scan(int step, int pause, int detect)
3 office 74 {
9 office 75 if (!_serialPort.IsOpen)
76 {
77 _serialPort.Open();
78 }
79  
80 _serialPort.DiscardInBuffer();
81  
82 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.ON });
83  
3 office 84 try
85 {
86  
5 office 87 _currentFrequency = _minFrequency;
3 office 88  
89 do
90 {
5 office 91 var taskCompletionSource = new TaskCompletionSource<bool>();
3 office 92  
5 office 93 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
9 office 94 Task.Delay(TimeSpan.FromSeconds(pause), _scanningCancellationToken)
95 .ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None);
5 office 96 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
3 office 97  
7 office 98 using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
99 {
100 soundPlayer.Play();
9 office 101 await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency }, _scanningCancellationToken);
7 office 102 }
5 office 103  
9 office 104 using (var memoryStream = new MemoryStream())
105 {
106 _serialPort.DiscardInBuffer();
5 office 107  
9 office 108 await taskCompletionSource.Task;
109  
110 var count = _serialPort.BaudRate / sizeof(byte) * pause;
111 await _serialPort.CopyToAsync(memoryStream, count, _scanningCancellationToken);
112  
113 memoryStream.Position = 0L;
114  
11 office 115 // TODO: radios
9 office 116 var result = Encoding.ASCII.GetString(memoryStream.ToArray());
11 office 117 foreach (var split in result.Split(Radios.Generic.Constants.EOT))
9 office 118 {
17 office 119 if(string.IsNullOrEmpty(split))
120 {
121 continue;
122 }
123  
124 try
9 office 125 {
18 office 126 switch (_catAssemblies.CatParse<BusyState>("BY", new object[] { $"{split}{Radios.Generic.Constants.EOT}" }))
17 office 127 {
128 case BusyState.ON:
129 if (!_configuration.Notifications.TryGetNotificationState(NotificationType.SignalScanDetect, out var notificationState))
130 {
131 var toastFrom = new ToastForm(
132 $"{Resources.Signal_detected_during_scan}",
133 $"{Resources.Frequency}: {_currentFrequency}Hz",
134 notificationState.LingerTime,
135 Constants.AssemblyIcon);
12 office 136  
17 office 137 toastFrom.Show();
12 office 138  
17 office 139 await Task.Delay(TimeSpan.FromSeconds(detect), _scanningCancellationToken);
140 }
141 continue;
142 }
9 office 143 }
18 office 144 catch (TargetInvocationException exception) when (exception.InnerException is UnmatchedRadioResponseException)
17 office 145 {
146 // suppress
147 }
18 office 148 catch (Exception exception)
17 office 149 {
18 office 150 Log.Warning(exception, Resources.Unexpected_failure_while_scanning);
17 office 151 }
9 office 152 }
153 }
154  
5 office 155 _currentFrequency = _currentFrequency + step;
156 if(_currentFrequency > _maxFrequency)
3 office 157 {
5 office 158 _currentFrequency = _minFrequency;
3 office 159 }
5 office 160 if(_currentFrequency < _minFrequency)
3 office 161 {
5 office 162 _currentFrequency = _minFrequency;
3 office 163 }
164  
5 office 165 } while(!_scanningCancellationToken.IsCancellationRequested);
3 office 166 }
167 catch(Exception exception)
168 {
169 Log.Error(exception, Resources.Scanning_aborted);
170 }
9 office 171 finally
172 {
173 _catAssemblies.CatWrite<InformationState>("AI", new object[] { InformationState.OFF });
174  
175 if (_serialPort.IsOpen)
176 {
177 _serialPort.Close();
178  
179 _serialPort.DiscardInBuffer();
180 }
181 }
3 office 182 }
183 }
184 }