CRCChecker.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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. #include <FpConfig.hpp>
  12. #include <cstdio> // For snprintf
  13. #include <Utils/CRCChecker.hpp>
  14. #include <Fw/Types/Assert.hpp>
  15. #include <Os/File.hpp>
  16. #include <Os/FileSystem.hpp>
  17. #include <Utils/Hash/Hash.hpp>
  18. namespace Utils {
  19. crc_stat_t create_checksum_file(const char* const fname)
  20. {
  21. FW_ASSERT(fname != nullptr);
  22. NATIVE_INT_TYPE i;
  23. NATIVE_INT_TYPE blocks;
  24. NATIVE_INT_TYPE remaining_bytes;
  25. FwSizeType filesize;
  26. Os::File f;
  27. Os::FileSystem::Status fs_stat;
  28. Os::File::Status stat;
  29. Utils::Hash hash;
  30. U32 checksum;
  31. I32 s_stat;
  32. NATIVE_INT_TYPE int_file_size;
  33. NATIVE_INT_TYPE bytes_to_read;
  34. NATIVE_INT_TYPE bytes_to_write;
  35. char hashFilename[CRC_MAX_FILENAME_SIZE];
  36. char block_data[CRC_FILE_READ_BLOCK];
  37. fs_stat = Os::FileSystem::getFileSize(fname, filesize);
  38. if(fs_stat != Os::FileSystem::OP_OK)
  39. {
  40. return FAILED_FILE_SIZE;
  41. }
  42. int_file_size = static_cast<NATIVE_INT_TYPE>(filesize);
  43. if(static_cast<FwSizeType>(int_file_size) != filesize)
  44. {
  45. return FAILED_FILE_SIZE_CAST;
  46. }
  47. // Open file
  48. stat = f.open(fname, Os::File::OPEN_READ);
  49. if(stat != Os::File::OP_OK)
  50. {
  51. return FAILED_FILE_OPEN;
  52. }
  53. // Read file
  54. bytes_to_read = CRC_FILE_READ_BLOCK;
  55. blocks = int_file_size / CRC_FILE_READ_BLOCK;
  56. for(i = 0; i < blocks; i++)
  57. {
  58. stat = f.read(block_data, bytes_to_read);
  59. if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK)
  60. {
  61. f.close();
  62. return FAILED_FILE_READ;
  63. }
  64. hash.update(block_data, bytes_to_read);
  65. }
  66. remaining_bytes = int_file_size % CRC_FILE_READ_BLOCK;
  67. bytes_to_read = remaining_bytes;
  68. if(remaining_bytes > 0)
  69. {
  70. stat = f.read(block_data, bytes_to_read);
  71. if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes)
  72. {
  73. f.close();
  74. return FAILED_FILE_READ;
  75. }
  76. hash.update(block_data, remaining_bytes);
  77. }
  78. // close file
  79. f.close();
  80. // generate checksum
  81. hash.final(checksum);
  82. // open checksum file
  83. s_stat = snprintf(hashFilename, CRC_MAX_FILENAME_SIZE, "%s%s", fname, HASH_EXTENSION_STRING);
  84. FW_ASSERT(s_stat > 0);
  85. stat = f.open(hashFilename, Os::File::OPEN_WRITE);
  86. if(stat != Os::File::OP_OK)
  87. {
  88. return FAILED_FILE_CRC_OPEN;
  89. }
  90. // Write checksum file
  91. bytes_to_write = sizeof(checksum);
  92. stat = f.write(reinterpret_cast<U8*>(&checksum), bytes_to_write);
  93. if(stat != Os::File::OP_OK || sizeof(checksum) != bytes_to_write)
  94. {
  95. f.close();
  96. return FAILED_FILE_CRC_WRITE;
  97. }
  98. // close checksum file
  99. f.close();
  100. return PASSED_FILE_CRC_WRITE;
  101. }
  102. crc_stat_t read_crc32_from_file(const char* const fname, U32 &checksum_from_file) {
  103. Os::File f;
  104. Os::File::Status stat;
  105. char hashFilename[CRC_MAX_FILENAME_SIZE];
  106. FW_ASSERT(fname != nullptr);
  107. // open checksum file
  108. I32 s_stat = snprintf(hashFilename, CRC_MAX_FILENAME_SIZE, "%s%s", fname, HASH_EXTENSION_STRING);
  109. FW_ASSERT(s_stat > 0);
  110. stat = f.open(hashFilename, Os::File::OPEN_READ);
  111. if(stat != Os::File::OP_OK)
  112. {
  113. return FAILED_FILE_CRC_OPEN;
  114. }
  115. // Read checksum file
  116. NATIVE_INT_TYPE checksum_from_file_size = sizeof(checksum_from_file);
  117. stat = f.read(reinterpret_cast<U8*>(&checksum_from_file), checksum_from_file_size);
  118. if(stat != Os::File::OP_OK || checksum_from_file_size != sizeof(checksum_from_file))
  119. {
  120. f.close();
  121. return FAILED_FILE_CRC_READ;
  122. }
  123. // close checksum file
  124. f.close();
  125. return PASSED_FILE_CRC_CHECK;
  126. }
  127. crc_stat_t verify_checksum(const char* const fname, U32 &expected, U32 &actual)
  128. {
  129. FW_ASSERT(fname != nullptr);
  130. NATIVE_INT_TYPE i;
  131. NATIVE_INT_TYPE blocks;
  132. NATIVE_INT_TYPE remaining_bytes;
  133. FwSizeType filesize;
  134. Os::File f;
  135. Os::FileSystem::Status fs_stat;
  136. Os::File::Status stat;
  137. Utils::Hash hash;
  138. U32 checksum;
  139. U32 checksum_from_file;
  140. NATIVE_INT_TYPE int_file_size;
  141. NATIVE_INT_TYPE bytes_to_read;
  142. char block_data[CRC_FILE_READ_BLOCK];
  143. fs_stat = Os::FileSystem::getFileSize(fname, filesize);
  144. if(fs_stat != Os::FileSystem::OP_OK)
  145. {
  146. return FAILED_FILE_SIZE;
  147. }
  148. int_file_size = static_cast<NATIVE_INT_TYPE>(filesize);
  149. if(static_cast<FwSizeType>(int_file_size) != filesize)
  150. {
  151. return FAILED_FILE_SIZE_CAST;
  152. }
  153. // Open file
  154. stat = f.open(fname, Os::File::OPEN_READ);
  155. if(stat != Os::File::OP_OK)
  156. {
  157. return FAILED_FILE_OPEN;
  158. }
  159. // Read file
  160. bytes_to_read = CRC_FILE_READ_BLOCK;
  161. blocks = int_file_size / CRC_FILE_READ_BLOCK;
  162. for(i = 0; i < blocks; i++)
  163. {
  164. stat = f.read(block_data, bytes_to_read);
  165. if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK)
  166. {
  167. f.close();
  168. return FAILED_FILE_READ;
  169. }
  170. hash.update(block_data, bytes_to_read);
  171. }
  172. remaining_bytes = int_file_size % CRC_FILE_READ_BLOCK;
  173. bytes_to_read = remaining_bytes;
  174. if(remaining_bytes > 0)
  175. {
  176. stat = f.read(block_data, bytes_to_read);
  177. if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes)
  178. {
  179. f.close();
  180. return FAILED_FILE_READ;
  181. }
  182. hash.update(block_data, remaining_bytes);
  183. }
  184. // close file
  185. f.close();
  186. // generate checksum
  187. hash.final(checksum);
  188. crc_stat_t crcstat = read_crc32_from_file(fname, checksum_from_file);
  189. if (crcstat != PASSED_FILE_CRC_CHECK) {
  190. return crcstat;
  191. }
  192. // compare checksums
  193. if(checksum != checksum_from_file)
  194. {
  195. expected = checksum_from_file;
  196. actual = checksum;
  197. return FAILED_FILE_CRC_CHECK;
  198. }
  199. expected = checksum_from_file;
  200. actual = checksum;
  201. return PASSED_FILE_CRC_CHECK;
  202. }
  203. }