/*********************************************************************************************************************/ /*!@file s19FileHandler.cs * @brief Handle for Motorola-S19 files. * *====================================================================================================================\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 * Functions:\n * Reading S19 files,\n * Support of S0, S2, S5 and S8 records (24Bit addresses and 16Bit record counter),\n * Building S5 record and place it at the end of the file,\n * Replacing bytes and generating S2 record for CRC.\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 { /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief s19FileHandler class. * @author Thomas Wiedebusch * @date 19-Feb-2016..24-Feb-2016 * */ /*---------------------------------------------------------------------------------------------------------------*/ public class s19FileHandler_t { //class variables String inputFile_str; //file name String outputFile_str; //file name String fileLine_str; //one line of the file crcGenrator_memSetFn_t MemSetFn_vdp; //set data to address of working memory crcGenrator_memGetFn_t MemGetFn_u8p; //get data from working memory bool s8RecordFoundInFile_bol = false; //S8 record detected UInt32 s8RecordFileLine_u32 = 0; //S8 record line in file bool crcRecordFoundInFile_bol = false; //S2 record with CRC address detected UInt32 crcRecordFileLine_u32 = 0; //S2 record with CRC address line in file bool placeCrcToFile_bol; //CRC output to file is required UInt32 crcAddress_u32; //address for CRC bool s5RecordFoundInFile_bol = false; //S5 record detected UInt32 s5RecordFileLine_u32 = 0; //S5 record line in file bool s5RecordPlacedInoutputFile_bol = false; //S5 record not applied to output file //S19-Record string, protocol const String fileHeader_cstr = "S0"; const String dataRecord24BitAddress_cstr = "S2"; const String dataRecordCounter16Bit_cstr = "S5"; const String startAddress24Bit_cstr = "S8"; const Byte s19RecordIdStrSize_cu8 = 2; //size of S19 identifier const Byte s19RecordLengthStrSize_cu8 = 2; //size of S19 length const Byte s0RecordAddressStrSize_cu8 = 4; //size of S0 address const Byte s2RecordAddressStrSize_cu8 = 6; //size of S2 address const Byte s8RecordAddressStrSize_cu8 = 6; //size of S8 address const Byte s19RecordDataCrcStrSize_cu8 = 4; //size of S19 CRC16 data const Byte s19RecordDataStrSize_cu8 = 2; //size of S19 data const Byte s5RecordCountStrSize_cu8 = 4; //size of S5 counter const Byte s19RecordCheckStrSize_cu8 = 2; //size of S19 checksum //S19-Record extracted String s19RecordId_str; //record identifier containing the "S" and a number Byte s19RecordLength_u8; //length for data and check UInt32 s19RecordAddress_u32; //data address for CRC generator module const Byte maxS19RecordData_cu8 = 32; //number of maximum data bytes in one record Byte[] s19RecordData_u8a = new Byte[maxS19RecordData_cu8]; //data fields for dispatch to CRC generator Byte s19RecordRecChecksum_u8; //checksum read for length, address and data //calculations Byte s19RecordCalcChecksum_u8; //rebuild checksum based on file data UInt16 s2RecordCounter_u16 = 0; //S2 record counter UInt32 fileLineCtr_u32 = 0; //actual accessed file line const Byte addressFieldNotUsed_cu8 = 0; //address not used (S5-Record) for checksum calculation const Byte addressField16BitSize_cu8 = 2; //16 bit address size (S0-Record) for checksum calculation const Byte addressField24BitSize_cu8 = 3; //24 bit address size (S2, S8-Records) for checksum calculation /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Constructor for S19 class:\n * -initializes file,\n * -this constructor will only be called if the input file has been found,\n * -sets delegates to memory set and get function being able to dispatch read data.\n * @author Thomas Wiedebusch * @date 19-Feb-2016..21-Feb-2016 * @param[in] inputFileIn_str file name for input file * @param[in] outputFileIn_str file name for output file, can be identical with input file * @param[in] MemSetInFn_vdp set function to dispatch data to memory * @param[in] MemGetInFn_vdp get function to read data from memory * */ /*---------------------------------------------------------------------------------------------------------------*/ public s19FileHandler_t(String inputFileIn_str, String outputFileIn_str, crcGenrator_memSetFn_t MemSetInFn_vdp, crcGenrator_memGetFn_t MemGetInFn_u8p, UInt32 crcAddressIn_u32, bool placeCrcToFileIn_bol) { inputFile_str = inputFileIn_str; outputFile_str = outputFileIn_str; MemSetFn_vdp = MemSetInFn_vdp; MemGetFn_u8p = MemGetInFn_u8p; placeCrcToFile_bol = placeCrcToFileIn_bol; crcAddress_u32 = crcAddressIn_u32; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Read input file and store to output file:\n * -reads every line, format has been checked,\n * -replaces CRC if required,\n * -creates S5 record before the end of file S8 record. * @author Thomas Wiedebusch * @date 23-Feb-2016..24-Feb-2016 * @param[in] crcResult_u16 result of CRC calculation * */ /*---------------------------------------------------------------------------------------------------------------*/ public void CreateOutputFile_vd(UInt16 crcResult_u16) { //the file line counter will be used to reference the input of already detected records fileLineCtr_u32 = 0; //mark that s5 record hasn't be accessed s5RecordPlacedInoutputFile_bol = false; try { //check if file exits if (File.Exists(inputFile_str)) { //opens file for read StreamReader inputFile_st = new StreamReader(inputFile_str); if (File.Exists(outputFile_str)) { //erase it File.Delete(outputFile_str); } //open it for write access StreamWriter outputFile_st = new StreamWriter(outputFile_str, true); //read single line until and output it to the output file do { //read one line of the input file fileLine_str = inputFile_st.ReadLine(); //output of CRC to file is required if (placeCrcToFile_bol) { //replace CRC data or build a new entry containing CRC data only BuildS19CrcRecord_vd(crcResult_u16, outputFile_st); }//output of CRC to file is required //check for S5 record generation, replace current S5 record or insert before S8 record if (!s5RecordPlacedInoutputFile_bol) { if ((s5RecordFoundInFile_bol && (s5RecordFileLine_u32 == fileLineCtr_u32)) || (s8RecordFoundInFile_bol && (s8RecordFileLine_u32 == fileLineCtr_u32))) { BuildS5Record_vd(outputFile_st); }//replace S5 or insert before S8 record }//S5 not generated //write all lines to output file outputFile_st.WriteLine( fileLine_str); //change file line of input file fileLineCtr_u32++; } while (!inputFile_st.EndOfStream); //place S5 record at file end if not already found if (!s5RecordPlacedInoutputFile_bol) { //places S5 directly at file end position BuildS5Record_vd(outputFile_st); } //release files inputFile_st.Close(); outputFile_st.Close(); //if the output file is equal to the input file, erase input file and rename temporary output file if (crcProgram_t.fileUndefined_cstr == outputFile_str) { File.Delete(inputFile_str); if (File.Exists(outputFile_str)) { //rename output to input file name, output file will be deleted File.Move(outputFile_str, inputFile_str); } } }//input file exists }//try catch { } } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Build S5 record:\n * -places it directly to output file if S8 record detected,\n * -replaces it if old S5 record detected. * @author Thomas Wiedebusch * @date 24-Feb-2016 * @param[in] outputFile_st output file stream object * */ /*---------------------------------------------------------------------------------------------------------------*/ void BuildS5Record_vd(StreamWriter outputFile_st) { //build the S5 record s19RecordId_str = dataRecordCounter16Bit_cstr; //build a new record just containing the S5 without address s19RecordLength_u8 = s5RecordCountStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2; //set counter value s19RecordData_u8a[0] = (Byte)((s2RecordCounter_u16 >> 8) & 0xFF); s19RecordData_u8a[1] = (Byte)(s2RecordCounter_u16 & 0xFF); //if S8 record found in file, build a new record and place it directly if (s8RecordFoundInFile_bol && (s8RecordFileLine_u32 == fileLineCtr_u32)) { outputFile_st.WriteLine(BuildS19Record_str(addressFieldNotUsed_cu8)); s5RecordPlacedInoutputFile_bol = true; } //replace file line string if s5 record else if (s5RecordFoundInFile_bol && (s5RecordFileLine_u32 == fileLineCtr_u32)) { //create s5-Record string for file output fileLine_str = BuildS19Record_str(addressFieldNotUsed_cu8); s5RecordPlacedInoutputFile_bol = true; } //Nor S8 neither S5 record detected in input file, output S5 directly else { outputFile_st.WriteLine(BuildS19Record_str(addressFieldNotUsed_cu8)); s5RecordPlacedInoutputFile_bol = true; } } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Build CRC record:\n * -places it directly to output file if new record required,\n * -replaces data in existing S2 record at CRC address and overwrites actual fileLine_str. * @author Thomas Wiedebusch * @date 24-Feb-2016..26-Feb-2016 * @param[in] crcResult_u16 result of CRC calculation * @param[in] outputFile_st output file stream object * */ /*---------------------------------------------------------------------------------------------------------------*/ void BuildS19CrcRecord_vd(UInt16 crcResult_u16, StreamWriter outputFile_st) { s19RecordId_str = dataRecord24BitAddress_cstr; //if CRC record address is NOT found in file, build a new record and place it directly behind the S0 if (!crcRecordFoundInFile_bol) { //output only on file line counter equals 1 if (1 == fileLineCtr_u32) { //build a new record just containing the CRC at specified address s19RecordLength_u8 = s2RecordAddressStrSize_cu8 / 2 + s19RecordDataCrcStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2; s19RecordAddress_u32 = crcAddress_u32; //set CRC16 value s19RecordData_u8a[0] = (Byte)(crcResult_u16 & 0xFF); s19RecordData_u8a[1] = (Byte)((crcResult_u16 >> 8) & 0xFF); //create s2-Record string for file output and write this additional line to file outputFile_st.WriteLine(BuildS19Record_str(addressField24BitSize_cu8)); //remove CRC to file request placeCrcToFile_bol = false; }//file line counter == 1 }//CRC record is NOT in input file, a new one has been placed to output file //replace CRC record, this has previously being identified by its file line counter in input file else if (fileLineCtr_u32 == crcRecordFileLine_u32) { //first the length, data and address is being filled, ignore return value ExtractAndCheckS2Record_bol(); //search address of CRC in S2-Record UInt32 searchAddress_u32 = s19RecordAddress_u32; Byte ctr_u8 = 0; while ((crcAddress_u32 < searchAddress_u32) && (ctr_u8 < maxS19RecordData_cu8)) { searchAddress_u32++; ctr_u8++; } //replace cells with CRC16 value s19RecordData_u8a[ctr_u8++] = (Byte)(crcResult_u16 & 0xFF); s19RecordData_u8a[ctr_u8] = (Byte)((crcResult_u16 >> 8) & 0xFF); //create s2-Record string for file output fileLine_str = BuildS19Record_str(addressField24BitSize_cu8); //remove CRC to file request placeCrcToFile_bol = false; }//replace CRC record } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Assembling a S19-Record from:\n * -s19RecordId_str,\n * -s19RecordLength_u8,\n * -s19RecordAddress_u32,\n * -s19RecordData_u8a,\n * -s19RecordCalcChecksum_u8. * @author Thomas Wiedebusch * @date 24-Feb-2016 * @param[in] s19AddressByteLength_u8 length of address field (0, 2, 3 byte) * @return s19Record_str entirely assembled S19-Record * */ /*---------------------------------------------------------------------------------------------------------------*/ String BuildS19Record_str(Byte s19AddressByteLength_u8) { String s19Record_str = s19RecordId_str; //place the length s19Record_str += s19RecordLength_u8.ToString("X2"); //for 16 bit or 24 bit address fields if (addressField24BitSize_cu8 == s19AddressByteLength_u8) { s19Record_str += s19RecordAddress_u32.ToString("X6"); } else if(addressField16BitSize_cu8 == s19AddressByteLength_u8) { s19Record_str += s19RecordAddress_u32.ToString("X4"); } //place data bytes Byte dataSize_u8 = (Byte)(s19RecordLength_u8 - s19RecordCheckStrSize_cu8 / 2 - s19AddressByteLength_u8); for (Byte dataCtr_u8 = 0; dataCtr_u8 < dataSize_u8; dataCtr_u8++) { s19Record_str += s19RecordData_u8a[dataCtr_u8].ToString("X2"); } //build the checksum BuildS19RecordChecksum_vd(s19AddressByteLength_u8); //place the calculated checksum s19Record_str += s19RecordCalcChecksum_u8.ToString("X2"); return s19Record_str; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Read file and dispatch the S2-Records to the CRC generator:\n * -reads every line and checks format. * @author Thomas Wiedebusch * @date 23-Feb-2016..25-Feb-2016 * @return file format valid * */ /*---------------------------------------------------------------------------------------------------------------*/ public bool ValidateInputFile_bol() { bool returnValue_bol = false; fileLineCtr_u32 = 0; try { //check if file exits if (File.Exists(inputFile_str)) { //resets s2 record counter s2RecordCounter_u16 = 0; //opens file for read StreamReader inputFile_st = new StreamReader(inputFile_str); //read single line until file end or validation failed do { fileLine_str = inputFile_st.ReadLine(); //decode the file line returnValue_bol = ProcessInputFileLine_bol(); //change file line counter after check and line counter reminder for the records fileLineCtr_u32++; } while (returnValue_bol && !inputFile_st.EndOfStream); //release file inputFile_st.Close(); } }//try catch { } return returnValue_bol; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Builds the S19 Record checksum, the S19 fields have to be prepared in advance:\n * -Byte wise accumulation as word from length until last data byte,\n * -ones complement of accumulation result,\n * -masked out lower byte and typecast lower byte to byte,\n * -s19RecordLength_u8 (length of address + data + checksum)\n * -s19RecordAddress_u32,\n * -s19RecordData_u8a[],\n * -result is always being placed to s19RecordCalcChecksum_u8 (length + address + data). * @author Thomas Wiedebusch * @date 24-Feb-2016 * @param[in] s19AddressByteLength_u8 length of address field (0, 2, 3 byte) * */ /*---------------------------------------------------------------------------------------------------------------*/ void BuildS19RecordChecksum_vd(Byte s19AddressByteLength_u8) { UInt16 accu_u16 = (UInt16)s19RecordLength_u8; //for 16 bit or 24 bit address fields if (s19AddressByteLength_u8 > addressFieldNotUsed_cu8) { accu_u16 += (UInt16)((s19RecordAddress_u32 >> 8) & 0x00FF); accu_u16 += (UInt16)(s19RecordAddress_u32 & 0x00FF); //for 24 bit address filed if (s19AddressByteLength_u8 > addressField16BitSize_cu8) { accu_u16 += (UInt16)((s19RecordAddress_u32 >> 16) & 0x00FF); } } Byte dataSize_u8 = (Byte)(s19RecordLength_u8 - s19RecordCheckStrSize_cu8 / 2 - s19AddressByteLength_u8); for (Byte ctr_u8 = 0; ctr_u8 < dataSize_u8; ctr_u8++) { accu_u16 += (UInt16)s19RecordData_u8a[ctr_u8]; } s19RecordCalcChecksum_u8 = (Byte)(~accu_u16 & 0x00FF); } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Extract the information given by the read line from file:\n * -extracts the record identifier S0, S2, S5 or S8,\n * -dispatches S2 records to CRC generator memory,\n * -branches to the extract subroutines for the record types,\n * -sets record counters and reminders. * @author Thomas Wiedebusch * @date 22-Feb-2016..25-Feb-2016 * @return s19 file validated * */ /*---------------------------------------------------------------------------------------------------------------*/ bool ProcessInputFileLine_bol() { bool returnValue_bol = false; try { //copy identifier s19RecordId_str = fileLine_str.Substring(0, s19RecordIdStrSize_cu8); switch (s19RecordId_str) { case fileHeader_cstr: returnValue_bol = ExtractAndCheckS0Record_bol(); break; case dataRecord24BitAddress_cstr: if (ExtractAndCheckS2Record_bol()) { returnValue_bol = true; //s2 record counter s2RecordCounter_u16++; //dispatch content to CRC generator Byte dataSize_u8 = (Byte)(s19RecordLength_u8 - s19RecordCheckStrSize_cu8 / 2 - s2RecordAddressStrSize_cu8 / 2); for (Byte ctr_u8 = 0; ctr_u8 < dataSize_u8; ctr_u8++) { MemSetFn_vdp(s19RecordAddress_u32, s19RecordData_u8a[ctr_u8]); //check for CRC address in S2 record if (crcAddress_u32 == s19RecordAddress_u32) { //remind S2 with CRC content crcRecordFoundInFile_bol = true; crcRecordFileLine_u32 = fileLineCtr_u32; }//CRC address found //setup next address after CRC check s19RecordAddress_u32++; }//data copied } break; case dataRecordCounter16Bit_cstr: if (ExtractAndCheckS5Record_bol()) { returnValue_bol = true; //remind S8 content s5RecordFoundInFile_bol = true; s5RecordFileLine_u32 = fileLineCtr_u32; } break; case startAddress24Bit_cstr: if (ExtractAndCheckS8Record_bol()) { returnValue_bol = true; //remind S8 content s8RecordFoundInFile_bol = true; s8RecordFileLine_u32 = fileLineCtr_u32; } break; default: break; }//switch }//try catch { } return returnValue_bol; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Extract the information given by the read line from file:\n * -copies data to hexadecimal data buffer,\ * -builds the checksum and validates it. * @author Thomas Wiedebusch * @date 22-Feb-2016..24-Feb-2016 * @return s19 file validated * */ /*---------------------------------------------------------------------------------------------------------------*/ bool ExtractAndCheckS0Record_bol() { bool returnValue_bol = false; Byte stringPositionCtr_u8 = s19RecordIdStrSize_cu8; try { //extract the length String var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordLengthStrSize_cu8); s19RecordLength_u8 = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //limit length to avoid access of behind the border if (s19RecordLength_u8 > maxS19RecordData_cu8 + s0RecordAddressStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2) { s19RecordLength_u8 = maxS19RecordData_cu8 + s0RecordAddressStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2; } //extract the address and accumulate it, it should be 0 for S0 record stringPositionCtr_u8 += s19RecordLengthStrSize_cu8; var_str = fileLine_str.Substring(stringPositionCtr_u8, s0RecordAddressStrSize_cu8); s19RecordAddress_u32 = UInt32.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //extract and accumulate data stringPositionCtr_u8 += s0RecordAddressStrSize_cu8; for (Byte ctr_u8 = 0; ctr_u8 < s19RecordLength_u8 - s19RecordCheckStrSize_cu8 / 2 - s0RecordAddressStrSize_cu8 / 2; ctr_u8++) { var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordDataStrSize_cu8); s19RecordData_u8a[ctr_u8] = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); stringPositionCtr_u8 += s19RecordDataStrSize_cu8; } //read the checksum var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordCheckStrSize_cu8); s19RecordRecChecksum_u8 = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //build new checksum BuildS19RecordChecksum_vd(addressField16BitSize_cu8); //compare the calculated with the received checksum if (s19RecordCalcChecksum_u8 == s19RecordRecChecksum_u8) { returnValue_bol = true; } }//try catch { } return returnValue_bol; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Extract the information given by the read line from file:\n * -copies data to hexadecimal data buffer,\ * -builds the checksum and validates it. * @author Thomas Wiedebusch * @date 22-Feb-2016..24-Feb-2016 * @return s19 file validated * */ /*---------------------------------------------------------------------------------------------------------------*/ bool ExtractAndCheckS8Record_bol() { bool returnValue_bol = false; Byte stringPositionCtr_u8 = s19RecordIdStrSize_cu8; try { //extract the length String var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordLengthStrSize_cu8); s19RecordLength_u8 = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //limit length to avoid access of behind the border if (s19RecordLength_u8 > s8RecordAddressStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2) { s19RecordLength_u8 = s8RecordAddressStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2; } //extract the address and accumulate it stringPositionCtr_u8 += s19RecordLengthStrSize_cu8; var_str = fileLine_str.Substring(stringPositionCtr_u8, s8RecordAddressStrSize_cu8); s19RecordAddress_u32 = UInt32.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //read the checksum stringPositionCtr_u8 += s8RecordAddressStrSize_cu8; var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordCheckStrSize_cu8); s19RecordRecChecksum_u8 = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //build new checksum BuildS19RecordChecksum_vd(addressField24BitSize_cu8); //compare the calculated with the received checksum if (s19RecordCalcChecksum_u8 == s19RecordRecChecksum_u8) { returnValue_bol = true; } }//try catch { } return returnValue_bol; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Extract the information given by the read line from file:\n * -builds the base address,\n * -copies data to hexadecimal data buffer,\n * -builds the checksum and validates it. * @author Thomas Wiedebusch * @date 22-Feb-2016..24-Feb-2016 * @return s19 file validated * */ /*---------------------------------------------------------------------------------------------------------------*/ bool ExtractAndCheckS2Record_bol() { bool returnValue_bol = false; Byte stringPositionCtr_u8 = s19RecordIdStrSize_cu8; try { //extract the length String var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordLengthStrSize_cu8); s19RecordLength_u8 = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //limit length to avoid access of behind the border if (s19RecordLength_u8 > maxS19RecordData_cu8 + s2RecordAddressStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2) { s19RecordLength_u8 = maxS19RecordData_cu8 + s2RecordAddressStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2; } //extract the address and accumulate it stringPositionCtr_u8 += s19RecordLengthStrSize_cu8; var_str = fileLine_str.Substring(stringPositionCtr_u8, s2RecordAddressStrSize_cu8); s19RecordAddress_u32 = UInt32.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //extract and accumulate data stringPositionCtr_u8 += s2RecordAddressStrSize_cu8; Byte dataSize_u8 = (Byte)(s19RecordLength_u8 - s19RecordCheckStrSize_cu8 / 2 - s2RecordAddressStrSize_cu8 / 2); for (Byte ctr_u8 = 0; ctr_u8 < dataSize_u8; ctr_u8++) { var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordDataStrSize_cu8); s19RecordData_u8a[ctr_u8] = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); stringPositionCtr_u8 += s19RecordDataStrSize_cu8; } //read the checksum var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordCheckStrSize_cu8); s19RecordRecChecksum_u8 = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //build new checksum BuildS19RecordChecksum_vd(addressField24BitSize_cu8); //compare the calculated with the received checksum if (s19RecordCalcChecksum_u8 == s19RecordRecChecksum_u8) { returnValue_bol = true; }//checksum okay }//try catch { } return returnValue_bol; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ /*!@brief Extract the information given by the read line from file:\n * -copies data to hexadecimal data buffer,\ * -builds the checksum and validates it. * @author Thomas Wiedebusch * @date 22-Feb-2016..24-Feb-2014 * @return s19 file validated * */ /*---------------------------------------------------------------------------------------------------------------*/ bool ExtractAndCheckS5Record_bol() { bool returnValue_bol = false; Byte stringPositionCtr_u8 = s19RecordIdStrSize_cu8; try { //extract the length which should always be 3 String var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordLengthStrSize_cu8); s19RecordLength_u8 = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //limit length to avoid access of behind the border if (s19RecordLength_u8 > s5RecordCountStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2) { s19RecordLength_u8 = s5RecordCountStrSize_cu8 / 2 + s19RecordCheckStrSize_cu8 / 2; } //extract and accumulate the counts stringPositionCtr_u8 += s19RecordLengthStrSize_cu8; var_str = fileLine_str.Substring(stringPositionCtr_u8, s5RecordCountStrSize_cu8); UInt16 s2RecordCtr_u16 = UInt16.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //read the checksum stringPositionCtr_u8 += s5RecordCountStrSize_cu8; var_str = fileLine_str.Substring(stringPositionCtr_u8, s19RecordCheckStrSize_cu8); s19RecordRecChecksum_u8 = Byte.Parse(var_str, System.Globalization.NumberStyles.HexNumber); //build new checksum BuildS19RecordChecksum_vd(addressFieldNotUsed_cu8); //compare the calculated with the received checksum if (s19RecordCalcChecksum_u8 == s19RecordRecChecksum_u8) { returnValue_bol = true; } }//try catch { } return returnValue_bol; } /**/ /*---------------------------------------------------------------------------------------------------------------*/ }//class s19FileHandler }//namespace CRC_CCITT /*=====================================END OF FILE===================================================================*/