F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
ValidateFileCommon.cpp
Go to the documentation of this file.
1 #include <Os/File.hpp>
2 #include <Os/FileSystem.hpp>
3 #include <Os/ValidateFile.hpp>
4 #include <Utils/Hash/Hash.hpp>
5 
6 namespace Os {
7 
8 File::Status computeHash(const char* fileName, Utils::HashBuffer& hashBuffer) {
9  File::Status status;
10 
11  // Open file:
12  File file;
13  status = file.open(fileName, File::OPEN_READ);
14  if (File::OP_OK != status) {
15  return status;
16  }
17 
18  // Get the file size:
19  FileSystem::Status fs_status;
20  FwSizeType fileSize = 0;
21  fs_status = FileSystem::getFileSize(fileName, fileSize);
22  if (FileSystem::OP_OK != fs_status) {
23  return File::BAD_SIZE;
24  }
25  const FwSizeType max_itr = (fileSize / VFILE_HASH_CHUNK_SIZE + 1);
26 
27  // Read all data from file and update hash:
28  Utils::Hash hash;
29  hash.init();
30  U8 buffer[VFILE_HASH_CHUNK_SIZE];
31  FwSizeType size = 0;
32  FwSizeType cnt = 0;
33  while (cnt <= max_itr) {
34  // Read out chunk from file:
35  size = sizeof(buffer);
36  status = file.read(buffer, size, Os::File::WaitType::NO_WAIT);
37  if (File::OP_OK != status) {
38  return status;
39  }
40  // If end of file, break:
41  if (size == 0) {
42  break;
43  }
44  // Add chunk to hash calculation:
45  hash.update(&buffer, static_cast<FwSizeType>(size));
46  cnt++;
47  }
48  file.close();
49 
50  // We should not have left the loop because of cnt > max_itr:
51  FW_ASSERT(size == 0);
52  FW_ASSERT(cnt <= max_itr);
53 
54  // Calculate hash:
55  Utils::HashBuffer computedHashBuffer;
56  hash.final(computedHashBuffer);
57  hashBuffer = computedHashBuffer;
58 
59  return status;
60 }
61 
62 File::Status readHash(const char* hashFileName, Utils::HashBuffer& hashBuffer) {
63  File::Status status;
64 
65  // Open hash file:
66  File hashFile;
67  status = hashFile.open(hashFileName, File::OPEN_READ);
68  if (File::OP_OK != status) {
69  return status;
70  }
71 
72  // Read hash from checksum file:
73  unsigned char savedHash[HASH_DIGEST_LENGTH];
74  FwSizeType size = static_cast<FwSizeType>(hashBuffer.getBuffCapacity());
75  status = hashFile.read(savedHash, size);
76  if (File::OP_OK != status) {
77  return status;
78  }
79  if (static_cast<FwSizeType>(size) != hashBuffer.getBuffCapacity()) {
80  return File::BAD_SIZE;
81  }
82  hashFile.close();
83 
84  // Return the hash buffer:
85  Utils::HashBuffer savedHashBuffer(savedHash, static_cast<FwSizeType>(size));
86  hashBuffer = savedHashBuffer;
87 
88  return status;
89 }
90 
91 File::Status writeHash(const char* hashFileName, Utils::HashBuffer hashBuffer) {
92  // Open hash file:
93  File hashFile;
94  File::Status status;
95  status = hashFile.open(hashFileName, File::OPEN_WRITE);
96  if (File::OP_OK != status) {
97  return status;
98  }
99 
100  // Write out the hash
101  FwSizeType size = static_cast<FwSizeType>(hashBuffer.getBuffLength());
102  status = hashFile.write(hashBuffer.getBuffAddr(), size, Os::File::WaitType::NO_WAIT);
103  if (File::OP_OK != status) {
104  return status;
105  }
106  if (static_cast<FwSizeType>(size) != hashBuffer.getBuffLength()) {
107  return File::BAD_SIZE;
108  }
109  hashFile.close();
110 
111  return status;
112 }
113 
114 // Enum and function for translating from a status to a validation status:
116 
118  switch (type) {
119  case FileType:
120  switch (status) {
121  case File::OP_OK:
123  case File::DOESNT_EXIST:
125  case File::NO_SPACE:
126  return ValidateFile::NO_SPACE;
127  case File::NO_PERMISSION:
129  case File::BAD_SIZE:
131  case File::NOT_OPENED:
133  case File::OTHER_ERROR:
135  default:
136  FW_ASSERT(0, status);
137  }
138  break;
139  case HashFileType:
140  switch (status) {
141  case File::OP_OK:
143  case File::DOESNT_EXIST:
145  case File::NO_SPACE:
146  return ValidateFile::NO_SPACE;
147  case File::NO_PERMISSION:
149  case File::BAD_SIZE:
151  case File::NOT_OPENED:
153  case File::OTHER_ERROR:
155  default:
156  FW_ASSERT(0, status);
157  }
158  break;
159  default:
160  FW_ASSERT(0, type);
161  }
162 
164 }
165 
166 ValidateFile::Status ValidateFile::validate(const char* fileName, const char* hashFileName) {
167  Utils::HashBuffer hashBuffer; // pass by reference - final value is unused
168  return validate(fileName, hashFileName, hashBuffer);
169 }
170 
172  const char* hashFileName,
173  Utils::HashBuffer& hashBuffer) {
174  File::Status status;
175 
176  // Read the hash file:
177  Utils::HashBuffer savedHash;
178  status = readHash(hashFileName, savedHash);
179  if (File::OP_OK != status) {
180  return translateStatus(status, HashFileType);
181  }
182 
183  // Compute the file's hash:
184  Utils::HashBuffer computedHash;
185  status = computeHash(fileName, computedHash);
186  if (File::OP_OK != status) {
187  return translateStatus(status, FileType);
188  }
189 
190  // Compare hashes and return:
191  if (savedHash != computedHash) {
193  }
194 
195  hashBuffer = savedHash;
196 
198 }
199 
201  const char* hashFileName,
202  Utils::HashBuffer& hashBuffer) {
203  File::Status status;
204 
205  // Compute the file's hash:
206  status = computeHash(fileName, hashBuffer);
207  if (File::OP_OK != status) {
208  return translateStatus(status, FileType);
209  }
210 
211  status = writeHash(hashFileName, hashBuffer);
212  if (File::OP_OK != status) {
213  return translateStatus(status, HashFileType);
214  }
215 
217 }
218 
219 ValidateFile::Status ValidateFile::createValidation(const char* fileName, const char* hashFileName) {
220  Utils::HashBuffer hashBuffer; // pass by reference - final value is unused
221  return createValidation(fileName, hashFileName, hashBuffer);
222 }
223 
224 } // namespace Os
void update(const void *const data, const FwSizeType len)
Definition: CRC32.cpp:56
File doesn&#39;t exist (for read)
#define HASH_DIGEST_LENGTH
Definition: CRC32.hpp:18
No permission to read/write file.
A catch-all for other errors. Have to look in implementation-specific code.
PlatformSizeType FwSizeType
Invalid size parameter.
No permission to read/write file.
Definition: File.hpp:43
Open file for writing.
Definition: File.hpp:33
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
Validation file doesn&#39;t exist (for read)
void init()
Definition: CRC32.cpp:50
void final(HashBuffer &buffer)
Definition: CRC32.cpp:67
The validation of the file passed.
Serializable::SizeType getBuffLength() const
returns current buffer size
No space left.
Definition: File.hpp:42
FwSizeType getBuffCapacity() const
File doesn&#39;t exist (for read)
Definition: File.hpp:41
Status validate(const char *fileName, const char *hashFileName, Utils::HashBuffer &hashBuffer)
Validate the contents of a file &#39;fileName&#39; against its hash.
File::Status computeHash(const char *fileName, Utils::HashBuffer &hashBuffer)
void close() override
close the file, if not opened then do nothing
Definition: File.cpp:70
Status write(const U8 *buffer, FwSizeType &size)
write data to this file from the supplied buffer bounded by size
Definition: File.cpp:187
A generic interface for creating and comparing hash values.
Definition: Hash.hpp:24
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
Status createValidation(const char *fileName, const char *hash, Utils::HashBuffer &hashBuffer)
static Status getFileSize(const char *path, FwSizeType &size)
Get the size of the file (in bytes) at the specified path.
Definition: FileSystem.cpp:225
Status read(U8 *buffer, FwSizeType &size)
read data from this file into supplied buffer bounded by size
Definition: File.cpp:168
No space left on the device for writing.
No permission to read/write file.
file hasn&#39;t been opened yet
Definition: File.hpp:45
Operation was successful.
Definition: File.hpp:40
A catch-all for other errors. Have to look in implementation-specific code.
Definition: File.hpp:51
Defines a file class to validate files or generate a file validator file.
Open file for reading.
Definition: File.hpp:31
A container class for holding a hash buffer.
Definition: HashBuffer.hpp:26
Operation was successful.
Definition: FileSystem.hpp:24
File::Status writeHash(const char *hashFileName, Utils::HashBuffer hashBuffer)
Invalid size parameter.
Definition: File.hpp:44
#define VFILE_HASH_CHUNK_SIZE
ValidateFile::Status translateStatus(File::Status status, StatusFileType type)
File::Status readHash(const char *hashFileName, Utils::HashBuffer &hashBuffer)
#define FW_ASSERT(...)
Definition: Assert.hpp:14
The validation of the file did not pass.