F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 <FpConfig.hpp>
13 #include <cstdio> // For snprintf
14 #include <Utils/CRCChecker.hpp>
15 #include <Fw/Types/Assert.hpp>
16 #include <Os/File.hpp>
17 #include <Os/FileSystem.hpp>
18 #include <Utils/Hash/Hash.hpp>
19 
20 namespace Utils {
21 
22  crc_stat_t create_checksum_file(const char* const fname)
23  {
24  FW_ASSERT(fname != nullptr);
25 
27  FwSignedSizeType blocks;
28  FwSignedSizeType remaining_bytes;
29  FwSignedSizeType filesize;
30  Os::File f;
31  Os::FileSystem::Status fs_stat;
32  Os::File::Status stat;
33  Utils::Hash hash;
34  U32 checksum;
35  I32 s_stat;
36  FwSignedSizeType int_file_size;
37  FwSignedSizeType bytes_to_read;
38  FwSignedSizeType bytes_to_write;
39  CHAR hashFilename[CRC_MAX_FILENAME_SIZE];
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  int_file_size = filesize;
49 
50  // Open file
51  stat = f.open(fname, Os::File::OPEN_READ);
52  if(stat != Os::File::OP_OK)
53  {
54  return FAILED_FILE_OPEN;
55  }
56 
57  // Read file
58  bytes_to_read = CRC_FILE_READ_BLOCK;
59  blocks = int_file_size / CRC_FILE_READ_BLOCK;
60  for(i = 0; i < blocks; i++)
61  {
62  stat = f.read(block_data, bytes_to_read);
63  if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK)
64  {
65  f.close();
66  return FAILED_FILE_READ;
67  }
68 
69  hash.update(block_data, static_cast<NATIVE_INT_TYPE>(bytes_to_read));
70  }
71 
72  remaining_bytes = int_file_size % CRC_FILE_READ_BLOCK;
73  bytes_to_read = remaining_bytes;
74  if(remaining_bytes > 0)
75  {
76  stat = f.read(block_data, bytes_to_read);
77  if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes)
78  {
79  f.close();
80  return FAILED_FILE_READ;
81  }
82 
83  hash.update(block_data, static_cast<NATIVE_INT_TYPE>(remaining_bytes));
84  }
85 
86  // close file
87  f.close();
88 
89  // generate checksum
90  hash.final(checksum);
91 
92  // open checksum file
93  s_stat = snprintf(hashFilename, CRC_MAX_FILENAME_SIZE, "%s%s", fname, HASH_EXTENSION_STRING);
94  FW_ASSERT(s_stat > 0);
95 
96  stat = f.open(hashFilename, Os::File::OPEN_WRITE);
97  if(stat != Os::File::OP_OK)
98  {
99  return FAILED_FILE_CRC_OPEN;
100  }
101 
102  // Write checksum file
103  bytes_to_write = sizeof(checksum);
104  stat = f.write(reinterpret_cast<U8*>(&checksum), bytes_to_write);
105  if(stat != Os::File::OP_OK || sizeof(checksum) != bytes_to_write)
106  {
107  f.close();
108  return FAILED_FILE_CRC_WRITE;
109  }
110 
111  // close checksum file
112  f.close();
113 
114  return PASSED_FILE_CRC_WRITE;
115  }
116 
117  crc_stat_t read_crc32_from_file(const char* const fname, U32 &checksum_from_file) {
118  Os::File f;
119  Os::File::Status stat;
120  char hashFilename[CRC_MAX_FILENAME_SIZE];
121  FW_ASSERT(fname != nullptr);
122  // open checksum file
123  I32 s_stat = snprintf(hashFilename, CRC_MAX_FILENAME_SIZE, "%s%s", fname, HASH_EXTENSION_STRING);
124  FW_ASSERT(s_stat > 0);
125 
126  stat = f.open(hashFilename, Os::File::OPEN_READ);
127  if(stat != Os::File::OP_OK)
128  {
129  return FAILED_FILE_CRC_OPEN;
130  }
131 
132  // Read checksum file
133  FwSignedSizeType checksum_from_file_size = static_cast<FwSignedSizeType>(sizeof(checksum_from_file));
134  stat = f.read(reinterpret_cast<U8*>(&checksum_from_file), checksum_from_file_size);
135  if(stat != Os::File::OP_OK || checksum_from_file_size != sizeof(checksum_from_file))
136  {
137  f.close();
138  return FAILED_FILE_CRC_READ;
139  }
140 
141  // close checksum file
142  f.close();
143  return PASSED_FILE_CRC_CHECK;
144  }
145 
146  crc_stat_t verify_checksum(const char* const fname, U32 &expected, U32 &actual)
147  {
148  FW_ASSERT(fname != nullptr);
149 
151  FwSignedSizeType blocks;
152  PlatformIntType remaining_bytes;
153  FwSignedSizeType filesize;
154  Os::File f;
155  Os::FileSystem::Status fs_stat;
156  Os::File::Status stat;
157  Utils::Hash hash;
158  U32 checksum;
159  U32 checksum_from_file;
160  FwSignedSizeType int_file_size;
161  FwSignedSizeType bytes_to_read;
162  U8 block_data[CRC_FILE_READ_BLOCK];
163 
164  fs_stat = Os::FileSystem::getFileSize(fname, filesize);
165  if(fs_stat != Os::FileSystem::OP_OK)
166  {
167  return FAILED_FILE_SIZE;
168  }
169 
170  int_file_size = static_cast<NATIVE_INT_TYPE>(filesize);
171  if(static_cast<FwSignedSizeType>(int_file_size) != filesize)
172  {
173  return FAILED_FILE_SIZE_CAST;
174  }
175 
176  // Open file
177  stat = f.open(fname, Os::File::OPEN_READ);
178  if(stat != Os::File::OP_OK)
179  {
180  return FAILED_FILE_OPEN;
181  }
182 
183  // Read file
184  bytes_to_read = CRC_FILE_READ_BLOCK;
185  blocks = filesize / CRC_FILE_READ_BLOCK;
186  for(i = 0; i < blocks; i++)
187  {
188  stat = f.read(block_data, bytes_to_read);
189  if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK)
190  {
191  f.close();
192  return FAILED_FILE_READ;
193  }
194 
195  hash.update(block_data, static_cast<NATIVE_INT_TYPE>(bytes_to_read));
196  }
197 
198  remaining_bytes = static_cast<PlatformIntType>(int_file_size % CRC_FILE_READ_BLOCK);
199  bytes_to_read = remaining_bytes;
200  if(remaining_bytes > 0)
201  {
202  stat = f.read(block_data, bytes_to_read);
203  if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes)
204  {
205  f.close();
206  return FAILED_FILE_READ;
207  }
208 
209  hash.update(block_data, remaining_bytes);
210  }
211 
212  // close file
213  f.close();
214  // generate checksum
215  hash.final(checksum);
216 
217  crc_stat_t crcstat = read_crc32_from_file(fname, checksum_from_file);
218  if (crcstat != PASSED_FILE_CRC_CHECK) {
219  return crcstat;
220  }
221 
222  // compare checksums
223  if(checksum != checksum_from_file)
224  {
225  expected = checksum_from_file;
226  actual = checksum;
227  return FAILED_FILE_CRC_CHECK;
228  }
229 
230  expected = checksum_from_file;
231  actual = checksum;
232  return PASSED_FILE_CRC_CHECK;
233  }
234 
235 }
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition: BasicTypes.h:55
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:30
char CHAR
Definition: BasicTypes.h:32
#define HASH_EXTENSION_STRING
Definition: CRC32.hpp:25
int PlatformIntType
DefaultTypes.hpp provides fallback defaults for the platform types.
PlatformSignedSizeType FwSignedSizeType
Definition: FpConfig.h:30
C++-compatible configuration header for fprime configuration.
Status read(U8 *buffer, FwSignedSizeType &size)
read data from this file into supplied buffer bounded by size
Definition: File.cpp:143
void close() override
close the file, if not opened then do nothing
Definition: File.cpp:70
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
Definition: File.cpp:45
Status write(const U8 *buffer, FwSignedSizeType &size)
write data to this file from the supplied buffer bounded by size
Definition: File.cpp:163
@ OP_OK
Operation was successful.
Definition: File.hpp:30
@ OPEN_WRITE
Open file for writing.
Definition: File.hpp:23
@ OPEN_READ
Open file for reading.
Definition: File.hpp:21
static Status getFileSize(const char *path, FwSignedSizeType &size)
Get the size of the file (in bytes) at the specified path.
Definition: FileSystem.cpp:227
@ OP_OK
Operation was successful.
Definition: FileSystem.hpp:25
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
void update(const void *const data, const NATIVE_INT_TYPE len)
Definition: CRC32.cpp:53
void final(HashBuffer &buffer)
Definition: CRC32.cpp:64
crc_stat_t read_crc32_from_file(const char *const fname, U32 &checksum_from_file)
Definition: CRCChecker.cpp:117
crc_stat_t create_checksum_file(const char *const fname)
Definition: CRCChecker.cpp:22
static const U32 CRC_MAX_FILENAME_SIZE
Definition: CRCChecker.hpp:20
crc_stat_t verify_checksum(const char *const fname, U32 &expected, U32 &actual)
Definition: CRCChecker.cpp:146
@ FAILED_FILE_READ
Definition: CRCChecker.hpp:29
@ FAILED_FILE_CRC_WRITE
Definition: CRCChecker.hpp:32
@ PASSED_FILE_CRC_WRITE
Definition: CRCChecker.hpp:25
@ FAILED_FILE_CRC_CHECK
Definition: CRCChecker.hpp:33
@ FAILED_FILE_CRC_READ
Definition: CRCChecker.hpp:31
@ PASSED_FILE_CRC_CHECK
Definition: CRCChecker.hpp:24
@ FAILED_FILE_CRC_OPEN
Definition: CRCChecker.hpp:30
@ FAILED_FILE_SIZE_CAST
Definition: CRCChecker.hpp:27
@ FAILED_FILE_SIZE
Definition: CRCChecker.hpp:26
@ FAILED_FILE_OPEN
Definition: CRCChecker.hpp:28
static const NATIVE_INT_TYPE CRC_FILE_READ_BLOCK
Definition: CRCChecker.hpp:19