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

@@ -0,0 +1,55 @@
// UNCLASSIFIED
/*-------------------------------------------------------------------------
RAYTHEON PROPRIETARY
WARNING - THIS DOCUMENT CONTAINS TECHNICAL DATA WHOSE EXPORT OR DISCLOSURE
TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED BY THE INTERNATIONAL
TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTIONS 120-130). VIOLATIONS
ARE SUBJECT TO SEVERE CRIMINAL PENALTIES.
DISTRIBUTION STATEMENT F: FURTHER DISSEMINATION ONLY AS DIRECTED BY MISSILE
DEFENSE AGENCY, MDA/GMY NEXT GENERATION INTERCEPTOR PROJECT OFFICE
(DATE OF DETERMINATION 14 JUNE 2021) OR HIGHER DOD AUTHORITY.
OTHER REQUESTS FOR THIS DOCUMENT SHALL BE REFERRED TO: MISSILE DEFENSE
AGENCY, CONTRACTS DIRECTORATE, ATTN: GMY-K, BLDG. 5222 MARTIN ROAD,
REDSTONE ARSENAL, AL 35898.
WARNING - THIS DOCUMENT CONTAINS TECHNICAL DATA WHOSE EXPORT IS RESTRICTED
BY THE ARMS EXPORT CONTROL ACT (TITLE 22, U.S.C., SEC 2751, ET SEQ.) OR
THE EXPORT ADMINISTRATION ACT OF 1979 (TITLE 50, U.S.C., APP.2401 ET SEQ),
AS AMENDED. VIOLATIONS OF THESE EXPORT LAWS ARE SUBJECT TO SEVERE CRIMINAL
PENALTIES. DISSEMINATE IN ACCORDANCE WITH PROVISIONS OF
DOD DIRECTIVE 5230.25
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
-------------------------------------------------------------------------*/
using System;
namespace MeasurementManagerLib
{
public class MalMeasurementManagerNullReferenceException : Exception
{
protected MalMeasurementManagerNullReferenceException() { }
public MalMeasurementManagerNullReferenceException(Type type)
: base($"Reference to object of type {type.Name} is null. Please create an instance of the object.")
{
}
public MalMeasurementManagerNullReferenceException(string message)
: base(message)
{
}
public MalMeasurementManagerNullReferenceException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

View File

@@ -32,9 +32,6 @@ INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using Raytheon.Instruments;
using static MeasurementManagerLib.BitMeasurementManager;
@@ -45,23 +42,249 @@ namespace MeasurementManagerLib
/// </summary>
public class MalMeasurementLibManager : IDisposable
{
public FpgaMeasurementManager FpgaMeasurementManager { get; set; }
public PowerSupplyMeasurementManager PowerSupplyMeasurementManager { get; set; }
public SwitchMeasurementManager SwitchMeasurementManager { get; set; }
public BitMeasurementManager BitMeasurementManager { get; set; }
public BitGenSoftMeasurementManager BitGenSoftMeasurementManager { get; set; }
public ChillerCartMeasurementManager ChillerMeasurementManager { get; set; }
public DioMeasurementManager DioMeasurementManager { get; set; }
public JtagMeasurementManager JtagMeasurementManager { get; set; }
public VideoRecorderMeasurementManager VideoRecorderMeasurementManager { get; set; }
public RelayMeasurementManager RelayMeasurementManager { get; set; }
public RfMeasurementManager RfMeasurementManager { get; set; }
public SpaceChamberLSPSMeasurementManager SpaceChamberLSPSMeasurementManager { get; set; }
public TelemetryMeasurementManager TelemetryMeasurementManager { get; set; }
public CryoMeasurementManager CryoMeasurementManager { get; set; }
public OpticalBenchMeasurementManager OpticalBenchMeasurementManager { get; set; }
private FpgaMeasurementManager _fpgaMeasurementManager;
private PowerSupplyMeasurementManager _powerSupplyMeasurementManager;
private SwitchMeasurementManager _switchMeasurementManager;
private BitMeasurementManager _bitMeasurementManager;
private CoeMeasurementManager _coeMeasurementManager;
private ChillerCartMeasurementManager _chillerMeasurementManager;
private DioMeasurementManager _dioMeasurementManager;
private JtagMeasurementManager _jtagMeasurementManager;
private VideoRecorderMeasurementManager _videoRecorderMeasurementManager;
private RelayMeasurementManager _relayMeasurementManager;
private RfMeasurementManager _rfMeasurementManager;
private SpaceChamberLspsMeasurementManager _spaceChamberLspsMeasurementManager;
private TelemetryMeasurementManager _telemetryMeasurementManager;
private CryoMeasurementManager _cryoMeasurementManager;
private OpticalBenchMeasurementManager _opticalBenchMeasurementManager;
public IInstrumentManager InstrumentManager { get; set; }
public FpgaMeasurementManager FpgaMeasurementManager
{
get
{
if (_fpgaMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(FpgaMeasurementManager));
return _fpgaMeasurementManager;
}
private set
{
_fpgaMeasurementManager = value;
}
}
public PowerSupplyMeasurementManager PowerSupplyMeasurementManager
{
get
{
if (_powerSupplyMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(PowerSupplyMeasurementManager));
return _powerSupplyMeasurementManager;
}
private set
{
_powerSupplyMeasurementManager = value;
}
}
public SwitchMeasurementManager SwitchMeasurementManager
{
get
{
if (_switchMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(SwitchMeasurementManager));
return _switchMeasurementManager;
}
private set
{
_switchMeasurementManager = value;
}
}
public BitMeasurementManager BitMeasurementManager
{
get
{
if (_bitMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(BitMeasurementManager));
return _bitMeasurementManager;
}
private set
{
_bitMeasurementManager = value;
}
}
public CoeMeasurementManager CoeMeasurementManager
{
get
{
if (_coeMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(CoeMeasurementManager));
return _coeMeasurementManager;
}
private set
{
_coeMeasurementManager = value;
}
}
public ChillerCartMeasurementManager ChillerMeasurementManager
{
get
{
if (_chillerMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(ChillerCartMeasurementManager));
return _chillerMeasurementManager;
}
private set
{
_chillerMeasurementManager = value;
}
}
public DioMeasurementManager DioMeasurementManager
{
get
{
if (_dioMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(DioMeasurementManager));
return _dioMeasurementManager;
}
private set
{
_dioMeasurementManager = value;
}
}
public JtagMeasurementManager JtagMeasurementManager
{
get
{
if (_jtagMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(JtagMeasurementManager));
return _jtagMeasurementManager;
}
private set
{
_jtagMeasurementManager = value;
}
}
public VideoRecorderMeasurementManager VideoRecorderMeasurementManager
{
get
{
if (_videoRecorderMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(VideoRecorderMeasurementManager));
return _videoRecorderMeasurementManager;
}
private set
{
_videoRecorderMeasurementManager = value;
}
}
public RelayMeasurementManager RelayMeasurementManager
{
get
{
if (_relayMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(RelayMeasurementManager));
return _relayMeasurementManager;
}
private set
{
_relayMeasurementManager = value;
}
}
public RfMeasurementManager RfMeasurementManager
{
get
{
if (_rfMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(RfMeasurementManager));
return _rfMeasurementManager;
}
private set
{
_rfMeasurementManager = value;
}
}
public SpaceChamberLspsMeasurementManager SpaceChamberLspsMeasurementManager
{
get
{
if (_spaceChamberLspsMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(SpaceChamberLspsMeasurementManager));
return _spaceChamberLspsMeasurementManager;
}
private set
{
_spaceChamberLspsMeasurementManager = value;
}
}
public TelemetryMeasurementManager TelemetryMeasurementManager
{
get
{
if (_telemetryMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(TelemetryMeasurementManager));
return _telemetryMeasurementManager;
}
private set
{
_telemetryMeasurementManager = value;
}
}
public CryoMeasurementManager CryoMeasurementManager
{
get
{
if (_cryoMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(CryoMeasurementManager));
return _cryoMeasurementManager;
}
private set
{
_cryoMeasurementManager = value;
}
}
public OpticalBenchMeasurementManager OpticalBenchMeasurementManager
{
get
{
if (_opticalBenchMeasurementManager == null)
throw new MalMeasurementManagerNullReferenceException(typeof(OpticalBenchMeasurementManager));
return _opticalBenchMeasurementManager;
}
private set
{
_opticalBenchMeasurementManager = value;
}
}
public IInstrumentManager InstrumentManager { get; private set; }
~MalMeasurementLibManager()
{
@@ -98,34 +321,36 @@ namespace MeasurementManagerLib
/// Initialize the BIT interface manager
/// </summary>
/// <param name="measurementDefFile"></param>
/// <param name="instrumentDefFile"></param>
/// <param name="comDeviceName"></param>
/// <param name="comNodeName"></param>
/// <param name="binDataLogFilename"></param>
/// <param name="asciiDataLogFileName"></param>
/// <param name="callback"></param>
public void InitializeBitMeasurementManager(string measurementDefFile, string comDeviceName, string comNodeName, string binDataLogFilename, string asciiDataLogFileName, MessageReceivedDelegate callback)
{
// create the object once no matter how many times the host calls this
if (BitMeasurementManager == null)
if (_bitMeasurementManager == null)
{
BitMeasurementManager = new BitMeasurementManager(InstrumentManager, measurementDefFile, comDeviceName, comNodeName, binDataLogFilename, asciiDataLogFileName, callback);
_bitMeasurementManager = new BitMeasurementManager(InstrumentManager, measurementDefFile, comDeviceName, comNodeName, binDataLogFilename, asciiDataLogFileName, callback);
}
}
/// <summary>
/// Initialize the BIT interface manager
/// </summary>
/// <param name="instrumentDefFilePath"></param>
/// <param name="instrumentName"></param>
/// <param name="testType"></param>
public void InitializeBitGenSoftMeasurementManager(List<string> instrumentNames)
/// <param name="instrumentNames"></param>
public void InitializeCoeMeasurementManager(string coeMeasurementManagerConfigFullPath)
{
if (BitGenSoftMeasurementManager == null)
if (_coeMeasurementManager == null)
{
BitGenSoftMeasurementManager = new BitGenSoftMeasurementManager(InstrumentManager, instrumentNames);
_coeMeasurementManager = new CoeMeasurementManager(InstrumentManager, coeMeasurementManagerConfigFullPath);
_coeMeasurementManager.InitNodes();
}
}
/// <summary>
/// Initialize the Chiller interface manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="chillerName"></param>
/// <param name="flowMeeterName"></param>
/// <param name="tempSensorName"></param>
@@ -133,90 +358,81 @@ namespace MeasurementManagerLib
public void InitializeChillerCartMeasurementManager(string chillerName, string flowMeeterName, string tempSensorName, string errorLog)
{
// create the object once no matter how many times the host calls this
if (ChillerMeasurementManager == null)
if (_chillerMeasurementManager == null)
{
ChillerMeasurementManager = new ChillerCartMeasurementManager(InstrumentManager, chillerName, flowMeeterName, tempSensorName, errorLog);
_chillerMeasurementManager = new ChillerCartMeasurementManager(InstrumentManager, chillerName, flowMeeterName, tempSensorName, errorLog);
}
}
/// <summary>
/// Initialize the Dio interface manager
/// </summary>
/// <param name="measurementDefFile"></param>
/// <param name="instrumentDefFile"></param>
public void InitializeDioMeasurementManager()
{
// create the object once no matter how many times the host calls this
if (DioMeasurementManager == null)
if (_dioMeasurementManager == null)
{
DioMeasurementManager = new DioMeasurementManager(InstrumentManager);
_dioMeasurementManager = new DioMeasurementManager(InstrumentManager);
}
}
/// <summary>
/// Initialize the Jtag interface manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="instrumentName"></param>
/// <param name="measurementDefFile"></param>
/// <param name="errorLogFileName"></param>
public void InitializeJtagMeasurementManager(string instrumentName, string measurementDefFile)
{
// create the object once no matter how many times the host calls this
if (JtagMeasurementManager == null)
if (_jtagMeasurementManager == null)
{
JtagMeasurementManager = new JtagMeasurementManager(InstrumentManager, instrumentName, measurementDefFile);
_jtagMeasurementManager = new JtagMeasurementManager(InstrumentManager, instrumentName, measurementDefFile);
}
}
/// <summary>
/// Initialize the fpga communication manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="instrumentNames"></param>
/// <param name="instrumentDefFile"></param>
public void InitializeFpgaMeasurementManager(List<string> instrumentNames, string instrumentDefFile)
{
// create the object once no matter how many times the host calls this
if (FpgaMeasurementManager == null)
if (_fpgaMeasurementManager == null)
{
FpgaMeasurementManager = new FpgaMeasurementManager(InstrumentManager, instrumentNames, instrumentDefFile);
_fpgaMeasurementManager = new FpgaMeasurementManager(InstrumentManager, instrumentNames, instrumentDefFile);
}
}
/// <summary>
/// Initialize the power system and connect to the power supplies
/// </summary>
/// <param name="measurementDefFile"></param>
/// <param name="instrumentDefFile"></param>
public void InitializePowerSupplyMeasurementManager()
{
// create the object once no matter how many times the host calls this
if (PowerSupplyMeasurementManager == null)
if (_powerSupplyMeasurementManager == null)
{
PowerSupplyMeasurementManager = new PowerSupplyMeasurementManager(InstrumentManager);
_powerSupplyMeasurementManager = new PowerSupplyMeasurementManager(InstrumentManager);
}
}
/// <summary>
/// Initialize the relay manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="instrumentNames"></param>
/// <param name="configFileName"></param>
public void InitializeRelayMeasurementManager(List<string> instrumentNames, string configFileName)
{
// create the object once no matter how many times the host calls this
if (RelayMeasurementManager == null)
if (_relayMeasurementManager == null)
{
RelayMeasurementManager = new RelayMeasurementManager(InstrumentManager, instrumentNames, configFileName);
_relayMeasurementManager = new RelayMeasurementManager(InstrumentManager, instrumentNames, configFileName);
}
}
/// <summary>
/// Initializes Rf Measurement Manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="switchInstrumentNames"></param>
/// <param name="powerMeeterName"></param>
/// <param name="signalGeneratorName"></param>
@@ -225,62 +441,55 @@ namespace MeasurementManagerLib
public void InitializeRfMeasurementManager(List<string> switchInstrumentNames, string powerMeeterName, string signalGeneratorName, string specAnalyzerName, string configFileName)
{
// create the object once no matter how many times the host calls this
if (RfMeasurementManager == null)
if (_rfMeasurementManager == null)
{
RfMeasurementManager = new RfMeasurementManager(InstrumentManager, switchInstrumentNames, powerMeeterName, signalGeneratorName, specAnalyzerName, configFileName);
_rfMeasurementManager = new RfMeasurementManager(InstrumentManager, switchInstrumentNames, powerMeeterName, signalGeneratorName, specAnalyzerName, configFileName);
}
}
/// <summary>
/// Initializes Space Chamber LSPS Measurement Manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="lspsChamber"></param>
/// <param name="netCdfData"></param>
public void InitializeSpaceChamberLSPSMeasurementManager(string lspsChamber, string netCdfData)
{
// create the object once no matter how many times the host calls this
if (SpaceChamberLSPSMeasurementManager == null)
if (_spaceChamberLspsMeasurementManager == null)
{
SpaceChamberLSPSMeasurementManager = new SpaceChamberLSPSMeasurementManager(InstrumentManager, lspsChamber, netCdfData);
_spaceChamberLspsMeasurementManager = new SpaceChamberLspsMeasurementManager(InstrumentManager, lspsChamber, netCdfData);
}
}
/// <summary>
/// Initializes Switch Measurement Manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="switchCardNames"></param>
/// <param name="dmmName"></param>
/// <param name="scopeName"></param>
/// <param name="configFileName"></param>
public void InitializeSwitchMeasurementManager()
/// <param name="switchMeasurementManagerConfigFullPath"></param>
public void InitializeSwitchMeasurementManager(string switchMeasurementManagerConfigFullPath, bool skipDmmInitialization = false)
{
// create the object once no matter how many times the host calls this
if (SwitchMeasurementManager == null)
if (_switchMeasurementManager == null)
{
SwitchMeasurementManager = new SwitchMeasurementManager(InstrumentManager);
_switchMeasurementManager = new SwitchMeasurementManager(InstrumentManager, switchMeasurementManagerConfigFullPath, skipDmmInitialization);
}
}
/// <summary>
/// Initialize the video recorder manager
/// </summary>
/// <param name="measurementDefFile"></param>
/// <param name="instrumentDefFile"></param>
/// <param name="deviceName"></param>
public void InitializeVideoRecorderMeasurementManager(string deviceName)
{
// create the object once no matter how many times the host calls this
if (VideoRecorderMeasurementManager == null)
if (_videoRecorderMeasurementManager == null)
{
VideoRecorderMeasurementManager = new VideoRecorderMeasurementManager(InstrumentManager, deviceName);
_videoRecorderMeasurementManager = new VideoRecorderMeasurementManager(InstrumentManager, deviceName);
}
}
/// <summary>
/// Initializes Cryo Measurement Manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="commDeviceName"></param>
/// <param name="serialDeviceName"></param>
/// <param name="isThereHardware"></param>
@@ -288,40 +497,39 @@ namespace MeasurementManagerLib
public void InitializeCryoMeasurementManager(string commDeviceName, string serialDeviceName, bool isThereHardware, string errorLogFileName)
{
// create the object once no matter how many times the host calls this
if (CryoMeasurementManager == null)
if (_cryoMeasurementManager == null)
{
CryoMeasurementManager = new CryoMeasurementManager(InstrumentManager, commDeviceName, serialDeviceName, isThereHardware, errorLogFileName);
_cryoMeasurementManager = new CryoMeasurementManager(InstrumentManager, commDeviceName, serialDeviceName, isThereHardware, errorLogFileName);
}
}
/// <summary>
/// Initializes Optical Bench Measurement Manager
/// </summary>
/// <param name="InstrumentManager"></param>
/// <param name="instrumentName"></param>
/// <param name="measurementDefFile"></param>
/// <param name="instrumentDefFile"></param>
public void InitializeOpticalBenchMeasurementManager(string instrumentName, string measurementDefFile, string instrumentDefFile)
{
// create the object once no matter how many times the host calls this
if (OpticalBenchMeasurementManager == null)
if (_opticalBenchMeasurementManager == null)
{
OpticalBenchMeasurementManager = new OpticalBenchMeasurementManager(InstrumentManager, instrumentName, measurementDefFile, instrumentDefFile);
_opticalBenchMeasurementManager = new OpticalBenchMeasurementManager(InstrumentManager, instrumentName, measurementDefFile, instrumentDefFile);
}
}
/// <summary>
/// initializes Telemetry Measurement Manager for multiple instruments
/// </summary>
/// <param name="measurementDefFile"></param>
/// <param name="instrumentDefFile"></param>
/// <param name="instrumentNames"></param>
/// <param name="telemetryMalFile"></param>
public void InitializeTelemetryMeasurementManager(List<string> instrumentNames, string telemetryMalFile)
{
// create the object once no matter how many times the host calls this
if (TelemetryMeasurementManager == null)
if (_telemetryMeasurementManager == null)
{
TelemetryMeasurementManager = new TelemetryMeasurementManager(InstrumentManager, instrumentNames, telemetryMalFile);
_telemetryMeasurementManager = new TelemetryMeasurementManager(InstrumentManager, instrumentNames, telemetryMalFile);
}
}

View File

@@ -19,9 +19,9 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Managers\BitGenSoftMeasurementManager\BitGenSoftMeasurementManager.csproj" />
<ProjectReference Include="..\..\Managers\BitMeasurementManager\BitMeasurementManager.csproj" />
<ProjectReference Include="..\..\Managers\ChillerCartMeasurementManager\ChillerCartMeasurementManager.csproj" />
<ProjectReference Include="..\..\Managers\CoeMeasurementManager\CoeMeasurementManager.csproj" />
<ProjectReference Include="..\..\Managers\CryoMeasurementManager\CryoMeasurementManager.csproj" />
<ProjectReference Include="..\..\Managers\DioMeasurementManager\DioMeasurementManager.csproj" />
<ProjectReference Include="..\..\Managers\FpgaMeasurementManager\FpgaMeasurementManager.csproj" />

View File

@@ -1,215 +0,0 @@
// **********************************************************************************************************
// BITCommand.cs
// 8/31/2023
// NGI - Next Generation Interceptor
//
// Contract No. HQ0856-21-C-0003/1022000209
//
// DISTRIBUTION STATEMENT F: FURTHER DISSEMINATION ONLY AS DIRECTED BY
// MISSILE DEFENSE AGENCY, MDA/GMY NEXT GENERATION INTERCEPTOR PROJECT
// OFFICE (DATE OF DETERMINATION 14 JUNE 2021) OR HIGHER DOD AUTHORITY.
// OTHER REQUESTS FOR THIS DOCUMENT SHALL BE REFERRED TO: MISSILE DEFENSE
// AGENCY, CONTRACTS DIRECTORATE, ATTN: GMYK, BLDG. 5222 MARTIN ROAD,
// REDSTONE ARSENAL, AL 35898.
//
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA WHOSE EXPORT IS
// RESTRICTED BY THE ARMS EXPORT CONTROL ACT (TITLE 22, U.S.C.,
// SECTION 2751, ET SEQ.) OR THE EXPORT ADMINISTRATION ACT OF 1979
// (TITLE 50 U.S.C. APP. 2401 ET SEQ.), AS AMENDED. VIOLATIONS OF
// THESE EXPORT LAWS ARE SUBJECT TO SEVERE CRIMINAL PENALTIES.
// DISSEMINATE IN ACCORDANCE WITH PROVISIONS OF DOD DIRECTIVE 5230.25.
//
// 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)
// **********************************************************************************************************
// Ignore Spelling: Deserialized
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace BitGenSoftMeasurementManagerLib
{
[XmlType(TypeName = "ResponseMessageType")]
public enum ResponseMessageType
{
U, // Unknown or Undefined
R, // Required
E, // Error
P // Parametric
}
[XmlType(TypeName = "ParamType")]
public enum ParameterType
{
U, // Unknown or Undefined will default to string
N, // Numeric
S, // String
A, // Array
P // p-data array
}
[XmlType(TypeName = "BITResponseMsg")]
public class BITResponseMsg
{
[XmlAttribute("type")]
public ResponseMessageType ResponseType { get; set; }
[XmlText]
public string Name { get; set; }
}
[XmlType("Value")]
public class BITParameter
{
[XmlAttribute(AttributeName = "name")]
public string Key { get; set; }
[XmlAttribute(AttributeName = "type")]
public ParameterType ParameterType { get; set; }
[XmlAttribute(AttributeName = "delim")]
public string Delim { get; set; }
[XmlText]
public string Value { get; set; }
}
[Serializable]
public class BITCommand
{
[XmlElement(ElementName = "Command")]
public string Command { get; set; }
[XmlElement(ElementName = "CommandTimeout")]
public uint CommandTimeout { get; set; }
[XmlArray("CommandParameters")]
[XmlArrayItem("Value", Type = typeof(BITParameter))]
public List<BITParameter> CommandParameters { get; set; } = new List<BITParameter>();
[XmlArray("CommandResponses")]
[XmlArrayItem("BITResponseMsg", Type = typeof(BITResponseMsg))]
public List<BITResponseMsg> CommandResponses { get; set; } = new List<BITResponseMsg>();
[XmlElement(ElementName = "ParametricResponse")]
public string ParametricResponse { get; set; }
[XmlElement(ElementName = "ParametricTimeout")]
public uint ParametricTimeout { get; set; }
[XmlArray("ResponseParameters")]
[XmlArrayItem("Value", Type = typeof(BITParameter))]
public List<BITParameter> ResponseParameters { get; set; } = new List<BITParameter>();
/// <summary>
/// converts one hex parameter string into parameter array
/// </summary>
public void UnfoldHexParameters()
{
if (!CommandParameters.Any(p => p.ParameterType == ParameterType.P))
return;
var paramList = CommandParameters.Where(p => p.ParameterType == ParameterType.P).ToList();
List<BITParameter> removeList = new List<BITParameter>();
foreach (BITParameter param in paramList)
{
AddPDataArrayValues(param.Key, param.Value, param.Delim);
removeList.Add(param);
}
CommandParameters.RemoveAll(c => removeList.Contains(c));
}
/// <summary>
/// takes a hex string and breaks it up into individual characters
/// then inserts them as parameters
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="delim"></param>
private void AddPDataArrayValues(string key, string value, string delim)
{
var parms = BreakByPages(value, delim);
int index = 0;
foreach (var item in parms)
{
string itemKey = $"{key}[{index++}]";
string itemValue = item;
CommandParameters.Add(new BITParameter { Key = itemKey, Value = itemValue } );
}
}
/// <summary>
/// takes a large hex string and breaks it in multiple pages based on the known header
/// adjusts the size of the page to be divisible by 4 bytes
/// and also adds a 12 byte footer of zero values to the end of the page
/// </summary>
/// <param name="hexStr"></param>
/// <param name="header"></param>
/// <returns></returns>
private static IEnumerable<string> BreakByPages(string hexStr, string header)
{
const int footerSize = 12;
string[] pages = hexStr.Split(new[] { header }, StringSplitOptions.RemoveEmptyEntries);
foreach (string page in pages)
{
string completePage = header + page;
int pageSize = (completePage.Length + 7) & ~7;
string paddedPage = completePage.PadRight(pageSize + (footerSize * 2), '0');
IEnumerable<string> hexChars = BreakIntoHexCharacters(paddedPage);
foreach (string hexChar in hexChars)
{
yield return hexChar;
}
}
}
/// <summary>
/// takes a large string of hex characters and breaks it into individual hex values
/// then yields these values to the calling code
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
public static IEnumerable<string> BreakIntoHexCharacters(string hexString)
{
int characterSize = 2;
int length = hexString.Length;
for (int i = 0; i < length; i += characterSize)
{
if (i + characterSize > length)
{
hexString = hexString.PadRight(i + characterSize, '0');
}
yield return "0x" + hexString.Substring(i, characterSize);
}
}
}
}

View File

@@ -1,936 +0,0 @@
// **********************************************************************************************************
// BitGenSoftMeasurementManager.cs
// 7/28/2022
// 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 NLog;
using Raytheon.Common;
using Raytheon.Instruments;
using Raytheon.Instruments.Exceptions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BitGenSoftMeasurementManagerLib;
namespace MeasurementManagerLib
{
/// <summary>
/// Bit Gen Soft Measurement Manager class
/// </summary>
public class BitGenSoftMeasurementManager : IDisposable
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
private readonly Dictionary<string, IBit> _bitNodes = new Dictionary<string, IBit>();
private readonly IInstrumentManager _instrumentManager;
private IConfigurationManager _configurationManager;
private int _checkForMessageIntervalMs = 10;
/// <summary>
/// constructor that will create a list of BIT instruments
/// </summary>
/// <param name="instrumentManager"></param>
/// <param name="instrumentNames"></param>
public BitGenSoftMeasurementManager(IInstrumentManager instrumentManager, List<string> instrumentNames)
: this(instrumentManager)
{
try
{
foreach (string instrumentName in instrumentNames)
{
var bitNode = (IBit)_instrumentManager.GetGenericInstrument(instrumentName);
if (bitNode == null)
{
_logger.Error("Error creating TCP BIT device, check your settings");
}
else
{
_bitNodes.Add(instrumentName, bitNode);
}
}
}
catch (Exception ex)
{
_logger.Error($"Unable to create BIT instrument\n{ex.Message}");
}
}
/// <summary>
/// in case instrument manager was passed from upper level
/// </summary>
/// <param name="instrumentManager"></param>
private BitGenSoftMeasurementManager(IInstrumentManager instrumentManager)
{
_instrumentManager = instrumentManager;
InitializeConfigurationManager();
}
/// <summary>
/// initializes configuration manager,
/// will use configuration path from General Instrument Manager if available
/// otherwise will try to use the instruments path
/// </summary>
private void InitializeConfigurationManager()
{
string defaultPath;
if (_instrumentManager is GeneralInstrumentManager generalinstrumentManager)
{
defaultPath = generalinstrumentManager._configLocation;
}
else
{
defaultPath = _instrumentManager._partsLocation;
}
_configurationManager = new RaytheonConfigurationManager(defaultPath);
var config = _configurationManager.GetConfiguration("BitGenSoftMeasurementManager");
_checkForMessageIntervalMs = config.GetConfigurationValue("Settings", "CheckForMessageIntervalMs", 10);
}
/// <summary>
/// initialize COE nodes based on test type
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="testType"></param>
public void InitNodes()
{
foreach (var node in _bitNodes)
{
try
{
IBit bitNode = node.Value;
bitNode.Initialize();
bitNode.Open();
}
catch (Exception ex)
{
_logger.Error(ex, ex.Message);
}
}
}
/// <summary>
/// close all connections
/// </summary>
/// <exception cref="NotImplementedException"></exception>
public void Dispose()
{
foreach (var bitNode in _bitNodes)
{
bitNode.Value?.Shutdown();
}
}
/// <summary>
/// straight pass-through the message and parameters
/// </summary>
/// <param name="messageId"></param>
/// <param name="timeoutInMs"></param>
/// <param name="messageParams"></param>
/// <returns></returns>
public bool RunBIT(string messageId, uint timeoutInMs, IEnumerable<KeyValuePair<string, string>> messageParams = null)
{
if (_bitNodes.Any())
{
IBit bitNode = _bitNodes.First().Value;
return bitNode.RunBIT(messageId, timeoutInMs, messageParams);
}
else
{
_logger.Error($"Unable to locate BIT node. No nodes defined");
return false;
}
}
/// <summary>
/// straight pass-through the message and parameters
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="messageId"></param>
/// <param name="timeoutInMs"></param>
/// <param name="messageParams"></param>
/// <returns></returns>
public bool RunBIT(string instrumentName, string messageId, uint timeoutInMs, IEnumerable<KeyValuePair<string, string>> messageParams = null)
{
if (_bitNodes.ContainsKey(instrumentName))
{
return _bitNodes[instrumentName].RunBIT(messageId, timeoutInMs, messageParams);
}
else
{
_logger.Error($"Unable to locate BIT node {instrumentName}");
return false;
}
}
/// <summary>
/// always runs the request on the first node,
/// </summary>
/// <param name="messageIdOut"></param>
/// <param name="messageIdIn"></param>
/// <param name="timeoutInMs"></param>
/// <param name="messageParams"></param>
/// <returns></returns>
public BitTestResults RunBITWaitForResults(string messageIdOut,
string messageIdIn,
uint timeoutInMs,
IEnumerable<KeyValuePair<string, string>> messageParams = null)
{
if (_bitNodes.Any())
{
IBit bitNode = _bitNodes.First().Value;
return bitNode.RunBITWaitForResults(messageIdOut, messageIdIn, timeoutInMs, messageParams);
}
else
{
_logger.Error($"Unable to locate BIT node. No nodes defined");
return null;
}
}
/// <summary>
/// run BIT message and wait for result from the instrument based on the name
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="messageIdOut"></param>
/// <param name="messageIdIn"></param>
/// <param name="timeoutInMs"></param>
/// <param name="messageParams"></param>
/// <returns></returns>
public BitTestResults RunBITWaitForResults(string instrumentName,
string messageIdOut,
string messageIdIn,
uint timeoutInMs,
IEnumerable<KeyValuePair<string, string>> messageParams = null)
{
if (_bitNodes.ContainsKey(instrumentName))
{
return _bitNodes[instrumentName].RunBITWaitForResults(messageIdOut, messageIdIn, timeoutInMs, messageParams);
}
else
{
_logger.Error($"Unable to locate BIT node {instrumentName}");
return null;
}
}
/// <summary>
/// RunBITWaitForResults for the whole list of BIT Commands
/// runs on the first node
/// </summary>
/// <param name="commands"></param>
/// <returns></returns>
public List<BitTestResults> RunBITWaitForResultsList(List<BITCommand> commands)
{
if (_bitNodes.Any())
{
return RunBITWaitForResultsList(commands, _bitNodes.First().Value);
}
else
{
_logger.Error("Unable to locate BIT node. No nodes defined");
return null;
}
}
/// <summary>
/// RunBITWaitForResults for the whole list of BIT Commands
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="commands"></param>
/// <returns></returns>
public List<BitTestResults> RunBITWaitForResultsList(string instrumentName, List<BITCommand> commands)
{
if (_bitNodes.ContainsKey(instrumentName))
{
return RunBITWaitForResultsList(commands, _bitNodes[instrumentName]);
}
else
{
_logger.Error($"Unable to locate BIT node {instrumentName}");
return null;
}
}
/// <summary>
/// Runs BIT command and returns the results as a list
/// </summary>
/// <param name="commands"></param>
/// <returns></returns>
public async Task<List<BitTestResults>> RunBITWaitForResultsListAsync(List<BITCommand> commands)
{
if (_bitNodes.Any())
{
return await RunBITWaitForResultsListAsync(commands, _bitNodes.First().Value);
}
else
{
_logger.Error("Unable to locate BIT node. No nodes defined");
return null;
}
}
/// <summary>
/// Runs BIT command for specific instrument and returns the results as a list
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="commands"></param>
/// <returns></returns>
public async Task<List<BitTestResults>> RunBITWaitForResultsListAsync(string instrumentName, List<BITCommand> commands)
{
if (_bitNodes.ContainsKey(instrumentName))
{
return await RunBITWaitForResultsListAsync(commands, _bitNodes[instrumentName]);
}
else
{
_logger.Error($"Unable to locate BIT node {instrumentName}");
return null;
}
}
/// <summary>
/// asynchronously runs BIT command and waits for multiple results including parametric messages
/// </summary>
/// <param name="instrumentName">BIT instrument to run command</param>
/// <param name="bitCommandId">main command</param>
/// <param name="timeout">timeout value in ms for the main response</param>
/// <param name="commandParams">optional parameters for the main command</param>
/// <param name="parametricResponseIds">list of additional response messages with their respective timeouts to wait for</param>
/// <param name="timeout2">parametric timeout value in ms</param>
/// <param name="errorMessageId">nack response id when provided will be expected as a possible response for either main response or parametric response</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<List<BitTestResults>> RunBITWaitForResultsAsync( string instrumentName,
string bitCommandId,
int retries,
uint timeout,
IEnumerable<KeyValuePair<string, string>> commandParams = null,
List<string> parametricResponseIds = null,
uint timeout2 = 0,
string errorMessageId = null)
{
IBit bitGenSoftManager = _bitNodes[instrumentName] ?? throw new Exception("BitGenSoftManager is null. Unable to perform operation.");
BITCommand command = BuildBITCommand(bitCommandId, retries, timeout, commandParams, parametricResponseIds, timeout2, errorMessageId);
return await RunBITWaitForResultsListAsync(new List<BITCommand> { command }, bitGenSoftManager);
}
/// <summary>
/// keep reading any of the messages from the list
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="parametricResponseIds"></param>
/// <param name="timeOut"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task KeepReadingBitResultsListAsync(string instrumentName, List<string> parametricResponseIds, CancellationToken token)
{
IBit bitNode = _bitNodes[instrumentName] ?? throw new Exception("BitGenSoftManager is null. Unable to perform operation.");
await KeepReadingBitResultsListAsync(parametricResponseIds, token, bitNode);
}
/// <summary>
/// keep reading any of the messages from the list from the first node
/// </summary>
/// <param name="parametricResponseIds"></param>
/// <param name="timeOut"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task KeepReadingBitResultsListAsync(List<string> parametricResponseIds, CancellationToken token)
{
IBit bitNode = _bitNodes.First().Value;
await KeepReadingBitResultsListAsync(parametricResponseIds, token, bitNode);
}
/// <summary>
/// looking for a any of the messages from the list
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="parametricResponseIds"></param>
/// <param name="timeOut"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<List<BitTestResults>> GetBitResultsListAsync(string instrumentName, List<string> parametricResponseIds, int timeOut)
{
IBit bitNode = _bitNodes[instrumentName] ?? throw new Exception("BitGenSoftManager is null. Unable to perform operation.");
return await GetBitResultsListAsync(parametricResponseIds, timeOut, bitNode);
}
/// <summary>
/// looking for a any of the messages from the list on the first node
/// </summary>
/// <param name="parametricResponseIds"></param>
/// <param name="timeOut"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<List<BitTestResults>> GetBitResultsListAsync(List<string> parametricResponseIds, int timeOut)
{
IBit bitNode = _bitNodes.First().Value;
return await GetBitResultsListAsync(parametricResponseIds, timeOut, bitNode);
}
/// <summary>
/// look for results in the node until either result was found or canceled
/// </summary>
/// <param name="token"></param>
/// <param name="responseId"></param>
/// <returns></returns>
public async Task<BitTestResults> GetBITResultsAsync(CancellationToken token, string responseId)
{
IBit bitNode = _bitNodes.First().Value;
return await GetBITResultsAsync(token, responseId, bitNode);
}
/// <summary>
/// look for results in the node until either result was found or canceled
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="token"></param>
/// <param name="responseId"></param>
/// <returns></returns>
public async Task<BitTestResults> GetBITResultsAsync(string instrumentName, CancellationToken token, string responseId)
{
IBit bitNode = _bitNodes[instrumentName] ?? throw new Exception("BitGenSoftManager is null. Unable to perform operation.");
return await GetBITResultsAsync(token, responseId, bitNode);
}
/// <summary>
/// look for results in either node
/// </summary>
/// <param name="messageId"></param>
/// <returns></returns>
public BitTestResults GetBITResults(string messageId)
{
_logger.Trace($"Getting BIT result for: {messageId}.");
if (_bitNodes.Any())
{
IBit bitNode = _bitNodes.First().Value;
return bitNode.GetBITResults(messageId);
}
else
return null;
}
/// <summary>
/// look for results in either node
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="messageId"></param>
/// <returns></returns>
public BitTestResults GetBITResults(string instrumentName, string messageId)
{
_logger.Trace($"{instrumentName} Getting BIT result for: {messageId}.");
return _bitNodes.ContainsKey(instrumentName) ? _bitNodes[instrumentName].GetBITResults(messageId) : null;
}
/// <summary>
/// opens a folder parse XML files for BITCommand definitions and returns a list
/// </summary>
/// <param name="dir"></param>
/// <returns></returns>
public Dictionary<string, List<BITCommand>> GetBITCommands(string directoryPath)
{
Dictionary<string, List<BITCommand>> bitCommands = new Dictionary<string, List<BITCommand>>();
try
{
string[] xmlFiles;
if (directoryPath.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase))
{
xmlFiles = new string[] {directoryPath};
}
else
{
// Get all XML files recursively in the specified directory
xmlFiles = Directory.GetFiles(directoryPath, "*.xml", SearchOption.TopDirectoryOnly);
}
foreach (string xmlFile in xmlFiles)
{
ConfigurationFile configFile = new ConfigurationFile(xmlFile);
List<string> sections = configFile.ReadAllSections();
foreach (string section in sections)
{
List<BITCommand> commands = configFile.ReadList<BITCommand>(section, "BIT_CMD");
if(bitCommands.ContainsKey(section))
{
_logger.Warn($"Found a duplicate BIT configuration section {section}, overwriting from {xmlFile} file.");
}
else
{
_logger.Trace($"Adding {section} commands from {xmlFile} file");
}
bitCommands[section] = commands;
}
}
}
catch (Exception ex)
{
_logger.Error(ex, $"Error reading BIT Command definitions in {directoryPath}");
throw;
}
return bitCommands;
}
#region Private functions
/// <summary>
/// will keep pumping messages from the receiving queue until canceled
/// </summary>
/// <param name="parametricResponseIds"></param>
/// <param name="token"></param>
/// <param name="bitNode"></param>
/// <returns></returns>
private async Task KeepReadingBitResultsListAsync(List<string> parametricResponseIds, CancellationToken token, IBit bitNode)
{
_logger.Trace($"{bitNode.Name} Start continuously reading these messages: {string.Join(", ", parametricResponseIds)}.");
Dictionary<uint, int> score = new Dictionary<uint, int>();
do
{
foreach (var responseId in parametricResponseIds)
{
BitTestResults bitTestresults = await GetBITResultsAsync(token, responseId, bitNode);
if (bitTestresults != null && !string.IsNullOrEmpty(bitTestresults.Label))
{
if(uint.TryParse(bitTestresults.Label, out uint label))
{
if(!score.ContainsKey(label))
{
score.Add(label, 1);
}
else
{
score[label]++;
}
}
}
}
//await Task.Delay(_checkForMessageIntervalMs);
} while (!token.IsCancellationRequested);
foreach (var item in score)
{
_logger.Trace($"{bitNode.Name} Dequeued the total of {item.Value} BIT messages for 0x{item.Key:X} label");
}
}
/// <summary>
///
/// </summary>
/// <param name="parametricResponseIds"></param>
/// <param name="timeOut"></param>
/// <param name="node"></param>
/// <returns></returns>
private async Task<List<BitTestResults>> GetBitResultsListAsync(List<string> parametricResponseIds, int timeOut, IBit node)
{
_logger.Trace($"{node.Name} Start continuously getting BIT results for these messages: {string.Join(", ", parametricResponseIds)}.");
List<BitTestResults> results = new List<BitTestResults>();
CancellationTokenSource tokenSource = new CancellationTokenSource();
List<Task<BitTestResults>> responseTasks = new List<Task<BitTestResults>>();
foreach (var responseId in parametricResponseIds)
{
responseTasks.Add(GetBITResultsAsync(tokenSource.Token, responseId, node));
}
Task timeoutTask = Task.Delay(timeOut);
var completedTask = await Task.WhenAny(responseTasks.Concat(new[] { timeoutTask }));
tokenSource.Cancel();
tokenSource.Dispose();
if (completedTask == timeoutTask)
{
_logger.Warn($"Timed out after {timeOut} ms while waiting on parametrized response message(s) {string.Join(", ", parametricResponseIds)}");
}
else
{
var completedResults = responseTasks.Where(t => t.Status == TaskStatus.RanToCompletion && t.Result != null).Select(t => t.Result);
results.AddRange(completedResults);
}
_logger.Trace($"{node.Name} Completed getting BIT results for these messages: {string.Join(", ", parametricResponseIds)}, found {results?.Count} results");
return results;
}
/// <summary>
/// look for results in the node until either result was found or canceled
/// </summary>
/// <param name="token"></param>
/// <param name="responseId"></param>
/// <param name="node"></param>
/// <returns></returns>
private async Task<BitTestResults> GetBITResultsAsync(CancellationToken token, string responseId, IBit node)
{
//_logger.Trace($"{node.Name} Start waiting for BIT message: {responseId}.");
BitTestResults bitTestResults = null;
do
{
await Task.Delay(_checkForMessageIntervalMs);
try
{
bitTestResults = node.GetBITResults(responseId);
}
catch (Exception ex)
{
_logger.Error(ex, ex.Message);
break;
}
} while (bitTestResults == null && !token.IsCancellationRequested);
//_logger.Trace($"{node.Name} Done waiting for BIT message: {responseId}.");
return bitTestResults;
}
/// <summary>
/// builds a command from parameters
/// </summary>
/// <param name="bitCommandId"></param>
/// <param name="retries"></param>
/// <param name="timeout"></param>
/// <param name="commandParams"></param>
/// <param name="parametricResponseIds"></param>
/// <param name="timeout2"></param>
/// <param name="errorMessageId"></param>
/// <returns></returns>
private static BITCommand BuildBITCommand(string bitCommandId,
int retries,
uint timeout,
IEnumerable<KeyValuePair<string, string>> commandParams = null,
List<string> parametricResponseIds = null,
uint timeout2 = 0,
string errorMessageId = null)
{
BITCommand bitCommand = new BITCommand
{
Command = bitCommandId,
CommandTimeout = timeout,
CommandParameters = new List<BITParameter>(),
CommandResponses = new List<BITResponseMsg>(),
ParametricResponse = retries.ToString(),
ParametricTimeout = timeout2
};
if (commandParams != null)
{
foreach (var commandParameter in commandParams)
{
bitCommand.CommandParameters.Add(new BITParameter
{
Key = commandParameter.Key,
Value = commandParameter.Value,
ParameterType = ParameterType.U
});
}
}
if(parametricResponseIds != null)
{
foreach (var response in parametricResponseIds)
{
bitCommand.CommandResponses.Add(new BITResponseMsg
{
Name = response,
ResponseType = ResponseMessageType.P
});
}
}
if(!string.IsNullOrEmpty(errorMessageId))
{
bitCommand.CommandResponses.Add(new BITResponseMsg
{
Name = errorMessageId,
ResponseType = ResponseMessageType.E
});
}
return bitCommand;
}
/// <summary>
///
/// </summary>
/// <param name="commands"></param>
/// <param name="node"></param>
/// <returns></returns>
private List<BitTestResults> RunBITWaitForResultsList(List<BITCommand> commands, IBit node)
{
List<BitTestResults> results = new List<BitTestResults>();
foreach (var command in commands)
{
string bitCommand = command.Command;
string bitResponseId = ResponseGroupForFirstBITCall(command);
uint timeout = command.CommandTimeout;
uint timeout2 = command.ParametricTimeout;
string strParamerticResponse = command.ParametricResponse;
int retries = 0;
if (int.TryParse(strParamerticResponse, out int tmpretries))
{
retries = tmpretries;
}
List<KeyValuePair<string, string>> commandParams = ConvertCommandParameters(command.CommandParameters);
int runIndex = 0;
do
{
runIndex++;
try
{
var result = node.RunBITWaitForResults(bitCommand, bitResponseId, timeout, commandParams);
results.Add(result);
}
catch (BitTimeoutException)
{
_logger.Warn($"Timeout after {timeout} ms on BIT command {bitCommand} waiting for result {bitResponseId}, retry number {runIndex}");
if (runIndex == retries)
{
throw;
}
}
} while (results == null && runIndex <= retries);
var responseGroup = ResponseGroupListForParameterBITCall(command);
if (responseGroup == null || !responseGroup.Any())
{
continue;
}
CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions options = new ParallelOptions
{
CancellationToken = cts.Token,
MaxDegreeOfParallelism = Environment.ProcessorCount
};
try
{
Parallel.ForEach(responseGroup, options, item =>
{
var totalWaitTimeMs = _checkForMessageIntervalMs;
BitTestResults parametricresults;
do
{
parametricresults = node.GetBITResults(item);
if (parametricresults != null)
{
break;
}
else
{
Thread.Sleep(_checkForMessageIntervalMs);
totalWaitTimeMs += _checkForMessageIntervalMs;
}
} while (totalWaitTimeMs < timeout2 && !cts.IsCancellationRequested);
if (parametricresults == null && !cts.IsCancellationRequested)
{
_logger.Warn($"Timed out while waiting on parametrized response message(s) for {command.Command} command");
}
if (parametricresults != null)
{
// replace earlier results (confirmation message) with parametric results
results.Add(parametricresults);
cts.Cancel();
}
});
}
catch (OperationCanceledException)
{
_logger.Trace($"Done waiting on parametrized response message(s) for {command.Command} command");
}
finally
{
cts.Dispose();
}
}
return results;
}
/// <summary>
/// runs bit command and then
/// </summary>
/// <param name="commands"></param>
/// <param name="node"></param>
/// <returns></returns>
private async Task<List<BitTestResults>> RunBITWaitForResultsListAsync(List<BITCommand> commands, IBit node)
{
List<BitTestResults> results = new List<BitTestResults>();
foreach (var command in commands)
{
string bitCommand = command.Command;
string bitResponseId = ResponseGroupForFirstBITCall(command);
uint timeout = command.CommandTimeout;
uint timeout2 = command.ParametricTimeout;
string strParamerticResponse = command.ParametricResponse;
int retries = 0;
if (int.TryParse(strParamerticResponse, out int tmpretries))
{
retries = tmpretries;
}
List<KeyValuePair<string, string>> commandParams = ConvertCommandParameters(command.CommandParameters);
int runIndex = 0;
do
{
runIndex++;
try
{
var result = await Task.Run(() => node.RunBITWaitForResults(bitCommand, bitResponseId, timeout, commandParams));
results.Add(result);
}
catch (BitTimeoutException)
{
_logger.Warn($"Timeout after {timeout} ms on BIT command {bitCommand} waiting for result {bitResponseId}, retry number {runIndex}");
if (runIndex == retries)
{
throw;
}
}
} while (results == null && runIndex <= retries);
var responseGroup = ResponseGroupListForParameterBITCall(command);
if (responseGroup == null || !responseGroup.Any())
{
continue;
}
var paramResults = await GetBitResultsListAsync(responseGroup, (int)timeout2, node);
if (paramResults != null)
{
results.AddRange(paramResults);
}
}
return results;
}
/// <summary>
/// for the initial BIT message expect to find R (main Response)
/// if any responses marked as E (error) add it to the list as alternative expected response, separated by comma
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
private static string ResponseGroupForFirstBITCall(BITCommand command)
{
StringBuilder resp = new StringBuilder();
var tempMainResponseGroup = command.CommandResponses.Where(m => m.ResponseType != ResponseMessageType.E).ToList();
if (tempMainResponseGroup != null)
{
// check for Rs first and if no messages marked with Rs than check for Us
var mainResponse = tempMainResponseGroup.FirstOrDefault(m => m.ResponseType == ResponseMessageType.R);
if (mainResponse != null)
{
resp.Append(mainResponse.Name);
}
}
// append all error message ids
foreach (var item in command.CommandResponses.Where(m => m.ResponseType == ResponseMessageType.E))
{
resp.Append(',');
resp.Append(item.Name);
}
return resp.ToString();
}
/// <summary>
/// for subsequent parameter response look for either P (parameterized) or U (undefined)
/// if any responses marked as E (error) add it to the list as alternative expected response
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
private static List<string> ResponseGroupListForParameterBITCall(BITCommand command)
{
List<string> resp = new List<string>();
bool parameterizedRespExpected = false;
var tempMainResponseGroup = command.CommandResponses.Where(m => m.ResponseType != ResponseMessageType.E).ToList();
if (tempMainResponseGroup != null)
{
// check for Rs first and if no messages marked with Rs than check for Us
var mainResponse = tempMainResponseGroup.FirstOrDefault(m => m.ResponseType == ResponseMessageType.P || m.ResponseType == ResponseMessageType.U);
if (mainResponse != null)
{
resp.Add(mainResponse.Name);
parameterizedRespExpected = true;
}
}
if (parameterizedRespExpected)
{
// append all error message ids
foreach (var item in command.CommandResponses.Where(m => m.ResponseType == ResponseMessageType.E))
{
resp.Add(item.Name);
}
}
return resp;
}
private static List<KeyValuePair<string, string>> ConvertCommandParameters(List<BITParameter> @in)
{
List<KeyValuePair<string, string>> parameters = new List<KeyValuePair<string, string>>();
foreach (var parameter in @in)
{
parameters.Add(new KeyValuePair<string, string>(parameter.Key, parameter.Value));
}
return parameters;
}
#endregion
}
}

View File

@@ -16,9 +16,9 @@ UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using System;
using System.Threading;
using System.Collections.Generic;
using Raytheon.Common;
using System.Threading;
using NLog;
namespace BitMeasurementManagerLib
{
@@ -34,6 +34,7 @@ namespace BitMeasurementManagerLib
private BitMessageIDs _messageIds;
private Dictionary<uint, List<BitConfigurableMessage>> _msgList;
private Dictionary<uint, AutoResetEvent> _receivedMsgEvents;
private readonly ILogger _logger;
#endregion
#region PrivateFuctions
@@ -43,6 +44,8 @@ namespace BitMeasurementManagerLib
/// </summary>
private BitMsgRxBuffer(BitMessageIDs messageIds)
{
_logger = LogManager.GetCurrentClassLogger();
_messageIds = messageIds;
_msgList = new Dictionary<uint, List<BitConfigurableMessage>>();
@@ -88,17 +91,17 @@ namespace BitMeasurementManagerLib
if (shouldWeDeleteOthers == true)
{
ErrorLogger.Instance().Write("BitMsgRxBuffer::AddMsg() - clearing list for " + msgId.ToString(), ErrorLogger.LogLevel.INFO);
_logger.Debug("clearing list for " + msgId.ToString());
ClearList(msgId);
}
if (_msgList.ContainsKey(msgId) == false)
{
ErrorLogger.Instance().Write("BitMsgRxBuffer::AddMsg() - creating new list for " + msgId.ToString(), ErrorLogger.LogLevel.INFO);
_logger.Debug("creating new list for " + msgId.ToString());
_msgList[msgId] = new List<BitConfigurableMessage>();
}
ErrorLogger.Instance().Write("BitMsgRxBuffer::AddMsg() - Adding " + msgId.ToString() + " to the list", ErrorLogger.LogLevel.INFO);
_logger.Debug("Adding " + msgId.ToString() + " to the list");
_msgList[msgId].Add(msg);
_receivedMsgEvents[msgId].Set();

View File

@@ -15,402 +15,331 @@ GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using Raytheon.Instruments;
using Raytheon.Common;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using NLog;
using Raytheon.Common;
using Raytheon.Instruments;
namespace BitMeasurementManagerLib
{
/// <summary>
/// An interface to sending/receiving data over TCP sockets
/// </summary>
internal class BitSimCommDeviceNode : ICommDevice, IDisposable
{
#region PrivateClassMembers
private ICommDevice _commDevice;
private BitMessageIDs _messageIds;
private IWorkerInterface _socketReadWorker;
private Thread _socketReadThread;
private readonly string _name;
private SelfTestResult _selfTestResult;
private State _state;
#endregion
/// <summary>
/// An interface to sending/receiving data over TCP sockets
/// </summary>
internal class BitSimCommDeviceNode : ICommDevice, IDisposable
{
#region PrivateClassMembers
private ICommDevice _commDevice;
private BitMessageIDs _messageIds;
private IWorkerInterface _socketReadWorker;
private Thread _socketReadThread;
private readonly string _name;
private SelfTestResult _selfTestResult;
private State _state;
private readonly ILogger _logger;
#endregion
#region PrivateFunctions
/// <summary>
/// The finalizer. Necessary for quitting the read thread
/// </summary>
~BitSimCommDeviceNode()
{
Dispose(false);
}
#region PrivateFunctions
/// <summary>
/// The finalizer. Necessary for quitting the read thread
/// </summary>
~BitSimCommDeviceNode()
{
Dispose(false);
}
/// <summary>
/// Quit the threads associated with the node
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
State initialState = _state;
/// <summary>
/// Quit the threads associated with the node
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
State initialState = _state;
// close the socket and threads
try
{
if (initialState == State.Ready)
{
Shutdown();
// close the socket and threads
if (initialState == State.Ready)
{
Shutdown();
_commDevice.Shutdown();
}
}
catch (Exception err)
{
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
}
}
_commDevice.Shutdown();
}
// dispose of the resources
try
{
if (initialState == State.Ready)
{
_socketReadWorker.Dispose();
_state = State.Uninitialized;
}
}
catch (Exception err)
{
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
}
}
}
}
// dispose of the resources
if (initialState == State.Ready)
{
_socketReadWorker.Dispose();
_state = State.Uninitialized;
}
}
}
#endregion
#endregion
#region PublicFuctions
#region PublicFuctions
/// <summary>
///
/// </summary>
/// <param name="name">The name of this instance</param>
/// <param name="messageIds"></param>
/// <param name="msgHandler"></param>
/// <param name="commReadWorkerBufferSize"></param>
/// <param name="readWorkerRestTimeInMs"></param>
public BitSimCommDeviceNode(string name, ICommDevice commDevice, BitMessageIDs messageIds, MsgDevice msgHandler, uint commReadWorkerBufferSize = 100000, uint readWorkerRestTimeInMs = 10)
{
_name = name;
/// <summary>
///
/// </summary>
/// <param name="name">The name of this instance</param>
/// <param name="messageIds"></param>
/// <param name="msgHandler"></param>
/// <param name="commReadWorkerBufferSize"></param>
/// <param name="readWorkerRestTimeInMs"></param>
public BitSimCommDeviceNode(string name, ICommDevice commDevice, BitMessageIDs messageIds, MsgDevice msgHandler, uint commReadWorkerBufferSize = 100000, uint readWorkerRestTimeInMs = 10)
{
_logger = LogManager.GetCurrentClassLogger();
_commDevice = commDevice;
_name = name;
_messageIds = messageIds;
_commDevice = commDevice;
_socketReadWorker = new CommReadWorker(this, msgHandler, commReadWorkerBufferSize, readWorkerRestTimeInMs);
_socketReadThread = new Thread(_socketReadWorker.DoWork);
_messageIds = messageIds;
// start the read thread
_socketReadThread.Start();
_socketReadWorker = new CommReadWorker(this, msgHandler, commReadWorkerBufferSize, readWorkerRestTimeInMs);
_socketReadThread = new Thread(_socketReadWorker.DoWork);
_selfTestResult = SelfTestResult.Unknown;
// start the read thread
_socketReadThread.Start();
_state = State.Uninitialized;
}
_selfTestResult = SelfTestResult.Unknown;
public void Open()
{
}
_state = State.Uninitialized;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool ClearErrors()
{
return true;
}
public void Open()
{
}
/// <summary>
///
/// </summary>
public bool DisplayEnabled
{
get
{
return false;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool ClearErrors()
{
return true;
}
set
{
throw new NotImplementedException();
}
}
/// <summary>
///
/// </summary>
public bool DisplayEnabled
{
get
{
return false;
}
/// <summary>
///
/// </summary>
public string DetailedStatus
{
get
{
return "This is a BIT Comm Sim Device Node " + _name;
}
}
set
{
throw new NotImplementedException();
}
}
public void Close()
{
Dispose();
}
/// <summary>
///
/// </summary>
public string DetailedStatus
{
get
{
return "This is a BIT Comm Sim Device Node " + _name;
}
}
/// <summary>
/// Close the device
/// </summary>
/*public void Close()
{
const int THREAD_QUIT_TIMEOUT_MS = 3000;
public void Close()
{
Dispose();
}
// tell the thread to quit
_socketReadWorker.QuitWork();
/// <summary>
///
/// </summary>
public void Dispose()
{
Dispose(true);
// close the socket which the thread might be blocked on
_commDevice.Close();
GC.SuppressFinalize(this);
}
if (_socketReadThread.IsAlive)
{
bool didThreadQuit = _socketReadThread.Join(THREAD_QUIT_TIMEOUT_MS);
/// <summary>
///
/// </summary>
public bool FrontPanelEnabled
{
get
{
throw new NotImplementedException();
}
if (didThreadQuit == false)
{
ErrorLogger.Instance().Write("BitSimCommDeviceNode::Close() - Logging Thread did not quit as expected, aborting it");
_socketReadThread.Abort();
}
else
{
ErrorLogger.Instance().Write("BitSimCommDeviceNode::Close() - Logging Thread quit successfully after join", ErrorLogger.LogLevel.INFO);
}
}
else
{
ErrorLogger.Instance().Write("BitSimCommDeviceNode::Close() - Logging Thread quit successfully", ErrorLogger.LogLevel.INFO);
}
}*/
set
{
throw new NotImplementedException();
}
}
/// <summary>
///
/// </summary>
public void Dispose()
{
try
{
Dispose(true);
/// <summary>
///
/// </summary>
public InstrumentMetadata Info
{
get
{
throw new NotImplementedException();
}
}
GC.SuppressFinalize(this);
}
catch (Exception err)
{
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
}
}
}
/// <summary>
///
/// </summary>
public void Initialize()
{
_commDevice.Initialize();
_state = State.Ready;
}
/// <summary>
///
/// </summary>
public bool FrontPanelEnabled
{
get
{
throw new NotImplementedException();
}
/// <summary>
///
/// </summary>
public string Name
{
get
{
return _name;
}
}
set
{
throw new NotImplementedException();
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public SelfTestResult PerformSelfTest()
{
return _commDevice.SelfTestResult;
}
/// <summary>
///
/// </summary>
public InstrumentMetadata Info
{
get
{
throw new NotImplementedException();
}
}
/// <summary>
/// Read data from the socket
/// </summary>
/// <param name="dataRead">The data that was read</param>
/// <returns>the number of bytes read</returns>
public uint Read(ref byte[] dataRead)
{
return 0;
}
/// <summary>
///
/// </summary>
public void Initialize()
{
_commDevice.Initialize();
_state = State.Ready;
}
/// <summary>
/// </summary>
public void Reset()
{
Close();
/// <summary>
///
/// </summary>
public string Name
{
get
{
return _name;
}
}
Initialize();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public SelfTestResult PerformSelfTest()
{
return _commDevice.SelfTestResult;
}
/// <summary>
///
/// </summary>
/// <param name="readTimeout"></param>
public void SetReadTimeout(uint readTimeout)
{
}
/// <summary>
/// Read data from the socket
/// </summary>
/// <param name="dataRead">The data that was read</param>
/// <returns>the number of bytes read</returns>
public uint Read(ref byte[] dataRead)
{
return 0;
}
/// <summary>
///
/// </summary>
public SelfTestResult SelfTestResult
{
get
{
return _selfTestResult;
}
}
/// <summary>
/// </summary>
public void Reset()
{
Close();
/// <summary>
///
/// </summary>
public State Status
{
get
{
return _state;
}
}
Initialize();
}
/// <summary>
///
/// </summary>
public void Shutdown()
{
const int THREAD_QUIT_TIMEOUT_MS = 3000;
/// <summary>
///
/// </summary>
/// <param name="readTimeout"></param>
public void SetReadTimeout(uint readTimeout)
{
}
if (_state == State.Ready)
{
// tell the thread to quit
_socketReadWorker.QuitWork();
/// <summary>
///
/// </summary>
public SelfTestResult SelfTestResult
{
get
{
return _selfTestResult;
}
}
// close the socket which the thread might be blocked on
_commDevice.Shutdown();
/// <summary>
///
/// </summary>
public State Status
{
get
{
return _state;
}
}
if (_socketReadThread.IsAlive)
{
bool didThreadQuit = _socketReadThread.Join(THREAD_QUIT_TIMEOUT_MS);
/// <summary>
///
/// </summary>
public void Shutdown()
{
const int THREAD_QUIT_TIMEOUT_MS = 3000;
if (didThreadQuit == false)
{
_logger.Debug("Logging Thread did not quit as expected, aborting it");
_socketReadThread.Abort();
}
else
{
_logger.Debug("Logging Thread quit successfully after join");
}
}
else
{
_logger.Debug("Logging Thread quit successfully");
}
}
if (_state == State.Ready)
{
// tell the thread to quit
_socketReadWorker.QuitWork();
_state = State.Uninitialized;
}
// close the socket which the thread might be blocked on
_commDevice.Shutdown();
/// <summary>
/// Send data on the socket
/// </summary>
/// <param name="dataToSend">The data to send</param>
/// <param name="numBytesToWrite">The number of bytes to write from the dataToSend buffer</param>
/// <returns>The number of bytes sent</returns>
public uint Write(byte[] dataToSend, uint numBytesToWrite)
{
// determine the id and get create the rsp message
IntPtr pDataPtr = Marshal.AllocHGlobal(dataToSend.Length);
Marshal.Copy(dataToSend, 0, pDataPtr, dataToSend.Length);
uint commandId = BitConfigurableMessageHeader.GetMessageId(pDataPtr, (uint)dataToSend.Length);
Marshal.FreeHGlobal(pDataPtr);
if (_socketReadThread.IsAlive)
{
bool didThreadQuit = _socketReadThread.Join(THREAD_QUIT_TIMEOUT_MS);
bool isThereAResponse = _messageIds.IsThereAResponseMessage(commandId);
if (didThreadQuit == false)
{
ErrorLogger.Instance().Write("BitSimCommDeviceNode::Close() - Logging Thread did not quit as expected, aborting it");
_socketReadThread.Abort();
}
else
{
ErrorLogger.Instance().Write("BitSimCommDeviceNode::Close() - Logging Thread quit successfully after join", ErrorLogger.LogLevel.INFO);
}
}
else
{
ErrorLogger.Instance().Write("BitSimCommDeviceNode::Close() - Logging Thread quit successfully", ErrorLogger.LogLevel.INFO);
}
}
// if there is a rsp msg, create a dummy msg
if (isThereAResponse == true)
{
uint rspId = _messageIds.GetResponseId(commandId);
BitConfigurableMessage rspMessage = BitConfigurableMessageFactory.Instance().RetreiveMessage(rspId);
BitMsgRxBuffer.Instance().AddMsg(rspMessage);
//uint msgLen = rspMessage.GetEntireMsgLength();
//byte[] simData = new byte[msgLen];
//_msgHandler.AddData();
}
else
{
}
_state = State.Uninitialized;
}
return (uint)dataToSend.Length;
}
/// <summary>
/// Send data on the socket
/// </summary>
/// <param name="dataToSend">The data to send</param>
/// <param name="numBytesToWrite">The number of bytes to write from the dataToSend buffer</param>
/// <returns>The number of bytes sent</returns>
public uint Write(byte[] dataToSend, uint numBytesToWrite)
{
// determine the id and get create the rsp message
IntPtr pDataPtr = Marshal.AllocHGlobal(dataToSend.Length);
Marshal.Copy(dataToSend, 0, pDataPtr, dataToSend.Length);
uint commandId = BitConfigurableMessageHeader.GetMessageId(pDataPtr, (uint)dataToSend.Length);
Marshal.FreeHGlobal(pDataPtr);
bool isThereAResponse = _messageIds.IsThereAResponseMessage(commandId);
// if there is a rsp msg, create a dummy msg
if (isThereAResponse == true)
{
uint rspId = _messageIds.GetResponseId(commandId);
BitConfigurableMessage rspMessage = BitConfigurableMessageFactory.Instance().RetreiveMessage(rspId);
BitMsgRxBuffer.Instance().AddMsg(rspMessage);
//uint msgLen = rspMessage.GetEntireMsgLength();
//byte[] simData = new byte[msgLen];
//_msgHandler.AddData();
}
else
{
}
return (uint)dataToSend.Length;
}
#endregion
}
#endregion
}
}

