238 lines
9.1 KiB
C#
238 lines
9.1 KiB
C#
// 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 NLog;
|
|
using Raytheon.Common;
|
|
|
|
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;
|
|
private readonly ILogger _logger;
|
|
#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)
|
|
{
|
|
_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;
|
|
}
|
|
|
|
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 = "unknown id received: " + id.ToString("X8") + " When resyncing threw away " + numBytesToRemove.ToString() + " Bytes";
|
|
_logger.Warn(msg);
|
|
bytesToRemove = numBytesToRemove;
|
|
return false;
|
|
}
|
|
|
|
// look at secondary ID if applicable
|
|
if (isSecondaryIdUsed == true)
|
|
{
|
|
if (secondaryId != _headerDef.secondaryMsgIdExpectedValue)
|
|
{
|
|
uint numBytesToRemove = Resync(pData, numBytesInPdata);
|
|
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;
|
|
}
|
|
}
|
|
|
|
uint msgSize = _messageIdToSizeMap.GetSize(id);
|
|
|
|
// do we have enough data to make the complete message
|
|
if (numBytesInPdata < msgSize)
|
|
{
|
|
_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;
|
|
}
|
|
|
|
// everything has checked out, set the return params
|
|
bytesToRemove = msgSize;
|
|
|
|
if (_shallWePerformVerboseParserLogging == true)
|
|
{
|
|
_logger.Debug("found msg: " + id.ToString() + " which has " + msgSize.ToString() + " bytes");
|
|
}
|
|
|
|
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)
|
|
{
|
|
_logger.Debug("Begin");
|
|
|
|
// 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)
|
|
{
|
|
_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;
|
|
}
|
|
|
|
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;
|
|
_logger.Debug("Detected message ID: " + id.ToString("X8") + ". Detected Secondary ID: " + secondaryId.ToString("X8") + " Resync complete. Removing " + bytesToRemove.ToString() + " Bytes");
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
didWeFindMsg = true;
|
|
_logger.Debug("Detected message ID: " + id.ToString("X8") + ". Resync complete. Removing " + bytesToRemove.ToString() + " Bytes");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
_logger.Debug("returning " + bytesToRemove.ToString());
|
|
|
|
return bytesToRemove;
|
|
|
|
}
|
|
#endregion
|
|
|
|
#region PublicFuctions
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="messageIds"></param>
|
|
/// <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;
|
|
_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
|
|
}
|
|
}
|