Major upgrade

This commit is contained in:
Duc
2025-10-24 15:18:11 -07:00
parent fd85735c93
commit ce583d1664
478 changed files with 237518 additions and 47610 deletions

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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>

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}
}