/*********************************************************************************************************************/ /*!@file crcProgram.cs * @brief Main file for CRC_CCITT. * *====================================================================================================================\n * @copyright * * ___________________________________________________________________________________________________________________\n * Copyright (c) 2016 SENSUS, GmbH.\n * All Rights Reserved.\n * \n * Confidential property of\n * SENSUS GmbH,\n * Meineckestr. 10, 30880 LAATZEN, GERMANY\n * \n * Design by\n * Hard- und Softwareentwicklung Thomas Wiedebusch,\n * Ostermarsch 17c, 31191 ALGERMISSEN/UMMELN, GERMANY\n * \n *====================================================================================================================\n * @intro * *____________________________________________________________________________________________________________________\n * crcProgram:\n * - Initial CRC16 calculation for polynomial 0x1021,\n * inputs: -file_in name of s19 | txt file,\n * [-file_out name of s19 | txt file],\n * -start_address1=0..0xFFFFFE\n * -end_address1=0..0xFFFFFF | -length1=0..0xFFFFFF\n * [-start_address2=0..0xFFFFFE]\n * [-end_address2=0..0xFFFFFF | -length2=0..0xFFFFFE]\n * [-crc_address=0..0xFFFFFF]\n * [-seed=0..0xFFFF]\n * [-order=MMSB_FIRST|LSB_FIRST]\n * *====================================================================================================================\n * @version * *____________________________________________________________________________________________________________________\n * V1.00 19-Feb-2016..26.Feb-2016 by Thomas Wiedebusch\n * - Initial. * * *====================================================================================================================\n */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace CRC_CCITT { class crcProgram_t { //class variables public const String fileUndefined_cstr = "undefined"; const UInt16 searchIgnoreBytesOfString_cu16 = 3; static String inputFile_strs = fileUndefined_cstr; static String outputFile_strs = fileUndefined_cstr; static UInt32 crcAddress_u32s = 0; static UInt32 startAddress1_u32s = 0; static UInt32 endAddress1_u32s = 0; static UInt32 length1_u32s = 0; //optional input parameters static UInt32 startAddress2_u32s = 0; //second address range undefined static UInt32 endAddress2_u32s = 0; //second address range undefined static UInt32 length2_u32s = 0; //second address range undefined static UInt16 seed_u16s = 0xFFFF; //default value static bool wordAccess_bols = false; //default BYTE access static bool lsbFirst_bols = false; //default MSB first //internal variables static UInt16 crcResult_u16s = 0; static bool crcAddressDefined_bols = false; //assume missing arguments static Byte argsNumber_u8s = 0; /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Main program. * @author Thomas Wiedebusch * @date 19-Feb-2016..25-Feb-2016 * @param[in] args_st * @return exit code * */ /*---------------------------------------------------------------------------------------------------------------*/ static void Main(string[] args_str) { try { //required input parameters argsNumber_u8s = (Byte)args_str.GetLength(0); //check number of command line args and start of syntax for command line parameter input"-" if ((argsNumber_u8s > 2) && ("-" == args_str[0].Substring(0, 1))) { //extract information given by command line input ParseCommandLineArguments_vds(args_str); //check and init input parameters CheckAndLimitInput_vds(); }//check number of command line parameters and string "-" as start for parameter input }//try catch { } //set the address ranges for output to console, therefore the arguments have to be extracted BuildAddressRanges_vds(); //initial messages for input display to user after address build DisplayStartMsg_vds(); //check for sufficient number of input parameters and defined file to process if(((endAddress1_u32s > 0) && (length1_u32s > 0)) && (String.Compare(inputFile_strs, fileUndefined_cstr) != 0)) { //check for physically file existence if (File.Exists( inputFile_strs)) { //confirm the file has been file found DisplayFileInformationMsg_vds(); //start the file and CRC processing if (Process_bols()) { //output crc result to console DisplayResultMsg_vds(); } else { //file has unknown format DispalyUnknownFileFormatErrorMsg_vd(); } } else { //input file can't be found, don't start processing DisplayInFileNotFoundErrorMsg_vds(); } } else//if parameters are missing or help request { DisplayMissedParamErrorMsg_vds(); }//argumentsSufficient_bols }//Main /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Process file and CRC. * @author Thomas Wiedebusch * @date 21-Feb-2016..25-Feb-2016 * @return files valid * */ /*---------------------------------------------------------------------------------------------------------------*/ static bool Process_bols() { bool returnValue_bol = false; //initialize CRC generator crcGenerator_t crcGenerator_cl = new crcGenerator_t(startAddress1_u32s, length1_u32s, startAddress2_u32s, length2_u32s, seed_u16s, wordAccess_bols, lsbFirst_bols); crcGenrator_memSetFn_t MemSetFn_vdp = crcGenerator_cl.MemSetFn_vdp(); crcGenrator_memGetFn_t MemGetFn_u8p = crcGenerator_cl.MemGetFn_u8p(); //initialize s19 file handler s19FileHandler_t s19FileHandler_cl = new s19FileHandler_t(inputFile_strs, outputFile_strs, MemSetFn_vdp, MemGetFn_u8p, crcAddress_u32s, crcAddressDefined_bols); //initialize txt file handler txtFileHandler_t txtFileHandler_cl = new txtFileHandler_t(inputFile_strs, outputFile_strs, MemSetFn_vdp, MemGetFn_u8p, crcAddress_u32s, crcAddressDefined_bols); //read file, extract and copy to memory, returns false on corrupted record if (s19FileHandler_cl.ValidateInputFile_bol()) { returnValue_bol = true; //process crc crcResult_u16s = crcGenerator_cl.CrcCalculate_u16(); //create the output file s19FileHandler_cl.CreateOutputFile_vd(crcResult_u16s); } //read file, extract and copy to memory, returns false on corrupted record else if (txtFileHandler_cl.ValidateInputFile_bol()) { returnValue_bol = true; //process crc crcResult_u16s = crcGenerator_cl.CrcCalculate_u16(); //create the output file txtFileHandler_cl.CreateOutputFile_vd(crcResult_u16s); } return returnValue_bol; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Safety module to avoid wrong input ranges:\n * Takes input range from crcGenerator_t class. * @author Thomas Wiedebusch * @date 21-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ static void CheckAndLimitInput_vds() { //get the defined input range for addresses from crcGenerator class UInt32 maxAddress_u32 = crcGenerator_t.maxMemBytes_cu32; if (startAddress1_u32s > maxAddress_u32) { startAddress1_u32s = maxAddress_u32; } if (startAddress2_u32s > maxAddress_u32) { startAddress2_u32s = maxAddress_u32; } if (endAddress1_u32s > maxAddress_u32) { endAddress1_u32s = maxAddress_u32; } if (endAddress2_u32s > maxAddress_u32) { endAddress2_u32s = maxAddress_u32; } if (length1_u32s + startAddress1_u32s > maxAddress_u32) { length1_u32s = maxAddress_u32 - startAddress1_u32s; } if (length2_u32s + startAddress2_u32s > maxAddress_u32) { length2_u32s = maxAddress_u32 - startAddress2_u32s; } if (crcAddress_u32s > maxAddress_u32) { crcAddress_u32s = maxAddress_u32; } } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Build address ranges out of end addresses or lengths. * @author Thomas Wiedebusch * @date 21-Feb-2016..23-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ static void BuildAddressRanges_vds() { //check for start and end address if (endAddress1_u32s < startAddress1_u32s) { endAddress1_u32s = startAddress1_u32s; } //check first address range if( length1_u32s > 0) { endAddress1_u32s = startAddress1_u32s + length1_u32s; } else { length1_u32s = endAddress1_u32s - startAddress1_u32s; }//first address range is defined //check for start and end address if (endAddress2_u32s < startAddress2_u32s) { endAddress2_u32s = startAddress2_u32s; } //check second address range if (length2_u32s > 0) { endAddress2_u32s = startAddress2_u32s + length2_u32s; } else { length2_u32s = endAddress2_u32s - startAddress2_u32s; }//second address range is defined } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Parse command line arguments:\n * -extracts the path and file information,\n * -extracts and assigns the variables. * @author Thomas Wiedebusch * @date 19-Feb-2016..23-Feb-2016 * @param[in] args_st command line arguments * */ /*---------------------------------------------------------------------------------------------------------------*/ static void ParseCommandLineArguments_vds(String[] args_str) { //assign numerical values to the variables or strings to strings for (Byte ctr_u8 = 0; ctr_u8 < argsNumber_u8s; ctr_u8++) { try { //read args string String argsString_str = args_str[ctr_u8]; //search for "=" UInt16 stringCtr_u16 = 0; UInt16 stringLength_u16 = (UInt16)argsString_str.Length; //avoid access on string size below size of ignored bytes, may be possible on additional wrong space if (stringLength_u16 > searchIgnoreBytesOfString_cu16) { //remove at least the 3 digits to avoid search overrun stringLength_u16 -= searchIgnoreBytesOfString_cu16; while ((stringCtr_u16 != argsString_str.IndexOf("=", stringCtr_u16)) && (stringCtr_u16 < stringLength_u16)) { stringCtr_u16++; } //extract compare string String compareString_str = argsString_str.Substring(1, stringCtr_u16 - 1); String textString_str; //deliver and convert string to variable switch (compareString_str) { case "file_in": //extract text and remove the "=" before the text inputFile_strs = argsString_str.Substring(stringCtr_u16 + 1, argsString_str.Length - stringCtr_u16 - 1); break; case "file_out": //extract text and remove the "=" before the text outputFile_strs = argsString_str.Substring(stringCtr_u16 + 1, argsString_str.Length - stringCtr_u16 - 1); break; case "crc_address": crcAddressDefined_bols = true; crcAddress_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16); ; break; case "start_address1": startAddress1_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16); break; case "end_address1": endAddress1_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16); break; case "length1": length1_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16); break; case "start_address2": startAddress2_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16); break; case "end_address2": endAddress2_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16); break; case "length2": length2_u32s = ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16); break; case "seed": seed_u16s = (UInt16)ExtractUint32HexNumberFromString_u32s(argsString_str, stringCtr_u16); break; case "order": //extract text and remove the "=" before the text textString_str = argsString_str.Substring(stringCtr_u16 + 1, argsString_str.Length - stringCtr_u16 - 1); if (0 == String.Compare(textString_str, "LSB_FIRST")) { lsbFirst_bols = true; } break; case "size": //extract text and remove the "=" before the text textString_str = argsString_str.Substring(stringCtr_u16 + 1, argsString_str.Length - stringCtr_u16 - 1); if (0 == String.Compare(textString_str, "WORD")) { wordAccess_bols = true; } break; default: break; }//switch }//string length minimum }//try catch { } }//all arguments access } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Converts input string of hex number to uint32. * @author Thomas Wiedebusch * @date 19-Feb-2016..23-Feb-2016 * @param[in] argsString_st input string * @param[in] stringCtr_u16 string counter at last parameter identifier "=" * @return number_u32 extracted uint32 * */ /*---------------------------------------------------------------------------------------------------------------*/ static UInt32 ExtractUint32HexNumberFromString_u32s(String argsString_str, UInt16 stringCtr_u16) { UInt32 number_u32 = 0; try { //extract variable and remove the "=0x" before the hexadecimal number String variableString_str = argsString_str.Substring(stringCtr_u16 + searchIgnoreBytesOfString_cu16, argsString_str.Length - stringCtr_u16 - searchIgnoreBytesOfString_cu16); number_u32 = UInt32.Parse(variableString_str, System.Globalization.NumberStyles.HexNumber); }//try catch { } return number_u32; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Display start message. * @author Thomas Wiedebusch * @date 19-Feb-2016..25-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ static void DisplayStartMsg_vds() { //output program information Console.WriteLine("================================================================================"); Console.WriteLine(" CRC_CCITT (CRC16 Polynomial 0x1021) Builder!"); Console.WriteLine(" File input formats are Motorola-s19 and TI-txt files"); Console.WriteLine(""); Console.WriteLine(" Version V1.00"); Console.WriteLine(""); Console.WriteLine(" Copyright (c) 2016 SENSUS GmbH, Laatzen, Germany"); Console.WriteLine(" All rights reserved"); Console.WriteLine(" Written by Thomas Wiedebusch"); Console.WriteLine("================================================================================"); //Scanned address and size information Console.WriteLine("Start address1: 0x{0:X}", startAddress1_u32s); Console.WriteLine("Length1: 0x{0:X}", length1_u32s); Console.WriteLine("End address1: 0x{0:X}", endAddress1_u32s); if ((startAddress2_u32s > 0) && (length2_u32s > 0)) { Console.WriteLine("Start address2: 0x{0:X}", startAddress2_u32s); Console.WriteLine("Length2: 0x{0:X}", length2_u32s); Console.WriteLine("End address2: 0x{0:X}", endAddress2_u32s); } //output seed value Console.WriteLine("Seed: 0x{0:X4}", seed_u16s); //check data format if (wordAccess_bols) { Console.WriteLine("Access format: WORD"); } else { Console.WriteLine("Access format: BYTE"); } //check access order if (lsbFirst_bols) { Console.WriteLine("Access order: LSB_FIRST"); } else { Console.WriteLine("Access order: MSB_FIRST"); } Console.WriteLine(""); } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Display insufficient parameter error message. * @author Thomas Wiedebusch * @date 19-Feb-2016..25-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ static void DisplayMissedParamErrorMsg_vds() { Console.WriteLine("================================================================================"); Console.WriteLine("PARAMETERS ARE MISSED OR WRONG FORMAT, CRC CALCULATION CAN'T BE EXECUTED!"); Console.WriteLine("================================================================================"); Console.WriteLine(""); Console.WriteLine("Required parameters for CRC16 calculation (order independent):"); Console.WriteLine("-file_in=file_name is the name of the input file as string, required"); Console.WriteLine("[-file_out=file_name] is the name of the output file as string, optional"); Console.WriteLine("[-crc_address=0x0..0xFFFFFF] required for file out, else only console display"); Console.WriteLine("-start_address1=0x0..0xFFFFFF required"); Console.WriteLine("-end_address1|length1=0x0..0xFFFFFF required"); Console.WriteLine("[-start_address2=0x0..0xFFFFFF] optional, default 0x0"); Console.WriteLine("[-end_address2|length1=0..0xFFFFFF] optional, default 0x0"); Console.WriteLine("[-seed=0x0..0xFFFF] optional, default 0xFFFF"); Console.WriteLine("[-size=BYTE|WORD] optional, default BYTE"); Console.WriteLine("[-order=MSB_FIRST|LSB_FIRST] optional, default MSB_FIRST"); Console.WriteLine(""); Console.WriteLine("================================================================================"); Console.WriteLine(""); } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Display result message. * @author Thomas Wiedebusch * @date 19-Feb-2016..25-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ static void DisplayResultMsg_vds() { if (crcAddressDefined_bols) { Console.WriteLine("CRC address: 0x{0:X}", crcAddress_u32s); } Console.WriteLine("Computed CRC16: 0x{0:X4}", crcResult_u16s); Console.WriteLine(""); } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Display file information message. * @author Thomas Wiedebusch * @date 21-Feb-2016..24-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ static void DisplayFileInformationMsg_vds() { //In/output file information Console.WriteLine("Input File: " + inputFile_strs); //if the output file is not explicitly defined output file = input file if (fileUndefined_cstr == outputFile_strs) { Console.WriteLine("Output File: " + inputFile_strs); } else { Console.WriteLine("Output File: " + outputFile_strs); } Console.WriteLine(""); } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Display input file not found. * @author Thomas Wiedebusch * @date 21-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ static void DisplayInFileNotFoundErrorMsg_vds() { Console.WriteLine("INPUT FILE \"" + inputFile_strs + "\" NOT FOUND!"); Console.WriteLine(""); } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Display file format is unknown. * @author Thomas Wiedebusch * @date 21-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ static void DispalyUnknownFileFormatErrorMsg_vd() { Console.WriteLine("UNEXPECTED FILE FORMAT!"); Console.WriteLine("Input file is corrupted or not a Motorola-s19 or TI-txt file!"); Console.WriteLine(""); } /**/ /*---------------------------------------------------------------------------------------------------------------*/ }//class crcProgram }//namespace CRC_CCITT /*=====================================END OF FILE===================================================================*/