View File

@@ -15,357 +15,316 @@ GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using Raytheon.Common;
using System;
using System.Threading;
using NLog;
using Raytheon.Common;
namespace Raytheon.Instruments
{
/// <summary>
/// An interface to sending/receiving data over comm devices
/// </summary>
internal class CommDeviceNode : ICommDevice, IDisposable
{
#region PrivateClassMembers
private ICommDevice _commDevice;
private IWorkerInterface _socketReadWorker;
private Thread _socketReadThread;
private readonly string _name;
private SelfTestResult _selfTestResult;
private State _state;
/// <summary>
/// An interface to sending/receiving data over comm devices
/// </summary>
internal class CommDeviceNode : ICommDevice, IDisposable
{
#region PrivateClassMembers
private ICommDevice _commDevice;
private IWorkerInterface _socketReadWorker;
private Thread _socketReadThread;
private readonly string _name;
private SelfTestResult _selfTestResult;
private State _state;
private uint _commReadWorkerBufferSize;
private uint _readWorkerRestTimeInMs;
private MsgDevice _msgHandler;
private uint _commReadWorkerBufferSize;
private uint _readWorkerRestTimeInMs;
private MsgDevice _msgHandler;
private readonly ILogger _logger;
#endregion
#endregion
#region PrivateFuctions
/// <summary>
/// The finalizer. Necessary for quitting the read thread
/// </summary>
~CommDeviceNode()
{
Dispose(false);
}
#region PrivateFuctions
/// <summary>
/// The finalizer. Necessary for quitting the read thread
/// </summary>
~CommDeviceNode()
{
Dispose(false);
}
/// <summary>
/// Quit the threads associated with the node
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
State initialState = _state;
/// <summary>
/// Quit the threads associated with the node
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
State initialState = _state;
// close the socket and threads
try
{
if (initialState == State.Ready)
{
Shutdown();
_commDevice.Shutdown();
}
}
catch (Exception err)
{
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
}
}
// close the socket and threads
if (initialState == State.Ready)
{
Shutdown();
_commDevice.Shutdown();
}
// dispose of the resources
try
{
if (initialState == State.Ready)
{
_socketReadWorker.Dispose();
_state = State.Uninitialized;
}
}
catch (Exception err)
{
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
}
}
}
}
// dispose of the resources
if (initialState == State.Ready)
{
_socketReadWorker.Dispose();
_state = State.Uninitialized;
}
}
}
#endregion
#endregion
#region PublicFuctions
#region PublicFuctions
/// <summary>
/// The constructor
/// </summary>
/// <param name="name">The name of this instance</param>
/// <param name="commDevice">The communication device</param>
/// <param name="msgHandler">The message handler for this interface</param>
/// <param name="commReadWorkerBufferSize">The number of bytes for the buffer internal to this class. Each individual read will read upto this buffer size (or until the timeout happens)</param>
/// <param name="readWorkerRestTimeInMs">Number of ms to reset between read calls on the comm interface</param>
public CommDeviceNode(string name, ICommDevice commDevice, MsgDevice msgHandler, uint commReadWorkerBufferSize = 100000, uint readWorkerRestTimeInMs = 10)
{
_name = name;
_commDevice = commDevice;
_commReadWorkerBufferSize = commReadWorkerBufferSize;
_readWorkerRestTimeInMs = readWorkerRestTimeInMs;
_msgHandler = msgHandler;
/// <summary>
/// The constructor
/// </summary>
/// <param name="name">The name of this instance</param>
/// <param name="commDevice">The communication device</param>
/// <param name="msgHandler">The message handler for this interface</param>
/// <param name="commReadWorkerBufferSize">The number of bytes for the buffer internal to this class. Each individual read will read upto this buffer size (or until the timeout happens)</param>
/// <param name="readWorkerRestTimeInMs">Number of ms to reset between read calls on the comm interface</param>
public CommDeviceNode(string name, ICommDevice commDevice, MsgDevice msgHandler, uint commReadWorkerBufferSize = 100000, uint readWorkerRestTimeInMs = 10)
{
_logger = LogManager.GetCurrentClassLogger();
_name = name;
_commDevice = commDevice;
Open();
}
_commReadWorkerBufferSize = commReadWorkerBufferSize;
_readWorkerRestTimeInMs = readWorkerRestTimeInMs;
_msgHandler = msgHandler;
/// <summary>
/// Starts communication thread
/// </summary>
public void Open()
{
_socketReadWorker = new CommReadWorker(this, _msgHandler, _commReadWorkerBufferSize, _readWorkerRestTimeInMs);
_socketReadThread = new Thread(_socketReadWorker.DoWork);
Open();
}
// start the read thread
_socketReadThread.Start();
/// <summary>
/// Starts communication thread
/// </summary>
public void Open()
{
_socketReadWorker = new CommReadWorker(this, _msgHandler, _commReadWorkerBufferSize, _readWorkerRestTimeInMs);
_socketReadThread = new Thread(_socketReadWorker.DoWork);
_selfTestResult = SelfTestResult.Unknown;
_state = State.Uninitialized;
}
// start the read thread
_socketReadThread.Start();
_selfTestResult = SelfTestResult.Unknown;
_state = State.Uninitialized;
}
/// <summary>
/// there is no error msg repository
/// </summary>
/// <returns></returns>
public bool ClearErrors()
{
return false;
}
/// <summary>
/// there is no error msg repository
/// </summary>
/// <returns></returns>
public bool ClearErrors()
{
return false;
}
/// <summary>
///
/// </summary>
public bool DisplayEnabled
{
get
{
return false;
}
set
{
throw new NotImplementedException();
}
}
/// <summary>
///
/// </summary>
public bool DisplayEnabled
{
get
{
return false;
}
set
{
throw new NotImplementedException();
}
}
/// <summary>
///
/// </summary>
public string DetailedStatus
{
get
{
return "This is a Comm Sim Device Node " + _name;
}
}
/// <summary>
///
/// </summary>
public string DetailedStatus
{
get
{
return "This is a Comm Sim Device Node " + _name;
}
}
/// <summary>
///
/// </summary>
public void Dispose()
{
try
{
Dispose(true);
/// <summary>
///
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
catch (Exception err)
{
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
{
return false;
}
set
{
throw new NotImplementedException();
}
}
/// <summary>
///
/// </summary>
public bool FrontPanelEnabled
{
get
{
return false;
}
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()
{
_commDevice.Initialize();
_state = State.Ready;
}
/// <summary>
///
/// </summary>
public void Initialize()
{
_commDevice.Initialize();
_state = State.Ready;
}
/// <summary>
///
/// </summary>
public string Name
{
get
{
return _name;
}
}
/// <summary>
///
/// </summary>
public string Name
{
get
{
return _name;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public SelfTestResult PerformSelfTest()
{
throw new NotImplementedException();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public SelfTestResult PerformSelfTest()
{
throw new NotImplementedException();
}
/// <summary>
/// Read data from the socket
/// </summary>
/// <param name="dataRead">The data that was read</param>
/// <returns>the number of bytes read</returns>
public uint Read(ref byte[] dataRead)
{
return _commDevice.Read(ref dataRead);
}
/// <summary>
/// Read data from the socket
/// </summary>
/// <param name="dataRead">The data that was read</param>
/// <returns>the number of bytes read</returns>
public uint Read(ref byte[] dataRead)
{
return _commDevice.Read(ref dataRead);
}
/// <summary>
/// Resets communications
/// </summary>
public void Reset()
{
Close();
Open();
}
/// <summary>
/// Resets communications
/// </summary>
public void Reset()
{
Close();
Open();
}
/// <summary>
///
/// </summary>
/// <param name="readTimeout"></param>
public void SetReadTimeout(uint readTimeout)
{
_commDevice.SetReadTimeout(readTimeout);
}
/// <summary>
///
/// </summary>
/// <param name="readTimeout"></param>
public void SetReadTimeout(uint readTimeout)
{
_commDevice.SetReadTimeout(readTimeout);
}
/// <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>
/// Close communications
/// </summary>
public void Close()
{
Shutdown();
}
/// <summary>
/// Close communications
/// </summary>
public void Close()
{
Shutdown();
}
/// <summary>
/// Close communications
/// </summary>
public void Shutdown()
{
if (_state == State.Ready)
{
const int THREAD_QUIT_TIMEOUT_MS = 3000;
/// <summary>
/// Close communications
/// </summary>
public void Shutdown()
{
if (_state == State.Ready)
{
const int THREAD_QUIT_TIMEOUT_MS = 3000;
// tell the thread to quit
_socketReadWorker.QuitWork();
// tell the thread to quit
_socketReadWorker.QuitWork();
// close the socket which the thread might be blocked on
_commDevice.Shutdown();
// close the socket which the thread might be blocked on
_commDevice.Shutdown();
if (_socketReadThread.IsAlive)
{
bool didThreadQuit = _socketReadThread.Join(THREAD_QUIT_TIMEOUT_MS);
if (_socketReadThread.IsAlive)
{
bool didThreadQuit = _socketReadThread.Join(THREAD_QUIT_TIMEOUT_MS);
if (didThreadQuit == false)
{
ErrorLogger.Instance().Write("CommDeviceNode::Close() - Logging Thread did not quit as expected, aborting it");
_socketReadThread.Abort();
}
else
{
ErrorLogger.Instance().Write("CommDeviceNode::Close() - Logging Thread quit successfully after join", ErrorLogger.LogLevel.INFO);
}
}
else
{
ErrorLogger.Instance().Write("CommDeviceNode::Close() - Logging Thread quit successfully", ErrorLogger.LogLevel.INFO);
}
}
if (didThreadQuit == false)
{
_socketReadThread.Abort();
}
else
{
_logger.Debug("Logging Thread quit successfully after join");
}
}
else
{
_logger.Debug("Logging Thread quit successfully");
}
}
_state = State.Uninitialized;
}
_state = State.Uninitialized;
}
/// <summary>
/// Send data on the socket
/// </summary>
/// <param name="dataToSend">The data to send</param>
/// <param name="numBytesToWrite">The number of bytes to write from the dataToSend buffer</param>
/// <returns>The number of bytes sent</returns>
public uint Write(byte[] dataToSend, uint numBytesToWrite)
{
return _commDevice.Write(dataToSend, numBytesToWrite);
}
/// <summary>
/// Send data on the socket
/// </summary>
/// <param name="dataToSend">The data to send</param>
/// <param name="numBytesToWrite">The number of bytes to write from the dataToSend buffer</param>
/// <returns>The number of bytes sent</returns>
public uint Write(byte[] dataToSend, uint numBytesToWrite)
{
return _commDevice.Write(dataToSend, numBytesToWrite);
}
#endregion
}
#endregion
}
}

View File

@@ -17,8 +17,7 @@ UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
using System;
using System.Threading;
using System.Net.Sockets;
using Raytheon.Instruments;
using NLog;
using Raytheon.Common;
namespace Raytheon.Instruments
@@ -35,6 +34,7 @@ namespace Raytheon.Instruments
private AutoResetEvent _quitEvent;
private byte[] _dataRead;
private readonly uint _timeToRestBetweenReadsInMs;
private readonly ILogger _logger;
#endregion
#region PublicFuctions
@@ -48,6 +48,7 @@ namespace Raytheon.Instruments
/// <param name="timeToRestBetweenReadsInMs">Number of ms to rest after a read call</param>
public CommReadWorker(ICommDevice commNode, MsgDevice msghandler, uint bufferSize, uint timeToRestBetweenReadsInMs)
{
_logger = LogManager.GetCurrentClassLogger();
_commNode = commNode;
_threadQuitControl = false;
_msgHandler = msghandler;
@@ -69,23 +70,9 @@ namespace Raytheon.Instruments
/// </summary>
public void Dispose()
{
try
{
Dispose(true);
Dispose(true);
GC.SuppressFinalize(this);
}
catch (Exception err)
{
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>
@@ -110,33 +97,14 @@ namespace Raytheon.Instruments
// not using timeToRestBetweenReadsInMs. Just going to wait 1 ms and get back to the read
if (_quitEvent.WaitOne(1))
{
ErrorLogger.Instance().Write("CommReadWorker::DoWork() - received signal to quit", ErrorLogger.LogLevel.INFO);
_logger.Debug("received signal to quit");
_threadQuitControl = true;
}
}
catch (SocketException e)
{
if (e.SocketErrorCode == SocketError.TimedOut)
{
//expected
}
else
{
ErrorLogger.Instance().Write("CommReadWorker::DoWork() - " + e.Message, ErrorLogger.LogLevel.ERROR);
}
}
catch (Exception e)
{
ErrorLogger.Instance().Write("CommReadWorker::DoWork() - " + e.Message, ErrorLogger.LogLevel.ERROR);
}
catch (Exception) { }
}
ErrorLogger.Instance().Write("CommReadWorker::DoWork() - exiting", ErrorLogger.LogLevel.INFO);
}
catch (Exception err)
{
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
}
catch (Exception) { }
}
/// <summary>
@@ -154,23 +122,9 @@ namespace Raytheon.Instruments
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
try
if (disposing)
{
if (disposing)
{
_quitEvent.Dispose();
}
}
catch (Exception err)
{
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
}
_quitEvent.Dispose();
}
}
#endregion

