HamBook – Rev 61
?pathlinks?
using System;
using System.IO;
using System.Media;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Configuration;
using HamBook.Properties;
using HamBook.Radios;
using HamBook.Radios.Generic;
using RJCP.IO.Ports;
using Serilog;
using Toasts;
using static System.Windows.Forms.AxHost;
using Toasts = Toasts.Toasts;
namespace HamBook
{
public class BandScan
{
private readonly CatAssemblies _catAssemblies;
private readonly Configuration.Configuration _configuration;
private readonly int _maxFrequency;
private readonly int _minFrequency;
private readonly SerialPortStream _serialPort;
private int _currentFrequency;
private CancellationToken _scanningCancellationToken;
private CancellationTokenSource _scanningCancellationTokenSource;
private Thread _scanThread;
private global::Toasts.Toasts _toasts;
private BandScan()
{
}
public BandScan(CatAssemblies catAssemblies, int min, int max, SerialPortStream serialPort,
Configuration.Configuration configuration) : this()
{
_catAssemblies = catAssemblies;
_minFrequency = min;
_maxFrequency = max;
_serialPort = serialPort;
_configuration = configuration;
}
public void Start(int stepFrequency, int pauseTime, int pauseDetectTime, bool autoTune = false)
{
if (_scanThread != null)
{
if (!_scanningCancellationToken.IsCancellationRequested) _scanningCancellationTokenSource.Cancel();
_scanThread.Join();
_scanThread = null;
}
_scanningCancellationTokenSource = new CancellationTokenSource();
_scanningCancellationToken = _scanningCancellationTokenSource.Token;
_toasts = new global::Toasts.Toasts(_scanningCancellationToken);
_scanThread = new Thread(Scan);
_scanThread.Start(new BandScanParameters(stepFrequency, pauseTime, pauseDetectTime, autoTune));
}
public void Stop()
{
if (_scanThread != null)
{
if (!_scanningCancellationToken.IsCancellationRequested) _scanningCancellationTokenSource.Cancel();
_scanThread.Join();
_scanThread = null;
}
if (_toasts != null)
{
_toasts.Dispose();
_toasts = null;
}
}
private async void Scan(object obj)
{
var bandScanParameters = (BandScanParameters)obj;
if (!_serialPort.IsOpen) _serialPort.Open();
_serialPort.DiscardInBuffer();
try
{
_currentFrequency = _minFrequency;
do
{
using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly()
.GetManifestResourceStream("HamBook.Effects.pot.wav")))
{
soundPlayer.Play();
await _catAssemblies.CatWriteAsync<int>("FA", new object[] { _currentFrequency },
_scanningCancellationToken);
}
if (bandScanParameters.AutoTune)
{
await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNER_ON },
_scanningCancellationToken);
do
{
await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);
try
{
var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { },
_scanningCancellationToken);
if (tuneState != TunerState.TUNER_ON) break;
}
catch (Exception)
{
// retry
}
} while (!_scanningCancellationToken.IsCancellationRequested);
await _catAssemblies.CatWriteAsync<TunerState>("AC", new object[] { TunerState.TUNING_START },
_scanningCancellationToken);
do
{
await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);
try
{
var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { },
_scanningCancellationToken);
if (tuneState != TunerState.TUNING_START) break;
}
catch (Exception)
{
// retry
}
} while (!_scanningCancellationToken.IsCancellationRequested);
}
await _catAssemblies.CatWriteAsyncManual<InformationState>("AI", new object[] { InformationState.ON }, _scanningCancellationToken);
try
{
using (var memoryStream = new MemoryStream())
{
do
{
var taskCompletionSource = new TaskCompletionSource<bool>();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Delay(TimeSpan.FromSeconds(bandScanParameters.PauseTime), _scanningCancellationToken)
.ContinueWith(_ => taskCompletionSource.TrySetResult(true), CancellationToken.None);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
await taskCompletionSource.Task;
memoryStream.Position = 0L;
await _serialPort.CopyToAsync(memoryStream, _serialPort.BytesToRead,
_scanningCancellationToken);
var signal = false;
var result = Encoding.ASCII.GetString(memoryStream.ToArray());
foreach (var split in result.Split(Radios.Yaesu.FT_891.Constants.Eot))
{
if (!_catAssemblies.CatParse<BusyState>("BY",
new object[] { $"{split}{Radios.Yaesu.FT_891.Constants.Eot}" },
out var busyState))
{
continue;
}
if (busyState == BusyState.ON)
{
signal = true;
}
}
if (!signal)
{
break;
}
if (!_configuration.Notifications.TryGetNotificationState(
NotificationType.SignalScanDetect, out var notificationState) ||
!notificationState.Enabled)
{
continue;
}
var toastFrom = new ToastForm(
$"{Resources.Signal_detected_during_scan}",
$"{Resources.Frequency}: {_currentFrequency}Hz")
{
LingerTime = notificationState.LingerTime,
Icon = Constants.AssemblyIcon
};
System.Windows.Forms.Application.Run(toastFrom);
} while (!_scanningCancellationToken.IsCancellationRequested);
}
}
catch (Exception exception)
{
Log.Warning(exception, Resources.Error_encountered_while_scanning_for_signal);
}
finally
{
await _catAssemblies.CatWriteAsyncManual<InformationState>("AI", new object[] { InformationState.OFF }, _scanningCancellationToken);
}
_currentFrequency = _currentFrequency + bandScanParameters.StepFrequency;
if (_currentFrequency > _maxFrequency) _currentFrequency = _minFrequency;
if (_currentFrequency < _minFrequency) _currentFrequency = _minFrequency;
} while (!_scanningCancellationToken.IsCancellationRequested);
}
catch (Exception exception)
{
Log.Error(exception, Resources.Scanning_aborted);
}
finally
{
if (_serialPort.IsOpen)
{
_serialPort.Close();
_serialPort.DiscardInBuffer();
}
}
}
}
}
Generated by GNU Enscript 1.6.5.90.