storage.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. }
  36. #ifndef FURI_RAM_EXEC
  37. storage_int_init(&app->storage[ST_INT]);
  38. #endif
  39. storage_ext_init(&app->storage[ST_EXT]);
  40. // sd icon gui
  41. app->sd_gui.enabled = false;
  42. app->sd_gui.view_port = view_port_alloc();
  43. view_port_set_width(app->sd_gui.view_port, icon_get_width(ICON_SD_MOUNTED));
  44. view_port_draw_callback_set(app->sd_gui.view_port, storage_app_sd_icon_draw_callback, app);
  45. view_port_enabled_set(app->sd_gui.view_port, false);
  46. Gui* gui = furi_record_open(RECORD_GUI);
  47. gui_add_view_port(gui, app->sd_gui.view_port, GuiLayerStatusBarLeft);
  48. furi_record_close(RECORD_GUI);
  49. return app;
  50. }
  51. void storage_tick(Storage* app) {
  52. for(uint8_t i = 0; i < STORAGE_COUNT; i++) {
  53. StorageApi api = app->storage[i].api;
  54. if(api.tick != NULL) {
  55. api.tick(&app->storage[i]);
  56. }
  57. }
  58. // storage not enabled but was enabled (sd card unmount)
  59. if(app->storage[ST_EXT].status == StorageStatusNotReady && app->sd_gui.enabled == true) {
  60. app->sd_gui.enabled = false;
  61. view_port_enabled_set(app->sd_gui.view_port, false);
  62. FURI_LOG_I(TAG, "SD card unmount");
  63. StorageEvent event = {.type = StorageEventTypeCardUnmount};
  64. furi_pubsub_publish(app->pubsub, &event);
  65. }
  66. // storage enabled (or in error state) but was not enabled (sd card mount)
  67. if((app->storage[ST_EXT].status == StorageStatusOK ||
  68. app->storage[ST_EXT].status == StorageStatusNotMounted ||
  69. app->storage[ST_EXT].status == StorageStatusNoFS ||
  70. app->storage[ST_EXT].status == StorageStatusNotAccessible ||
  71. app->storage[ST_EXT].status == StorageStatusErrorInternal) &&
  72. app->sd_gui.enabled == false) {
  73. app->sd_gui.enabled = true;
  74. view_port_enabled_set(app->sd_gui.view_port, true);
  75. if(app->storage[ST_EXT].status == StorageStatusOK) {
  76. FURI_LOG_I(TAG, "SD card mount");
  77. StorageEvent event = {.type = StorageEventTypeCardMount};
  78. furi_pubsub_publish(app->pubsub, &event);
  79. } else {
  80. FURI_LOG_I(TAG, "SD card mount error");
  81. StorageEvent event = {.type = StorageEventTypeCardMountError};
  82. furi_pubsub_publish(app->pubsub, &event);
  83. }
  84. }
  85. }
  86. int32_t storage_srv(void* p) {
  87. UNUSED(p);
  88. Storage* app = storage_app_alloc();
  89. furi_record_create(RECORD_STORAGE, app);
  90. StorageMessage message;
  91. while(1) {
  92. if(furi_message_queue_get(app->message_queue, &message, STORAGE_TICK) == FuriStatusOk) {
  93. storage_process_message(app, &message);
  94. } else {
  95. storage_tick(app);
  96. }
  97. }
  98. return 0;
  99. }