Major upgrade
This commit is contained in:
@@ -1,360 +1,348 @@
|
||||
// Ignore Spelling: Geu Sdlc
|
||||
|
||||
using System;
|
||||
using Raytheon.GuidedElectronicsUnit;
|
||||
using System.Threading;
|
||||
using Raytheon.Common;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using Raytheon.GuidedElectronicsUnit;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
public class CommDeviceGeuSdlc : ICommDevice, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
public class CommDeviceGeuSdlc : ICommDevice, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
private GuidedElectronicsUnit.GuidedElectronicsUnit _guidanceElectronicsUnit;
|
||||
private readonly bool _idQuery = false;
|
||||
private readonly bool _reset = false;
|
||||
private readonly SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private readonly string _instrumentDriverSetup;
|
||||
private readonly int _pollingRate;
|
||||
private readonly string _resourceName;
|
||||
private static readonly object _syncObj = new object();
|
||||
private GuidedElectronicsUnit.GuidedElectronicsUnit _guidanceElectronicsUnit;
|
||||
private readonly bool _idQuery = false;
|
||||
private readonly bool _reset = false;
|
||||
private readonly SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private readonly string _instrumentDriverSetup;
|
||||
private readonly int _pollingRate;
|
||||
private static readonly object _syncObj = new object();
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
#endregion
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#region PrivatelassFunctions
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommDeviceGeuSdlc()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
#region PrivatelassFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close resources
|
||||
try
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_guidanceElectronicsUnit.Close();
|
||||
_guidanceElectronicsUnit.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommDeviceGeuSdlc()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Some HSS corrections
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="numDWords"></param>
|
||||
private static unsafe void PerformHssSwirl(ref byte[] data, uint numDWords)
|
||||
{
|
||||
fixed (byte* pBytePtr = &data[0])
|
||||
{
|
||||
for (int i = 0; i < numDWords; i++)
|
||||
{
|
||||
// swap the first word
|
||||
ushort* pWord1 = (ushort*)pBytePtr + (i * 2);
|
||||
*pWord1 = Util.Swap(*pWord1);
|
||||
|
||||
//swap the second word
|
||||
ushort* pWord2 = (ushort*)pBytePtr + ((i * 2) + 1);
|
||||
*pWord2 = Util.Swap(*pWord2);
|
||||
|
||||
// now swap the dword
|
||||
uint* pDWord = (uint*)pBytePtr + i;
|
||||
*pDWord = Util.SwapHighAndLowBytes(*pDWord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicClassFunctions
|
||||
|
||||
bool IInstrument.DisplayEnabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
bool IInstrument.FrontPanelEnabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
InstrumentMetadata IInstrument.Info => throw new NotImplementedException();
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceGeuSdlc(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
_resourceName = deviceName;
|
||||
_guidanceElectronicsUnit = null;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_idQuery = _configuration.GetConfigurationValue("CommDeviceGeuSdlc", "IdQuery", true);
|
||||
_reset = _configuration.GetConfigurationValue("CommDeviceGeuSdlc", "Reset", true);
|
||||
_instrumentDriverSetup = _configuration.GetConfigurationValue("CommDeviceGeuSdlc", "InstrumentDriverSetup", "");
|
||||
_pollingRate = _configuration.GetConfigurationValue("CommDeviceGeuSdlc", "PollingRate", 10);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor. Does not initialize anything. Use Initialize() to create the handle to the hardware
|
||||
/// </summary>
|
||||
/// <param name="resourceName"></param>
|
||||
/// <param name="idQuery"></param>
|
||||
/// <param name="reset"></param>
|
||||
public CommDeviceGeuSdlc(string resourceName, bool idQuery, bool reset, string instrumentDriverSetup = "", int pollingRate = 10)
|
||||
{
|
||||
_resourceName = resourceName;
|
||||
_idQuery = idQuery;
|
||||
_reset = reset;
|
||||
_guidanceElectronicsUnit = null;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
_instrumentDriverSetup = instrumentDriverSetup;
|
||||
_pollingRate = pollingRate;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool IInstrument.ClearErrors()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a HSS GEU SDLC Device called " + _resourceName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a handle to the hardware
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
const uint AUTO_FWDING_ADDR = 0x00080100;
|
||||
const uint WRITE_OFFSET = 0x00200000;
|
||||
const uint ENABLE_AUTO_FWDING = 0b0000_0001;
|
||||
const uint ENABLE_TLP_HDR = 0b0000_0010;
|
||||
//const uint INSERT_MSG_CNT = 0b0000_0100;
|
||||
|
||||
_guidanceElectronicsUnit = new GuidedElectronicsUnit.GuidedElectronicsUnit(_resourceName, _idQuery, _reset,
|
||||
$"QueryInstrStatus=true, Simulate=false, DriverSetup= {_instrumentDriverSetup}, PollingInterval={_pollingRate}");
|
||||
|
||||
_guidanceElectronicsUnit.LowLevel.HSSub9100.EnableIO = ControlState.Enabled;
|
||||
|
||||
_guidanceElectronicsUnit.LowLevel.HSSub9100.WriteRegister(AUTO_FWDING_ADDR + WRITE_OFFSET, ENABLE_AUTO_FWDING | ENABLE_TLP_HDR);
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _resourceName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
SelfTestResult IInstrument.PerformSelfTest()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dataRead"></param>
|
||||
/// <returns></returns>
|
||||
uint ICommDevice.Read(ref byte[] dataRead)
|
||||
{
|
||||
|
||||
if (_guidanceElectronicsUnit == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte[] sdlcMsgs = new byte[0];
|
||||
lock (_syncObj)
|
||||
{
|
||||
// read all of the data that is available
|
||||
sdlcMsgs = _guidanceElectronicsUnit.GsKwSyncronousDataLinkControl.FetchMessageData();
|
||||
}
|
||||
|
||||
if (sdlcMsgs.Length > dataRead.Length)
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close resources
|
||||
try
|
||||
{
|
||||
throw new Exception("The data buffer that the host provided is: " + dataRead.Length + " bytes, there are: " + sdlcMsgs.Length + " bytes of SDLC data. Need to increase the host buffer size");
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_guidanceElectronicsUnit.Close();
|
||||
_guidanceElectronicsUnit.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(sdlcMsgs, 0, dataRead, 0, sdlcMsgs.Length);
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (uint)sdlcMsgs.Length;
|
||||
}
|
||||
/// <summary>
|
||||
/// Some HSS corrections
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="numDWords"></param>
|
||||
private static unsafe void PerformHssSwirl(ref byte[] data, uint numDWords)
|
||||
{
|
||||
fixed (byte* pBytePtr = &data[0])
|
||||
{
|
||||
for (int i = 0; i < numDWords; i++)
|
||||
{
|
||||
// swap the first word
|
||||
ushort* pWord1 = (ushort*)pBytePtr + (i * 2);
|
||||
*pWord1 = Util.Swap(*pWord1);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void IInstrument.Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_guidanceElectronicsUnit.Close();
|
||||
_state = State.Uninitialized;
|
||||
Thread.Sleep(500);
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
//swap the second word
|
||||
ushort* pWord2 = (ushort*)pBytePtr + ((i * 2) + 1);
|
||||
*pWord2 = Util.Swap(*pWord2);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
// now swap the dword
|
||||
uint* pDWord = (uint*)pBytePtr + i;
|
||||
*pDWord = Util.SwapHighAndLowBytes(*pDWord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
void ICommDevice.SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void IInstrument.Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_guidanceElectronicsUnit != null)
|
||||
{
|
||||
_guidanceElectronicsUnit.LowLevel.HSSub9100.EnableIO = ControlState.Disabled;
|
||||
#region PublicClassFunctions
|
||||
|
||||
_guidanceElectronicsUnit.Close();
|
||||
_guidanceElectronicsUnit.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool IInstrument.DisplayEnabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
bool IInstrument.FrontPanelEnabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
InstrumentMetadata IInstrument.Info => throw new NotImplementedException();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceGeuSdlc(string deviceName, IConfigurationManager configurationManager)
|
||||
{
|
||||
Name = deviceName;
|
||||
_guidanceElectronicsUnit = null;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
uint ICommDevice.Write(byte[] data, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (numBytesToWrite % 4 != 0)
|
||||
{
|
||||
throw new Exception("Data is not dword aligned");
|
||||
}
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
// do all of the HSS Tx only byte order corrections
|
||||
PerformHssSwirl(ref data, numBytesToWrite / 4);
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
var tempArr = new uint[data.Length / 4];
|
||||
Buffer.BlockCopy(data, 0, tempArr, 0, (int)numBytesToWrite);
|
||||
_guidanceElectronicsUnit.GsKwSyncronousDataLinkControl.SendMessage(tempArr);
|
||||
}
|
||||
return numBytesToWrite;
|
||||
}
|
||||
_idQuery = _configuration.GetConfigurationValue("CommDeviceGeuSdlc", "IdQuery", true);
|
||||
_reset = _configuration.GetConfigurationValue("CommDeviceGeuSdlc", "Reset", true);
|
||||
_instrumentDriverSetup = _configuration.GetConfigurationValue("CommDeviceGeuSdlc", "InstrumentDriverSetup", "");
|
||||
_pollingRate = _configuration.GetConfigurationValue("CommDeviceGeuSdlc", "PollingRate", 10);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// The constructor. Does not initialize anything. Use Initialize() to create the handle to the hardware
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="idQuery"></param>
|
||||
/// <param name="reset"></param>
|
||||
public CommDeviceGeuSdlc(string deviceName, bool idQuery, bool reset, string instrumentDriverSetup = "", int pollingRate = 10)
|
||||
{
|
||||
Name = deviceName;
|
||||
_idQuery = idQuery;
|
||||
_reset = reset;
|
||||
_guidanceElectronicsUnit = null;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
_instrumentDriverSetup = instrumentDriverSetup;
|
||||
_pollingRate = pollingRate;
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool IInstrument.ClearErrors()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a HSS GEU SDLC Device called " + Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a handle to the hardware
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
const uint AUTO_FWDING_ADDR = 0x00080100;
|
||||
const uint WRITE_OFFSET = 0x00200000;
|
||||
const uint ENABLE_AUTO_FWDING = 0b0000_0001;
|
||||
const uint ENABLE_TLP_HDR = 0b0000_0010;
|
||||
//const uint INSERT_MSG_CNT = 0b0000_0100;
|
||||
|
||||
_guidanceElectronicsUnit = new GuidedElectronicsUnit.GuidedElectronicsUnit(Name, _idQuery, _reset,
|
||||
$"QueryInstrStatus=true, Simulate=false, DriverSetup= {_instrumentDriverSetup}, PollingInterval={_pollingRate}");
|
||||
|
||||
_guidanceElectronicsUnit.LowLevel.HSSub9100.EnableIO = ControlState.Enabled;
|
||||
|
||||
_guidanceElectronicsUnit.LowLevel.HSSub9100.WriteRegister(AUTO_FWDING_ADDR + WRITE_OFFSET, ENABLE_AUTO_FWDING | ENABLE_TLP_HDR);
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
SelfTestResult IInstrument.PerformSelfTest()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dataRead"></param>
|
||||
/// <returns></returns>
|
||||
uint ICommDevice.Read(ref byte[] dataRead)
|
||||
{
|
||||
|
||||
if (_guidanceElectronicsUnit == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte[] sdlcMsgs = new byte[0];
|
||||
lock (_syncObj)
|
||||
{
|
||||
// read all of the data that is available
|
||||
sdlcMsgs = _guidanceElectronicsUnit.GsKwSyncronousDataLinkControl.FetchMessageData();
|
||||
}
|
||||
|
||||
if (sdlcMsgs.Length > dataRead.Length)
|
||||
{
|
||||
throw new Exception("The data buffer that the host provided is: " + dataRead.Length + " bytes, there are: " + sdlcMsgs.Length + " bytes of SDLC data. Need to increase the host buffer size");
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(sdlcMsgs, 0, dataRead, 0, sdlcMsgs.Length);
|
||||
|
||||
return (uint)sdlcMsgs.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void IInstrument.Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_guidanceElectronicsUnit.Close();
|
||||
_state = State.Uninitialized;
|
||||
Thread.Sleep(500);
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
void ICommDevice.SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void IInstrument.Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_guidanceElectronicsUnit != null)
|
||||
{
|
||||
_guidanceElectronicsUnit.LowLevel.HSSub9100.EnableIO = ControlState.Disabled;
|
||||
|
||||
_guidanceElectronicsUnit.Close();
|
||||
_guidanceElectronicsUnit.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
uint ICommDevice.Write(byte[] data, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (numBytesToWrite % 4 != 0)
|
||||
{
|
||||
throw new Exception("Data is not dword aligned");
|
||||
}
|
||||
|
||||
// do all of the HSS Tx only byte order corrections
|
||||
PerformHssSwirl(ref data, numBytesToWrite / 4);
|
||||
|
||||
var tempArr = new uint[data.Length / 4];
|
||||
Buffer.BlockCopy(data, 0, tempArr, 0, (int)numBytesToWrite);
|
||||
_guidanceElectronicsUnit.GsKwSyncronousDataLinkControl.SendMessage(tempArr);
|
||||
}
|
||||
return numBytesToWrite;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,71 +32,64 @@
|
||||
// **********************************************************************************************************
|
||||
// Ignore Spelling: Sdlc Geu
|
||||
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceGeuSdlcFactory")]
|
||||
public class CommDeviceGeuSdlcFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceGeuSdlcFactory")]
|
||||
public class CommDeviceGeuSdlcFactory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
|
||||
public CommDeviceGeuSdlcFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceGeuSdlcFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null )
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
public CommDeviceGeuSdlcFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
/// <summary>
|
||||
/// CommDeviceGeuSdlcFactory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceGeuSdlcFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommDeviceGeuSdlc(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceGeuSdlc(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
@@ -107,12 +100,10 @@ namespace Raytheon.Instruments
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommDeviceSim(name, _configurationManager, _logger);
|
||||
return new CommDeviceSim(name, _configurationManager);
|
||||
else
|
||||
return new CommDeviceGeuSdlc(name, _configurationManager, _logger);
|
||||
return new CommDeviceGeuSdlc(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -125,17 +116,17 @@ namespace Raytheon.Instruments
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
// **********************************************************************************************************
|
||||
// CommDeviceSerialAsync.cs
|
||||
// 4/3/2024
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON
|
||||
// COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT.
|
||||
// DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON
|
||||
// COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED
|
||||
// TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF
|
||||
// RAYTHEON COMPANY.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceSerial : ICommDevice
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
private int _defaultReadTimeout;
|
||||
private int _defaultReadBufferSize;
|
||||
private object _syncObj = new object();
|
||||
|
||||
private SerialPort _serialPort;
|
||||
|
||||
private string _comPortName;
|
||||
private int _baudRate;
|
||||
private Parity _parity;
|
||||
private int _dataBits;
|
||||
private StopBits _stopBits;
|
||||
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
|
||||
#region Public Functions
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceSerial(string deviceName, IConfigurationManager configurationManager)
|
||||
{
|
||||
_name = deviceName;
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(deviceName);
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
_comPortName = _configuration.GetConfigurationValue(_name, "COMPortName");
|
||||
int.TryParse(_configuration.GetConfigurationValue(_name, "BaudRate"), out _baudRate);
|
||||
Enum.TryParse(_configuration.GetConfigurationValue(_name, "Parity"), true, out _parity);
|
||||
int.TryParse(_configuration.GetConfigurationValue(_name, "DataBits"), out _dataBits);
|
||||
Enum.TryParse(_configuration.GetConfigurationValue(_name, "StopBits"), true, out _stopBits);
|
||||
|
||||
int.TryParse(_configuration.GetConfigurationValue(_name, "ReadTimeout"), out _defaultReadTimeout);
|
||||
int.TryParse(_configuration.GetConfigurationValue(_name, "BufferSize"), out _defaultReadBufferSize);
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destructor
|
||||
/// </summary>
|
||||
~CommDeviceSerial()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
Open();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens COM serial port for communications
|
||||
/// </summary>
|
||||
public void Open()
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_serialPort = new SerialPort(_comPortName, _baudRate, _parity, _dataBits, _stopBits);
|
||||
_serialPort.Open();
|
||||
_serialPort.ReadTimeout = _defaultReadTimeout;
|
||||
_state = State.Ready;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
if (_serialPort != null)
|
||||
_serialPort.Close();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
if (dataRead == null)
|
||||
dataRead = new byte[_defaultReadBufferSize];
|
||||
|
||||
var bytesRead = _serialPort.Read(dataRead, 0, dataRead.Length);
|
||||
return (uint)bytesRead;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
if (timeoutMs > 0)
|
||||
_serialPort.ReadTimeout = (int)timeoutMs;
|
||||
else
|
||||
_serialPort.ReadTimeout = _defaultReadTimeout;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
_serialPort.Write(dataToSend, 0, (int)numBytesToWrite);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.CommDeviceSerial</AssemblyName>
|
||||
<Product>CommDevice Serial implementation</Product>
|
||||
<Description>CommDevice Serial COM implementation</Description>
|
||||
<OutputType>Library</OutputType>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.CommDevice.Contracts" Version="1.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CommDeviceSim\CommDeviceSim.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,129 @@
|
||||
// **********************************************************************************************************
|
||||
// CommDeviceSerialAsyncFactory.cs
|
||||
// 4/3/2024
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON
|
||||
// COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT.
|
||||
// DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON
|
||||
// COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED
|
||||
// TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF
|
||||
// RAYTHEON COMPANY.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceSerialFactory")]
|
||||
public class CommDeviceSerialFactory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommDeviceSerialFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CommDeviceSerialFactory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceSerialFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceSerial(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (simulateHw)
|
||||
return new CommDeviceSim(name, _configurationManager);
|
||||
else
|
||||
return new CommDeviceSerial(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,387 +30,314 @@
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceSerialAsync : ICommAsync
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceSerialAsync : ICommAsync
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
private uint _defaultReadTimeout;
|
||||
private uint _defaultSendTimeout;
|
||||
private uint _defaultReadBufferSize;
|
||||
private static readonly object _syncObj = new object();
|
||||
private uint _defaultReadTimeout;
|
||||
private uint _defaultSendTimeout;
|
||||
private uint _defaultReadBufferSize;
|
||||
private object _syncObj = new object();
|
||||
|
||||
private SerialPort _serialPort;
|
||||
private SerialPort _serialPort;
|
||||
|
||||
private readonly string _comPortName;
|
||||
private readonly int _baudRate;
|
||||
private readonly Parity _parity;
|
||||
private readonly int _dataBits;
|
||||
private readonly StopBits _stopBits;
|
||||
private string _comPortName;
|
||||
private int _baudRate;
|
||||
private Parity _parity;
|
||||
private int _dataBits;
|
||||
private StopBits _stopBits;
|
||||
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
#endregion
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
#endregion
|
||||
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket
|
||||
try
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Public Functions
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceSerialAsync(string deviceName, IConfigurationManager configurationManager)
|
||||
{
|
||||
_name = deviceName;
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(deviceName);
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
#region Public Functions
|
||||
_comPortName = _configuration.GetConfigurationValue(_name, "COMPortName");
|
||||
int.TryParse(_configuration.GetConfigurationValue(_name, "BaudRate"), out _baudRate);
|
||||
Enum.TryParse(_configuration.GetConfigurationValue(_name, "Parity"), true, out _parity);
|
||||
int.TryParse(_configuration.GetConfigurationValue(_name, "DataBits"), out _dataBits);
|
||||
Enum.TryParse(_configuration.GetConfigurationValue(_name, "StopBits"), true, out _stopBits);
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceSerialAsync(string name, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
_name = name;
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(name);
|
||||
_logger = logger;
|
||||
uint.TryParse(_configuration.GetConfigurationValue(_name, "ReadTimeout"), out _defaultReadTimeout);
|
||||
uint.TryParse(_configuration.GetConfigurationValue(_name, "SendTimeout"), out _defaultSendTimeout);
|
||||
uint.TryParse(_configuration.GetConfigurationValue(_name, "BufferSize"), out _defaultReadBufferSize);
|
||||
|
||||
_comPortName = _configuration.GetConfigurationValue("CommDeviceSerialAsync", "COMPortName", "COM15");
|
||||
_baudRate = _configuration.GetConfigurationValue("CommDeviceSerialAsync", "BaudRate", 115200);
|
||||
_parity = _configuration.GetConfigurationValue("CommDeviceSerialAsync", "Parity", Parity.None);
|
||||
_dataBits = _configuration.GetConfigurationValue("CommDeviceSerialAsync", "DataBits", 8);
|
||||
_stopBits = _configuration.GetConfigurationValue("CommDeviceSerialAsync", "StopBits", StopBits.One);
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
_defaultReadTimeout = _configuration.GetConfigurationValue<uint>("CommDeviceSerialAsync", "ReadTimeout", 25);
|
||||
_defaultSendTimeout = _configuration.GetConfigurationValue<uint>("CommDeviceSerialAsync", "SendTimeout", 5000);
|
||||
_defaultReadBufferSize = _configuration.GetConfigurationValue<uint>("CommDeviceSerialAsync", "BufferSize", 1024);
|
||||
/// <summary>
|
||||
/// Destructor
|
||||
/// </summary>
|
||||
~CommDeviceSerialAsync()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
Open();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
if (_state != State.Uninitialized)
|
||||
{
|
||||
_logger.Warn("Reinitialization of existing Serial Async Connection. Attempting to call Shutdown.");
|
||||
Shutdown();
|
||||
}
|
||||
/// <summary>
|
||||
/// Opens COM serial port for communications
|
||||
/// </summary>
|
||||
public void Open()
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_serialPort = new SerialPort(_comPortName, _baudRate, _parity, _dataBits, _stopBits);
|
||||
_serialPort.Open();
|
||||
_state = State.Ready;
|
||||
}
|
||||
}
|
||||
|
||||
_serialPort = new SerialPort(_comPortName, _baudRate, _parity, _dataBits, _stopBits);
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
if (_serialPort != null)
|
||||
_serialPort.Close();
|
||||
|
||||
Open();
|
||||
}
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens COM serial port for communications
|
||||
/// </summary>
|
||||
public void Open()
|
||||
{
|
||||
try
|
||||
{
|
||||
_serialPort.Open();
|
||||
_state = State.Ready;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex, ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<uint> ReadAsync(byte[] dataRead, CancellationToken token = default)
|
||||
{
|
||||
var bytesRead = await _serialPort.BaseStream.ReadAsync(dataRead, 0, dataRead.Length, token);
|
||||
return (uint)bytesRead;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
_logger.Debug("Shutting down");
|
||||
/// <summary>
|
||||
/// Read string from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<string> ReadAsync(CancellationToken token = default)
|
||||
{
|
||||
var data = await ReadLineAsync(token);
|
||||
return data;
|
||||
}
|
||||
|
||||
_serialPort.Close();
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
if (_serialPort == null)
|
||||
return;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
_serialPort.ReadTimeout = (int)timeoutMs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<uint> ReadAsync(byte[] dataRead, CancellationToken token = default)
|
||||
{
|
||||
var bytesRead = await _serialPort.BaseStream.ReadAsync(dataRead, 0, dataRead.Length, token);
|
||||
return (uint)bytesRead;
|
||||
}
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<uint> WriteAsync(byte[] dataToSend, uint numBytesToWrite, CancellationToken token = default)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return 0;
|
||||
|
||||
/// <summary>
|
||||
/// Read string from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<string> ReadAsync(CancellationToken token = default)
|
||||
{
|
||||
var data = await ReadLineAsync(token);
|
||||
return data;
|
||||
}
|
||||
await _serialPort.BaseStream.WriteAsync(dataToSend, 0, (int)numBytesToWrite, token);
|
||||
return numBytesToWrite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
if (_serialPort == null)
|
||||
return;
|
||||
/// <summary>
|
||||
/// Write string data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task WriteAsync(string message, CancellationToken token = default)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return;
|
||||
|
||||
_logger.Trace($"Setting Reader Timeout: {timeoutMs} Ms");
|
||||
_serialPort.ReadTimeout = (int)timeoutMs;
|
||||
}
|
||||
await WriteLineAsync(message, token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<uint> WriteAsync(byte[] dataToSend, uint numBytesToWrite, CancellationToken token = default)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return 0;
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendCommandGetResponseAsync(string message, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Writing message to ({_comPortName}), bytes: {dataToSend?.Length}");
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(message, cancellationToken);
|
||||
string readResponse = await ReadAsync(cancellationToken);
|
||||
return readResponse;
|
||||
}
|
||||
}
|
||||
|
||||
await _serialPort.BaseStream.WriteAsync(dataToSend, 0, (int)numBytesToWrite, token);
|
||||
return numBytesToWrite;
|
||||
}
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<byte[]> SendCommandGetResponseAsync(byte[] data, CancellationToken token = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return null;
|
||||
|
||||
/// <summary>
|
||||
/// Write string data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task WriteAsync(string message, CancellationToken token = default)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return;
|
||||
await WriteAsync(data, (uint)data.Length, token);
|
||||
_serialPort.ReadTimeout = timeoutInMs;
|
||||
var response = new byte[data.Length];
|
||||
await ReadAsync(response, token);
|
||||
return response;
|
||||
}
|
||||
|
||||
_logger.Trace($"Writing message to ({_comPortName}), message: {message}");
|
||||
await WriteLineAsync(message, token);
|
||||
}
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<string> dataReceived)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return;
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendCommandGetResponseAsync(string message, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return null;
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var data = await ReadAsync(cancellationToken);
|
||||
dataReceived?.Invoke(data);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_comPortName}), message: {message}");
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<byte[]> dataReceived)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return;
|
||||
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(message, cancellationToken);
|
||||
string readResponse = await ReadAsync(cancellationToken);
|
||||
_logger.Trace($"Received response: {readResponse}");
|
||||
return readResponse;
|
||||
}
|
||||
}
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var data = new byte[_defaultReadBufferSize]; // Adjust buffer size as needed
|
||||
var bytesRead = await ReadAsync(data, cancellationToken);
|
||||
Array.Resize(ref data, (int)bytesRead);
|
||||
dataReceived?.Invoke(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<byte[]> SendCommandGetResponseAsync(byte[] data, CancellationToken token = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return null;
|
||||
#endregion
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_comPortName}), message: {data}");
|
||||
#region private functions
|
||||
/// <summary>
|
||||
/// reads line async
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> ReadLineAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var line = await Task.Run(() => _serialPort.ReadLine(), cancellationToken);
|
||||
return line;
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
_logger.Error(ex, ex.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
await WriteAsync(data, (uint)data.Length, token);
|
||||
_serialPort.ReadTimeout = timeoutInMs;
|
||||
var response = new byte[data.Length];
|
||||
await ReadAsync(response, token);
|
||||
return response;
|
||||
}
|
||||
/// <summary>
|
||||
/// writes line async
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
private async Task WriteLineAsync(string message, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
await Task.Run(() => _serialPort.WriteLine(message), cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
_logger.Error(ex, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<string> dataReceived)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return;
|
||||
|
||||
_logger.Debug($"Starting continuous reading from {_comPortName} ...");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var data = await ReadAsync(cancellationToken);
|
||||
dataReceived?.Invoke(data);
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_comPortName} ...");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<byte[]> dataReceived)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return;
|
||||
|
||||
_logger.Debug($"Starting continuous reading from {_comPortName} ...");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var data = new byte[_defaultReadBufferSize]; // Adjust buffer size as needed
|
||||
var bytesRead = await ReadAsync(data, cancellationToken);
|
||||
Array.Resize(ref data, (int)bytesRead);
|
||||
dataReceived?.Invoke(data);
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_comPortName} ...");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private functions
|
||||
/// <summary>
|
||||
/// reads line async
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> ReadLineAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var line = await Task.Run(() => _serialPort.ReadLine(), cancellationToken);
|
||||
return line;
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
_logger.Error(ex, ex.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes line async
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
private async Task WriteLineAsync(string message, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
await Task.Run(() => _serialPort.WriteLine(message), cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
_logger.Error(ex, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,71 +30,63 @@
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceSerialAsyncFactory")]
|
||||
public class CommDeviceSerialAsyncFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceSerialAsyncFactory")]
|
||||
public class CommDeviceSerialAsyncFactory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommDeviceSerialAsyncFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
public CommDeviceSerialAsyncFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceSerialAsyncFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
/// <summary>
|
||||
/// CommDeviceSerialAsyncFactory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceSerialAsyncFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommAsync));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommDeviceSerialAsync(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommAsync));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceSerialAsync(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
@@ -105,9 +97,7 @@ namespace Raytheon.Instruments
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
return new CommDeviceSerialAsync(name, _configurationManager, _logger);
|
||||
return new CommDeviceSerialAsync(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -120,17 +110,17 @@ namespace Raytheon.Instruments
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,301 +15,296 @@ GOVERNMENT.
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceSim : ICommDevice
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private static object _syncObj = new Object();
|
||||
private readonly string _name;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceSim : ICommDevice
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private static object _syncObj = new Object();
|
||||
private readonly string _name;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
#endregion
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#region PrivateFunctions
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommDeviceSim()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
#region PrivateFunctions
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommDeviceSim()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
||||
#region PublicFuctions
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceSim(string name, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
_name = name;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
#region PublicFuctions
|
||||
|
||||
_logger = logger;
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceSim(string deviceName, IConfigurationManager configurationManager)
|
||||
{
|
||||
_name = deviceName;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
}
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public CommDeviceSim(string name)
|
||||
{
|
||||
_name = name;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
public CommDeviceSim(string deviceName)
|
||||
{
|
||||
_name = deviceName;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a Comm Device Sim called " + _name;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a Comm Device Sim called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
/// <summary>
|
||||
/// Dispose of the resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on device " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on device " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/*public void Open()
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/*public void Open()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
}
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Pass;
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_selfTestResult = SelfTestResult.Pass;
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
return (uint)dataRead.Length;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Read data from the device.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
return (uint)dataRead.Length;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeout"></param>
|
||||
public void SetReadTimeout(uint timeout)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeout"></param>
|
||||
public void SetReadTimeout(uint timeout)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to write</param>
|
||||
/// <param name="numBytesToWrite">The number of bytes to write</param>
|
||||
/// <returns>THe number of bytes that were written</returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
return numBytesToWrite;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Write data to the device
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to write</param>
|
||||
/// <param name="numBytesToWrite">The number of bytes to write</param>
|
||||
/// <returns>THe number of bytes that were written</returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
return numBytesToWrite;
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public void Close()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
public void Open()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,61 @@
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceSimFactory")]
|
||||
public class CommDeviceSimFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceSimFactory")]
|
||||
public class CommDeviceSimFactory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
|
||||
public CommDeviceSimFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceSimFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
public CommDeviceSimFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceSimFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommDeviceSim(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceSim(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
@@ -73,9 +66,7 @@ namespace Raytheon.Instruments
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
return new CommDeviceSim(name, _configurationManager, _logger);
|
||||
return new CommDeviceSim(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -88,17 +79,17 @@ namespace Raytheon.Instruments
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,503 +15,497 @@ GOVERNMENT.
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for controlling a Commtech SUPERFSCC/4-PCIE-11
|
||||
/// </summary>
|
||||
public class CommDeviceSuperFscc422 : ICommDevice, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
/// <summary>
|
||||
/// Class for controlling a Commtech SUPERFSCC/4-PCIE-11
|
||||
/// </summary>
|
||||
public class CommDeviceSuperFscc422 : ICommDevice, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
private const uint _DEFAULT_READ_TIMEOUT = 10;
|
||||
private const uint _RX_FIFO_BUFFER_SIZE = 8192;
|
||||
private const uint _TX_FIFO_BUFFER_SIZE = 4096;
|
||||
// The Super FSCC can DMA can stream data at 50 Mbits/sec
|
||||
// The driver automatically transfers data from the FIFO into the MemoryCap which has a configurable size. Default to ~GB
|
||||
private const uint _DEFAULT_READ_TIMEOUT = 10;
|
||||
private const uint _RX_FIFO_BUFFER_SIZE = 8192;
|
||||
private const uint _TX_FIFO_BUFFER_SIZE = 4096;
|
||||
// The Super FSCC can DMA can stream data at 50 Mbits/sec
|
||||
// The driver automatically transfers data from the FIFO into the MemoryCap which has a configurable size. Default to ~GB
|
||||
|
||||
private uint _readTimeout;
|
||||
private Fscc.Port _fscc;
|
||||
private static object _syncObj = new Object();
|
||||
private readonly string _name;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private readonly uint _portNum;
|
||||
private readonly uint _clockFreq;
|
||||
private readonly bool _shallWeReceiveMultiple;
|
||||
private readonly bool _shallWeAppendStatus;
|
||||
private readonly uint _bgrRegister;
|
||||
private readonly uint _ccr0Register;
|
||||
private readonly uint _ccr0SofResetValue;
|
||||
private readonly uint _ccr1Register;
|
||||
private readonly uint _ccr2Register;
|
||||
private readonly uint _dpllrRegister;
|
||||
private readonly uint _fcrRegister;
|
||||
private readonly uint _fifotRegister;
|
||||
private readonly uint _imrRegister;
|
||||
private readonly uint _pprRegister;
|
||||
private readonly uint _ramrRegister;
|
||||
private readonly uint _rarRegister;
|
||||
private readonly uint _smrRegister;
|
||||
private readonly uint _ssrRegister;
|
||||
private readonly uint _tcrRegister;
|
||||
private readonly uint _tmrRegister;
|
||||
private readonly uint _tsrRegister;
|
||||
private uint _readTimeout;
|
||||
private Fscc.Port _fscc;
|
||||
private static object _syncObj = new Object();
|
||||
private readonly string _name;
|
||||
private SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private readonly uint _portNum;
|
||||
private readonly uint _clockFreq;
|
||||
private readonly bool _shallWeReceiveMultiple;
|
||||
private readonly bool _shallWeAppendStatus;
|
||||
private readonly uint _bgrRegister;
|
||||
private readonly uint _ccr0Register;
|
||||
private readonly uint _ccr0SofResetValue;
|
||||
private readonly uint _ccr1Register;
|
||||
private readonly uint _ccr2Register;
|
||||
private readonly uint _dpllrRegister;
|
||||
private readonly uint _fcrRegister;
|
||||
private readonly uint _fifotRegister;
|
||||
private readonly uint _imrRegister;
|
||||
private readonly uint _pprRegister;
|
||||
private readonly uint _ramrRegister;
|
||||
private readonly uint _rarRegister;
|
||||
private readonly uint _smrRegister;
|
||||
private readonly uint _ssrRegister;
|
||||
private readonly uint _tcrRegister;
|
||||
private readonly uint _tmrRegister;
|
||||
private readonly uint _tsrRegister;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommDeviceSuperFscc422()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_fscc.Dispose();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceSuperFscc422(string deviceName, IConfigurationManager configurationManager)
|
||||
{
|
||||
_name = deviceName;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
_portNum = _configuration.GetConfigurationValue<uint>("SuperFscc422", "PortNum", 0);
|
||||
_clockFreq = _configuration.GetConfigurationValue<uint>("SuperFscc422", "ClockFreq", 0);
|
||||
_shallWeReceiveMultiple = _configuration.GetConfigurationValue("SuperFscc422", "ShallWeReceiveMultiple", false);
|
||||
_shallWeAppendStatus = _configuration.GetConfigurationValue("SuperFscc422", "ShallWeAppendStatus", false);
|
||||
_bgrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "BgrRegister", 0);
|
||||
_ccr0Register = _configuration.GetConfigurationValue<uint>("SuperFscc422", "Ccr0Register", 0);
|
||||
_ccr0SofResetValue = _configuration.GetConfigurationValue<uint>("SuperFscc422", "Ccr0SofResetValue", 0);
|
||||
_ccr1Register = _configuration.GetConfigurationValue<uint>("SuperFscc422", "Ccr1Register", 0);
|
||||
_ccr2Register = _configuration.GetConfigurationValue<uint>("SuperFscc422", "Ccr2Register", 0);
|
||||
_dpllrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "DpllrRegister", 0);
|
||||
_fcrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "FcrRegister", 0);
|
||||
_fifotRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "FifotRegister", 0);
|
||||
_imrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "ImrRegister", 0);
|
||||
_pprRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "PprRegister", 0);
|
||||
_ramrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "RamrRegister", 0);
|
||||
_rarRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "RarRegister", 0);
|
||||
_smrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "SmrRegister", 0);
|
||||
_ssrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "SsrRegister", 0);
|
||||
_tcrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "TcrRegister", 0);
|
||||
_tmrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "TmrRegister", 0);
|
||||
_tsrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "TsrRegister", 0);
|
||||
|
||||
_readTimeout = _DEFAULT_READ_TIMEOUT;
|
||||
|
||||
// created in Initialize()
|
||||
_fscc = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
/// <summary>
|
||||
/// Opens the port and initializes the registers
|
||||
/// </summary>
|
||||
/// <param name="portNum"></param>
|
||||
/// <param name="clockFreq"></param>
|
||||
/// <param name="shallWeReceiveMultiple"></param>
|
||||
/// <param name="shallWeAppendStatus"></param>
|
||||
/// <param name="bgrRegister"></param>
|
||||
/// <param name="ccr0Register"></param>
|
||||
/// <param name="ccr0SofResetValue"></param>
|
||||
/// <param name="ccr1Register"></param>
|
||||
/// <param name="ccr2Register"></param>
|
||||
/// <param name="dpllrRegister"></param>
|
||||
/// <param name="fcrRegister"></param>
|
||||
/// <param name="fifotRegister"></param>
|
||||
/// <param name="imrRegister"></param>
|
||||
/// <param name="pprRegister"></param>
|
||||
/// <param name="ramrRegister"></param>
|
||||
/// <param name="rarRegister"></param>
|
||||
/// <param name="smrRegister"></param>
|
||||
/// <param name="ssrRegister"></param>
|
||||
/// <param name="tcrRegister"></param>
|
||||
/// <param name="tmrRegister"></param>
|
||||
/// <param name="tsrRegister"></param>
|
||||
public CommDeviceSuperFscc422(string deviceName, uint portNum, uint clockFreq, bool shallWeReceiveMultiple, bool shallWeAppendStatus, uint bgrRegister, uint ccr0Register,
|
||||
uint ccr0SofResetValue, uint ccr1Register, uint ccr2Register, uint dpllrRegister, uint fcrRegister, uint fifotRegister,
|
||||
uint imrRegister, uint pprRegister, uint ramrRegister, uint rarRegister, uint smrRegister, uint ssrRegister, uint tcrRegister, uint tmrRegister, uint tsrRegister)
|
||||
{
|
||||
_name = deviceName;
|
||||
_portNum = portNum;
|
||||
_clockFreq = clockFreq;
|
||||
_shallWeReceiveMultiple = shallWeReceiveMultiple;
|
||||
_shallWeAppendStatus = shallWeAppendStatus;
|
||||
_bgrRegister = bgrRegister;
|
||||
_ccr0Register = ccr0Register;
|
||||
_ccr0SofResetValue = ccr0SofResetValue;
|
||||
_ccr1Register = ccr1Register;
|
||||
_ccr2Register = ccr2Register;
|
||||
_dpllrRegister = dpllrRegister;
|
||||
_fcrRegister = fcrRegister;
|
||||
_fifotRegister = fifotRegister;
|
||||
_imrRegister = imrRegister;
|
||||
_pprRegister = pprRegister;
|
||||
_ramrRegister = ramrRegister;
|
||||
_rarRegister = rarRegister;
|
||||
_smrRegister = smrRegister;
|
||||
_ssrRegister = ssrRegister;
|
||||
_tcrRegister = tcrRegister;
|
||||
_tmrRegister = tmrRegister;
|
||||
_tsrRegister = tsrRegister;
|
||||
|
||||
#endregion
|
||||
_readTimeout = _DEFAULT_READ_TIMEOUT;
|
||||
|
||||
#region PrivateFuctions
|
||||
// created in Initialize()
|
||||
_fscc = null;
|
||||
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommDeviceSuperFscc422()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_fscc.Dispose();
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#region PublicFuctions
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceSuperFscc422(string name, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
_name = name;
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FSCC 422 Device called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
_logger = logger;
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_portNum = _configuration.GetConfigurationValue<uint>("SuperFscc422", "PortNum", 0);
|
||||
_clockFreq = _configuration.GetConfigurationValue<uint>("SuperFscc422", "ClockFreq", 0);
|
||||
_shallWeReceiveMultiple = _configuration.GetConfigurationValue("SuperFscc422", "ShallWeReceiveMultiple", false);
|
||||
_shallWeAppendStatus = _configuration.GetConfigurationValue("SuperFscc422", "ShallWeAppendStatus", false);
|
||||
_bgrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "BgrRegister", 0);
|
||||
_ccr0Register = _configuration.GetConfigurationValue<uint>("SuperFscc422", "Ccr0Register", 0);
|
||||
_ccr0SofResetValue = _configuration.GetConfigurationValue<uint>("SuperFscc422", "Ccr0SofResetValue", 0);
|
||||
_ccr1Register = _configuration.GetConfigurationValue<uint>("SuperFscc422", "Ccr1Register", 0);
|
||||
_ccr2Register = _configuration.GetConfigurationValue<uint>("SuperFscc422", "Ccr2Register", 0);
|
||||
_dpllrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "DpllrRegister", 0);
|
||||
_fcrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "FcrRegister", 0);
|
||||
_fifotRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "FifotRegister", 0);
|
||||
_imrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "ImrRegister", 0);
|
||||
_pprRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "PprRegister", 0);
|
||||
_ramrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "RamrRegister", 0);
|
||||
_rarRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "RarRegister", 0);
|
||||
_smrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "SmrRegister", 0);
|
||||
_ssrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "SsrRegister", 0);
|
||||
_tcrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "TcrRegister", 0);
|
||||
_tmrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "TmrRegister", 0);
|
||||
_tsrRegister = _configuration.GetConfigurationValue<uint>("SuperFscc422", "TsrRegister", 0);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
_readTimeout = _DEFAULT_READ_TIMEOUT;
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
// created in Initialize()
|
||||
_fscc = null;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_fscc = new Fscc.Port(_portNum);
|
||||
|
||||
/// <summary>
|
||||
/// Opens the port and initializes the registers
|
||||
/// </summary>
|
||||
/// <param name="portNum"></param>
|
||||
/// <param name="clockFreq"></param>
|
||||
/// <param name="shallWeReceiveMultiple"></param>
|
||||
/// <param name="shallWeAppendStatus"></param>
|
||||
/// <param name="bgrRegister"></param>
|
||||
/// <param name="ccr0Register"></param>
|
||||
/// <param name="ccr0SofResetValue"></param>
|
||||
/// <param name="ccr1Register"></param>
|
||||
/// <param name="ccr2Register"></param>
|
||||
/// <param name="dpllrRegister"></param>
|
||||
/// <param name="fcrRegister"></param>
|
||||
/// <param name="fifotRegister"></param>
|
||||
/// <param name="imrRegister"></param>
|
||||
/// <param name="pprRegister"></param>
|
||||
/// <param name="ramrRegister"></param>
|
||||
/// <param name="rarRegister"></param>
|
||||
/// <param name="smrRegister"></param>
|
||||
/// <param name="ssrRegister"></param>
|
||||
/// <param name="tcrRegister"></param>
|
||||
/// <param name="tmrRegister"></param>
|
||||
/// <param name="tsrRegister"></param>
|
||||
public CommDeviceSuperFscc422(string name, uint portNum, uint clockFreq, bool shallWeReceiveMultiple, bool shallWeAppendStatus, uint bgrRegister, uint ccr0Register,
|
||||
uint ccr0SofResetValue, uint ccr1Register, uint ccr2Register, uint dpllrRegister, uint fcrRegister, uint fifotRegister,
|
||||
uint imrRegister, uint pprRegister, uint ramrRegister, uint rarRegister, uint smrRegister, uint ssrRegister, uint tcrRegister, uint tmrRegister, uint tsrRegister)
|
||||
{
|
||||
_name = name;
|
||||
_portNum = portNum;
|
||||
_clockFreq = clockFreq;
|
||||
_shallWeReceiveMultiple = shallWeReceiveMultiple;
|
||||
_shallWeAppendStatus = shallWeAppendStatus;
|
||||
_bgrRegister = bgrRegister;
|
||||
_ccr0Register = ccr0Register;
|
||||
_ccr0SofResetValue = ccr0SofResetValue;
|
||||
_ccr1Register = ccr1Register;
|
||||
_ccr2Register = ccr2Register;
|
||||
_dpllrRegister = dpllrRegister;
|
||||
_fcrRegister = fcrRegister;
|
||||
_fifotRegister = fifotRegister;
|
||||
_imrRegister = imrRegister;
|
||||
_pprRegister = pprRegister;
|
||||
_ramrRegister = ramrRegister;
|
||||
_rarRegister = rarRegister;
|
||||
_smrRegister = smrRegister;
|
||||
_ssrRegister = ssrRegister;
|
||||
_tcrRegister = tcrRegister;
|
||||
_tmrRegister = tmrRegister;
|
||||
_tsrRegister = tsrRegister;
|
||||
// false means that each read will return a single sdlc packet
|
||||
// true means that each read will return everything in the buffer (multiple packets)
|
||||
_fscc.RxMultiple = _shallWeReceiveMultiple;
|
||||
|
||||
_readTimeout = _DEFAULT_READ_TIMEOUT;
|
||||
// if this to true...extra 2 bytes arrive at the end of every frame (first two bytes of STAR)
|
||||
// The class processing the data needs to be aware of the extra two bytes
|
||||
_fscc.AppendStatus = _shallWeAppendStatus;
|
||||
|
||||
// created in Initialize()
|
||||
_fscc = null;
|
||||
// ignore timeouts
|
||||
_fscc.IgnoreTimeout = true;
|
||||
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
// purge the port
|
||||
_fscc.Purge(true, true);
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
// set the registers
|
||||
_fscc.Registers.BGR = _bgrRegister;
|
||||
_fscc.Registers.CCR0 = _ccr0Register;
|
||||
_fscc.Registers.CCR1 = _ccr1Register;
|
||||
_fscc.Registers.CCR2 = _ccr2Register;
|
||||
_fscc.Registers.DPLLR = _dpllrRegister;
|
||||
_fscc.Registers.FCR = _fcrRegister;
|
||||
_fscc.Registers.FIFOT = _fifotRegister;
|
||||
_fscc.Registers.IMR = _imrRegister;
|
||||
_fscc.Registers.PPR = _pprRegister;
|
||||
_fscc.Registers.RAMR = _ramrRegister;
|
||||
_fscc.Registers.RAR = _rarRegister;
|
||||
_fscc.Registers.SMR = _smrRegister;
|
||||
_fscc.Registers.SSR = _ssrRegister;
|
||||
_fscc.Registers.TCR = _tcrRegister;
|
||||
_fscc.Registers.TMR = _tmrRegister;
|
||||
_fscc.Registers.TSR = _tsrRegister;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// false means that each read will return a single sdlc packet
|
||||
// true means that each read will return everything in the buffer (multiple packets)
|
||||
_fscc.RxMultiple = _shallWeReceiveMultiple;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
_fscc.ClockFrequency = _clockFreq;
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
// if this to true...extra 2 bytes arrive at the end of every frame (first two bytes of STAR)
|
||||
// The class processing the data needs to be aware of the extra two bytes
|
||||
_fscc.AppendStatus = _shallWeAppendStatus;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a FSCC 422 Device called " + _name;
|
||||
}
|
||||
}
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on device " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
/// Read data from the device.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint numBytesRead = _fscc.Read(dataRead, (uint)dataRead.Length, _readTimeout);
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
return numBytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Soft reset procedure as suggested by the vendor
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_fscc.Registers.CCR0 = _ccr0SofResetValue;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_fscc = new Fscc.Port(_portNum);
|
||||
_fscc.Purge(true, true);
|
||||
|
||||
// false means that each read will return a single sdlc packet
|
||||
// true means that each read will return everything in the buffer (multiple packets)
|
||||
_fscc.RxMultiple = _shallWeReceiveMultiple;
|
||||
_fscc.Registers.CCR0 = _ccr0Register;
|
||||
}
|
||||
}
|
||||
|
||||
// if this to true...extra 2 bytes arrive at the end of every frame (first two bytes of STAR)
|
||||
// The class processing the data needs to be aware of the extra two bytes
|
||||
_fscc.AppendStatus = _shallWeAppendStatus;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_readTimeout = timeoutMs;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore timeouts
|
||||
_fscc.IgnoreTimeout = true;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
// purge the port
|
||||
_fscc.Purge(true, true);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
// set the registers
|
||||
_fscc.Registers.BGR = _bgrRegister;
|
||||
_fscc.Registers.CCR0 = _ccr0Register;
|
||||
_fscc.Registers.CCR1 = _ccr1Register;
|
||||
_fscc.Registers.CCR2 = _ccr2Register;
|
||||
_fscc.Registers.DPLLR = _dpllrRegister;
|
||||
_fscc.Registers.FCR = _fcrRegister;
|
||||
_fscc.Registers.FIFOT = _fifotRegister;
|
||||
_fscc.Registers.IMR = _imrRegister;
|
||||
_fscc.Registers.PPR = _pprRegister;
|
||||
_fscc.Registers.RAMR = _ramrRegister;
|
||||
_fscc.Registers.RAR = _rarRegister;
|
||||
_fscc.Registers.SMR = _smrRegister;
|
||||
_fscc.Registers.SSR = _ssrRegister;
|
||||
_fscc.Registers.TCR = _tcrRegister;
|
||||
_fscc.Registers.TMR = _tmrRegister;
|
||||
_fscc.Registers.TSR = _tsrRegister;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_fscc.Dispose();
|
||||
|
||||
// false means that each read will return a single sdlc packet
|
||||
// true means that each read will return everything in the buffer (multiple packets)
|
||||
_fscc.RxMultiple = _shallWeReceiveMultiple;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_fscc.ClockFrequency = _clockFreq;
|
||||
/// <summary>
|
||||
/// Write data to the device
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to write</param>
|
||||
/// <param name="numBytesToWrite">The number of bytes to write</param>
|
||||
/// <returns>THe number of bytes that were written</returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint numWritten = _fscc.Write(dataToSend, numBytesToWrite);
|
||||
|
||||
// if this to true...extra 2 bytes arrive at the end of every frame (first two bytes of STAR)
|
||||
// The class processing the data needs to be aware of the extra two bytes
|
||||
_fscc.AppendStatus = _shallWeAppendStatus;
|
||||
if (numWritten != numBytesToWrite)
|
||||
{
|
||||
throw new Exception("num written " + numWritten + " not as expected: " + numBytesToWrite);
|
||||
}
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on device " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return numWritten;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
}
|
||||
public void Close()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
public void Open()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint numBytesRead = _fscc.Read(dataRead, (uint)dataRead.Length, _readTimeout);
|
||||
|
||||
return numBytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Soft reset procedure as suggested by the vendor
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_fscc.Registers.CCR0 = _ccr0SofResetValue;
|
||||
|
||||
_fscc.Purge(true, true);
|
||||
|
||||
_fscc.Registers.CCR0 = _ccr0Register;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_readTimeout = timeoutMs;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_fscc.Dispose();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to write</param>
|
||||
/// <param name="numBytesToWrite">The number of bytes to write</param>
|
||||
/// <returns>THe number of bytes that were written</returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint numWritten = _fscc.Write(dataToSend, numBytesToWrite);
|
||||
|
||||
if (numWritten != numBytesToWrite)
|
||||
{
|
||||
throw new Exception("num written " + numWritten + " not as expected: " + numBytesToWrite);
|
||||
}
|
||||
|
||||
return numWritten;
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,60 @@
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceSuperFscc422Factory")]
|
||||
public class CommDeviceSuperFscc422Factory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceSuperFscc422Factory")]
|
||||
public class CommDeviceSuperFscc422Factory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
public CommDeviceSuperFscc422Factory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
public CommDeviceSuperFscc422Factory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceSuperFscc422Factory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
/// <summary>
|
||||
/// CommDeviceSuperFscc422Factory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceSuperFscc422Factory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommDeviceSuperFscc422(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceSuperFscc422(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
@@ -73,12 +65,10 @@ namespace Raytheon.Instruments
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
if (simulateHw)
|
||||
return new CommDeviceSim(name, _configurationManager, _logger);
|
||||
return new CommDeviceSim(name, _configurationManager);
|
||||
else
|
||||
return new CommDeviceSuperFscc422(name, _configurationManager, _logger);
|
||||
return new CommDeviceSuperFscc422(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -91,71 +81,71 @@ namespace Raytheon.Instruments
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="instrumentDefFile"></param>
|
||||
/// <param name="iniSectionName"></param>
|
||||
/// <param name="isThereHardware"></param>
|
||||
/// <returns></returns>
|
||||
public static ICommDevice CreateFastCommDevice(string instrumentDefFile, string iniSectionName, bool isThereHardware)
|
||||
{
|
||||
const string FAST_COMM_FSCC = "FAST_COMM_FSCC";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="instrumentDefFile"></param>
|
||||
/// <param name="iniSectionName"></param>
|
||||
/// <param name="isThereHardware"></param>
|
||||
/// <returns></returns>
|
||||
public static ICommDevice CreateFastCommDevice(string instrumentDefFile, string iniSectionName, bool isThereHardware)
|
||||
{
|
||||
const string FAST_COMM_FSCC = "FAST_COMM_FSCC";
|
||||
|
||||
IniFile iniReader = new IniFile(instrumentDefFile);
|
||||
IniFile iniReader = new IniFile(instrumentDefFile);
|
||||
|
||||
bool shallWeDebug = Convert.ToBoolean(iniReader.ReadValue(FAST_COMM_FSCC, "SHALL_WE_DEBUG"));
|
||||
uint port = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "PORT"));
|
||||
uint clock = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CLOCK_FREQUENCY"), 16);
|
||||
uint bgr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "BGR_REGISTER"), 16);
|
||||
uint ccr0 = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CCR0_REGISTER"), 16);
|
||||
uint ccr0Reset = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CCR0_SOF_RESET_VALUE"), 16);
|
||||
uint ccr1 = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CCR1_REGISTER"), 16);
|
||||
uint ccr2 = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CCR2_REGISTER"), 16);
|
||||
uint dpllr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "DPLLR_REGISTER"), 16);
|
||||
uint fcr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "FCR_REGISTER"), 16);
|
||||
uint fifot = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "FIFO_T_REGISTER"), 16);
|
||||
uint imr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "IMR_REGISTER"), 16);
|
||||
uint ppr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "PPR_REGISTER"), 16);
|
||||
uint ramr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "RAMR_REGISTER"), 16);
|
||||
uint rar = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "RAR_REGISTER"), 16);
|
||||
uint smr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "SMR_REGISTER"), 16);
|
||||
uint ssr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "SSR_REGISTER"), 16);
|
||||
uint tcr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "TCR_REGISTER"), 16);
|
||||
uint tmr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "TMR_REGISTER"), 16);
|
||||
uint tsr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "TSR_REGISTER"), 16);
|
||||
bool shallWeDebug = Convert.ToBoolean(iniReader.ReadValue(FAST_COMM_FSCC, "SHALL_WE_DEBUG"));
|
||||
uint port = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "PORT"));
|
||||
uint clock = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CLOCK_FREQUENCY"), 16);
|
||||
uint bgr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "BGR_REGISTER"), 16);
|
||||
uint ccr0 = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CCR0_REGISTER"), 16);
|
||||
uint ccr0Reset = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CCR0_SOF_RESET_VALUE"), 16);
|
||||
uint ccr1 = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CCR1_REGISTER"), 16);
|
||||
uint ccr2 = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "CCR2_REGISTER"), 16);
|
||||
uint dpllr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "DPLLR_REGISTER"), 16);
|
||||
uint fcr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "FCR_REGISTER"), 16);
|
||||
uint fifot = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "FIFO_T_REGISTER"), 16);
|
||||
uint imr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "IMR_REGISTER"), 16);
|
||||
uint ppr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "PPR_REGISTER"), 16);
|
||||
uint ramr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "RAMR_REGISTER"), 16);
|
||||
uint rar = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "RAR_REGISTER"), 16);
|
||||
uint smr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "SMR_REGISTER"), 16);
|
||||
uint ssr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "SSR_REGISTER"), 16);
|
||||
uint tcr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "TCR_REGISTER"), 16);
|
||||
uint tmr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "TMR_REGISTER"), 16);
|
||||
uint tsr = Convert.ToUInt32(iniReader.ReadValue(FAST_COMM_FSCC, "TSR_REGISTER"), 16);
|
||||
|
||||
bool shallWeReceiveMultiple = true;
|
||||
bool shallWeAppendStatus = false;
|
||||
bool shallWeReceiveMultiple = true;
|
||||
bool shallWeAppendStatus = false;
|
||||
|
||||
if (shallWeDebug == true)
|
||||
{
|
||||
shallWeReceiveMultiple = false;
|
||||
shallWeAppendStatus = true;
|
||||
}
|
||||
if (shallWeDebug == true)
|
||||
{
|
||||
shallWeReceiveMultiple = false;
|
||||
shallWeAppendStatus = true;
|
||||
}
|
||||
|
||||
if (isThereHardware == true)
|
||||
{
|
||||
return new CommDeviceSuperFscc422(iniSectionName, port, clock, shallWeReceiveMultiple, shallWeAppendStatus, bgr, ccr0, ccr0Reset, ccr1, ccr2, dpllr, fcr, fifot, imr, ppr, ramr, rar, smr, ssr, tcr, tmr, tsr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CommDeviceSim(iniSectionName);
|
||||
}
|
||||
}
|
||||
if (isThereHardware == true)
|
||||
{
|
||||
return new CommDeviceSuperFscc422(iniSectionName, port, clock, shallWeReceiveMultiple, shallWeAppendStatus, bgr, ccr0, ccr0Reset, ccr1, ccr2, dpllr, fcr, fifot, imr, ppr, ramr, rar, smr, ssr, tcr, tmr, tsr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CommDeviceSim(iniSectionName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,436 +30,431 @@
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceTcpAsync : ICommAsync
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
private uint _defaultReadTimeout;
|
||||
private uint _defaultSendTimeout;
|
||||
private uint _defaultReadBufferSize;
|
||||
private static readonly object _syncObj = new object();
|
||||
private TcpClient _tcpClient;
|
||||
private TcpListener _tcpListener;
|
||||
private NetworkStream _tcpIpStream;
|
||||
private int _port;
|
||||
private string _remoteAddress;
|
||||
private int _remotePort;
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
public void Open() => Initialize();
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket
|
||||
try
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Functions
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceTcpAsync(string name, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
_name = name;
|
||||
|
||||
// _tcpClient is created in Initialize()
|
||||
_tcpClient = null;
|
||||
_tcpIpStream = null;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
if (_state != State.Uninitialized)
|
||||
{
|
||||
_logger.Warn("Reinitialization of existing TCP Async Connection. Attempting to call Shutdown.");
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
_defaultReadTimeout = _configuration.GetConfigurationValue<uint>("TcpClient", "ReadTimeout", 25);
|
||||
_defaultSendTimeout = _configuration.GetConfigurationValue<uint>("TcpClient", "SendTimeout", 5000);
|
||||
_defaultReadBufferSize = _configuration.GetConfigurationValue<uint>("TcpClient", "BufferSize", 1024);
|
||||
|
||||
_remoteAddress = _configuration.GetConfigurationValue("TcpClient", "RemoteAddress", "127.0.0.1");
|
||||
_port = _configuration.GetConfigurationValue("TcpClient", "Port", 0);
|
||||
|
||||
if (string.IsNullOrEmpty(_remoteAddress))
|
||||
{
|
||||
_tcpListener = new TcpListener(IPAddress.Any, _port);
|
||||
_tcpListener.Start();
|
||||
|
||||
_logger.Debug($"{MethodBase.GetCurrentMethod().Name} Started Listening on Port: {_port}");
|
||||
|
||||
Task.Run(async () => await _tcpListener.AcceptTcpClientAsync()).ContinueWith(t =>
|
||||
{
|
||||
_tcpClient = t.Result;
|
||||
|
||||
_remoteAddress = ((IPEndPoint)_tcpClient.Client.RemoteEndPoint).Address.ToString();
|
||||
_remotePort = ((IPEndPoint)_tcpClient.Client.RemoteEndPoint).Port;
|
||||
|
||||
_logger.Debug($"{MethodBase.GetCurrentMethod().Name} Connection Established from Remote Address: {_remoteAddress}:{_remotePort}");
|
||||
|
||||
// set timeouts
|
||||
_tcpClient.Client.SendTimeout = (int)_defaultSendTimeout;
|
||||
_tcpClient.Client.ReceiveTimeout = (int)_defaultReadTimeout;
|
||||
|
||||
// get the stream
|
||||
_tcpIpStream = _tcpClient.GetStream();
|
||||
|
||||
_state = State.Ready;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_remotePort = _port;
|
||||
_tcpClient = new TcpClient(_remoteAddress, _remotePort);
|
||||
|
||||
_logger.Debug($"{MethodBase.GetCurrentMethod().Name} Connected to Remote Address {_remoteAddress}:{_remotePort}");
|
||||
|
||||
// set timeouts
|
||||
_tcpClient.Client.SendTimeout = (int)_defaultSendTimeout;
|
||||
_tcpClient.Client.ReceiveTimeout = (int)_defaultReadTimeout;
|
||||
|
||||
// get the stream
|
||||
_tcpIpStream = _tcpClient.GetStream();
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
_logger.Debug("Shutting down");
|
||||
_tcpClient?.Dispose();
|
||||
_tcpClient = null;
|
||||
|
||||
_tcpListener?.Stop();
|
||||
_tcpListener = null;
|
||||
|
||||
_tcpIpStream?.Dispose();
|
||||
_tcpIpStream = null;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<uint> ReadAsync(byte[] dataRead, CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return 0;
|
||||
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var bytesRead = await _tcpIpStream.ReadAsync(dataRead, 0, dataRead.Length, token);
|
||||
|
||||
_logger.Trace($"Reading Data, bytes received: {bytesRead}");
|
||||
|
||||
_state = State.Ready;
|
||||
return (uint)bytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read string from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<string> ReadAsync(CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return null;
|
||||
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var buffer = new byte[_defaultReadBufferSize];
|
||||
var bytesRead = await _tcpIpStream.ReadAsync(buffer, 0, buffer.Length, token);
|
||||
_state = State.Ready;
|
||||
|
||||
var message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
|
||||
|
||||
_logger.Trace($"Reading Data, message received: {message}");
|
||||
|
||||
return message;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
_logger.Trace($"Setting Reader Timeout: {timeoutMs} Ms");
|
||||
|
||||
_tcpClient.Client.ReceiveTimeout = (int)timeoutMs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<uint> WriteAsync(byte[] dataToSend, uint numBytesToWrite, CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return 0;
|
||||
|
||||
_logger.Trace($"Writing message to ({_remoteAddress}:{_remotePort}), bytes: {dataToSend?.Length}");
|
||||
|
||||
_state = State.Busy;
|
||||
await _tcpIpStream.WriteAsync(dataToSend, 0, (int)numBytesToWrite, token);
|
||||
_state = State.Ready;
|
||||
return numBytesToWrite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task WriteAsync(string message, CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return;
|
||||
|
||||
_logger.Trace($"Writing message to ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
_state = State.Busy;
|
||||
var buffer = Encoding.UTF8.GetBytes(message);
|
||||
await _tcpIpStream.WriteAsync(buffer, 0, buffer.Length, token);
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendCommandGetResponseAsync(string message, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(message, cancellationToken);
|
||||
string readResponse = await ReadAsync(cancellationToken);
|
||||
_logger.Trace($"Received response: {readResponse}");
|
||||
return readResponse;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<byte[]> SendCommandGetResponseAsync(byte[] data, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_remoteAddress}:{_remotePort}), message: {data}");
|
||||
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(data, (uint)data.Length, cancellationToken);
|
||||
byte[] buffer = new byte[_defaultReadBufferSize];
|
||||
uint bytesRead = await ReadAsync(buffer, cancellationToken);
|
||||
_logger.Trace($"Received response of size: {bytesRead}");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<string> dataReceived)
|
||||
{
|
||||
_logger.Debug($"Starting continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
|
||||
byte[] buffer = new byte[_defaultReadBufferSize];
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint bytesRead = await ReadAsync(buffer, cancellationToken);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
string data = Encoding.UTF8.GetString(buffer, 0, (int)bytesRead);
|
||||
|
||||
_logger.Trace($"Message received from {_remoteAddress}:{_remotePort}: {data}");
|
||||
|
||||
dataReceived(data);
|
||||
Array.Clear(buffer, 0, (int)bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<byte[]> dataReceived)
|
||||
{
|
||||
_logger.Debug($"Starting continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
|
||||
byte[] buffer = new byte[_defaultReadBufferSize];
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint bytesRead = await ReadAsync(buffer, cancellationToken);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
_logger.Trace($"Message received from {_remoteAddress}:{_remotePort}: size {bytesRead}");
|
||||
byte[] bufferCopy = new byte[bytesRead];
|
||||
Array.Copy(buffer, bufferCopy, bytesRead);
|
||||
dataReceived(bufferCopy);
|
||||
Array.Clear(buffer, 0, (int)bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceTcpAsync : ICommAsync
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
|
||||
private uint _defaultReadTimeout;
|
||||
private uint _defaultSendTimeout;
|
||||
private uint _defaultReadBufferSize;
|
||||
private static readonly object _syncObj = new object();
|
||||
private TcpClient _tcpClient;
|
||||
private TcpListener _tcpListener;
|
||||
private NetworkStream _tcpIpStream;
|
||||
private int _port;
|
||||
private string _remoteAddress;
|
||||
private int _remotePort;
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
public void Open() => Initialize();
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket
|
||||
try
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Functions
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceTcpAsync(string deviceName, IConfigurationManager configurationManager)
|
||||
{
|
||||
_name = deviceName;
|
||||
|
||||
// _tcpClient is created in Initialize()
|
||||
_tcpClient = null;
|
||||
_tcpIpStream = null;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
if (_state != State.Uninitialized)
|
||||
{
|
||||
_logger.Warn("Reinitialization of existing TCP Async Connection. Attempting to call Shutdown.");
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
_defaultReadTimeout = _configuration.GetConfigurationValue<uint>("TcpClient", "ReadTimeout", 25);
|
||||
_defaultSendTimeout = _configuration.GetConfigurationValue<uint>("TcpClient", "SendTimeout", 5000);
|
||||
_defaultReadBufferSize = _configuration.GetConfigurationValue<uint>("TcpClient", "BufferSize", 1024);
|
||||
|
||||
_remoteAddress = _configuration.GetConfigurationValue("TcpClient", "RemoteAddress", "127.0.0.1");
|
||||
_port = _configuration.GetConfigurationValue("TcpClient", "Port", 0);
|
||||
|
||||
if (string.IsNullOrEmpty(_remoteAddress))
|
||||
{
|
||||
_tcpListener = new TcpListener(IPAddress.Any, _port);
|
||||
_tcpListener.Start();
|
||||
|
||||
_logger.Debug($"{MethodBase.GetCurrentMethod().Name} Started Listening on Port: {_port}");
|
||||
|
||||
Task.Run(async () => await _tcpListener.AcceptTcpClientAsync()).ContinueWith(t =>
|
||||
{
|
||||
_tcpClient = t.Result;
|
||||
|
||||
_remoteAddress = ((IPEndPoint)_tcpClient.Client.RemoteEndPoint).Address.ToString();
|
||||
_remotePort = ((IPEndPoint)_tcpClient.Client.RemoteEndPoint).Port;
|
||||
|
||||
_logger.Debug($"{MethodBase.GetCurrentMethod().Name} Connection Established from Remote Address: {_remoteAddress}:{_remotePort}");
|
||||
|
||||
// set timeouts
|
||||
_tcpClient.Client.SendTimeout = (int)_defaultSendTimeout;
|
||||
_tcpClient.Client.ReceiveTimeout = (int)_defaultReadTimeout;
|
||||
|
||||
// get the stream
|
||||
_tcpIpStream = _tcpClient.GetStream();
|
||||
|
||||
_state = State.Ready;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_remotePort = _port;
|
||||
_tcpClient = new TcpClient(_remoteAddress, _remotePort);
|
||||
|
||||
_logger.Debug($"{MethodBase.GetCurrentMethod().Name} Connected to Remote Address {_remoteAddress}:{_remotePort}");
|
||||
|
||||
// set timeouts
|
||||
_tcpClient.Client.SendTimeout = (int)_defaultSendTimeout;
|
||||
_tcpClient.Client.ReceiveTimeout = (int)_defaultReadTimeout;
|
||||
|
||||
// get the stream
|
||||
_tcpIpStream = _tcpClient.GetStream();
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
_logger.Debug("Shutting down");
|
||||
_tcpClient?.Dispose();
|
||||
_tcpClient = null;
|
||||
|
||||
_tcpListener?.Stop();
|
||||
_tcpListener = null;
|
||||
|
||||
_tcpIpStream?.Dispose();
|
||||
_tcpIpStream = null;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<uint> ReadAsync(byte[] dataRead, CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return 0;
|
||||
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var bytesRead = await _tcpIpStream.ReadAsync(dataRead, 0, dataRead.Length, token);
|
||||
|
||||
_logger.Trace($"Reading Data, bytes received: {bytesRead}");
|
||||
|
||||
_state = State.Ready;
|
||||
return (uint)bytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read string from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<string> ReadAsync(CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return null;
|
||||
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var buffer = new byte[_defaultReadBufferSize];
|
||||
var bytesRead = await _tcpIpStream.ReadAsync(buffer, 0, buffer.Length, token);
|
||||
_state = State.Ready;
|
||||
|
||||
var message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
|
||||
|
||||
_logger.Trace($"Reading Data, message received: {message}");
|
||||
|
||||
return message;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
_logger.Trace($"Setting Reader Timeout: {timeoutMs} Ms");
|
||||
|
||||
_tcpClient.Client.ReceiveTimeout = (int)timeoutMs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<uint> WriteAsync(byte[] dataToSend, uint numBytesToWrite, CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return 0;
|
||||
|
||||
_logger.Trace($"Writing message to ({_remoteAddress}:{_remotePort}), bytes: {dataToSend?.Length}");
|
||||
|
||||
_state = State.Busy;
|
||||
await _tcpIpStream.WriteAsync(dataToSend, 0, (int)numBytesToWrite, token);
|
||||
_state = State.Ready;
|
||||
return numBytesToWrite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task WriteAsync(string message, CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return;
|
||||
|
||||
_logger.Trace($"Writing message to ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
_state = State.Busy;
|
||||
var buffer = Encoding.UTF8.GetBytes(message);
|
||||
await _tcpIpStream.WriteAsync(buffer, 0, buffer.Length, token);
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendCommandGetResponseAsync(string message, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(message, cancellationToken);
|
||||
string readResponse = await ReadAsync(cancellationToken);
|
||||
_logger.Trace($"Received response: {readResponse}");
|
||||
return readResponse;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<byte[]> SendCommandGetResponseAsync(byte[] data, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_remoteAddress}:{_remotePort}), message: {data}");
|
||||
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(data, (uint)data.Length, cancellationToken);
|
||||
byte[] buffer = new byte[_defaultReadBufferSize];
|
||||
uint bytesRead = await ReadAsync(buffer, cancellationToken);
|
||||
_logger.Trace($"Received response of size: {bytesRead}");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<string> dataReceived)
|
||||
{
|
||||
_logger.Debug($"Starting continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
|
||||
byte[] buffer = new byte[_defaultReadBufferSize];
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint bytesRead = await ReadAsync(buffer, cancellationToken);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
string data = Encoding.UTF8.GetString(buffer, 0, (int)bytesRead);
|
||||
|
||||
_logger.Trace($"Message received from {_remoteAddress}:{_remotePort}: {data}");
|
||||
|
||||
dataReceived(data);
|
||||
Array.Clear(buffer, 0, (int)bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<byte[]> dataReceived)
|
||||
{
|
||||
_logger.Debug($"Starting continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
|
||||
byte[] buffer = new byte[_defaultReadBufferSize];
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (_tcpIpStream == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint bytesRead = await ReadAsync(buffer, cancellationToken);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
_logger.Trace($"Message received from {_remoteAddress}:{_remotePort}: size {bytesRead}");
|
||||
byte[] bufferCopy = new byte[bytesRead];
|
||||
Array.Copy(buffer, bufferCopy, bytesRead);
|
||||
dataReceived(bufferCopy);
|
||||
Array.Clear(buffer, 0, (int)bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,71 +30,64 @@
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceTcpAsyncFactory")]
|
||||
public class CommDeviceTcpAsyncFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceTcpAsyncFactory")]
|
||||
public class CommDeviceTcpAsyncFactory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
|
||||
public CommDeviceTcpAsyncFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceTcpAsyncFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
public CommDeviceTcpAsyncFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
/// <summary>
|
||||
/// CommDeviceTcpAsyncFactory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceTcpAsyncFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommAsync));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommDeviceTcpAsync(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommAsync));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceTcpAsync(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
@@ -105,9 +98,7 @@ namespace Raytheon.Instruments
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
return new CommDeviceTcpAsync(name, _configurationManager, _logger);
|
||||
return new CommDeviceTcpAsync(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -120,17 +111,17 @@ namespace Raytheon.Instruments
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,375 +15,370 @@ GOVERNMENT.
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for controlling a TCP client communication device
|
||||
/// </summary>
|
||||
public class CommDeviceTcpClient : ICommDevice, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private const uint _DEFAULT_READ_TIMEOUT = 25;
|
||||
private const uint _DEFAULT_SEND_TIMEOUT = 5000;
|
||||
private const uint _DEFAULT_READ_BUFFER_SIZE = 1024;
|
||||
private static object _syncObj = new object();
|
||||
private TcpClient _tcpClient;
|
||||
private NetworkStream _tcpIpStream;
|
||||
private readonly int _remotePort;
|
||||
private readonly string _remoteAddress;
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
/// <summary>
|
||||
/// Class for controlling a TCP client communication device
|
||||
/// </summary>
|
||||
public class CommDeviceTcpClient : ICommDevice, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private const uint _DEFAULT_READ_TIMEOUT = 25;
|
||||
private const uint _DEFAULT_SEND_TIMEOUT = 5000;
|
||||
private const uint _DEFAULT_READ_BUFFER_SIZE = 1024;
|
||||
private static object _syncObj = new object();
|
||||
private TcpClient _tcpClient;
|
||||
private NetworkStream _tcpIpStream;
|
||||
private readonly int _remotePort;
|
||||
private readonly string _remoteAddress;
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
#endregion
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
public void Open() => Initialize();
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
public void Open() => Initialize();
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket
|
||||
try
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket
|
||||
try
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Public Functions
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceTcpClient(string name, IConfigurationManager configurationManager, ILogger logger, string remoteAddress = "", int remotePort = 0)
|
||||
{
|
||||
_name = name;
|
||||
#region Public Functions
|
||||
|
||||
// _tcpClient is created in Initialize()
|
||||
_tcpClient = null;
|
||||
_tcpIpStream = null;
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceTcpClient(string deviceName, IConfigurationManager configurationManager, string remoteAddress = "", int remotePort = 0)
|
||||
{
|
||||
_name = deviceName;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
// _tcpClient is created in Initialize()
|
||||
_tcpClient = null;
|
||||
_tcpIpStream = null;
|
||||
|
||||
_logger = logger;
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
if(string.IsNullOrEmpty(remoteAddress))
|
||||
{
|
||||
_remoteAddress = _configuration.GetConfigurationValue("TcpClient", "RemoteAddress", "127.0.0.1");
|
||||
}
|
||||
else
|
||||
{
|
||||
_remoteAddress = remoteAddress;
|
||||
}
|
||||
|
||||
if(remotePort == 0)
|
||||
{
|
||||
_remotePort = _configuration.GetConfigurationValue("TcpClient", "RemotePort", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_remotePort = remotePort;
|
||||
}
|
||||
}
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
/// <summary>
|
||||
/// legacy constructor
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this device</param>
|
||||
/// <param name="remoteAddress">The address of the server</param>
|
||||
/// <param name="remotePort">The port that the server is listening on</param>
|
||||
public CommDeviceTcpClient(string name, string remoteAddress, int remotePort)
|
||||
{
|
||||
_name = name;
|
||||
_remotePort = remotePort;
|
||||
_remoteAddress = remoteAddress;
|
||||
if (string.IsNullOrEmpty(remoteAddress))
|
||||
{
|
||||
_remoteAddress = _configuration.GetConfigurationValue("TcpClient", "RemoteAddress", "127.0.0.1");
|
||||
}
|
||||
else
|
||||
{
|
||||
_remoteAddress = remoteAddress;
|
||||
}
|
||||
|
||||
// _tcpClient is created in Initialize()
|
||||
_tcpClient = null;
|
||||
_tcpIpStream = null;
|
||||
if (remotePort == 0)
|
||||
{
|
||||
_remotePort = _configuration.GetConfigurationValue("TcpClient", "RemotePort", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_remotePort = remotePort;
|
||||
}
|
||||
}
|
||||
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
/// <summary>
|
||||
/// legacy constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName">The name of this device</param>
|
||||
/// <param name="remoteAddress">The address of the server</param>
|
||||
/// <param name="remotePort">The port that the server is listening on</param>
|
||||
public CommDeviceTcpClient(string deviceName, string remoteAddress, int remotePort)
|
||||
{
|
||||
_name = deviceName;
|
||||
_remotePort = remotePort;
|
||||
_remoteAddress = remoteAddress;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
// _tcpClient is created in Initialize()
|
||||
_tcpClient = null;
|
||||
_tcpIpStream = null;
|
||||
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_tcpClient = new TcpClient(_remoteAddress, _remotePort);
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
// set timeouts
|
||||
_tcpClient.Client.SendTimeout = (int)_DEFAULT_SEND_TIMEOUT;
|
||||
_tcpClient.Client.ReceiveTimeout = (int)_DEFAULT_READ_TIMEOUT;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
// get the stream
|
||||
_tcpIpStream = _tcpClient.GetStream();
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_tcpClient = new TcpClient(_remoteAddress, _remotePort);
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"expected the state to be Uninitialized, state was: {_state} on device {_name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
// set timeouts
|
||||
_tcpClient.Client.SendTimeout = (int)_DEFAULT_SEND_TIMEOUT;
|
||||
_tcpClient.Client.ReceiveTimeout = (int)_DEFAULT_READ_TIMEOUT;
|
||||
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_tcpIpStream.Dispose();
|
||||
_tcpClient.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
// get the stream
|
||||
_tcpIpStream = _tcpClient.GetStream();
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
uint numBytesRead = (uint)(_tcpIpStream.Read(dataRead, 0, dataRead.Length));
|
||||
_state = State.Ready;
|
||||
return numBytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"expected the state to be Uninitialized, state was: {_state} on device {_name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<uint> ReadAsync(byte[] dataRead)
|
||||
{
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var bytesRead = await _tcpIpStream.ReadAsync(dataRead, 0, dataRead.Length);
|
||||
_state = State.Ready;
|
||||
return (uint)bytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_tcpIpStream.Dispose();
|
||||
_tcpClient.Dispose();
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read string from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<string> ReadAsync(CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var buffer = new byte[_DEFAULT_READ_BUFFER_SIZE];
|
||||
var bytesRead = await _tcpIpStream.ReadAsync(buffer, 0, buffer.Length, token);
|
||||
_state = State.Ready;
|
||||
return Encoding.UTF8.GetString(buffer, 0, bytesRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Read data from the device.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
uint numBytesRead = (uint)(_tcpIpStream.Read(dataRead, 0, dataRead.Length));
|
||||
_state = State.Ready;
|
||||
return numBytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<uint> ReadAsync(byte[] dataRead)
|
||||
{
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var bytesRead = await _tcpIpStream.ReadAsync(dataRead, 0, dataRead.Length);
|
||||
_state = State.Ready;
|
||||
return (uint)bytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read string from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<string> ReadAsync(CancellationToken token = default)
|
||||
{
|
||||
if (_tcpIpStream.DataAvailable == true)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var buffer = new byte[_DEFAULT_READ_BUFFER_SIZE];
|
||||
var bytesRead = await _tcpIpStream.ReadAsync(buffer, 0, buffer.Length, token);
|
||||
_state = State.Ready;
|
||||
return Encoding.UTF8.GetString(buffer, 0, bytesRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
_tcpClient.Client.ReceiveTimeout = (int)timeoutMs;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
_tcpClient.Client.ReceiveTimeout = (int)timeoutMs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to write</param>
|
||||
/// <param name="numBytesToWrite">The number of bytes to write</param>
|
||||
/// <returns>The number of bytes that were written</returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_state = State.Busy;
|
||||
_tcpIpStream.Write(dataToSend, 0, (int)numBytesToWrite);
|
||||
_state = State.Ready;
|
||||
return numBytesToWrite;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Write data to the device
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to write</param>
|
||||
/// <param name="numBytesToWrite">The number of bytes to write</param>
|
||||
/// <returns>The number of bytes that were written</returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_state = State.Busy;
|
||||
_tcpIpStream.Write(dataToSend, 0, (int)numBytesToWrite);
|
||||
_state = State.Ready;
|
||||
return numBytesToWrite;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<uint> WriteAsync(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
_state = State.Busy;
|
||||
await _tcpIpStream.WriteAsync(dataToSend, 0, (int)numBytesToWrite);
|
||||
_state = State.Ready;
|
||||
return numBytesToWrite;
|
||||
}
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<uint> WriteAsync(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
_state = State.Busy;
|
||||
await _tcpIpStream.WriteAsync(dataToSend, 0, (int)numBytesToWrite);
|
||||
_state = State.Ready;
|
||||
return numBytesToWrite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task WriteAsync(string message)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var buffer = Encoding.UTF8.GetBytes(message);
|
||||
await _tcpIpStream.WriteAsync(buffer, 0, buffer.Length);
|
||||
_state = State.Ready;
|
||||
}
|
||||
/// <summary>
|
||||
/// Write string data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public async Task WriteAsync(string message)
|
||||
{
|
||||
_state = State.Busy;
|
||||
var buffer = Encoding.UTF8.GetBytes(message);
|
||||
await _tcpIpStream.WriteAsync(buffer, 0, buffer.Length);
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendCommandGetResponseAsync(string message, int timeoutInMs = 5000)
|
||||
{
|
||||
_logger.Info($"Sending command waiting for response ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendCommandGetResponseAsync(string message, int timeoutInMs = 5000)
|
||||
{
|
||||
_logger.Info($"Sending command waiting for response ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
await WriteAsync(message);
|
||||
await WriteAsync(message);
|
||||
|
||||
CancellationTokenSource tokenSource = new CancellationTokenSource(new TimeSpan(0, 0, 0, 0, milliseconds:timeoutInMs));
|
||||
CancellationTokenSource tokenSource = new CancellationTokenSource(new TimeSpan(0, 0, 0, 0, milliseconds: timeoutInMs));
|
||||
|
||||
string readResponse = await ReadAsync(tokenSource.Token);
|
||||
string readResponse = await ReadAsync(tokenSource.Token);
|
||||
|
||||
_logger.Info($"Received response: {readResponse}");
|
||||
_logger.Info($"Received response: {readResponse}");
|
||||
|
||||
return readResponse;
|
||||
}
|
||||
return readResponse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<string> dataReceived)
|
||||
{
|
||||
_logger.Info($"About to start continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<string> dataReceived)
|
||||
{
|
||||
_logger.Info($"About to start continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
|
||||
byte[] buffer = new byte[_DEFAULT_READ_BUFFER_SIZE];
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
int bytesRead = await _tcpIpStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
string data = Encoding.UTF8.GetString(buffer, 0, bytesRead);
|
||||
byte[] buffer = new byte[_DEFAULT_READ_BUFFER_SIZE];
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
int bytesRead = await _tcpIpStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
string data = Encoding.UTF8.GetString(buffer, 0, bytesRead);
|
||||
|
||||
_logger.Info($"Message received from {_remoteAddress}:{_remotePort}: {data}");
|
||||
_logger.Info($"Message received from {_remoteAddress}:{_remotePort}: {data}");
|
||||
|
||||
dataReceived(data);
|
||||
Array.Clear(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
dataReceived(data);
|
||||
Array.Clear(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,61 @@
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceTcpClientFactory")]
|
||||
public class CommDeviceTcpClientFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceTcpClientFactory")]
|
||||
public class CommDeviceTcpClientFactory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
|
||||
public CommDeviceTcpClientFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceTcpClientFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
public CommDeviceTcpClientFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
/// <summary>
|
||||
/// CommDeviceTcpClientFactory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceTcpClientFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommDeviceTcpClient(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceTcpClient(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
@@ -73,9 +66,7 @@ namespace Raytheon.Instruments
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
return new CommDeviceTcpClient(name, _configurationManager, _logger);
|
||||
return new CommDeviceTcpClient(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -88,17 +79,17 @@ namespace Raytheon.Instruments
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,421 +15,402 @@ GOVERNMENT.
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for controlling a UDP communication device
|
||||
/// </summary>
|
||||
public class CommDeviceUdp : ICommDevice, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private const uint _DEFAULT_SEND_TIMEOUT = 5000;
|
||||
/// <summary>
|
||||
/// Class for controlling a UDP communication device
|
||||
/// </summary>
|
||||
public class CommDeviceUdp : ICommDevice, IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private const uint _DEFAULT_SEND_TIMEOUT = 5000;
|
||||
|
||||
private static readonly object _syncObj = new Object();
|
||||
private UdpClient _udpClient;
|
||||
private readonly int _localPort;
|
||||
private readonly int _remotePort;
|
||||
private readonly string _remoteAddress;
|
||||
private IPEndPoint _remoteIPEndPoint;
|
||||
private string _name;
|
||||
private readonly SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
private static readonly object _syncObj = new Object();
|
||||
private UdpClient _udpClient;
|
||||
private readonly int _localPort;
|
||||
private readonly int _remotePort;
|
||||
private readonly string _remoteAddress;
|
||||
private IPEndPoint _remoteIPEndPoint;
|
||||
private string _name;
|
||||
private readonly SelfTestResult _selfTestResult;
|
||||
private State _state;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
#endregion
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#region PrivateFunctions
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommDeviceUdp()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket and threads
|
||||
try
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_udpClient.Close();
|
||||
#region PrivateFunctions
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~CommDeviceUdp()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
_udpClient.Dispose();
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket and threads
|
||||
try
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_udpClient.Close();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_udpClient.Dispose();
|
||||
|
||||
#endregion
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region PublicFuctions
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceUdp(string deviceName, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
Name = deviceName;
|
||||
#region PublicFuctions
|
||||
|
||||
_logger = logger;
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceUdp(string deviceName, IConfigurationManager configurationManager)
|
||||
{
|
||||
Name = deviceName;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
_localPort = _configuration.GetConfigurationValue("CommDeviceUdp", "LocalPort", 0);
|
||||
_remotePort = _configuration.GetConfigurationValue("CommDeviceUdp", "RemotePort", 0);
|
||||
_remoteAddress = _configuration.GetConfigurationValue("CommDeviceUdp", "RemoteAddress", "127.0.0.1");
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
|
||||
// created in Initialize()
|
||||
_udpClient = null;
|
||||
_localPort = _configuration.GetConfigurationValue("CommDeviceUdp", "LocalPort", 0);
|
||||
_remotePort = _configuration.GetConfigurationValue("CommDeviceUdp", "RemotePort", 0);
|
||||
_remoteAddress = _configuration.GetConfigurationValue("CommDeviceUdp", "RemoteAddress", "127.0.0.1");
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
// created in Initialize()
|
||||
_udpClient = null;
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name">The name of this instance</param>
|
||||
/// <param name="localPort">the port on the local computer to use</param>
|
||||
/// <param name="remotePort">the port on the remote computer to send to</param>
|
||||
/// <param name="remoteAddress">the address to send to</param>
|
||||
public CommDeviceUdp(string name, int localPort, int remotePort, string remoteAddress)
|
||||
{
|
||||
_name = name;
|
||||
_localPort = localPort;
|
||||
_remotePort = remotePort;
|
||||
_remoteAddress = remoteAddress;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="deviceName">The name of this instance</param>
|
||||
/// <param name="localPort">the port on the local computer to use</param>
|
||||
/// <param name="remotePort">the port on the remote computer to send to</param>
|
||||
/// <param name="remoteAddress">the address to send to</param>
|
||||
public CommDeviceUdp(string deviceName, int localPort, int remotePort, string remoteAddress)
|
||||
{
|
||||
_name = deviceName;
|
||||
_localPort = localPort;
|
||||
_remotePort = remotePort;
|
||||
_remoteAddress = remoteAddress;
|
||||
|
||||
// created in Initialize()
|
||||
_udpClient = null;
|
||||
// created in Initialize()
|
||||
_udpClient = null;
|
||||
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
}
|
||||
_selfTestResult = SelfTestResult.Unknown;
|
||||
_state = State.Uninitialized;
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ClearErrors()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool DisplayEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a UDP Device called " + _name;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DetailedStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return "This is a UDP Device called " + _name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool FrontPanelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InstrumentMetadata Info
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_udpClient = new UdpClient(_localPort);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Uninitialized)
|
||||
{
|
||||
_udpClient = new UdpClient(_localPort);
|
||||
|
||||
_udpClient.Client.ReceiveBufferSize = int.MaxValue;
|
||||
_udpClient.Client.SendBufferSize = int.MaxValue;
|
||||
_udpClient.Client.ReceiveBufferSize = int.MaxValue;
|
||||
_udpClient.Client.SendBufferSize = int.MaxValue;
|
||||
|
||||
_udpClient.Client.SendTimeout = (int)_DEFAULT_SEND_TIMEOUT;
|
||||
_udpClient.Client.SendTimeout = (int)_DEFAULT_SEND_TIMEOUT;
|
||||
|
||||
// set an arbitrary short receive timeout. Don't want the read call to block
|
||||
_udpClient.Client.ReceiveTimeout = 5;
|
||||
// set an arbitrary short receive timeout. Don't want the read call to block
|
||||
_udpClient.Client.ReceiveTimeout = 5;
|
||||
|
||||
IPAddress remoteAddy = IPAddress.Parse(_remoteAddress);
|
||||
_remoteIPEndPoint = new IPEndPoint(remoteAddy, _remotePort);
|
||||
IPAddress remoteAddy = IPAddress.Parse(_remoteAddress);
|
||||
_remoteIPEndPoint = new IPEndPoint(remoteAddy, _remotePort);
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on device " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
_state = State.Ready;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString() + " on device " + _name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SelfTestResult PerformSelfTest()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataRead = _udpClient.Receive(ref _remoteIPEndPoint);
|
||||
/// <summary>
|
||||
/// Read data from the device.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public uint Read(ref byte[] dataRead)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataRead = _udpClient.Receive(ref _remoteIPEndPoint);
|
||||
|
||||
uint numBytesRead = (uint)(dataRead.Length);
|
||||
uint numBytesRead = (uint)(dataRead.Length);
|
||||
|
||||
return numBytesRead;
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
if (e.SocketErrorCode == SocketError.TimedOut)
|
||||
{
|
||||
// expected, do nothing
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return numBytesRead;
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
if (e.SocketErrorCode == SocketError.TimedOut)
|
||||
{
|
||||
// expected, do nothing
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SelfTestResult SelfTestResult
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selfTestResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public State Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_udpClient.Client.ReceiveTimeout = (int)timeoutMs;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_udpClient.Client.ReceiveTimeout = (int)timeoutMs;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_udpClient.Close();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_state == State.Ready)
|
||||
{
|
||||
_udpClient.Close();
|
||||
|
||||
_udpClient.Dispose();
|
||||
_udpClient.Dispose();
|
||||
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
_state = State.Uninitialized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to write</param>
|
||||
/// <param name="numBytesToWrite">The number of bytes to write</param>
|
||||
/// <returns>THe number of bytes that were written</returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
const uint MAX_BYTES_PER_PACKET = 65400;
|
||||
/// <summary>
|
||||
/// Write data to the device
|
||||
/// </summary>
|
||||
/// <param name="dataToSend">The data to write</param>
|
||||
/// <param name="numBytesToWrite">The number of bytes to write</param>
|
||||
/// <returns>THe number of bytes that were written</returns>
|
||||
public uint Write(byte[] dataToSend, uint numBytesToWrite)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
const uint MAX_BYTES_PER_PACKET = 65400;
|
||||
|
||||
uint index = 0;
|
||||
uint index = 0;
|
||||
|
||||
if (numBytesToWrite > MAX_BYTES_PER_PACKET)
|
||||
{
|
||||
uint numPacketsToSend = numBytesToWrite / MAX_BYTES_PER_PACKET;
|
||||
int packetsSent = 0;
|
||||
if (numBytesToWrite > MAX_BYTES_PER_PACKET)
|
||||
{
|
||||
uint numPacketsToSend = numBytesToWrite / MAX_BYTES_PER_PACKET;
|
||||
int packetsSent = 0;
|
||||
|
||||
while (packetsSent < numPacketsToSend)
|
||||
{
|
||||
Byte[] segment1 = new Byte[MAX_BYTES_PER_PACKET];
|
||||
Array.Copy(dataToSend, index, segment1, 0, MAX_BYTES_PER_PACKET);
|
||||
uint count = (uint)(_udpClient.Send(segment1, (int)MAX_BYTES_PER_PACKET, _remoteIPEndPoint));
|
||||
index += count;
|
||||
packetsSent++;
|
||||
}
|
||||
while (packetsSent < numPacketsToSend)
|
||||
{
|
||||
Byte[] segment1 = new Byte[MAX_BYTES_PER_PACKET];
|
||||
Array.Copy(dataToSend, index, segment1, 0, MAX_BYTES_PER_PACKET);
|
||||
uint count = (uint)(_udpClient.Send(segment1, (int)MAX_BYTES_PER_PACKET, _remoteIPEndPoint));
|
||||
index += count;
|
||||
packetsSent++;
|
||||
}
|
||||
|
||||
Byte[] segment = new Byte[MAX_BYTES_PER_PACKET];
|
||||
uint numBytesRemaining = numBytesToWrite - index;
|
||||
Array.Copy(dataToSend, index, segment, 0, numBytesRemaining);
|
||||
index += (uint)(_udpClient.Send(segment, (int)numBytesRemaining, _remoteIPEndPoint));
|
||||
}
|
||||
else
|
||||
{
|
||||
index = (uint)(_udpClient.Send(dataToSend, (int)numBytesToWrite, _remoteIPEndPoint));
|
||||
}
|
||||
Byte[] segment = new Byte[MAX_BYTES_PER_PACKET];
|
||||
uint numBytesRemaining = numBytesToWrite - index;
|
||||
Array.Copy(dataToSend, index, segment, 0, numBytesRemaining);
|
||||
index += (uint)(_udpClient.Send(segment, (int)numBytesRemaining, _remoteIPEndPoint));
|
||||
}
|
||||
else
|
||||
{
|
||||
index = (uint)(_udpClient.Send(dataToSend, (int)numBytesToWrite, _remoteIPEndPoint));
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
public void Close()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
public void Open()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,61 @@
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceUdpFactory")]
|
||||
public class CommDeviceUdpFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceUdpFactory")]
|
||||
public class CommDeviceUdpFactory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
|
||||
public CommDeviceUdpFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceUdpFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
public CommDeviceUdpFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
/// <summary>
|
||||
/// CommDeviceUdpFactory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceUdpFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommDeviceUdp(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommDevice));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceUdp(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
@@ -73,9 +66,7 @@ namespace Raytheon.Instruments
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
return new CommDeviceUdp(name, _configurationManager, _logger);
|
||||
return new CommDeviceUdp(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -88,17 +79,17 @@ namespace Raytheon.Instruments
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,439 +30,434 @@
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceUdpAsync : ICommAsync
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private uint _defaultReadTimeout;
|
||||
private uint _defaultSendTimeout;
|
||||
private uint _defaultReadBufferSize;
|
||||
private static readonly object _syncObj = new object();
|
||||
|
||||
private UdpClient _udpClient;
|
||||
private IPEndPoint _remoteEndPoint;
|
||||
|
||||
private int _localPort;
|
||||
private int _remotePort;
|
||||
private string _remoteAddress;
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
|
||||
/// <summary>
|
||||
/// NLog logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
public void Open() => Initialize();
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket
|
||||
try
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Functions
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceUdpAsync(string name, IConfigurationManager configurationManager, ILogger logger)
|
||||
{
|
||||
_name = name;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
if (_state != State.Uninitialized)
|
||||
{
|
||||
_logger.Warn("Reinitialization of existing UDP Async Connection. Attempting to call Shutdown.");
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
_defaultReadTimeout = _configuration.GetConfigurationValue<uint>("UdpClient", "ReadTimeout", 25);
|
||||
_defaultSendTimeout = _configuration.GetConfigurationValue<uint>("UdpClient", "SendTimeout", 5000);
|
||||
_defaultReadBufferSize = _configuration.GetConfigurationValue<uint>("UdpClient", "BufferSize", 1024);
|
||||
|
||||
_localPort = _configuration.GetConfigurationValue("UdpClient", "LocalPort", 0);
|
||||
|
||||
_remoteAddress = _configuration.GetConfigurationValue("UdpClient", "RemoteAddress", "127.0.0.1");
|
||||
_remotePort = _configuration.GetConfigurationValue("UdpClient", "RemotePort", 0);
|
||||
|
||||
_udpClient = new UdpClient();
|
||||
|
||||
if (string.IsNullOrEmpty(_remoteAddress))
|
||||
{
|
||||
_logger.Debug($"Initializing as UDP Server. Listening on port: {_localPort}");
|
||||
_udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, _localPort));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug($"Initializing as UDP Client. Ready to Talk to: {_remoteAddress}:{_remotePort}");
|
||||
// get the remote endpoint
|
||||
_remoteEndPoint = new IPEndPoint(IPAddress.Parse(_remoteAddress), _remotePort);
|
||||
}
|
||||
|
||||
// set timeouts
|
||||
_udpClient.Client.SendTimeout = (int)_defaultSendTimeout;
|
||||
_udpClient.Client.ReceiveTimeout = (int)_defaultReadTimeout;
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
_logger.Debug("Shutting Down...");
|
||||
_state = State.Uninitialized;
|
||||
_udpClient?.Dispose();
|
||||
_udpClient = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<uint> ReadAsync(byte[] dataRead, CancellationToken token = default)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return 0;
|
||||
|
||||
var received = await _udpClient.ReceiveAsync();
|
||||
Array.Copy(received.Buffer, dataRead, Math.Min(dataRead.Length, received.Buffer.Length));
|
||||
|
||||
UpdateRemoteAddressAndPort(received.RemoteEndPoint);
|
||||
|
||||
_logger.Trace($"Reading Data, bytes received: {received.Buffer?.Length}");
|
||||
|
||||
return (uint)received.Buffer.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read string from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<string> ReadAsync(CancellationToken token = default)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return null;
|
||||
|
||||
var received = await _udpClient.ReceiveAsync();
|
||||
|
||||
UpdateRemoteAddressAndPort(received.RemoteEndPoint);
|
||||
|
||||
var data = Encoding.UTF8.GetString(received.Buffer);
|
||||
|
||||
_logger.Trace($"Reading Data, message received: {data}");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return;
|
||||
|
||||
_logger.Trace($"Setting Reader Timeout: {timeoutMs} Ms");
|
||||
|
||||
_udpClient.Client.ReceiveTimeout = (int)timeoutMs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<uint> WriteAsync(byte[] dataToSend, uint numBytesToWrite, CancellationToken token = default)
|
||||
{
|
||||
if (_udpClient == null || _remoteEndPoint == null)
|
||||
return 0;
|
||||
|
||||
_logger.Trace($"Writing message to ({_remoteAddress}:{_remotePort}), bytes: {dataToSend?.Length}");
|
||||
|
||||
_state = State.Busy;
|
||||
await _udpClient.SendAsync(dataToSend, (int)numBytesToWrite, _remoteEndPoint);
|
||||
_state = State.Ready;
|
||||
return numBytesToWrite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task WriteAsync(string message, CancellationToken token = default)
|
||||
{
|
||||
if (_udpClient == null || _remoteEndPoint == null)
|
||||
return;
|
||||
|
||||
_logger.Trace($"Writing message to ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
_state = State.Busy;
|
||||
var dataToSend = Encoding.UTF8.GetBytes(message);
|
||||
await _udpClient.SendAsync(dataToSend, dataToSend.Length, _remoteEndPoint);
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendCommandGetResponseAsync(string message, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(message, cancellationToken);
|
||||
string readResponse = await ReadAsync(cancellationToken);
|
||||
_logger.Trace($"Received response: {readResponse}");
|
||||
|
||||
return readResponse;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<byte[]> SendCommandGetResponseAsync(byte[] data, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_remoteAddress}:{_remotePort}), message length: {data.Length}");
|
||||
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(data, (uint)data.Length, cancellationToken);
|
||||
byte[] buffer = new byte[_defaultReadBufferSize];
|
||||
uint bytesRead = await ReadAsync(buffer, cancellationToken);
|
||||
_logger.Trace($"Received response of size: {bytesRead}");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<string> dataReceived)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return;
|
||||
|
||||
_logger.Debug($"Starting continuous reading from port: {_localPort} ...");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
break;
|
||||
|
||||
var received = await ReceiveAsync(_udpClient, cancellationToken);
|
||||
|
||||
if (received != null && received.Buffer != null)
|
||||
{
|
||||
UpdateRemoteAddressAndPort(received.RemoteEndPoint);
|
||||
_logger.Trace($"Incoming Data from {_remoteAddress}:{_remotePort}: size {received.Buffer.Length}");
|
||||
string data = Encoding.UTF8.GetString(received.Buffer, 0, received.Buffer.Length);
|
||||
dataReceived(data);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<byte[]> dataReceived)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return;
|
||||
|
||||
_logger.Debug($"Starting continuous reading from port: {_localPort} ...");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
break;
|
||||
|
||||
var received = await ReceiveAsync(_udpClient, cancellationToken);
|
||||
if (received != null && received.Buffer != null)
|
||||
{
|
||||
UpdateRemoteAddressAndPort(received.RemoteEndPoint);
|
||||
_logger.Trace($"Incoming Data from {_remoteAddress}:{_remotePort}: size {received.Buffer.Length}");
|
||||
dataReceived(received.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Update client information for logging
|
||||
/// </summary>
|
||||
/// <param name="remoteEndPoint"></param>
|
||||
private void UpdateRemoteAddressAndPort(IPEndPoint remoteEndPoint)
|
||||
{
|
||||
if (remoteEndPoint == null)
|
||||
return;
|
||||
|
||||
if (_remotePort == 0 || string.IsNullOrEmpty(_remoteAddress))
|
||||
{
|
||||
_remotePort = remoteEndPoint.Port;
|
||||
_remoteAddress = remoteEndPoint.Address.ToString();
|
||||
}
|
||||
|
||||
if(_remoteEndPoint == null || _remoteEndPoint.Port != remoteEndPoint.Port )
|
||||
{
|
||||
// get the remote endpoint
|
||||
_remoteEndPoint = remoteEndPoint;
|
||||
|
||||
_logger.Debug($"Starting to receive data from {_remoteAddress}:{_remotePort}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ReceiveAsyc with cancellation token implementation
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="breakToken"></param>
|
||||
/// <returns></returns>
|
||||
private Task<UdpReceiveResult> ReceiveAsync(UdpClient client, CancellationToken breakToken) => breakToken.IsCancellationRequested
|
||||
? Task.Run(() => new UdpReceiveResult())
|
||||
: Task<UdpReceiveResult>.Factory.FromAsync
|
||||
((callback, state) => client.BeginReceive(callback, state), (ar) =>
|
||||
{
|
||||
if (breakToken.IsCancellationRequested)
|
||||
return new UdpReceiveResult();
|
||||
|
||||
IPEndPoint remoteEP = null;
|
||||
var buffer = client.EndReceive(ar, ref remoteEP);
|
||||
return new UdpReceiveResult(buffer, remoteEP);
|
||||
},null);
|
||||
|
||||
#endregion
|
||||
}
|
||||
/// <summary>
|
||||
/// A sim communication device
|
||||
/// </summary>
|
||||
public class CommDeviceUdpAsync : ICommAsync
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private uint _defaultReadTimeout;
|
||||
private uint _defaultSendTimeout;
|
||||
private uint _defaultReadBufferSize;
|
||||
private static readonly object _syncObj = new object();
|
||||
|
||||
private UdpClient _udpClient;
|
||||
private IPEndPoint _remoteEndPoint;
|
||||
|
||||
private int _localPort;
|
||||
private int _remotePort;
|
||||
private string _remoteAddress;
|
||||
private readonly string _name;
|
||||
private State _state;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
public bool ClearErrors() => false;
|
||||
public bool FrontPanelEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public bool DisplayEnabled { get => false; set => throw new NotImplementedException(); }
|
||||
public string DetailedStatus => $"This is a TCP/IP Device called {_name}";
|
||||
public InstrumentMetadata Info => throw new NotImplementedException();
|
||||
public State Status => _state;
|
||||
public string Name => _name;
|
||||
public SelfTestResult PerformSelfTest() => SelfTestResult;
|
||||
public SelfTestResult SelfTestResult => SelfTestResult.Unknown;
|
||||
public void Open() => Initialize();
|
||||
public void Close() => Shutdown();
|
||||
public void Reset()
|
||||
{
|
||||
Close();
|
||||
Open();
|
||||
}
|
||||
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of the resources contained by this object
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// close the socket
|
||||
try
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Functions
|
||||
|
||||
/// <summary>
|
||||
/// CommDevice factory constructor
|
||||
/// </summary>
|
||||
/// <param name="deviceName"></param>
|
||||
/// <param name="configurationManager"></param>
|
||||
public CommDeviceUdpAsync(string deviceName, IConfigurationManager configurationManager)
|
||||
{
|
||||
_name = deviceName;
|
||||
|
||||
_state = State.Uninitialized;
|
||||
|
||||
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
||||
|
||||
_configurationManager = configurationManager;
|
||||
_configuration = _configurationManager.GetConfiguration(Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initialize instrument
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
if (_state != State.Uninitialized)
|
||||
{
|
||||
_logger.Warn("Reinitialization of existing UDP Async Connection. Attempting to call Shutdown.");
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
_defaultReadTimeout = _configuration.GetConfigurationValue<uint>("UdpClient", "ReadTimeout", 25);
|
||||
_defaultSendTimeout = _configuration.GetConfigurationValue<uint>("UdpClient", "SendTimeout", 5000);
|
||||
_defaultReadBufferSize = _configuration.GetConfigurationValue<uint>("UdpClient", "BufferSize", 1024);
|
||||
|
||||
_localPort = _configuration.GetConfigurationValue("UdpClient", "LocalPort", 0);
|
||||
|
||||
_remoteAddress = _configuration.GetConfigurationValue("UdpClient", "RemoteAddress", "127.0.0.1");
|
||||
_remotePort = _configuration.GetConfigurationValue("UdpClient", "RemotePort", 0);
|
||||
|
||||
_udpClient = new UdpClient();
|
||||
|
||||
if (string.IsNullOrEmpty(_remoteAddress))
|
||||
{
|
||||
_logger.Debug($"Initializing as UDP Server. Listening on port: {_localPort}");
|
||||
_udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, _localPort));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug($"Initializing as UDP Client. Ready to Talk to: {_remoteAddress}:{_remotePort}");
|
||||
// get the remote endpoint
|
||||
_remoteEndPoint = new IPEndPoint(IPAddress.Parse(_remoteAddress), _remotePort);
|
||||
}
|
||||
|
||||
// set timeouts
|
||||
_udpClient.Client.SendTimeout = (int)_defaultSendTimeout;
|
||||
_udpClient.Client.ReceiveTimeout = (int)_defaultReadTimeout;
|
||||
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shuts down the device
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
_logger.Debug("Shutting Down...");
|
||||
_state = State.Uninitialized;
|
||||
_udpClient?.Dispose();
|
||||
_udpClient = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read data from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<uint> ReadAsync(byte[] dataRead, CancellationToken token = default)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return 0;
|
||||
|
||||
var received = await _udpClient.ReceiveAsync();
|
||||
Array.Copy(received.Buffer, dataRead, Math.Min(dataRead.Length, received.Buffer.Length));
|
||||
|
||||
UpdateRemoteAddressAndPort(received.RemoteEndPoint);
|
||||
|
||||
_logger.Trace($"Reading Data, bytes received: {received.Buffer?.Length}");
|
||||
|
||||
return (uint)received.Buffer.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read string from the device asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="dataRead">The buffer to put the data in</param>
|
||||
/// <returns>The number of bytes read</returns>
|
||||
public async Task<string> ReadAsync(CancellationToken token = default)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return null;
|
||||
|
||||
var received = await _udpClient.ReceiveAsync();
|
||||
|
||||
UpdateRemoteAddressAndPort(received.RemoteEndPoint);
|
||||
|
||||
var data = Encoding.UTF8.GetString(received.Buffer);
|
||||
|
||||
_logger.Trace($"Reading Data, message received: {data}");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the read timeout
|
||||
/// </summary>
|
||||
/// <param name="timeoutMs"></param>
|
||||
public void SetReadTimeout(uint timeoutMs)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return;
|
||||
|
||||
_logger.Trace($"Setting Reader Timeout: {timeoutMs} Ms");
|
||||
|
||||
_udpClient.Client.ReceiveTimeout = (int)timeoutMs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="dataToSend"></param>
|
||||
/// <param name="numBytesToWrite"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<uint> WriteAsync(byte[] dataToSend, uint numBytesToWrite, CancellationToken token = default)
|
||||
{
|
||||
if (_udpClient == null || _remoteEndPoint == null)
|
||||
return 0;
|
||||
|
||||
_logger.Trace($"Writing message to ({_remoteAddress}:{_remotePort}), bytes: {dataToSend?.Length}");
|
||||
|
||||
_state = State.Busy;
|
||||
await _udpClient.SendAsync(dataToSend, (int)numBytesToWrite, _remoteEndPoint);
|
||||
_state = State.Ready;
|
||||
return numBytesToWrite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string data to the device asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task WriteAsync(string message, CancellationToken token = default)
|
||||
{
|
||||
if (_udpClient == null || _remoteEndPoint == null)
|
||||
return;
|
||||
|
||||
_logger.Trace($"Writing message to ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
_state = State.Busy;
|
||||
var dataToSend = Encoding.UTF8.GetBytes(message);
|
||||
await _udpClient.SendAsync(dataToSend, dataToSend.Length, _remoteEndPoint);
|
||||
_state = State.Ready;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> SendCommandGetResponseAsync(string message, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_remoteAddress}:{_remotePort}), message: {message}");
|
||||
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(message, cancellationToken);
|
||||
string readResponse = await ReadAsync(cancellationToken);
|
||||
_logger.Trace($"Received response: {readResponse}");
|
||||
|
||||
return readResponse;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Command and Get Response asynchronously
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="timeoutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<byte[]> SendCommandGetResponseAsync(byte[] data, CancellationToken cancellationToken = default, int timeoutInMs = 5000)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return null;
|
||||
|
||||
_logger.Trace($"Sending command waiting for response from ({_remoteAddress}:{_remotePort}), message length: {data.Length}");
|
||||
|
||||
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeoutInMs)))
|
||||
{
|
||||
if (cancellationToken == default)
|
||||
{
|
||||
cancellationToken = cts.Token;
|
||||
}
|
||||
await WriteAsync(data, (uint)data.Length, cancellationToken);
|
||||
byte[] buffer = new byte[_defaultReadBufferSize];
|
||||
uint bytesRead = await ReadAsync(buffer, cancellationToken);
|
||||
_logger.Trace($"Received response of size: {bytesRead}");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<string> dataReceived)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return;
|
||||
|
||||
_logger.Debug($"Starting continuous reading from port: {_localPort} ...");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
break;
|
||||
|
||||
var received = await ReceiveAsync(_udpClient, cancellationToken);
|
||||
|
||||
if (received != null && received.Buffer != null)
|
||||
{
|
||||
UpdateRemoteAddressAndPort(received.RemoteEndPoint);
|
||||
_logger.Trace($"Incoming Data from {_remoteAddress}:{_remotePort}: size {received.Buffer.Length}");
|
||||
string data = Encoding.UTF8.GetString(received.Buffer, 0, received.Buffer.Length);
|
||||
dataReceived(data);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// keeps reading until canceled via token,
|
||||
/// received messages sent to dataReceived function
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="dataReceived"></param>
|
||||
/// <returns></returns>
|
||||
public async Task KeepReadingAsync(CancellationToken cancellationToken, Action<byte[]> dataReceived)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
return;
|
||||
|
||||
_logger.Debug($"Starting continuous reading from port: {_localPort} ...");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (_udpClient == null)
|
||||
break;
|
||||
|
||||
var received = await ReceiveAsync(_udpClient, cancellationToken);
|
||||
if (received != null && received.Buffer != null)
|
||||
{
|
||||
UpdateRemoteAddressAndPort(received.RemoteEndPoint);
|
||||
_logger.Trace($"Incoming Data from {_remoteAddress}:{_remotePort}: size {received.Buffer.Length}");
|
||||
dataReceived(received.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Finished continuous reading from {_remoteAddress}:{_remotePort} ...");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Functions
|
||||
/// <summary>
|
||||
/// Update client information for logging
|
||||
/// </summary>
|
||||
/// <param name="remoteEndPoint"></param>
|
||||
private void UpdateRemoteAddressAndPort(IPEndPoint remoteEndPoint)
|
||||
{
|
||||
if (remoteEndPoint == null)
|
||||
return;
|
||||
|
||||
if (_remotePort == 0 || string.IsNullOrEmpty(_remoteAddress))
|
||||
{
|
||||
_remotePort = remoteEndPoint.Port;
|
||||
_remoteAddress = remoteEndPoint.Address.ToString();
|
||||
}
|
||||
|
||||
if (_remoteEndPoint == null || _remoteEndPoint.Port != remoteEndPoint.Port)
|
||||
{
|
||||
// get the remote endpoint
|
||||
_remoteEndPoint = remoteEndPoint;
|
||||
|
||||
_logger.Debug($"Starting to receive data from {_remoteAddress}:{_remotePort}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ReceiveAsyc with cancellation token implementation
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="breakToken"></param>
|
||||
/// <returns></returns>
|
||||
private Task<UdpReceiveResult> ReceiveAsync(UdpClient client, CancellationToken breakToken) => breakToken.IsCancellationRequested
|
||||
? Task.Run(() => new UdpReceiveResult())
|
||||
: Task<UdpReceiveResult>.Factory.FromAsync
|
||||
((callback, state) => client.BeginReceive(callback, state), (ar) =>
|
||||
{
|
||||
if (breakToken.IsCancellationRequested)
|
||||
return new UdpReceiveResult();
|
||||
|
||||
IPEndPoint remoteEP = null;
|
||||
var buffer = client.EndReceive(ar, ref remoteEP);
|
||||
return new UdpReceiveResult(buffer, remoteEP);
|
||||
}, null);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,71 +30,64 @@
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceUdpAsyncFactory")]
|
||||
public class CommDeviceUdpAsyncFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private ILogger _logger;
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
[ExportInstrumentFactory(ModelNumber = "CommDeviceUdpAsyncFactory")]
|
||||
public class CommDeviceUdpAsyncFactory : IInstrumentFactory
|
||||
{
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
|
||||
public CommDeviceUdpAsyncFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
|
||||
/// <summary>
|
||||
/// CommDeviceUdpAsyncFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceUdpAsyncFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
public CommDeviceUdpAsyncFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
/// <summary>
|
||||
/// CommDeviceUdpAsyncFactory injection constructor
|
||||
/// </summary>
|
||||
[ImportingConstructor]
|
||||
public CommDeviceUdpAsyncFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommAsync));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new CommDeviceUdpAsync(name, _configurationManager, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_supportedInterfaces.Add(typeof(ICommAsync));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new CommDeviceUdpAsync(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
@@ -105,9 +98,7 @@ namespace Raytheon.Instruments
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
return new CommDeviceUdpAsync(name, _configurationManager, _logger);
|
||||
return new CommDeviceUdpAsync(name, _configurationManager);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -120,17 +111,17 @@ namespace Raytheon.Instruments
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// returns configuration based on the predefined path or default path c:/ProgramData/Raytheon/InstrumentManagerService
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user