F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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 FwSignedSizeType blocks;
28 FwSignedSizeType remaining_bytes;
29 FwSignedSizeType filesize;
30 Os::File f;
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 {
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();
109 }
110
111 // close checksum file
112 f.close();
113
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 {
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();
139 }
140
141 // close checksum file
142 f.close();
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;
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 {
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;
228 }
229
230 expected = checksum_from_file;
231 actual = checksum;
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.
@ OP_OK
Operation was successful.
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)
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