F´ Flight Software - C/C++ Documentation NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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