F´ Flight Software - C/C++ Documentation  NASA-v1.5.0
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 != NULL);
25 
27  NATIVE_INT_TYPE blocks;
28  NATIVE_INT_TYPE remaining_bytes;
29  U64 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  NATIVE_INT_TYPE int_file_size;
37  NATIVE_INT_TYPE bytes_to_read;
38  NATIVE_INT_TYPE bytes_to_write;
39  char hashFilename[CRC_MAX_FILENAME_SIZE];
40  char 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  if(static_cast<U64>(int_file_size) != filesize)
50  {
51  return FAILED_FILE_SIZE_CAST;
52  }
53 
54  // Open file
55  stat = f.open(fname, Os::File::OPEN_READ);
56  if(stat != Os::File::OP_OK)
57  {
58  return FAILED_FILE_OPEN;
59  }
60 
61  // Read file
62  bytes_to_read = CRC_FILE_READ_BLOCK;
63  blocks = int_file_size / CRC_FILE_READ_BLOCK;
64  for(i = 0; i < blocks; i++)
65  {
66  stat = f.read(block_data, bytes_to_read);
67  if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK)
68  {
69  f.close();
70  return FAILED_FILE_READ;
71  }
72 
73  hash.update(block_data, bytes_to_read);
74  }
75 
76  remaining_bytes = int_file_size % CRC_FILE_READ_BLOCK;
77  bytes_to_read = remaining_bytes;
78  if(remaining_bytes > 0)
79  {
80  stat = f.read(block_data, bytes_to_read);
81  if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes)
82  {
83  f.close();
84  return FAILED_FILE_READ;
85  }
86 
87  hash.update(block_data, remaining_bytes);
88  }
89 
90  // close file
91  f.close();
92 
93  // generate checksum
94  hash.final(checksum);
95 
96  // open checksum file
97  s_stat = snprintf(hashFilename, CRC_MAX_FILENAME_SIZE, "%s%s", fname, HASH_EXTENSION_STRING);
98  FW_ASSERT(s_stat > 0);
99 
100  stat = f.open(hashFilename, Os::File::OPEN_WRITE);
101  if(stat != Os::File::OP_OK)
102  {
103  return FAILED_FILE_CRC_OPEN;
104  }
105 
106  // Write checksum file
107  bytes_to_write = sizeof(checksum);
108  stat = f.write((U8*)(&checksum), bytes_to_write);
109  if(stat != Os::File::OP_OK || sizeof(checksum) != bytes_to_write)
110  {
111  f.close();
112  return FAILED_FILE_CRC_WRITE;
113  }
114 
115  // close checksum file
116  f.close();
117 
118  return PASSED_FILE_CRC_WRITE;
119  }
120 
121  crc_stat_t read_crc32_from_file(const char* const fname, U32 &checksum_from_file) {
122  Os::File f;
123  Os::File::Status stat;
124  char hashFilename[CRC_MAX_FILENAME_SIZE];
125  FW_ASSERT(fname != NULL);
126  // open checksum file
127  I32 s_stat = snprintf(hashFilename, CRC_MAX_FILENAME_SIZE, "%s%s", fname, HASH_EXTENSION_STRING);
128  FW_ASSERT(s_stat > 0);
129 
130  stat = f.open(hashFilename, Os::File::OPEN_READ);
131  if(stat != Os::File::OP_OK)
132  {
133  return FAILED_FILE_CRC_OPEN;
134  }
135 
136  // Read checksum file
137  NATIVE_INT_TYPE checksum_from_file_size = sizeof(checksum_from_file);
138  stat = f.read((U8*)(&checksum_from_file), checksum_from_file_size);
139  if(stat != Os::File::OP_OK || checksum_from_file_size != sizeof(checksum_from_file))
140  {
141  f.close();
142  return FAILED_FILE_CRC_READ;
143  }
144 
145  // close checksum file
146  f.close();
147  return PASSED_FILE_CRC_CHECK;
148  }
149 
150  crc_stat_t verify_checksum(const char* const fname, U32 &expected, U32 &actual)
151  {
152  FW_ASSERT(fname != NULL);
153 
154  NATIVE_INT_TYPE i;
155  NATIVE_INT_TYPE blocks;
156  NATIVE_INT_TYPE remaining_bytes;
157  U64 filesize;
158  Os::File f;
159  Os::FileSystem::Status fs_stat;
160  Os::File::Status stat;
161  Utils::Hash hash;
162  U32 checksum;
163  U32 checksum_from_file;
164  NATIVE_INT_TYPE int_file_size;
165  NATIVE_INT_TYPE bytes_to_read;
166  char block_data[CRC_FILE_READ_BLOCK];
167 
168  fs_stat = Os::FileSystem::getFileSize(fname, filesize);
169  if(fs_stat != Os::FileSystem::OP_OK)
170  {
171  return FAILED_FILE_SIZE;
172  }
173 
174  int_file_size = filesize;
175  if(static_cast<U64>(int_file_size) != filesize)
176  {
177  return FAILED_FILE_SIZE_CAST;
178  }
179 
180  // Open file
181  stat = f.open(fname, Os::File::OPEN_READ);
182  if(stat != Os::File::OP_OK)
183  {
184  return FAILED_FILE_OPEN;
185  }
186 
187  // Read file
188  bytes_to_read = CRC_FILE_READ_BLOCK;
189  blocks = int_file_size / CRC_FILE_READ_BLOCK;
190  for(i = 0; i < blocks; i++)
191  {
192  stat = f.read(block_data, bytes_to_read);
193  if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK)
194  {
195  f.close();
196  return FAILED_FILE_READ;
197  }
198 
199  hash.update(block_data, bytes_to_read);
200  }
201 
202  remaining_bytes = int_file_size % CRC_FILE_READ_BLOCK;
203  bytes_to_read = remaining_bytes;
204  if(remaining_bytes > 0)
205  {
206  stat = f.read(block_data, bytes_to_read);
207  if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes)
208  {
209  f.close();
210  return FAILED_FILE_READ;
211  }
212 
213  hash.update(block_data, remaining_bytes);
214  }
215 
216  // close file
217  f.close();
218  // generate checksum
219  hash.final(checksum);
220 
221  crc_stat_t crcstat = read_crc32_from_file(fname, checksum_from_file);
222  if (crcstat != PASSED_FILE_CRC_CHECK) {
223  return crcstat;
224  }
225 
226  // compare checksums
227  if(checksum != checksum_from_file)
228  {
229  expected = checksum_from_file;
230  actual = checksum;
231  return FAILED_FILE_CRC_CHECK;
232  }
233 
234  expected = checksum_from_file;
235  actual = checksum;
236  return PASSED_FILE_CRC_CHECK;
237  }
238 
239 }
HASH_EXTENSION_STRING
#define HASH_EXTENSION_STRING
Definition: CRC32.hpp:25
Utils::create_checksum_file
crc_stat_t create_checksum_file(const char *const fname)
Definition: CRCChecker.cpp:22
Os::FileSystem::Status
Status
Definition: FileSystem.hpp:15
Utils::CRC_MAX_FILENAME_SIZE
static const U32 CRC_MAX_FILENAME_SIZE
Definition: CRCChecker.hpp:20
Utils::FAILED_FILE_READ
@ FAILED_FILE_READ
Definition: CRCChecker.hpp:29
Os::File::close
void close(void)
close file
Definition: File.cpp:37
Os::File::read
Status read(void *buffer, NATIVE_INT_TYPE &size, bool waitForFull=true)
waitForFull = true to wait for all bytes to be read
Definition: File.cpp:29
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Utils::FAILED_FILE_CRC_WRITE
@ FAILED_FILE_CRC_WRITE
Definition: CRCChecker.hpp:32
Utils
Definition: CRCChecker.cpp:20
Utils::FAILED_FILE_SIZE_CAST
@ FAILED_FILE_SIZE_CAST
Definition: CRCChecker.hpp:27
Utils::FAILED_FILE_CRC_OPEN
@ FAILED_FILE_CRC_OPEN
Definition: CRCChecker.hpp:30
Utils::Hash::final
void final(HashBuffer &buffer)
Definition: CRC32.cpp:64
Utils::read_crc32_from_file
crc_stat_t read_crc32_from_file(const char *const fname, U32 &checksum_from_file)
Definition: CRCChecker.cpp:121
FileSystem.hpp
Assert.hpp
U64
#define U64(C)
Definition: sha.h:176
Os::File::write
Status write(const void *buffer, NATIVE_INT_TYPE &size, bool waitForDone=true)
write size; will return amount written or errno
Definition: File.cpp:33
Utils::FAILED_FILE_CRC_CHECK
@ FAILED_FILE_CRC_CHECK
Definition: CRCChecker.hpp:33
Os::FileSystem::OP_OK
@ OP_OK
Operation was successful.
Definition: FileSystem.hpp:16
Utils::crc_stat_t
crc_stat_t
Definition: CRCChecker.hpp:23
Hash.hpp
CRCChecker.hpp
Os::File::OPEN_WRITE
@ OPEN_WRITE
Open file for writing.
Definition: File.hpp:17
Utils::PASSED_FILE_CRC_CHECK
@ PASSED_FILE_CRC_CHECK
Definition: CRCChecker.hpp:24
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Os::File::open
Status open(const char *fileName, Mode mode)
open file. Writing creates file if it doesn't exist
Definition: File.cpp:13
File.hpp
FpConfig.hpp
ISF configuration file.
Utils::Hash
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
Utils::FAILED_FILE_SIZE
@ FAILED_FILE_SIZE
Definition: CRCChecker.hpp:26
Utils::Hash::update
void update(const void *const data, const NATIVE_INT_TYPE len)
Definition: CRC32.cpp:53
Os::File::Status
Status
Definition: File.hpp:24
Utils::PASSED_FILE_CRC_WRITE
@ PASSED_FILE_CRC_WRITE
Definition: CRCChecker.hpp:25
Utils::FAILED_FILE_OPEN
@ FAILED_FILE_OPEN
Definition: CRCChecker.hpp:28
Utils::CRC_FILE_READ_BLOCK
static const NATIVE_INT_TYPE CRC_FILE_READ_BLOCK
Definition: CRCChecker.hpp:19
Utils::verify_checksum
crc_stat_t verify_checksum(const char *const fname, U32 &expected, U32 &actual)
Definition: CRCChecker.cpp:150
Os::File::OP_OK
@ OP_OK
Operation was successful.
Definition: File.hpp:25
Os::FileSystem::getFileSize
Status getFileSize(const char *path, U64 &size)
append file origin to destination file. If boolean true, creates a brand new file if the destination ...
Definition: FileSystem.cpp:40
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
Os::File::OPEN_READ
@ OPEN_READ
Open file for reading.
Definition: File.hpp:16
NULL
#define NULL
NULL.
Definition: BasicTypes.hpp:100
Utils::FAILED_FILE_CRC_READ
@ FAILED_FILE_CRC_READ
Definition: CRCChecker.hpp:31
Os::File
Definition: File.hpp:11