storage.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include "storage.h"
  2. #include "storage_i.h"
  3. #include "storage_message.h"
  4. #include "storage_processing.h"
  5. #include "storage/storage_glue.h"
  6. #include "storages/storage_int.h"
  7. #include "storages/storage_ext.h"
  8. #include <assets_icons.h>
  9. #define STORAGE_TICK 1000
  10. #define ICON_SD_MOUNTED &I_SDcardMounted_11x8
  11. #define ICON_SD_ERROR &I_SDcardFail_11x8
  12. #define TAG RECORD_STORAGE
  13. static void storage_app_sd_icon_draw_callback(Canvas* canvas, void* context) {
  14. furi_assert(canvas);
  15. furi_assert(context);
  16. Storage* app = context;
  17. // here we don't care about thread race when reading / writing status
  18. switch(app->storage[ST_EXT].status) {
  19. case StorageStatusNotReady:
  20. break;
  21. case StorageStatusOK:
  22. canvas_draw_icon(canvas, 0, 0, ICON_SD_MOUNTED);
  23. break;
  24. default:
  25. canvas_draw_icon(canvas, 0, 0, ICON_SD_ERROR);
  26. break;
  27. }
  28. }
  29. Storage* storage_app_alloc() {
  30. Storage* app = malloc(sizeof(Storage));
  31. app->message_queue = furi_message_queue_alloc(8, sizeof(StorageMessage));
  32. app->pubsub = furi_pubsub_alloc();
  33. for(uint8_t i = 0; i < STORAGE_COUNT; i++) {
  34. storage_data_init(&app->storage[i]);
  35. storage_data_timestamp(&app->storage[i]);
  36. }
  37. #ifndef FURI_RAM_EXEC
  38. storage_int_init(&app->storage[ST_INT]);
  39. #endif
  40. storage_ext_init(&app->storage[ST_EXT]);
  41. // sd icon gui
  42. app->sd_gui.enabled = false;
  43. app->sd_gui.view_port = view_port_alloc();
  44. view_port_set_width(app->sd_gui.view_port, icon_get_width(ICON_SD_MOUNTED));
  45. view_port_draw_callback_set(app->sd_gui.view_port, storage_app_sd_icon_draw_callback, app);
  46. view_port_enabled_set(app->sd_gui.view_port, false);
  47. Gui* gui = furi_record_open(RECORD_GUI);
  48. gui_add_view_port(gui, app->sd_gui.view_port, GuiLayerStatusBarLeft);
  49. furi_record_close(RECORD_GUI);
  50. return app;
  51. }
  52. void storage_tick(Storage* app) {
  53. for(uint8_t i = 0; i < STORAGE_COUNT; i++) {
  54. StorageApi api = app->storage[i].api;
  55. if(api.tick != NULL) {
  56. api.tick(&app->storage[i]);
  57. }
  58. }
  59. // storage not enabled but was enabled (sd card unmount)
  60. if(app->storage[ST_EXT].status == StorageStatusNotReady && app->sd_gui.enabled == true) {
  61. app->sd_gui.enabled = false;
  62. view_port_enabled_set(app->sd_gui.view_port, false);
  63. FURI_LOG_I(TAG, "SD card unmount");
  64. StorageEvent event = {.type = StorageEventTypeCardUnmount};
  65. furi_pubsub_publish(app->pubsub, &event);
  66. }
  67. // storage enabled (or in error state) but was not enabled (sd card mount)
  68. if((app->storage[ST_EXT].status == StorageStatusOK ||
  69. app->storage[ST_EXT].status == StorageStatusNotMounted ||
  70. app->storage[ST_EXT].status == StorageStatusNoFS ||
  71. app->storage[ST_EXT].status == StorageStatusNotAccessible ||
  72. app->storage[ST_EXT].status == StorageStatusErrorInternal) &&
  73. app->sd_gui.enabled == false) {
  74. app->sd_gui.enabled = true;
  75. view_port_enabled_set(app->sd_gui.view_port, true);
  76. if(app->storage[ST_EXT].status == StorageStatusOK) {
  77. FURI_LOG_I(TAG, "SD card mount");
  78. StorageEvent event = {.type = StorageEventTypeCardMount};
  79. furi_pubsub_publish(app->pubsub, &event);
  80. } else {
  81. FURI_LOG_I(TAG, "SD card mount error");
  82. StorageEvent event = {.type = StorageEventTypeCardMountError};
  83. furi_pubsub_publish(app->pubsub, &event);
  84. }
  85. }
  86. }
  87. int32_t storage_srv(void* p) {
  88. UNUSED(p);
  89. Storage* app = storage_app_alloc();
  90. furi_record_create(RECORD_STORAGE, app);
  91. StorageMessage message;
  92. while(1) {
  93. if(furi_message_queue_get(app->message_queue, &message, STORAGE_TICK) == FuriStatusOk) {
  94. storage_process_message(app, &message);
  95. } else {
  96. storage_tick(app);
  97. }
  98. }
  99. return 0;
  100. }