laatzen/CRC_CCITT/crcProgram.cs
2021-10-01 11:09:20 +02:00

571 lines
23 KiB
C#

/*********************************************************************************************************************/
/*!@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===================================================================*/