// ********************************************************************************************************** // 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: 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., // 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 CommandParameters { get; set; } = new List(); [XmlArray("CommandResponses")] [XmlArrayItem("BITResponseMsg", Type = typeof(BITResponseMsg))] public List CommandResponses { get; set; } = new List(); [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 ResponseParameters { get; set; } = new List(); /// /// converts one hex parameter string into parameter array /// public void UnfoldHexParameters() { if (!CommandParameters.Any(p => p.ParameterType == ParameterType.P)) return; var paramList = CommandParameters.Where(p => p.ParameterType == ParameterType.P).ToList(); List removeList = new List(); foreach (BITParameter param in paramList) { AddPDataArrayValues(param.Key, param.Value, param.Delim); removeList.Add(param); } CommandParameters.RemoveAll(c => removeList.Contains(c)); } /// /// takes a hex string and breaks it up into individual characters /// then inserts them as parameters /// /// /// /// 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 } ); } } /// /// 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 /// /// /// /// private static IEnumerable 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 hexChars = BreakIntoHexCharacters(paddedPage); foreach (string hexChar in hexChars) { yield return hexChar; } } } /// /// takes a large string of hex characters and breaks it into individual hex values /// then yields these values to the calling code /// /// /// public static IEnumerable 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); } } } }