storage.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. #define STORAGE_TICK 1000
  9. #define ICON_SD_MOUNTED &I_SDcardMounted_11x8
  10. #define ICON_SD_ERROR &I_SDcardFail_11x8
  11. static void storage_app_sd_icon_draw_callback(Canvas* canvas, void* context) {
  12. furi_assert(canvas);
  13. furi_assert(context);
  14. Storage* app = context;
  15. // here we don't care about thread race when reading / writing status
  16. switch(app->storage[ST_EXT].status) {
  17. case StorageStatusNotReady:
  18. break;
  19. case StorageStatusOK:
  20. canvas_draw_icon(canvas, 0, 0, ICON_SD_MOUNTED);
  21. break;
  22. default:
  23. canvas_draw_icon(canvas, 0, 0, ICON_SD_ERROR);
  24. break;
  25. }
  26. }
  27. Storage* storage_app_alloc() {
  28. Storage* app = malloc(sizeof(Storage));
  29. app->message_queue = osMessageQueueNew(8, sizeof(StorageMessage), NULL);
  30. app->pubsub = furi_pubsub_alloc();
  31. for(uint8_t i = 0; i < STORAGE_COUNT; i++) {
  32. storage_data_init(&app->storage[i]);
  33. }
  34. storage_int_init(&app->storage[ST_INT]);
  35. storage_ext_init(&app->storage[ST_EXT]);
  36. // sd icon gui
  37. app->sd_gui.enabled = false;
  38. app->sd_gui.view_port = view_port_alloc();
  39. view_port_set_width(app->sd_gui.view_port, icon_get_width(ICON_SD_MOUNTED));
  40. view_port_draw_callback_set(app->sd_gui.view_port, storage_app_sd_icon_draw_callback, app);
  41. view_port_enabled_set(app->sd_gui.view_port, false);
  42. Gui* gui = furi_record_open("gui");
  43. gui_add_view_port(gui, app->sd_gui.view_port, GuiLayerStatusBarLeft);
  44. furi_record_close("gui");
  45. return app;
  46. }
  47. void storage_tick(Storage* app) {
  48. for(uint8_t i = 0; i < STORAGE_COUNT; i++) {
  49. StorageApi api = app->storage[i].api;
  50. if(api.tick != NULL) {
  51. api.tick(&app->storage[i]);
  52. }
  53. }
  54. if(app->storage[ST_EXT].status != app->prev_ext_storage_status) {
  55. app->prev_ext_storage_status = app->storage[ST_EXT].status;
  56. furi_pubsub_publish(app->pubsub, &app->storage[ST_EXT].status);
  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. }
  63. // storage enabled (or in error state) but was not enabled (sd card mount)
  64. if((app->storage[ST_EXT].status == StorageStatusOK ||
  65. app->storage[ST_EXT].status == StorageStatusNotMounted ||
  66. app->storage[ST_EXT].status == StorageStatusNoFS ||
  67. app->storage[ST_EXT].status == StorageStatusNotAccessible ||
  68. app->storage[ST_EXT].status == StorageStatusErrorInternal) &&
  69. app->sd_gui.enabled == false) {
  70. app->sd_gui.enabled = true;
  71. view_port_enabled_set(app->sd_gui.view_port, true);
  72. }
  73. }
  74. int32_t storage_srv(void* p) {
  75. Storage* app = storage_app_alloc();
  76. furi_record_create("storage", app);
  77. StorageMessage message;
  78. while(1) {
  79. if(osMessageQueueGet(app->message_queue, &message, NULL, STORAGE_TICK) == osOK) {
  80. storage_process_message(app, &message);
  81. } else {
  82. storage_tick(app);
  83. }
  84. }
  85. return 0;
  86. }