View File

@@ -15,8 +15,8 @@ GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using Raytheon.Common;
using System;
using Raytheon.Common;
namespace BitMeasurementManagerLib
{
@@ -71,8 +71,7 @@ namespace BitMeasurementManagerLib
// is there enough data?
if (numBytesInPdata <= headerDef.secondaryMsgIdByteLocation + headerDef.secondaryMsgIdDataLen)
{
ErrorLogger.Instance().Write("BitConfigurableMessageHeader::GetSecondaryCmdMessageId() - not enough data form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + (headerDef.secondaryMsgIdByteLocation + headerDef.secondaryMsgIdDataLen).ToString() + " for a header", ErrorLogger.LogLevel.INFO);
throw new Exception("BitConfigurableMessageHeader::GetSecondaryCmdMessageId() - not enough data form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + (headerDef.secondaryMsgIdByteLocation + headerDef.secondaryMsgIdDataLen).ToString() + " for a header");
throw new Exception("Not enough data form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + (headerDef.secondaryMsgIdByteLocation + headerDef.secondaryMsgIdDataLen).ToString() + " for a header");
}
if (headerDef.secondaryMsgIdByteLocation == 0)
@@ -141,8 +140,7 @@ namespace BitMeasurementManagerLib
// is there enough data?
if (numBytesInPdata <= headerDef.msgIdByteLocation + headerDef.msgIdDataLen)
{
ErrorLogger.Instance().Write("BitConfigurableMessageHeader::GetCmdMessageId() - not enough data form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + (headerDef.msgIdByteLocation + headerDef.msgIdDataLen).ToString() + " for a header", ErrorLogger.LogLevel.INFO);
throw new Exception("BitConfigurableMessageHeader::GetCmdMessageId() - not enough data form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + (headerDef.msgIdByteLocation + headerDef.msgIdDataLen).ToString() + " for a header");
throw new Exception("Not enough data form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + (headerDef.msgIdByteLocation + headerDef.msgIdDataLen).ToString() + " for a header");
}
uint cmdId = 0;

View File

@@ -16,9 +16,10 @@ UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using System;
using Raytheon.Common;
using System.IO;
using System.Collections.Generic;
using System.IO;
using NLog;
using Raytheon.Common;
namespace BitMeasurementManagerLib
{
@@ -48,6 +49,7 @@ namespace BitMeasurementManagerLib
private readonly bool _shallWeLogIncomingAsciiData;
private readonly uint _bitmask;
private readonly string _crcFieldName;
private readonly ILogger _logger;
#endregion
#region PublicFuctions
@@ -66,6 +68,7 @@ namespace BitMeasurementManagerLib
unsafe public BitMsgHandler(BitMessageIDs messageIds, MeasurementManagerLib.BitMeasurementManager.MessageReceivedDelegate callback, uint bufferSize, string binLogFileName, string asciiLogFileName, bool shallWeLogOutgoingBinData, bool shallWeLogOutgoingAsciiData, bool shallWeLogIncomingBinData, bool shallWeLogIncomingAsciiData, uint crcBitmask, string crcFieldName, bool shallWePerformVerboseParserLogging)
: base(new BitMsgParser(messageIds, shallWePerformVerboseParserLogging), bufferSize)
{
_logger = LogManager.GetCurrentClassLogger();
_messageIds = messageIds;
// hold onto the callback
@@ -166,7 +169,7 @@ namespace BitMeasurementManagerLib
{
if (_messageIds.ContainsId(msgId) == false)
{
ErrorLogger.Instance().Write("BitMsgHandler::OnCompleteMessage() - detected unknown msg id: " + msgId.ToString());
_logger.Warn("BitMsgHandler::OnCompleteMessage() - detected unknown msg id: " + msgId.ToString());
}
else
{
@@ -184,7 +187,7 @@ namespace BitMeasurementManagerLib
if (maskedStatus != 0)
{
ErrorLogger.Instance().Write($"Message Status register indicates that a CRC error may have occurred. Raw status read: 0x{rawStatus:X8}. Masked status value: 0x{maskedStatus:X8}");
_logger.Warn($"Message Status register indicates that a CRC error may have occurred. Raw status read: 0x{rawStatus:X8}. Masked status value: 0x{maskedStatus:X8}");
callbackValue = -1;
}
}
@@ -207,14 +210,10 @@ namespace BitMeasurementManagerLib
}
// some debugging
ErrorLogger.Instance().Write("BitMsgHandler::HandleMsg() - added message " + msgId.ToString("X8") + " to buffer ", ErrorLogger.LogLevel.INFO);
_logger.Debug("added message " + msgId.ToString("X8") + " to buffer ");
}
}
catch (Exception err)
{
//@@@ need to flow error to the host
ErrorLogger.Instance().Write("BitMsgHandler::HandleMsg() - caught an error: " + err.Message, ErrorLogger.LogLevel.ERROR);
}
catch { }
}
/// <summary>
@@ -271,7 +270,7 @@ namespace BitMeasurementManagerLib
{
if (_binWriter == null && _shallWeLogIncomingBinData == true)
{
throw new Exception("BitMsgHandler::WriteIncomingDataToLog() - Trying to log bin data before the log file is open");
throw new Exception("Trying to log bin data before the log file is open");
}
else if (_shallWeLogIncomingBinData == true)
{
@@ -292,7 +291,7 @@ namespace BitMeasurementManagerLib
{
if (_asciiWriter == null && _shallWeLogIncomingAsciiData == true)
{
throw new Exception("BitMsgHandler::WriteIncomingDataToLog() - Trying to log ascii data before the log file is open");
throw new Exception("Trying to log ascii data before the log file is open");
}
else if (_shallWeLogIncomingAsciiData == true)
{
@@ -318,7 +317,7 @@ namespace BitMeasurementManagerLib
{
if (_binWriter == null && _shallWeLogOutgoingBinData == true)
{
throw new Exception("BitMsgHandler::WriteOutgoingDataToLog() - Trying to log bin data before the log file is open");
throw new Exception("Trying to log bin data before the log file is open");
}
else if (_shallWeLogOutgoingBinData == true)
{
@@ -339,7 +338,7 @@ namespace BitMeasurementManagerLib
{
if (_asciiWriter == null && _shallWeLogOutgoingAsciiData == true)
{
throw new Exception("BitMsgHandler::WriteOutgoingDataToLog() - Trying to log ascii data before the log file is open");
throw new Exception("Trying to log ascii data before the log file is open");
}
else if (_shallWeLogOutgoingAsciiData == true)
{
@@ -362,25 +361,18 @@ namespace BitMeasurementManagerLib
{
if (disposing)
{
try
// call the parent dispose first
base.Dispose(disposing);
// now dispose of our resources
if (_binWriter != null)
{
// call the parent dispose first
base.Dispose(disposing);
// now dispose of our resources
if (_binWriter != null)
{
_binWriter.Dispose();
}
if (_asciiWriter != null)
{
_asciiWriter.Dispose();
}
_binWriter.Dispose();
}
catch (Exception err)
if (_asciiWriter != null)
{
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
_asciiWriter.Dispose();
}
}
}

View File

@@ -15,8 +15,9 @@ GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using Raytheon.Common;
using System;
using NLog;
using Raytheon.Common;
namespace BitMeasurementManagerLib
{
@@ -34,6 +35,7 @@ namespace BitMeasurementManagerLib
private readonly BitMessageIDs _messageIdToSizeMap;
private BitMsgEndianControl.HeaderDef _headerDef;
private readonly bool _shallWePerformVerboseParserLogging;
private readonly ILogger _logger;
#endregion
#region PrivateFuctions
@@ -54,7 +56,7 @@ namespace BitMeasurementManagerLib
if (numBytesInPdata < payloadHeaderSize)
{
ErrorLogger.Instance().Write("BitMsgParser::HandleData() - not enough data in the buffer to form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + payloadHeaderSize.ToString() + " for a header", ErrorLogger.LogLevel.INFO);
_logger.Debug("not enough data in the buffer to form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + payloadHeaderSize.ToString() + " for a header");
bytesToRemove = 0;
return false;
}
@@ -67,8 +69,8 @@ namespace BitMeasurementManagerLib
if (_messageIdToSizeMap.ContainsId(id) == false)
{
uint numBytesToRemove = Resync(pData, numBytesInPdata);
string msg = "BitMsgParser::HandleData() - unknown id received: " + id.ToString("X8") + " When resyncing threw away " + numBytesToRemove.ToString() + " Bytes";
ErrorLogger.Instance().Write(msg, ErrorLogger.LogLevel.ERROR);
string msg = "unknown id received: " + id.ToString("X8") + " When resyncing threw away " + numBytesToRemove.ToString() + " Bytes";
_logger.Warn(msg);
bytesToRemove = numBytesToRemove;
return false;
}
@@ -79,8 +81,8 @@ namespace BitMeasurementManagerLib
if (secondaryId != _headerDef.secondaryMsgIdExpectedValue)
{
uint numBytesToRemove = Resync(pData, numBytesInPdata);
string msg = "BitMsgParser::HandleData() - detected seondary ID: " + secondaryId.ToString("X8") + " was not as expected: " + _headerDef.secondaryMsgIdExpectedValue.ToString("X8") + " When resyncing threw away " + numBytesToRemove.ToString() + " Bytes";
ErrorLogger.Instance().Write(msg, ErrorLogger.LogLevel.ERROR);
string msg = "detected seondary ID: " + secondaryId.ToString("X8") + " was not as expected: " + _headerDef.secondaryMsgIdExpectedValue.ToString("X8") + " When resyncing threw away " + numBytesToRemove.ToString() + " Bytes";
_logger.Warn(msg);
bytesToRemove = numBytesToRemove;
return false;
}
@@ -91,7 +93,7 @@ namespace BitMeasurementManagerLib
// do we have enough data to make the complete message
if (numBytesInPdata < msgSize)
{
ErrorLogger.Instance().Write("BitMsgParser::HandleData() - not enough data in the buffer to form a entire message. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, expected msg size is: " + msgSize.ToString(), ErrorLogger.LogLevel.INFO);
_logger.Debug("not enough data in the buffer to form a entire message. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, expected msg size is: " + msgSize.ToString());
// need to wait for more data
bytesToRemove = 0;
return false;
@@ -102,7 +104,7 @@ namespace BitMeasurementManagerLib
if (_shallWePerformVerboseParserLogging == true)
{
ErrorLogger.Instance().Write("BitMsgParser::HandleData() - found msg: " + id.ToString() + " which has " + msgSize.ToString() + " bytes", ErrorLogger.LogLevel.INFO);
_logger.Debug("found msg: " + id.ToString() + " which has " + msgSize.ToString() + " bytes");
}
messageId = id;
@@ -118,7 +120,7 @@ namespace BitMeasurementManagerLib
/// <returns>The number of bytes to remove from the buffer</returns>
private uint Resync(IntPtr pData, uint numBytesInPdata)
{
ErrorLogger.Instance().Write("BitMsgParser::Resync() - Begin", ErrorLogger.LogLevel.INFO);
_logger.Debug("Begin");
// increment pData by 1
pData = IntPtr.Add(pData, 1);
@@ -138,7 +140,7 @@ namespace BitMeasurementManagerLib
if (numBytesInPdata < payloadHeaderSize)
{
ErrorLogger.Instance().Write("BitMsgParser::Resync() - not enough data in the buffer to form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + payloadHeaderSize.ToString() + " for a header. Removing " + bytesToRemove.ToString() + " bytes", ErrorLogger.LogLevel.INFO);
_logger.Debug("not enough data in the buffer to form a header. Buffer contained " + Convert.ToString(numBytesInPdata) + " bytes, needed " + payloadHeaderSize.ToString() + " for a header. Removing " + bytesToRemove.ToString() + " bytes");
break;
}
@@ -179,20 +181,20 @@ namespace BitMeasurementManagerLib
else
{
didWeFindMsg = true;
ErrorLogger.Instance().Write("BitMsgParser::Resync() - Detected message ID: " + id.ToString("X8") + ". Detected Secondary ID: " + secondaryId.ToString("X8") + " Resync complete. Removing " + bytesToRemove.ToString() + " Bytes", ErrorLogger.LogLevel.INFO);
_logger.Debug("Detected message ID: " + id.ToString("X8") + ". Detected Secondary ID: " + secondaryId.ToString("X8") + " Resync complete. Removing " + bytesToRemove.ToString() + " Bytes");
break;
}
}
else
{
didWeFindMsg = true;
ErrorLogger.Instance().Write("BitMsgParser::Resync() - Detected message ID: " + id.ToString("X8") + ". Resync complete. Removing " + bytesToRemove.ToString() + " Bytes", ErrorLogger.LogLevel.INFO);
_logger.Debug("Detected message ID: " + id.ToString("X8") + ". Resync complete. Removing " + bytesToRemove.ToString() + " Bytes");
break;
}
}
}
ErrorLogger.Instance().Write("BitMsgParser::Resync() - returning " + bytesToRemove.ToString(), ErrorLogger.LogLevel.INFO);
_logger.Debug("returning " + bytesToRemove.ToString());
return bytesToRemove;
@@ -208,6 +210,7 @@ namespace BitMeasurementManagerLib
/// <param name="shallWePerformVerboseParserLogging"></param>
public BitMsgParser(BitMessageIDs messageIds, bool shallWePerformVerboseParserLogging)
{
_logger = LogManager.GetCurrentClassLogger();
// Using it to hold onto valid message ids and the size
_messageIdToSizeMap = messageIds;
_shallWePerformVerboseParserLogging = shallWePerformVerboseParserLogging;

View File

@@ -15,12 +15,11 @@ GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using Raytheon.Instruments;
using Raytheon.Common;
using System;
using System.Threading;
using ChillerCartMeasurementManagerLib;
using NLog;
using Raytheon.Instruments;
namespace MeasurementManagerLib
{
@@ -165,15 +164,6 @@ namespace MeasurementManagerLib
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
}
}
try
{
ErrorLogger.Instance().Dispose();
}
catch (Exception)
{
// nothing to do
}
}
}

View File

@@ -16,10 +16,11 @@ UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using System;
using System.Threading;
using Raytheon.Common;
using System.IO;
using System.Threading;
using MeasurementManagerLib;
using NLog;
using Raytheon.Common;
namespace ChillerCartMeasurementManagerLib
{
@@ -37,6 +38,7 @@ namespace ChillerCartMeasurementManagerLib
private readonly ChillerCartMeasurementManager.ChillerDelegate _callback;
private readonly string _logFileName;
private readonly int _threadRestTimeMs;
private readonly ILogger _logger;
#endregion
#region PrivateFunctions
@@ -55,25 +57,11 @@ namespace ChillerCartMeasurementManagerLib
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
try
if (disposing)
{
if (disposing)
{
_fileWriter.Dispose();
_fileWriter.Dispose();
_quitEvent.Dispose();
}
}
catch (Exception err)
{
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
}
_quitEvent.Dispose();
}
}
#endregion
@@ -88,6 +76,8 @@ namespace ChillerCartMeasurementManagerLib
/// <param name="callback"></param>
public ChillerDataLogWorker(ChillerCartMeasurementManager controller, string logFileName, int threadRestTimeMs, ChillerCartMeasurementManager.ChillerDelegate callback)
{
_logger = LogManager.GetCurrentClassLogger();
_threadQuitControl = false;
_quitEvent = new AutoResetEvent(false);
@@ -123,23 +113,9 @@ namespace ChillerCartMeasurementManagerLib
/// </summary>
public void Dispose()
{
try
{
Dispose(true);
Dispose(true);
GC.SuppressFinalize(this);
}
catch (Exception err)
{
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>
@@ -176,7 +152,6 @@ namespace ChillerCartMeasurementManagerLib
catch (Exception e)
{
string msg = e.Message;
ErrorLogger.Instance().Write(msg + "\r\n" + e.StackTrace, ErrorLogger.LogLevel.ERROR);
_fileWriter.WriteLine(Util.GetTimeString() + ", " + msg);
@@ -184,12 +159,9 @@ namespace ChillerCartMeasurementManagerLib
_callback?.Invoke(-1, -1, -1);
}
}
ErrorLogger.Instance().Write("ChillerCartDataLogWorker::DoWork() - exiting", ErrorLogger.LogLevel.INFO);
}
catch (Exception err)
catch (Exception)
{
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
//Send error code to callback if valid
_callback?.Invoke(-1, -1, -1);
}

View File

@@ -16,10 +16,11 @@ UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using System;
using System.Threading;
using Raytheon.Common;
using System.IO;
using System.Threading;
using MeasurementManagerLib;
using NLog;
using Raytheon.Common;
namespace ChillerCartMeasurementManagerLib
{
@@ -37,6 +38,7 @@ namespace ChillerCartMeasurementManagerLib
private readonly ChillerCartMeasurementManager.FlowMeterDelegate _callback;
private readonly string _logFileName;
private readonly int _threadRestTimeMs;
private readonly ILogger _logger;
#endregion
#region PrivateFunctions
@@ -56,25 +58,11 @@ namespace ChillerCartMeasurementManagerLib
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
try
if (disposing)
{
if (disposing)
{
_fileWriter.Dispose();
_fileWriter.Dispose();
_quitEvent.Dispose();
}
}
catch (Exception err)
{
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
}
_quitEvent.Dispose();
}
}
#endregion
@@ -89,6 +77,8 @@ namespace ChillerCartMeasurementManagerLib
/// <param name="callback"></param>
public FlowMeterDataLogWorker(ChillerCartMeasurementManager controller, string logFileName, int threadRestTimeMs, ChillerCartMeasurementManager.FlowMeterDelegate callback)
{
_logger = LogManager.GetCurrentClassLogger();
_threadQuitControl = false;
_quitEvent = new AutoResetEvent(false);
@@ -122,23 +112,9 @@ namespace ChillerCartMeasurementManagerLib
/// </summary>
public void Dispose()
{
try
{
Dispose(true);
Dispose(true);
GC.SuppressFinalize(this);
}
catch (Exception err)
{
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>
@@ -175,8 +151,6 @@ namespace ChillerCartMeasurementManagerLib
{
string msg = e.Message;
ErrorLogger.Instance().Write(msg + "\r\n" + e.StackTrace, ErrorLogger.LogLevel.ERROR);
_fileWriter.WriteLine(Util.GetTimeString() + ", " + msg);
//Invoke the callback if valid
@@ -186,12 +160,9 @@ namespace ChillerCartMeasurementManagerLib
}
}
}
ErrorLogger.Instance().Write("FlowMeterDataLogWorker::DoWork() - exiting", ErrorLogger.LogLevel.INFO);
}
catch (Exception err)
catch (Exception)
{
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
//Send error code to callback if valid
if (_callback != null && _threadQuitControl == false)
{

View File

@@ -16,10 +16,11 @@ UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using System;
using System.Threading;
using Raytheon.Common;
using System.IO;
using System.Threading;
using MeasurementManagerLib;
using NLog;
using Raytheon.Common;
namespace ChillerCartMeasurementManagerLib
{
@@ -37,6 +38,7 @@ namespace ChillerCartMeasurementManagerLib
private readonly ChillerCartMeasurementManager.TemperatureDelegate _callback;
private readonly string _logFileName;
private readonly int _threadRestTimeMs;
private readonly ILogger _logger;
#endregion
@@ -57,25 +59,11 @@ namespace ChillerCartMeasurementManagerLib
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
try
if (disposing)
{
if (disposing)
{
_fileWriter.Dispose();
_fileWriter.Dispose();
_quitEvent.Dispose();
}
}
catch (Exception err)
{
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
}
_quitEvent.Dispose();
}
}
#endregion
@@ -91,6 +79,8 @@ namespace ChillerCartMeasurementManagerLib
/// <param name="callback"></param>
public TempDataLogWorker(ChillerCartMeasurementManager controller, string logFileName, int threadRestTimeMs, ChillerCartMeasurementManager.TemperatureDelegate callback)
{
_logger = LogManager.GetCurrentClassLogger();
_threadQuitControl = false;
_quitEvent = new AutoResetEvent(false);
@@ -125,23 +115,9 @@ namespace ChillerCartMeasurementManagerLib
/// </summary>
public void Dispose()
{
try
{
Dispose(true);
Dispose(true);
GC.SuppressFinalize(this);
}
catch (Exception err)
{
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>
@@ -177,7 +153,6 @@ namespace ChillerCartMeasurementManagerLib
catch (Exception e)
{
string msg = e.Message;
ErrorLogger.Instance().Write(msg + "\r\n" + e.StackTrace, ErrorLogger.LogLevel.ERROR);
_fileWriter.WriteLine(Util.GetTimeString() + ", " + msg);
@@ -185,12 +160,9 @@ namespace ChillerCartMeasurementManagerLib
_callback?.Invoke(-1, -1);
}
}
ErrorLogger.Instance().Write("TempDataLogWorker::DoWork() - exiting", ErrorLogger.LogLevel.INFO);
}
catch (Exception err)
catch (Exception)
{
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
//Send error code to callback if valid
_callback(-1, -1);
}

View File

@@ -0,0 +1,268 @@
// **********************************************************************************************************
// BitGenSoftMeasurementManager.cs
// 7/28/2022
// 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.Linq;
using System.Xml.XPath;
using NLog;
using Raytheon.Common;
using Raytheon.Common.Coe;
using Raytheon.Instruments;
namespace MeasurementManagerLib
{
/// <summary>
/// COE Measurement Manager class
/// </summary>
public class CoeMeasurementManager : IDisposable
{
private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
private readonly Dictionary<string, CoeComm> _coeNodes = new Dictionary<string, CoeComm>();
private readonly IInstrumentManager _instrumentManager;
public int CheckForMessageIntervalMs { get; private set; }
/// <summary>
/// constructor that will create a list of BIT instruments
/// </summary>
/// <param name="instrumentManager"></param>
/// <param name="switchMeasurementManagerConfigFullPath"></param>
public CoeMeasurementManager(IInstrumentManager instrumentManager, string coeMeasurementManagerConfigFullPath)
{
try
{
_instrumentManager = instrumentManager;
ConfigurationFile configurationFile = new ConfigurationFile(coeMeasurementManagerConfigFullPath);
CheckForMessageIntervalMs = 10;
if (Int32.TryParse(configurationFile.ReadValue("GENERAL", "CheckForMessageIntervalMs"), out int val))
{
CheckForMessageIntervalMs = val;
}
ICollection<object> coeNodeList = _instrumentManager.GetInstruments(typeof(CoeComm));
foreach (CoeComm node in coeNodeList)
{
_coeNodes.Add(node.Name, node);
}
}
catch (Exception)
{
throw;
}
}
~CoeMeasurementManager()
{
_logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() ...");
foreach (var node in _coeNodes)
{
try
{
CoeComm coeNode = node.Value;
coeNode.Shutdown();
}
catch { }
}
}
/// <summary>
/// Get XML Docs
/// </summary>
public object GetXmlDocs(string coeDevice)
{
return _coeNodes[coeDevice].GetXmlDocs();
}
/// <summary>
/// Create a message
/// </summary>
public Message CreateMessage(string coeDevice, string messageName)
{
Message msg = null;
MessageXmlDocument msgXmlDocument = null;
Dictionary<string, MessageXmlDocument> xmlDocs = new Dictionary<string, MessageXmlDocument>();
var xmlDocObject = GetXmlDocs(coeDevice);
if (xmlDocObject != null && xmlDocObject.GetType() == xmlDocs.GetType())
{
xmlDocs = (Dictionary<string, MessageXmlDocument>)xmlDocObject;
foreach (KeyValuePair<string, MessageXmlDocument> item in xmlDocs)
{
XPathNavigator Node = xmlDocs[item.Key].CreateNavigator();
XPathNodeIterator Nodeset = Node.Select("interface/message/name");
while (Nodeset.MoveNext())
{
if (String.Equals(Nodeset.Current.Value, messageName, StringComparison.OrdinalIgnoreCase))
{
msgXmlDocument = item.Value;
break;
}
}
if (msgXmlDocument != null)
break;
}
}
if (msgXmlDocument != null)
{
msg = new Message(messageName, msgXmlDocument, _coeNodes[coeDevice].ShallLogMessage(messageName));
msg.Default();
}
return msg;
}
/// <summary>
/// initialize COE nodes based on test type
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="testType"></param>
public void InitNodes()
{
foreach (var node in _coeNodes)
{
try
{
CoeComm coeNode = node.Value;
coeNode.Initialize();
coeNode.Open();
}
catch (Exception)
{
throw;
}
}
}
/// <summary>
/// close all connections
/// </summary>
/// <exception cref="NotImplementedException"></exception>
public void Dispose()
{
foreach (var coeNode in _coeNodes)
{
coeNode.Value?.Shutdown();
}
}
/// <summary>
/// Send message using the first available device
/// </summary>
/// <param name="messageId"></param>
/// <param name="timeoutInMs"></param>
/// <param name="messageParams"></param>
/// <returns></returns>
public bool SendMessage(string messageId, IEnumerable<KeyValuePair<string, string>> messageParams = null)
{
if (_coeNodes.Any())
{
CoeComm coeNode = _coeNodes.First().Value;
return coeNode.SendMessage(messageId, messageParams);
}
else
{
throw new Exception($"Unable to locate COE node. No nodes defined");
}
}
/// <summary>
/// Send message from a particular device
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="messageId"></param>
/// <param name="timeoutInMs"></param>
/// <param name="messageParams"></param>
/// <returns></returns>
public bool SendMessage(string instrumentName, string messageId, IEnumerable<KeyValuePair<string, string>> messageParams = null)
{
if (_coeNodes.ContainsKey(instrumentName))
{
return _coeNodes[instrumentName].SendMessage(messageId, messageParams);
}
else
{
throw new Exception($"Unable to locate COE node {instrumentName}");
}
}
/// <summary>
/// Get subscribed message from UUT using the first device
/// </summary>
/// <param name="messageId"></param>
/// <returns></returns>
public CoeResponseMsgData GetNextResponseInQueue(string messageId)
{
if (_coeNodes.Any())
{
CoeComm coeNode = _coeNodes.First().Value;
return coeNode.GetNextResponseInQueue(messageId);
}
else
return null;
}
/// <summary>
/// Get subscribed message from UUT from a particular device
/// </summary>
/// <param name="instrumentName"></param>
/// <param name="messageId"></param>
/// <returns></returns>
public CoeResponseMsgData GetNextResponseInQueue(string instrumentName, string messageId)
{
return _coeNodes.ContainsKey(instrumentName) ? _coeNodes[instrumentName].GetNextResponseInQueue(messageId) : null;
}
/// <summary>
/// Clear the queue for a particular response message.
/// This is useful if we have a large size queue and we don't want to dequeue each item to get
/// to the newest item. So we clear the queue first, before trying to get the newest item in the queue
/// </summary>
public void ClearResponseMessageQueue(string instrumentName, string messageId)
{
if (_coeNodes.ContainsKey(instrumentName))
{
_coeNodes[instrumentName].ClearResponseMessageQueue(messageId);
}
}
}
}

View File

@@ -3,9 +3,9 @@
<Import Project="$(SolutionDir)Solution.props" />
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<AssemblyName>BitGenSoftMeasurementManager</AssemblyName>
<AssemblyName>CoeMeasurementManager</AssemblyName>
<Product>Composable Test Software Library</Product>
<Description>Bit GenSoft Measurement Manager</Description>
<Description>COE Measurement Manager</Description>
<OutputType>Library</OutputType>
<!-- Static versioning (Suitable for Development) -->
@@ -16,7 +16,7 @@
<ItemGroup>
<PackageReference Include="NLog" Version="5.0.0" />
<PackageReference Include="Raytheon.Instruments.InstrumentManager.GeneralInstrumentManager" Version="1.5.0" />
<PackageReference Include="Raytheon.Instruments.BIT.Contracts" Version="1.4.0" />
<PackageReference Include="Raytheon.Instruments.CoeComm.Contracts" Version="1.4.0" />
</ItemGroup>
</Project>

View File

@@ -15,26 +15,24 @@ GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using NLog;
using Raytheon.Common;
using Raytheon.Instruments;
using Raytheon.Instruments.GeneralIO;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.Linq;
using System.Threading;
using NLog;
using Raytheon.Instruments;
namespace MeasurementManagerLib
{
/// <summary>
/// This class manages IDIO instruments and provides an abstraction
/// This class manages DIO instruments and provides an abstraction
/// </summary>
public class DioMeasurementManager : IDisposable
{
#region PrivateClassMembers
private SortedDictionary<string, IGeneralIO> _signalNameToObjectMap = new SortedDictionary<string, IGeneralIO>();
{
#region PrivateClassMembers
private SortedDictionary<string, IGeneralIO> _signalNameToDioModuleMap = new SortedDictionary<string, IGeneralIO>();
public Dictionary<string, IODatatypes.DIOChannelInfo> SignalNameToChannelInfoMap { get; private set; }
private static NLog.ILogger _logger;
#endregion
@@ -49,22 +47,27 @@ namespace MeasurementManagerLib
{
_logger = LogManager.GetCurrentClassLogger();
SignalNameToChannelInfoMap = new Dictionary<string, IODatatypes.DIOChannelInfo>();
ICollection<object> dioModuleList = instrumentManager.GetInstruments(typeof(IGeneralIO));
// populate the maps
foreach (IGeneralIO dioModule in dioModuleList)
{
dioModule.Initialize();
List<string> signalNames = dioModule.GetSignalNames();
Dictionary<string, IODatatypes.DIOChannelInfo> signalNameToChannelInfoMap = dioModule.GetAllSignals();
foreach (string signalName in signalNames)
{
if (_signalNameToObjectMap.ContainsKey(signalName.ToUpper()))
// add signal map for this DIO module to master signal map
signalNameToChannelInfoMap.ToList().ForEach(x => SignalNameToChannelInfoMap.Add(x.Key, x.Value));
foreach (KeyValuePair<string, IODatatypes.DIOChannelInfo> item in signalNameToChannelInfoMap)
{
if (_signalNameToDioModuleMap.ContainsKey(item.Key.ToUpper()))
{
throw new Exception("There is more than 1 DIO card that have the same signal name: " + signalName);
throw new Exception("There is more than 1 DIO card that have the same signal name: " + item.Key);
}
_signalNameToObjectMap[signalName.ToUpper()] = dioModule;
_signalNameToDioModuleMap[item.Key.ToUpper()] = dioModule;
}
}
}
@@ -100,7 +103,7 @@ namespace MeasurementManagerLib
/// <returns>0 if the signal is low, 1 if the signal is high</returns>
public IODatatypes.BitState GetInputSignalState(string signalName)
{
return _signalNameToObjectMap[signalName.ToUpper()].GetBitState(signalName);
return _signalNameToDioModuleMap[signalName.ToUpper()].GetBitState(signalName);
}
/// <summary>
@@ -111,7 +114,7 @@ namespace MeasurementManagerLib
/// <param name="timeToSleepMs">number of ms to wait after setting signal</param>
public void SetOutputSignalState(string signalName, IODatatypes.BitState state, uint timeToSleepMs = 100)
{
_signalNameToObjectMap[signalName.ToUpper()].SetBit(signalName, state);
_signalNameToDioModuleMap[signalName.ToUpper()].SetBit(signalName, state);
// wait a bit
Thread.Sleep((int)timeToSleepMs);
@@ -125,40 +128,24 @@ namespace MeasurementManagerLib
/// The Finalizer
/// </summary>
~DioMeasurementManager()
{
Dispose(false);
}
{
Dispose(false);
}
/// <summary>
///
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
foreach (KeyValuePair<string, IGeneralIO> entry in _signalNameToObjectMap)
{
try
{
entry.Value.Shutdown();
}
catch (Exception err)
{
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
}
}
try
{
ErrorLogger.Instance().Dispose();
}
catch (Exception)
{
// nothing to do
}
}
}
#endregion
}
/// <summary>
///
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
foreach (KeyValuePair<string, IGeneralIO> entry in _signalNameToDioModuleMap)
{
entry.Value.Shutdown();
}
}
}
#endregion
}
}

View File

@@ -1,246 +0,0 @@
// UNCLASSIFIED
/*-------------------------------------------------------------------------
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.
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Threading;
using Raytheon.Common;
using System.IO;
using Raytheon.Instruments;
using Raytheon.Instruments.PowerSupply;
namespace MeasurementManagerLib
{
/// <summary>
/// A worker for iterating through each supply in the system, querying its' data, logging it out, and issuing callbacks to the host
/// </summary>
internal class PowerSupplyDataLogWorker : IWorkerInterface
{
#region PrivateClassMembers
private bool _threadQuitControl;
private AutoResetEvent _quitEvent;
private StreamWriter _fileWriter;
private readonly string _logFilePath;
private readonly int _threadRestTimeMs;
private readonly PowerSupplyMeasurementManager.PowerMonitorDelegate _callback;
private readonly PowerSupplyMeasurementManager _controller;
#endregion
#region PrivateFunctions
/// <summary>
/// Finalizer
/// </summary>
~PowerSupplyDataLogWorker()
{
Dispose(false);
}
/// <summary>
/// Release of resources
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
try
{
if (disposing)
{
_fileWriter.Dispose();
_quitEvent.Dispose();
}
}
catch (Exception err)
{
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
}
}
}
#endregion
#region PublicFuctions
/// <summary>
/// The constructor
/// </summary>
/// <param name="controller">The controller for the power supplies</param>
/// <param name="fileName">The file name to log the data to</param>
/// <param name="threadRestTimeMs">The number os ms to rest after each iteration through the loop</param>
/// <param name="callback">The host callback function. If null, no callback is issued</param>
public PowerSupplyDataLogWorker(PowerSupplyMeasurementManager controller, string fileName, int threadRestTimeMs, PowerSupplyMeasurementManager.PowerMonitorDelegate callback)
{
_controller = controller;
// these gets set in SetControlParams
_logFilePath = fileName;
_callback = callback;
_threadRestTimeMs = threadRestTimeMs;
_fileWriter = new StreamWriter(_logFilePath, true);
_threadQuitControl = false;
_quitEvent = new AutoResetEvent(false);
}
/// <summary>
/// Dispose of this object. Needed for releasing thread/comm resources
/// </summary>
public void Dispose()
{
try
{
Dispose(true);
GC.SuppressFinalize(this);
}
catch (Exception err)
{
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
}
}
}
/// <summary>
/// Loops thorugh each supply in the system, queries the status, logs it out and calls the host callback
/// </summary>
public void DoWork()
{
try
{
//Used to handle the labels at the top of the CSV log file generated
const string LOG_PREFIX = "DateTime,Module,Voltage,VoltageSetpoint,Current,IsOutputOn,fault status";
// callback error codes
const int NO_ERROR = 0;
const int ERROR = -1;
List<string> powerModules = _controller.GetPowerModuleList();
_fileWriter.WriteLine(LOG_PREFIX);
while (_threadQuitControl == false)
{
try
{
if (_quitEvent.WaitOne(_threadRestTimeMs))
{
_threadQuitControl = true;
}
else
{
//string callbackData = CALLBACK_PREFIX;
List<PowerMonitorCallbackData> callBackDataList = new List<PowerMonitorCallbackData>();
//get data from each supply
foreach (string powerModule in powerModules)
{
// check for quit event and exit if needed
if (_quitEvent.WaitOne(1) == true)
{
_threadQuitControl = true;
break;
}
PowerData data = _controller.ReadPowerData(powerModule);
PowerMonitorCallbackData callbackData;
callbackData.powerModule = powerModule;
callbackData.voltage = data.Voltage;
callbackData.voltageSetpoint = data.VoltageSetpoint;
callbackData.current = data.Current;
callbackData.outputStatus = data.OutputStatus;
callbackData.ovpocpStatus = data.FaultStatus;
callbackData.overVoltageProtectionValue = data.OverVoltageProtection;
callbackData.overCurrentProtectionValue = data.OverCurrentProtection;
callBackDataList.Add(callbackData);
string log = Util.GetTimeString() + "," + powerModule + "," + Convert.ToString(data.Voltage) + "," + Convert.ToString(data.VoltageSetpoint) + "," + Convert.ToString(data.Current) + "," + Convert.ToString(data.OutputStatus) + "," + Convert.ToString(data.FaultStatus);
// log out the data
_fileWriter.WriteLine(log);
_fileWriter.Flush();
// check for quit event and exit if needed
if (_quitEvent.WaitOne(1) == true)
{
_threadQuitControl = true;
break;
}
}
// At this point our return and log strings are both built, so return back the data string on the callback
if (_callback != null && _threadQuitControl == false && callBackDataList.Count != 0)
{
_callback(callBackDataList, NO_ERROR);
}
}
}
catch (Exception e)
{
string msg = e.Message;
ErrorLogger.Instance().Write(msg + "\r\n" + e.StackTrace, ErrorLogger.LogLevel.ERROR);
_fileWriter.WriteLine(Util.GetTimeString() + ", " + msg);
// if callbacks are enabled, alert the host to the error
if (_callback != null && _threadQuitControl == false)
{
_callback(null, ERROR);
}
}
}
ErrorLogger.Instance().Write("PowerSupplyDataLogWorker::DoWork() - exiting", ErrorLogger.LogLevel.INFO);
}
catch (Exception err)
{
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
}
}
/// <summary>
/// Stops the thread, closes the datalogger and calls move file
/// </summary>
public void QuitWork()
{
_threadQuitControl = true;
_quitEvent.Set();
}
#endregion
}
}

View File

@@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace MeasurementManagerLib
{
public class SpaceChamberLSPSMeasurementManager
public class SpaceChamberLspsMeasurementManager
{
private INetCdfData netCdfData_ = null;
private readonly ILspsChamber lspsChamber_;
@@ -25,7 +25,7 @@ namespace MeasurementManagerLib
/// </summary>
/// <param name="instrumentManager"></param>
/// <param name="deviceName"></param>
public SpaceChamberLSPSMeasurementManager(IInstrumentManager instrumentManager, string lspsChamber, string netCdfData)
public SpaceChamberLspsMeasurementManager(IInstrumentManager instrumentManager, string lspsChamber, string netCdfData)
{
_logger = LogManager.GetCurrentClassLogger();
_logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() method...");