Big changes

This commit is contained in:
Duc
2025-03-13 12:04:22 -07:00
parent c689fcb7f9
commit ffa9905494
748 changed files with 199255 additions and 3743 deletions

View File

@@ -0,0 +1,389 @@
// 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 Raytheon.Common;
using System.IO;
using System.Collections.Generic;
namespace BitMeasurementManagerLib
{
/// <summary>
/// Handles received messages from the UUT
/// </summary>
internal class BitMsgHandler : MsgDevice
{
#region PublicClassMembers
public enum ErrorCodes
{
NO_ERROR = 0,
UNKNOWN_MSG_ID = 1
};
#endregion
#region PrivateClassMembers
private static object _syncObj = new Object();
private BinaryWriter _binWriter;
private StreamWriter _asciiWriter;
private MeasurementManagerLib.BitMeasurementManager.MessageReceivedDelegate _callback;
private SortedDictionary<uint, bool> _callbackControl;
private readonly BitMessageIDs _messageIds;
private readonly bool _shallWeLogOutgoingBinData;
private readonly bool _shallWeLogOutgoingAsciiData;
private readonly bool _shallWeLogIncomingBinData;
private readonly bool _shallWeLogIncomingAsciiData;
private readonly uint _bitmask;
private readonly string _crcFieldName;
#endregion
#region PublicFuctions
/// <summary>
/// The constructor
/// </summary>
/// <param name="callback">Host callback for received messages</param>
/// <param name="bufferSize">The size of the internal parsing buffer</param>
/// <param name="binLogFileName">THe binary file log name</param>
/// <param name="asciiLogFileName">The ascii file log name</param>
/// <param name="shallWeLogOutgoingBinData"></param>
/// <param name="shallWeLogOutgoingAsciiData"></param>
/// <param name="shallWeLogIncomingBinData"></param>
/// <param name="shallWeLogIncomingAsciiData"></param>
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)
{
_messageIds = messageIds;
// hold onto the callback
_callback = callback;
_shallWeLogOutgoingBinData = shallWeLogOutgoingBinData;
_shallWeLogOutgoingAsciiData = shallWeLogOutgoingAsciiData;
_shallWeLogIncomingBinData = shallWeLogIncomingBinData;
_shallWeLogIncomingAsciiData = shallWeLogIncomingAsciiData;
_bitmask = crcBitmask;
_crcFieldName = crcFieldName;
// set all messages to not issue a callback. Host can change it as necessary
_callbackControl = new SortedDictionary<uint, bool>();
List<uint> msgIds = messageIds.GetAllIds();
foreach (uint id in msgIds)
{
_callbackControl[id] = false;
}
_binWriter = null;
_asciiWriter = null;
SetLogFileNames(binLogFileName, asciiLogFileName);
// set the callback
base.SetCompleteMessageCallback(this.OnCompleteMessage);
}
/// <summary>
/// The finalizer
/// </summary>
~BitMsgHandler()
{
Dispose(false);
}
/// <summary>
/// Add data to the buffer. For this Handler, we are just going to log out the data
/// </summary>
/// <param name="data">The data to add</param>
/// <param name="numBytes">The number of bytes in the data buffer</param>
public override void AddData(byte[] data, uint numBytes)
{
// log out raw data and add to buffer for processing
lock (_syncObj)
{
WriteIncomingDataToLog(data, (int)numBytes);
AddToBuffer(data, numBytes);
}
}
/// <summary>
/// Clear all data from the buffer. We are just logging out data, no buffer to clear
/// </summary>
public void ClearData()
{
ClearBuffer();
}
/// <summary>
///
/// </summary>
public void CloseDataFiles()
{
lock (_syncObj)
{
if (_binWriter != null)
{
_binWriter.Close();
_binWriter.Dispose();
_binWriter = null;
}
if (_asciiWriter != null)
{
_asciiWriter.Close();
_asciiWriter.Dispose();
_asciiWriter = null;
}
}
}
/// <summary>
/// The callback function for when a complete message is received. We are just logging out data, no messages to handle.
/// </summary>
/// <param name="msgId">The id of the message received</param>
/// <param name="pData">The data for the message received</param>
/// <param name="numBytes">the number of bytes in pData</param>
/// <param name="errorCode">The parser error code</param>
unsafe public void OnCompleteMessage(uint msgId, IntPtr pData, uint numBytes, uint errorCode)
{
try
{
if (_messageIds.ContainsId(msgId) == false)
{
ErrorLogger.Instance().Write("BitMsgHandler::OnCompleteMessage() - detected unknown msg id: " + msgId.ToString());
}
else
{
// create the msg and parse it
BitConfigurableMessage msg = BitConfigurableMessageFactory.Instance().RetreiveMessage(msgId);
msg.Parse(pData);
int callbackValue = 0;
// check for crc errors
if (_bitmask != 0x00000000)
{
uint rawStatus = msg.GetDataItemByName<uint>(_crcFieldName);
var maskedStatus = rawStatus & _bitmask;
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}");
callbackValue = -1;
}
}
// get the ascii msg
string asciiMessage = msg.ToString();
// log it
WriteIncomingDataToLog(asciiMessage);
// add the message to the buffer in case the host wants it
BitMsgRxBuffer.Instance().AddMsg(msg, false);
// issue callback if requested
uint id = msg.GetMessageId();
if (_callbackControl[id] == true)
{
_callback(id, msg.GetEntireMsgLength(), callbackValue);
}
// some debugging
ErrorLogger.Instance().Write("BitMsgHandler::HandleMsg() - added message " + msgId.ToString("X8") + " to buffer ", ErrorLogger.LogLevel.INFO);
}
}
catch (Exception err)
{
//@@@ need to flow error to the host
ErrorLogger.Instance().Write("BitMsgHandler::HandleMsg() - caught an error: " + err.Message, ErrorLogger.LogLevel.ERROR);
}
}
/// <summary>
/// Subscribe a callback to a specific msg
/// </summary>
/// <param name="msgId">The msg to subscribe to</param>
/// <param name="shallWeIssueCallback">true to get the callbacks, false to not get them</param>
public void SetCallbackControl(uint msgId, bool shallWeIssueCallback)
{
_callbackControl[msgId] = shallWeIssueCallback;
}
/// <summary>
/// Set the data file log names. Closes the previous file and opens a new one
/// </summary>
/// <param name="binLogFileName">The binary file log name</param>
/// <param name="asciiLogFileName">The ascii file log name</param>
public void SetLogFileNames(string binFileName, string asciiFileName)
{
lock (_syncObj)
{
if (_binWriter != null)
{
_binWriter.Close();
}
_binWriter = new BinaryWriter(File.Open(binFileName, FileMode.Create));
if (_asciiWriter != null)
{
_asciiWriter.Close();
}
_asciiWriter = new StreamWriter(File.Open(asciiFileName, FileMode.Create));
}
}
/// <summary>
/// Stops the message handler
/// </summary>
public void QuitHandler()
{
base.QuitThread();
}
/// <summary>
/// Write bin data to a file
/// </summary>
/// <param name="data">The data to write</param>
/// <param name="numBytes">The number of bytes to write</param>
public void WriteIncomingDataToLog(byte[] data, int numBytes)
{
lock (_syncObj)
{
if (_binWriter == null && _shallWeLogIncomingBinData == true)
{
throw new Exception("BitMsgHandler::WriteIncomingDataToLog() - Trying to log bin data before the log file is open");
}
else if (_shallWeLogIncomingBinData == true)
{
// write the data out and flush it for immediate viewing
_binWriter.Write(data, 0, (int)numBytes);
_binWriter.Flush();
}
}
}
/// <summary>
/// Write ascii data to a log file. Prepends a timestamp to the data
/// </summary>
/// <param name="data">The data to write</param>
public void WriteIncomingDataToLog(string data)
{
lock (_syncObj)
{
if (_asciiWriter == null && _shallWeLogIncomingAsciiData == true)
{
throw new Exception("BitMsgHandler::WriteIncomingDataToLog() - Trying to log ascii data before the log file is open");
}
else if (_shallWeLogIncomingAsciiData == true)
{
string timestamp = "Time: " + Util.GetTimeString();
string dataToLog = timestamp + "\r\n" + data;
_asciiWriter.WriteLine(dataToLog);
_asciiWriter.Flush();
}
}
}
/// <summary>
/// Write bin data to a file
/// </summary>
/// <param name="data">The data to write</param>
/// <param name="numBytes">The number of bytes to write</param>
public void WriteOutgoingDataToLog(byte[] data, int numBytes)
{
lock (_syncObj)
{
if (_binWriter == null && _shallWeLogOutgoingBinData == true)
{
throw new Exception("BitMsgHandler::WriteOutgoingDataToLog() - Trying to log bin data before the log file is open");
}
else if (_shallWeLogOutgoingBinData == true)
{
_binWriter.Write(data, 0, numBytes);
_binWriter.Flush();
}
}
}
/// <summary>
/// Write ascii data to a log file. Prepends a timestamp to the data
/// </summary>
/// <param name="data">The data to write</param>
public void WriteOutgoingDataToLog(string data)
{
lock (_syncObj)
{
if (_asciiWriter == null && _shallWeLogOutgoingAsciiData == true)
{
throw new Exception("BitMsgHandler::WriteOutgoingDataToLog() - Trying to log ascii data before the log file is open");
}
else if (_shallWeLogOutgoingAsciiData == true)
{
string timestamp = "Time: " + Util.GetTimeString();
string dataToLog = timestamp + "\r\n" + data;
_asciiWriter.WriteLine(dataToLog);
_asciiWriter.Flush();
}
}
}
/// <summary>
///
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
try
{
// call the parent dispose first
base.Dispose(disposing);
// now dispose of our resources
if (_binWriter != null)
{
_binWriter.Dispose();
}
if (_asciiWriter != null)
{
_asciiWriter.Dispose();
}
}
catch (Exception err)
{
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,234 @@
// 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 Raytheon.Common;
using System;
namespace BitMeasurementManagerLib
{
/// <summary>
/// Parses out messages that go between the VRSUI and the Test Controller
/// This class is meant to be used by both the test controller and the VRSUI, so it parses out messages that target either of those systems
/// </summary>
internal class BitMsgParser : IMsgParser
{
#region PublicClassMembers
#endregion
#region PrivateClassMembers
private readonly BitMessageIDs _messageIdToSizeMap;
private BitMsgEndianControl.HeaderDef _headerDef;
private readonly bool _shallWePerformVerboseParserLogging;
#endregion
#region PrivateFuctions
/// <summary>
///
/// </summary>
/// <param name="pData"></param>
/// <param name="numBytesInPdata"></param>
/// <param name="bytesToRemove"></param>
/// <param name="messageId"></param>
/// <param name="errorCode"></param>
/// <returns></returns>
private bool HandleData(IntPtr pData, uint numBytesInPdata, ref uint bytesToRemove, ref uint messageId, ref uint errorCode)
{
// check to see if we have enough data for at least a standard header
uint payloadHeaderSize = BitConfigurableMessageHeader.GetHeaderSize();
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);
bytesToRemove = 0;
return false;
}
uint id = BitConfigurableMessageHeader.GetMessageId(pData, numBytesInPdata);
bool isSecondaryIdUsed = false;
uint secondaryId = BitConfigurableMessageHeader.GetSecondaryMessageId(pData, numBytesInPdata, out isSecondaryIdUsed);
// check that this is an expected message
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);
bytesToRemove = numBytesToRemove;
return false;
}
// look at secondary ID if applicable
if (isSecondaryIdUsed == true)
{
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);
bytesToRemove = numBytesToRemove;
return false;
}
}
uint msgSize = _messageIdToSizeMap.GetSize(id);
// 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);
// need to wait for more data
bytesToRemove = 0;
return false;
}
// everything has checked out, set the return params
bytesToRemove = msgSize;
if (_shallWePerformVerboseParserLogging == true)
{
ErrorLogger.Instance().Write("BitMsgParser::HandleData() - found msg: " + id.ToString() + " which has " + msgSize.ToString() + " bytes", ErrorLogger.LogLevel.INFO);
}
messageId = id;
return true;
}
/// <summary>
///
/// </summary>
/// <param name="pData"></param>
/// <param name="numBytesInPdata"></param>
/// <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);
// increment pData by 1
pData = IntPtr.Add(pData, 1);
// keep track of how many bytes to remove
uint bytesToRemove = 1;
// update bytes remaining
numBytesInPdata = numBytesInPdata - 1;
bool didWeFindMsg = false;
while (didWeFindMsg == false)
{
// check to see if we have enough data for at least a standard header
uint payloadHeaderSize = BitConfigurableMessageHeader.GetHeaderSize();
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);
break;
}
uint id = BitConfigurableMessageHeader.GetMessageId(pData, numBytesInPdata);
bool isSecondaryIdUsed = false;
uint secondaryId = BitConfigurableMessageHeader.GetSecondaryMessageId(pData, numBytesInPdata, out isSecondaryIdUsed);
// check that this is an expected message
if (_messageIdToSizeMap.ContainsId(id) == false)
{
// need to keep looking
// increment pData by 1
pData = IntPtr.Add(pData, 1);
// keep track of how many bytes to remove
bytesToRemove++;
// update bytes remaining
numBytesInPdata--;
}
else
{
// look at secondary ID if applicable
if (isSecondaryIdUsed == true)
{
if (secondaryId != _headerDef.secondaryMsgIdExpectedValue)
{
// need to keep looking
// increment pData by 1
pData = IntPtr.Add(pData, 1);
// keep track of how many bytes to remove
bytesToRemove++;
// update bytes remaining
numBytesInPdata--;
}
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);
break;
}
}
else
{
didWeFindMsg = true;
ErrorLogger.Instance().Write("BitMsgParser::Resync() - Detected message ID: " + id.ToString("X8") + ". Resync complete. Removing " + bytesToRemove.ToString() + " Bytes", ErrorLogger.LogLevel.INFO);
break;
}
}
}
ErrorLogger.Instance().Write("BitMsgParser::Resync() - returning " + bytesToRemove.ToString(), ErrorLogger.LogLevel.INFO);
return bytesToRemove;
}
#endregion
#region PublicFuctions
/// <summary>
///
/// </summary>
/// <param name="messageIds"></param>
/// <param name="shallWePerformVerboseParserLogging"></param>
public BitMsgParser(BitMessageIDs messageIds, bool shallWePerformVerboseParserLogging)
{
// Using it to hold onto valid message ids and the size
_messageIdToSizeMap = messageIds;
_shallWePerformVerboseParserLogging = shallWePerformVerboseParserLogging;
_headerDef = BitMsgEndianControl.Instance().GetHeaderDef();
}
/// <summary>
/// Search the data buffer for the next valid message
/// </summary>
/// <param name="pData">The data buffer to search</param>
/// <param name="numBytesInPdata">The number of bytes in pData</param>
/// <param name="bytesToRemove">The number of bytes to remove from the buffer</param>
/// <param name="messageId">The message id of the message that was found</param>
/// <returns>true if a message was found, false otherwise</returns>
public bool Run(IntPtr pData, uint numBytesInPdata, ref uint bytesToRemove, ref uint messageId, ref uint errorCode)
{
// default error code to 0;
errorCode = 0;
return HandleData(pData, numBytesInPdata, ref bytesToRemove, ref messageId, ref errorCode);
}
#endregion
}
}