Big changes
This commit is contained in:
@@ -0,0 +1,491 @@
|
||||
// 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 BitMeasurementManagerLib;
|
||||
using Raytheon.Instruments;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using static BitMeasurementManagerLib.BitConfigurableMessageFactory;
|
||||
using NLog;
|
||||
|
||||
namespace MeasurementManagerLib
|
||||
{
|
||||
/// <summary>
|
||||
/// This class interfaces to a host application for the purpose of sending and receiving messages to/from a UUT
|
||||
/// </summary>
|
||||
public class BitMeasurementManager : IDisposable
|
||||
{
|
||||
#region PublicClassMembers
|
||||
/// <summary>
|
||||
/// A delegate for host applications to get notified once a particular message arrives
|
||||
/// </summary>
|
||||
/// <param name="messageId">The message id that was received</param>
|
||||
/// <param name="messageDataLength">The number of bytes in the message</param>
|
||||
/// <param name="errorCode">An error code</param>
|
||||
public delegate void MessageReceivedDelegate(uint messageId, uint messageDataLength, int errorCode);
|
||||
#endregion
|
||||
|
||||
#region PrivateClassMembers
|
||||
private ICommDevice _commNode;
|
||||
private ICommDevice _commDevice;
|
||||
private BitMsgHandler _msgHandler;
|
||||
private BitMessageIDs _messageIds;
|
||||
private uint _readWorkerBufferSize;
|
||||
private uint _readWorkerRestTimeMs;
|
||||
private string _bitResultsFieldName;
|
||||
private static object _syncObj = new Object();
|
||||
|
||||
private static NLog.ILogger _logger;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this object.
|
||||
/// </summary>
|
||||
/// <param name="disposing">True = currently disposing, False = not disposing.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_commNode != null)
|
||||
{
|
||||
_commNode.Shutdown();
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (_msgHandler != null)
|
||||
{
|
||||
_msgHandler.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
_logger?.Error(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write bytes onto an interface
|
||||
/// </summary>
|
||||
/// <param name="message">the bytes to send</param>
|
||||
/// <param name="numBytesToSend">the number of bytes to send</param>
|
||||
private void SendMessage(byte[] message, uint numBytesToSend)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint numBytesSent = 0;
|
||||
|
||||
_msgHandler.WriteOutgoingDataToLog(message, (int)numBytesToSend);
|
||||
|
||||
numBytesSent = _commNode.Write(message, numBytesToSend);
|
||||
|
||||
if (numBytesSent != numBytesToSend)
|
||||
{
|
||||
throw new Exception("Sent " + numBytesSent.ToString() + " bytes, expected to send " + numBytesToSend.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send out a message and wait for a response
|
||||
/// </summary>
|
||||
/// <param name="messageToSend">The message to send</param>
|
||||
/// <param name="timeoutInMs">Timeout in ms</param>
|
||||
/// <returns></returns>
|
||||
private BitConfigurableMessage SendMessageGetRsp(BitConfigurableMessage messageToSend, uint timeoutInMs)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint cmdMessageId = messageToSend.GetMessageId();
|
||||
uint rspMessageId = _messageIds.GetResponseId(cmdMessageId);
|
||||
|
||||
// reset the rsp event
|
||||
BitMsgRxBuffer.Instance().ResetReceiveEvent(rspMessageId);
|
||||
|
||||
// send out the message
|
||||
SendMessage(messageToSend);
|
||||
|
||||
// wait for the response
|
||||
bool didWeGetTheMsg = BitMsgRxBuffer.Instance().WaitForRspMsg(rspMessageId, timeoutInMs);
|
||||
|
||||
if (didWeGetTheMsg == false)
|
||||
{
|
||||
throw new Exception("Did not receive msg: " + rspMessageId.ToString());
|
||||
}
|
||||
|
||||
return GetNewestMessage(rspMessageId);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
public BitMeasurementManager(IInstrumentManager instrumentManager,
|
||||
string measurementDefFile,
|
||||
string comDeviceName,
|
||||
string comNodeName,
|
||||
string binDataLogFilename,
|
||||
string asciiDataLogFileName,
|
||||
MessageReceivedDelegate callback)
|
||||
{
|
||||
const string CONFIGURATION_INI_SECTION_NAME = "CONFIGURATION";
|
||||
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
IniFile ini = new IniFile(measurementDefFile);
|
||||
|
||||
// hold onto the UUT byte order and header def
|
||||
bool shallWeByteSwap = Convert.ToBoolean(ini.ReadValue(CONFIGURATION_INI_SECTION_NAME, "SHALL_WE_BYTE_SWAP"));
|
||||
BitMsgEndianControl.Instance(shallWeByteSwap, ini);
|
||||
|
||||
_bitResultsFieldName = ini.ReadValue(CONFIGURATION_INI_SECTION_NAME, "BIT_RESULTS_FIELD_NAME");
|
||||
|
||||
string messageDefFile = ini.ReadValue(CONFIGURATION_INI_SECTION_NAME, "MESSAGE_DEF_FILE");
|
||||
string messageInpuStr = ini.ReadValue(CONFIGURATION_INI_SECTION_NAME, "MESSAGE_INPUT_TYPE");
|
||||
FactoryType bitMsgFactoryType = (FactoryType)Enum.Parse(typeof(FactoryType), messageInpuStr, true);
|
||||
|
||||
// initialize the BitMessageFactory
|
||||
BitConfigurableMessageFactory.Instance(messageDefFile, bitMsgFactoryType);
|
||||
|
||||
// initialize the Message ID List, set each message size and set the rsp IDs
|
||||
_messageIds = new BitMessageIDs();
|
||||
Dictionary<uint, BitConfigurableMessage> allMessages = BitConfigurableMessageFactory.Instance().RetreiveAllMessages();
|
||||
foreach (var msg in allMessages.Values)
|
||||
{
|
||||
uint messageId = msg.GetMessageId();
|
||||
uint msgRspId = msg.GetMessageRspId();
|
||||
_messageIds.AddId(messageId);
|
||||
|
||||
if (msgRspId != 0xffffffff)
|
||||
{
|
||||
_messageIds.SetRspId(messageId, msgRspId);
|
||||
}
|
||||
|
||||
_messageIds.SetMsgSize(msg.GetMessageId(), msg.GetEntireMsgLength());
|
||||
}
|
||||
|
||||
|
||||
BitMsgRxBuffer.Instance(_messageIds);
|
||||
|
||||
//_isThereHardware = isThereHardware;
|
||||
|
||||
uint parseBufferSize = Convert.ToUInt32(ini.ReadValue(CONFIGURATION_INI_SECTION_NAME, "PARSE_BUFFER_SIZE"));
|
||||
|
||||
bool shallWeLogOutgoingBinData = Convert.ToBoolean(ini.ReadValue("LOGGING", "SHALL_WE_LOG_OUTGOING_BIN"));
|
||||
bool shallWeLogOutgoingAsciiData = Convert.ToBoolean(ini.ReadValue("LOGGING", "SHALL_WE_LOG_OUTGOING_ASCII"));
|
||||
bool shallWeLogIncomingBinData = Convert.ToBoolean(ini.ReadValue("LOGGING", "SHALL_WE_LOG_INCOMING_BIN"));
|
||||
bool shallWeLogIncomingAsciiData = Convert.ToBoolean(ini.ReadValue("LOGGING", "SHALL_WE_LOG_INCOMING__ASCII"));
|
||||
bool shallWeLogParserVerboseInfo = Convert.ToBoolean(ini.ReadValue("LOGGING", "SHALL_WE_LOG_VERBOSE_PARSER_INFO"));
|
||||
|
||||
// get the CRC check info
|
||||
uint crcMask = Convert.ToUInt32(ini.ReadValue("CRC_STATUS", "BITMASK"), 16);
|
||||
string crcFieldName = ini.ReadValue("CRC_STATUS", "CRC_FIELD_LOGICAL_NAME");
|
||||
|
||||
// create the message handler
|
||||
_msgHandler = new BitMsgHandler(_messageIds, callback, parseBufferSize, binDataLogFilename, asciiDataLogFileName, shallWeLogOutgoingBinData, shallWeLogOutgoingAsciiData, shallWeLogIncomingBinData, shallWeLogIncomingAsciiData, crcMask, crcFieldName, shallWeLogParserVerboseInfo);
|
||||
|
||||
// create the communication device
|
||||
_commDevice = instrumentManager.GetInstrument<ICommDevice>(comDeviceName);
|
||||
_commDevice?.Initialize();
|
||||
|
||||
// get the read thread buffer size and thread rate
|
||||
_readWorkerBufferSize = Convert.ToUInt32(ini.ReadValue(CONFIGURATION_INI_SECTION_NAME, "READ_WORKER_BUFFER_SIZE"));
|
||||
_readWorkerRestTimeMs = Convert.ToUInt32(ini.ReadValue(CONFIGURATION_INI_SECTION_NAME, "READ_WORKER_REST_TIME_MS"));
|
||||
|
||||
// create the communication node
|
||||
_commNode = instrumentManager.GetInstrument<ICommDevice>(comNodeName);
|
||||
_commNode?.Initialize();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Finalizer
|
||||
/// </summary>
|
||||
~BitMeasurementManager()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dataToAdd"></param>
|
||||
public void AddDataTestFunction(byte[] dataToAdd)
|
||||
{
|
||||
_msgHandler.AddData(dataToAdd, (uint)dataToAdd.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the data files
|
||||
/// </summary>
|
||||
public void CloseDataFiles()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_msgHandler.CloseDataFiles();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiate a message object. The host configure its parameters prior to sending it
|
||||
/// </summary>
|
||||
/// <param name="messageId">The message id for the message to create</param>
|
||||
/// <returns>The message object</returns>
|
||||
public BitConfigurableMessage CreateMessage(uint messageId)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
BitConfigurableMessage message = BitConfigurableMessageFactory.Instance().RetreiveMessage(messageId);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release the resources
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public TType GetDataItemByName<TType>(BitConfigurableMessage message, string name)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
return message.GetDataItemByName<TType>(name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="dataItemName"></param>
|
||||
/// <returns></returns>
|
||||
public uint GetDataItemByNameUint(BitConfigurableMessage message, string dataItemName)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint dataValue = GetDataItemByName<uint>(message, dataItemName);
|
||||
|
||||
return dataValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a list of message IDs that are supported
|
||||
/// </summary>
|
||||
/// <returns>A list of message Ids</returns>
|
||||
public List<uint> GetSupportedMessages()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
List<uint> mesages = _messageIds.GetAllIds();
|
||||
|
||||
return mesages;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the newest message in the buffer
|
||||
/// </summary>
|
||||
/// <param name="rspMessageId">The message ID to Retrieve</param>
|
||||
/// <param name="shallWeDeleteOthers">True to delete all of the other messages of this ID</param>
|
||||
/// <returns>The retrieved message</returns>
|
||||
public BitConfigurableMessage GetNewestMessage(uint rspMessageId, bool shallWeDeleteOthers = true)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
BitConfigurableMessage messageToReturn = BitMsgRxBuffer.Instance().GetNewestMessage(rspMessageId, shallWeDeleteOthers);
|
||||
|
||||
return messageToReturn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the oldest message in the buffer
|
||||
/// </summary>
|
||||
/// <param name="rspMessageId">The message ID to Retrieve</param>
|
||||
/// <returns>The retrieved message</returns>
|
||||
public BitConfigurableMessage GetOldestMessage(uint rspMessageId)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
BitConfigurableMessage messageToReturn = BitMsgRxBuffer.Instance().GetOldestMessage(rspMessageId);
|
||||
|
||||
return messageToReturn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the communication device, if it is already open, it closes it and then reopens it
|
||||
/// </summary>
|
||||
public void OpenCommDevice()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
// shut it down and reinitialize
|
||||
_commNode.Shutdown();
|
||||
_commNode.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a BIT test, return the test results
|
||||
/// </summary>
|
||||
/// <param name="messageId"></param>
|
||||
/// <param name="timeoutInMs">The number of ms to wait for a response</param>
|
||||
/// <param name="messageParams"></param>
|
||||
/// <returns>The test result register</returns>
|
||||
public uint RunBitTest(uint messageId, uint timeoutInMs, params object[] messageParams)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
BitConfigurableMessage cmdMessage = BitConfigurableMessageFactory.Instance().RetreiveMessage(messageId);
|
||||
if (messageParams.Length > 0)
|
||||
{
|
||||
cmdMessage.SetParams(messageParams);
|
||||
}
|
||||
BitConfigurableMessage rspMessage = SendMessageGetRsp(cmdMessage, timeoutInMs);
|
||||
uint testResult = rspMessage.GetDataItemByName<uint>(_bitResultsFieldName.ToUpper());
|
||||
return testResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="messageId"></param>
|
||||
/// <param name="messageParams"></param>
|
||||
/// <returns></returns>
|
||||
public void SendMessage(uint messageId, params object[] messageParams)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
BitConfigurableMessage cmdMessage = BitConfigurableMessageFactory.Instance().RetreiveMessage(messageId);
|
||||
|
||||
if (messageParams.Length > 0)
|
||||
{
|
||||
cmdMessage.SetParams(messageParams);
|
||||
}
|
||||
|
||||
SendMessage(cmdMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send out a message and wait for a response
|
||||
/// </summary>
|
||||
/// <param name="messageId">The message ID to send</param>
|
||||
/// <param name="messageParams"></param>
|
||||
/// <returns>The response message for the command that was sent</returns>
|
||||
public BitConfigurableMessage SendMessageGetRsp(uint messageId, uint timeoutInMs, params object[] messageParams)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
BitConfigurableMessage cmdMessage = BitConfigurableMessageFactory.Instance().RetreiveMessage(messageId);
|
||||
|
||||
if (messageParams.Length > 0)
|
||||
{
|
||||
cmdMessage.SetParams(messageParams);
|
||||
}
|
||||
|
||||
BitConfigurableMessage rspMessage = SendMessageGetRsp(cmdMessage, timeoutInMs);
|
||||
return rspMessage;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send out a message on the comm interface
|
||||
/// </summary>
|
||||
/// <param name="message">The message to send</param>
|
||||
public void SendMessage(BitConfigurableMessage message)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
// get the ascii msg for logging just before sending
|
||||
string asciiMessage = message.ToString();
|
||||
|
||||
// get the formatted gu message
|
||||
uint messageNumBytes = message.GetEntireMsgLength();
|
||||
|
||||
// allocate an array to hold onto the data that we will send
|
||||
byte[] messageDataToSend = new byte[messageNumBytes];
|
||||
|
||||
// get a pointer to the data
|
||||
GCHandle messagePinnedArray = GCHandle.Alloc(messageDataToSend, GCHandleType.Pinned);
|
||||
IntPtr pMessageData = messagePinnedArray.AddrOfPinnedObject();
|
||||
|
||||
// get the encoded data to send
|
||||
message.Format(pMessageData);
|
||||
|
||||
// free the ptr
|
||||
messagePinnedArray.Free();
|
||||
|
||||
// log the data
|
||||
_msgHandler.WriteOutgoingDataToLog(asciiMessage);
|
||||
|
||||
// send the data
|
||||
SendMessage(messageDataToSend, messageNumBytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable or Disable the Callback for a specific message
|
||||
/// </summary>
|
||||
/// <param name="msgId"></param>
|
||||
/// <param name="shallWeEnableCallback"></param>
|
||||
public void SetCallbackControl(uint msgId, bool shallWeEnableCallback)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_msgHandler.SetCallbackControl(msgId, shallWeEnableCallback);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user