saved_struct.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "saved_struct.h"
  2. #include <furi.h>
  3. #include <stdint.h>
  4. #include <storage/storage.h>
  5. #define TAG "SavedStruct"
  6. typedef struct {
  7. uint8_t magic;
  8. uint8_t version;
  9. uint8_t checksum;
  10. uint8_t flags;
  11. uint32_t timestamp;
  12. } SavedStructHeader;
  13. bool saved_struct_save(const char* path,
  14. void* data,
  15. size_t size,
  16. uint8_t magic,
  17. uint8_t version) {
  18. furi_assert(path);
  19. furi_assert(data);
  20. furi_assert(size);
  21. SavedStructHeader header;
  22. FURI_LOG_I(TAG, "Saving \"%s\"", path);
  23. // Store
  24. Storage* storage = furi_record_open("storage");
  25. File* file = storage_file_alloc(storage);
  26. bool result = true;
  27. bool saved = storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
  28. if(!saved) {
  29. FURI_LOG_E(
  30. TAG,
  31. "Open failed \"%s\". Error: \'%s\'",
  32. path,
  33. storage_file_get_error_desc(file));
  34. result = false;
  35. }
  36. if(result) {
  37. // Calculate checksum
  38. uint8_t checksum = 0;
  39. uint8_t* source = data;
  40. for(size_t i = 0; i < size; i++) {
  41. checksum += source[i];
  42. }
  43. // Set header
  44. header.magic = magic;
  45. header.version = version;
  46. header.checksum = checksum;
  47. header.flags = 0;
  48. header.timestamp = 0;
  49. uint16_t bytes_count = storage_file_write(file, &header, sizeof(header));
  50. bytes_count += storage_file_write(file, data, size);
  51. if(bytes_count != (size + sizeof(header))) {
  52. FURI_LOG_E(
  53. TAG,
  54. "Write failed \"%s\". Error: \'%s\'",
  55. path,
  56. storage_file_get_error_desc(file));
  57. result = false;
  58. }
  59. }
  60. storage_file_close(file);
  61. storage_file_free(file);
  62. furi_record_close("storage");
  63. return result;
  64. }
  65. bool saved_struct_load(const char* path,
  66. void* data,
  67. size_t size,
  68. uint8_t magic,
  69. uint8_t version) {
  70. FURI_LOG_I(TAG, "Loading \"%s\"", path);
  71. SavedStructHeader header;
  72. uint8_t* data_read = furi_alloc(size);
  73. Storage* storage = furi_record_open("storage");
  74. File* file = storage_file_alloc(storage);
  75. bool result = true;
  76. bool loaded = storage_file_open(file, path, FSAM_READ, FSOM_OPEN_EXISTING);
  77. if (!loaded) {
  78. FURI_LOG_E(
  79. TAG,
  80. "Failed to read \"%s\". Error: %s",
  81. path,
  82. storage_file_get_error_desc(file));
  83. result = false;
  84. }
  85. if (result) {
  86. uint16_t bytes_count = storage_file_read(file, &header, sizeof(SavedStructHeader));
  87. bytes_count += storage_file_read(file, data_read, size);
  88. if(bytes_count != (sizeof(SavedStructHeader) + size)) {
  89. FURI_LOG_E(TAG, "Size mismatch of file \"%s\"", path);
  90. result = false;
  91. }
  92. }
  93. if(result && (header.magic != magic || header.version != version)) {
  94. FURI_LOG_E(
  95. TAG,
  96. "Magic(%d != %d) or Version(%d != %d) mismatch of file \"%s\"",
  97. header.magic,
  98. magic,
  99. header.version,
  100. version,
  101. path);
  102. result = false;
  103. }
  104. if(result) {
  105. uint8_t checksum = 0;
  106. const uint8_t* source = (const uint8_t*)data_read;
  107. for(size_t i = 0; i < size; i++) {
  108. checksum += source[i];
  109. }
  110. if(header.checksum != checksum) {
  111. FURI_LOG_E(
  112. TAG,
  113. "Checksum(%d != %d) mismatch of file \"%s\"",
  114. header.checksum,
  115. checksum,
  116. path);
  117. result = false;
  118. }
  119. }
  120. if (result) {
  121. memcpy(data, data_read, size);
  122. }
  123. storage_file_close(file);
  124. storage_file_free(file);
  125. furi_record_close("storage");
  126. free(data_read);
  127. return result;
  128. }