F´ Flight Software - C/C++ Documentation NASA-v1.6.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
20namespace Utils {
21
22 crc_stat_t create_checksum_file(const char* const fname)
23 {
24 FW_ASSERT(fname != nullptr);
25
27 NATIVE_INT_TYPE blocks;
28 NATIVE_INT_TYPE remaining_bytes;
29 FwSizeType filesize;
30 Os::File f;
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 = static_cast<NATIVE_INT_TYPE>(filesize);
49 if(static_cast<FwSizeType>(int_file_size) != filesize)
50 {
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 {
104 }
105
106 // Write checksum file
107 bytes_to_write = sizeof(checksum);
108 stat = f.write(reinterpret_cast<U8*>(&checksum), bytes_to_write);
109 if(stat != Os::File::OP_OK || sizeof(checksum) != bytes_to_write)
110 {
111 f.close();
113 }
114
115 // close checksum file
116 f.close();
117
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 != nullptr);
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 {
134 }
135
136 // Read checksum file
137 NATIVE_INT_TYPE checksum_from_file_size = sizeof(checksum_from_file);
138 stat = f.read(reinterpret_cast<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();
143 }
144
145 // close checksum file
146 f.close();
148 }
149
150 crc_stat_t verify_checksum(const char* const fname, U32 &expected, U32 &actual)
151 {
152 FW_ASSERT(fname != nullptr);
153
155 NATIVE_INT_TYPE blocks;
156 NATIVE_INT_TYPE remaining_bytes;
157 FwSizeType filesize;
158 Os::File f;
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 = static_cast<NATIVE_INT_TYPE>(filesize);
175 if(static_cast<FwSizeType>(int_file_size) != filesize)
176 {
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;
232 }
233
234 expected = checksum_from_file;
235 actual = checksum;
237 }
238
239}
#define FW_ASSERT(...)
Definition Assert.hpp:7
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:51
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:26
#define HASH_EXTENSION_STRING
Definition CRC32.hpp:25
PlatformSizeType FwSizeType
Definition FpConfig.h:18
C++-compatible configuration header for fprime configuration.
void close()
close file
Definition File.cpp:36
@ OP_OK
Operation was successful.
Definition File.hpp:24
Status write(const void *buffer, NATIVE_INT_TYPE &size, bool waitForDone=true)
write size; will return amount written or errno
Definition File.cpp:32
@ OPEN_WRITE
Open file for writing.
Definition File.hpp:16
@ OPEN_READ
Open file for reading.
Definition File.hpp:15
Status open(const char *fileName, Mode mode)
open file. Writing creates file if it doesn't exist
Definition File.cpp:12
Status read(void *buffer, NATIVE_INT_TYPE &size, bool waitForFull=true)
waitForFull = true to wait for all bytes to be read
Definition File.cpp:28
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
Status getFileSize(const char *path, FwSizeType &size)
append file origin to destination file. If boolean true, creates a brand new file if the destination ...
@ OP_OK
Operation was successful.
crc_stat_t read_crc32_from_file(const char *const fname, U32 &checksum_from_file)
crc_stat_t create_checksum_file(const char *const fname)
static const U32 CRC_MAX_FILENAME_SIZE
crc_stat_t verify_checksum(const char *const fname, U32 &expected, U32 &actual)
@ FAILED_FILE_READ
@ FAILED_FILE_CRC_WRITE
@ PASSED_FILE_CRC_WRITE
@ FAILED_FILE_CRC_CHECK
@ FAILED_FILE_CRC_READ
@ PASSED_FILE_CRC_CHECK
@ FAILED_FILE_CRC_OPEN
@ FAILED_FILE_SIZE_CAST
@ FAILED_FILE_SIZE
@ FAILED_FILE_OPEN
static const NATIVE_INT_TYPE CRC_FILE_READ_BLOCK