F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
CRCChecker.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title CRCChecker.cpp
3 // \author ortega
4 // \brief cpp file for a crc32 checker
5 //
6 // \copyright
7 // Copyright 2009-2020, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 // ======================================================================
11 
12 #include <Fw/FPrimeBasicTypes.hpp>
13 #include <Utils/CRCChecker.hpp>
14 #include <Fw/Types/Assert.hpp>
15 #include <Os/File.hpp>
16 #include <Os/FileSystem.hpp>
17 #include <Utils/Hash/Hash.hpp>
19 
20 namespace Utils {
22  "Cannot use CRC checker without full string formatting");
23 
24  crc_stat_t create_checksum_file(const char* const fname)
25  {
26  FW_ASSERT(fname != nullptr);
27 
28  FwSizeType i;
29  FwSizeType blocks;
30  FwSizeType remaining_bytes;
31  FwSizeType filesize;
32  Os::File f;
33  Os::FileSystem::Status fs_stat;
34  Os::File::Status stat;
35  Utils::Hash hash;
36  U32 checksum;
37  FwSizeType bytes_to_read;
38  FwSizeType bytes_to_write;
39  Fw::FileNameString hashFilename;
40  U8 block_data[CRC_FILE_READ_BLOCK];
41 
42  fs_stat = Os::FileSystem::getFileSize(fname, filesize);
43  if(fs_stat != Os::FileSystem::OP_OK)
44  {
45  return FAILED_FILE_SIZE;
46  }
47 
48  // Open file
49  stat = f.open(fname, Os::File::OPEN_READ);
50  if(stat != Os::File::OP_OK)
51  {
52  return FAILED_FILE_OPEN;
53  }
54 
55  // Read file
56  bytes_to_read = CRC_FILE_READ_BLOCK;
57  blocks = filesize / CRC_FILE_READ_BLOCK;
58  for(i = 0; i < blocks; i++)
59  {
60  stat = f.read(block_data, bytes_to_read);
61  if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK)
62  {
63  f.close();
64  return FAILED_FILE_READ;
65  }
66 
67  hash.update(block_data, bytes_to_read);
68  }
69 
70  remaining_bytes = filesize % CRC_FILE_READ_BLOCK;
71  bytes_to_read = remaining_bytes;
72  if(remaining_bytes > 0)
73  {
74  stat = f.read(block_data, bytes_to_read);
75  if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes)
76  {
77  f.close();
78  return FAILED_FILE_READ;
79  }
80 
81  hash.update(block_data, remaining_bytes);
82  }
83 
84  // close file
85  f.close();
86 
87  // generate checksum
88  hash.final(checksum);
89 
90  // open checksum file
91  Fw::FormatStatus formatStatus = hashFilename.format("%s%s", fname, HASH_EXTENSION_STRING);
92  FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS);
93 
94  stat = f.open(hashFilename.toChar(), Os::File::OPEN_WRITE);
95  if(stat != Os::File::OP_OK)
96  {
97  return FAILED_FILE_CRC_OPEN;
98  }
99 
100  // Write checksum file
101  bytes_to_write = sizeof(checksum);
102  stat = f.write(reinterpret_cast<U8*>(&checksum), bytes_to_write);
103  if(stat != Os::File::OP_OK || sizeof(checksum) != bytes_to_write)
104  {
105  f.close();
106  return FAILED_FILE_CRC_WRITE;
107  }
108 
109  // close checksum file
110  f.close();
111 
112  return PASSED_FILE_CRC_WRITE;
113  }
114 
115  crc_stat_t read_crc32_from_file(const char* const fname, U32 &checksum_from_file) {
116  Os::File f;
117  Os::File::Status stat;
118  Fw::FileNameString hashFilename;
119  FW_ASSERT(fname != nullptr);
120  // open checksum file
121  Fw::FormatStatus formatStatus = hashFilename.format("%s%s", fname, HASH_EXTENSION_STRING);
122  FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS);
123 
124  stat = f.open(hashFilename.toChar(), Os::File::OPEN_READ);
125  if(stat != Os::File::OP_OK)
126  {
127  return FAILED_FILE_CRC_OPEN;
128  }
129 
130  // Read checksum file
131  FwSizeType checksum_from_file_size = static_cast<FwSizeType>(sizeof(checksum_from_file));
132  stat = f.read(reinterpret_cast<U8*>(&checksum_from_file), checksum_from_file_size);
133  if(stat != Os::File::OP_OK || checksum_from_file_size != sizeof(checksum_from_file))
134  {
135  f.close();
136  return FAILED_FILE_CRC_READ;
137  }
138 
139  // close checksum file
140  f.close();
141  return PASSED_FILE_CRC_CHECK;
142  }
143 
144  crc_stat_t verify_checksum(const char* const fname, U32 &expected, U32 &actual)
145  {
146  FW_ASSERT(fname != nullptr);
147 
148  FwSizeType i;
149  FwSizeType blocks;
150  FwSizeType remaining_bytes;
151  FwSizeType filesize;
152  Os::File f;
153  Os::FileSystem::Status fs_stat;
154  Os::File::Status stat;
155  Utils::Hash hash;
156  U32 checksum;
157  U32 checksum_from_file;
158  FwSizeType bytes_to_read;
159  U8 block_data[CRC_FILE_READ_BLOCK];
160 
161  fs_stat = Os::FileSystem::getFileSize(fname, filesize);
162  if(fs_stat != Os::FileSystem::OP_OK)
163  {
164  return FAILED_FILE_SIZE;
165  }
166 
167  // Open file
168  stat = f.open(fname, Os::File::OPEN_READ);
169  if(stat != Os::File::OP_OK)
170  {
171  return FAILED_FILE_OPEN;
172  }
173 
174  // Read file
175  bytes_to_read = CRC_FILE_READ_BLOCK;
176  blocks = filesize / CRC_FILE_READ_BLOCK;
177  for(i = 0; i < blocks; i++)
178  {
179  stat = f.read(block_data, bytes_to_read);
180  if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK)
181  {
182  f.close();
183  return FAILED_FILE_READ;
184  }
185 
186  hash.update(block_data, static_cast<FwSizeType>(bytes_to_read));
187  }
188 
189  remaining_bytes = filesize % CRC_FILE_READ_BLOCK;
190  bytes_to_read = remaining_bytes;
191  if(remaining_bytes > 0)
192  {
193  stat = f.read(block_data, bytes_to_read);
194  if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes)
195  {
196  f.close();
197  return FAILED_FILE_READ;
198  }
199 
200  hash.update(block_data, remaining_bytes);
201  }
202 
203  // close file
204  f.close();
205  // generate checksum
206  hash.final(checksum);
207 
208  crc_stat_t crcstat = read_crc32_from_file(fname, checksum_from_file);
209  if (crcstat != PASSED_FILE_CRC_CHECK) {
210  return crcstat;
211  }
212 
213  // compare checksums
214  if(checksum != checksum_from_file)
215  {
216  expected = checksum_from_file;
217  actual = checksum;
218  return FAILED_FILE_CRC_CHECK;
219  }
220 
221  expected = checksum_from_file;
222  actual = checksum;
223  return PASSED_FILE_CRC_CHECK;
224  }
225 
226 }
void update(const void *const data, const FwSizeType len)
Definition: CRC32.cpp:56
PlatformSizeType FwSizeType
static const FwSignedSizeType CRC_FILE_READ_BLOCK
Definition: CRCChecker.hpp:19
Open file for writing.
Definition: File.hpp:23
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
void final(HashBuffer &buffer)
Definition: CRC32.cpp:67
crc_stat_t create_checksum_file(const char *const fname)
Definition: CRCChecker.cpp:24
crc_stat_t read_crc32_from_file(const char *const fname, U32 &checksum_from_file)
Definition: CRCChecker.cpp:115
const char * toChar() const
#define FW_USE_PRINTF_FAMILY_FUNCTIONS_IN_STRING_FORMATTING
Definition: FpConfig.h:97
void close() override
close the file, if not opened then do nothing
Definition: File.cpp:70
Status write(const U8 *buffer, FwSizeType &size)
write data to this file from the supplied buffer bounded by size
Definition: File.cpp:187
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
crc_stat_t verify_checksum(const char *const fname, U32 &expected, U32 &actual)
Definition: CRCChecker.cpp:144
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:55
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:56
static Status getFileSize(const char *path, FwSizeType &size)
Get the size of the file (in bytes) at the specified path.
Definition: FileSystem.cpp:226
Status read(U8 *buffer, FwSizeType &size)
read data from this file into supplied buffer bounded by size
Definition: File.cpp:168
Operation was successful.
Definition: File.hpp:30
Open file for reading.
Definition: File.hpp:21
#define HASH_EXTENSION_STRING
Definition: CRC32.hpp:25
Operation was successful.
Definition: FileSystem.hpp:25
#define FW_ASSERT(...)
Definition: Assert.hpp:14
FormatStatus
status of string format calls
Definition: format.hpp:18