Files
GenericTeProgramLibrary/Source/TSRealLib/HAL/Implementations/BIT/COEComm/coeCSharp/coeMessage.cs
2025-03-13 12:04:22 -07:00

392 lines
16 KiB
C#

// **********************************************************************************************************
// coeMessage.cs
// 6/1/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)
// **********************************************************************************************************
//\\<Unclassified>
//----------------------------------------------------------------------------//
// UNCLASSIFIED //
//----------------------------------------------------------------------------//
//\\<\Unclassified>
//\\<UnlimitedRights>
//----------------------------------------------------------------------------//
// Copyright %(copyright)s Raytheon Company. //
// This software was developed pursuant to Contract Number %(contractNumber)s //
// with the U.S. government. The U.S. government's rights in and to this //
// copyrighted software are as specified in DFARS 252.227-7014 which was made //
// part of the above contract. //
//----------------------------------------------------------------------------//
//\\<\UnlimitedRights>
//\\<EximUndetermined>
//----------------------------------------------------------------------------//
// WARNING - This document contains technical data and / or technology 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. //
// Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. //
// Section 730-774). This document CANNOT be exported (e.g., provided to a //
// supplier outside of the United States) or disclosed to a Non-U.S. Person, //
// wherever located, until a final jurisdiction and classification //
// determination has been completed and approved by Raytheon, and any //
// required U.S. Government approvals have been obtained. Violations are //
// subject to severe criminal penalties. //
//----------------------------------------------------------------------------//
//\\<\EximUndetermined>
using System;
using System.Runtime.InteropServices;
namespace Raytheon.Instruments.coeCSharp
{
/// <summary>
/// Message Attributes
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class MessageOffset : Attribute
{
readonly uint _bufferOffset;
public MessageOffset(uint bufferOffset)
{
_bufferOffset = bufferOffset;
}
public uint Offset
{
get { return _bufferOffset; }
}
}
[AttributeUsage(AttributeTargets.All)]
public class MessageSize : Attribute
{
readonly int _bufferSize;
public MessageSize(int bufferSize)
{
_bufferSize = bufferSize;
}
public int Size
{
get { return _bufferSize; }
}
}
/// <summary>
/// Message: base class
/// </summary>
public abstract class coeMessage : IDisposable
{
#region DLLImports
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_Create")]
private static extern IntPtr OE_Message_Create(IntPtr Buffer_Address,
uint Size,
int Create_Shared,
IntPtr ApplicationContext,
out coe.Status Status);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_Delete")]
private static extern coe.Status OE_Message_Delete(IntPtr Handle);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_set_Priority")]
private static extern coe.Status OE_Message_set_Priority(IntPtr Handle,
int Priority);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_get_Priority")]
private static extern int OE_Message_get_Priority(IntPtr Handle,
out coe.Status Status);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_set_Domain")]
private static extern coe.Status OE_Message_set_Domain(IntPtr Handle,
uint Domain);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_get_Domain")]
private static extern uint OE_Message_get_Domain(IntPtr Handle,
out coe.Status Status);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_set_Label")]
private static extern coe.Status OE_Message_set_Label(IntPtr Handle,
uint Label);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_get_Label")]
private static extern uint OE_Message_get_Label(IntPtr Handle,
out coe.Status Status);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_set_Data_Size")]
private static extern coe.Status OE_Message_set_Data_Size(IntPtr Handle,
uint Size);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_get_Data_Size")]
private static extern uint OE_Message_get_Data_Size(IntPtr Handle,
out coe.Status Status);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_get_Transmit_Timestamp")]
private static extern coe.Status OE_Message_get_Transmit_Timestamp(IntPtr Handle,
out ulong Seconds,
out uint Fraction_Of_Second);
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Message_get_Receive_Timestamp")]
private static extern coe.Status OE_Message_get_Receive_Timestamp(IntPtr Handle,
out ulong Seconds,
out uint Fraction_Of_Second);
#endregion
private bool disposed = false;
protected IntPtr m_Handle = IntPtr.Zero;
protected IntPtr m_UnmanagedBuffer = IntPtr.Zero;
protected int m_UnmanagedBufferSize = 0;
protected int m_Size;
protected byte[] m_Buffer;
//
// The following routines are provided for testing and access purposes
//
public IntPtr GetUnmanagedBuffer() { return m_UnmanagedBuffer; }
public byte[] GetManagedBuffer() { return m_Buffer; }
protected coeMessage(int size) : this(size, 0) { }
protected coeMessage(int size, uint label) : this(size, label, 0) { }
protected coeMessage(int size, uint label, int priority)
{
if (size == 0)
{
size = getPayloadSize();
}
if (size > 0)
{
m_Buffer = new byte[size];
m_UnmanagedBuffer = Marshal.AllocHGlobal((int)size);
m_UnmanagedBufferSize = (int)size;
}
m_Handle = OE_Message_Create(m_UnmanagedBuffer, (uint)size, coe.OE_FALSE, IntPtr.Zero, out coe.Status oe_status);
if (oe_status != coe.Status.SUCCESS)
{
m_Handle = IntPtr.Zero;
throw new Exception("Unable to create OE_Message. Error = " + oe_status);
}
else
{
m_Size = size;
// The message was created successfully
oe_status = OE_Message_set_Priority(m_Handle, priority);
if (oe_status != coe.Status.SUCCESS)
{
throw new Exception("Unable to set message priority to " + priority + ". Error = " + oe_status);
}
oe_status = OE_Message_set_Label(m_Handle, label);
if (oe_status != coe.Status.SUCCESS)
{
throw new Exception("Unable to set message priority to " + label + ". Error = " + oe_status);
}
}
}
~coeMessage()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (disposed) return;
if (disposing)
{
}
if (m_UnmanagedBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(m_UnmanagedBuffer);
m_UnmanagedBuffer = IntPtr.Zero;
}
if (m_Handle != IntPtr.Zero)
{
OE_Message_Delete(m_Handle);
m_Handle = IntPtr.Zero;
}
disposed = true;
}
internal IntPtr Handle
{
get { return m_Handle; }
}
public uint Domain
{
get
{
return OE_Message_get_Domain(m_Handle, out coe.Status status);
}
set
{
coe.Status status = OE_Message_set_Domain(m_Handle, value);
}
}
public uint Label
{
get
{
return OE_Message_get_Label(m_Handle, out coe.Status status);
}
set
{
coe.Status status = OE_Message_set_Label(m_Handle, value);
}
}
public int Priority
{
get
{
return OE_Message_get_Priority(m_Handle, out coe.Status status);
}
set
{
coe.Status status = OE_Message_set_Priority(m_Handle, value);
}
}
public uint Size
{
get
{
return OE_Message_get_Data_Size(m_Handle, out coe.Status status);
}
set
{
coe.Status status = OE_Message_set_Data_Size(m_Handle, value);
}
}
public int BufferSize
{
get
{
return m_UnmanagedBufferSize;
}
set
{
if (value > m_UnmanagedBufferSize)
{
uint savedDomain = Domain;
uint savedLabel = Label;
int savedPriority = Priority;
uint savedSize = Size;
if (m_UnmanagedBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(m_UnmanagedBuffer);
m_UnmanagedBuffer = IntPtr.Zero;
}
if (m_Handle != IntPtr.Zero)
{
OE_Message_Delete(m_Handle);
m_Handle = IntPtr.Zero;
}
m_Buffer = new byte[value];
m_UnmanagedBuffer = Marshal.AllocHGlobal((int)value);
m_UnmanagedBufferSize = (int)value;
m_Handle = OE_Message_Create(m_UnmanagedBuffer, (uint)value, coe.OE_FALSE, IntPtr.Zero, out coe.Status oe_status);
m_Size = value;
Domain = savedDomain;
Label = savedLabel;
Priority = savedPriority;
Size = savedSize;
}
}
}
public void GetSendTime(out ulong Seconds, out uint FractionOfSecond)
{
var status = OE_Message_get_Transmit_Timestamp(m_Handle, out ulong seconds, out uint fractionOfSecond);
Seconds = seconds;
FractionOfSecond = fractionOfSecond;
}
public void GetReceiveTime(out ulong Seconds, out uint FractionOfSecond)
{
var status = OE_Message_get_Receive_Timestamp(m_Handle, out ulong seconds, out uint fractionOfSecond);
Seconds = seconds;
FractionOfSecond = fractionOfSecond;
}
abstract public void Serialize();
abstract public void Deserialize();
// Serialization/Deserialization support
private void alignIndex(ref int dataBufferIndex,
int alignment)
{
int indexMisalignment = dataBufferIndex % alignment;
if (indexMisalignment > 0)
{
dataBufferIndex += alignment - indexMisalignment;
}
}
public int getPayloadSize()
{
int size = 0;
return serializationSupport.getPayloadSize(this, GetType(), ref size);
}
protected void copyToMessageBuffer(byte[] data)
{
Marshal.Copy(data, 0, m_UnmanagedBuffer, data.Length);
}
protected byte[] copyFromMessageBuffer()
{
byte[] data = null;
uint dataSize = OE_Message_get_Data_Size(m_Handle, out coe.Status status);
if (dataSize > 0)
{
Marshal.Copy(m_UnmanagedBuffer, m_Buffer, 0, (int)dataSize);
data = m_Buffer;
}
return data;
}
}
}
//\\<Unclassified>
//----------------------------------------------------------------------------//
// UNCLASSIFIED //
//----------------------------------------------------------------------------//
//\\<\Unclassified>