diff --git a/applications/external/mass_storage/application.fam b/applications/external/mass_storage/application.fam new file mode 100644 index 0000000000..251deed80c --- /dev/null +++ b/applications/external/mass_storage/application.fam @@ -0,0 +1,13 @@ +App( + appid="mass_storage", + name="USB Mass Storage", + apptype=FlipperAppType.EXTERNAL, + entry_point="mass_storage_app", + cdefines=["APP_MASS_STORAGE"], + requires=["gui"], + stack_size=1 * 1024, + order=2, + # fap_icon="", + fap_category="Misc", + fap_libs=["assets"], +) diff --git a/applications/external/mass_storage/helpers/mass_storage_scsi.c b/applications/external/mass_storage/helpers/mass_storage_scsi.c index d1114c889c..995f050765 100644 --- a/applications/external/mass_storage/helpers/mass_storage_scsi.c +++ b/applications/external/mass_storage/helpers/mass_storage_scsi.c @@ -1,7 +1,5 @@ #include "mass_storage_scsi.h" -#include - #define TAG "MassStorageSCSI" #define SCSI_TEST_UNIT_READY (0x00) diff --git a/applications/external/mass_storage/helpers/mass_storage_scsi.h b/applications/external/mass_storage/helpers/mass_storage_scsi.h index ec366ef3a3..27a6f6ebb7 100644 --- a/applications/external/mass_storage/helpers/mass_storage_scsi.h +++ b/applications/external/mass_storage/helpers/mass_storage_scsi.h @@ -2,7 +2,7 @@ #include -#define SCSI_BLOCK_SIZE (0x200) +#define SCSI_BLOCK_SIZE (0x200u) #define SCSI_SK_ILLEGAL_REQUEST (5) @@ -53,4 +53,4 @@ typedef struct { bool scsi_cmd_start(SCSISession* scsi, uint8_t* cmd, uint8_t len); bool scsi_cmd_rx_data(SCSISession* scsi, uint8_t* data, uint32_t len); bool scsi_cmd_tx_data(SCSISession* scsi, uint8_t* data, uint32_t* len, uint32_t cap); -bool scsi_cmd_end(SCSISession* scsi); \ No newline at end of file +bool scsi_cmd_end(SCSISession* scsi); diff --git a/applications/external/mass_storage/helpers/mass_storage_usb.c b/applications/external/mass_storage/helpers/mass_storage_usb.c index 6b8a7cf694..5a24b58981 100644 --- a/applications/external/mass_storage/helpers/mass_storage_usb.c +++ b/applications/external/mass_storage/helpers/mass_storage_usb.c @@ -8,7 +8,7 @@ #define USB_MSC_TX_EP (0x82) #define USB_MSC_RX_EP_SIZE (64) -#define USB_MSC_TX_EP_SIZE (64) +#define USB_MSC_TX_EP_SIZE (64u) #define USB_MSC_BOT_GET_MAX_LUN (0xFE) #define USB_MSC_BOT_RESET (0xFF) @@ -23,7 +23,7 @@ // must be SCSI_BLOCK_SIZE aligned // larger than 0x10000 exceeds size_t, storage_file_* ops fail -#define USB_MSC_BUF_MAX (0x10000 - SCSI_BLOCK_SIZE) +#define USB_MSC_BUF_MAX (0x10000u - SCSI_BLOCK_SIZE) static usbd_respond usb_ep_config(usbd_device* dev, uint8_t cfg); static usbd_respond usb_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback); @@ -79,7 +79,7 @@ static int32_t mass_thread_worker(void* context) { StateWriteCSW, } state = StateReadCBW; while(true) { - uint32_t flags = osThreadFlagsWait(EventAll, osFlagsWaitAny, osWaitForever); + uint32_t flags = furi_thread_flags_wait(EventAll, FuriFlagWaitAny, FuriFlagWaitAny); if(flags & EventExit) { FURI_LOG_I(TAG, "exit"); free(buf); @@ -235,7 +235,7 @@ static int32_t mass_thread_worker(void* context) { break; } if(len != sizeof(csw)) { - FURI_LOG_W(TAG, "bad csw write %d", len); + FURI_LOG_W(TAG, "bad csw write %ld", len); usbd_ep_stall(dev, USB_MSC_TX_EP); break; } @@ -255,6 +255,7 @@ static int32_t mass_thread_worker(void* context) { static MassStorageUsb* mass_cur = NULL; static void usb_init(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx) { + UNUSED(intf); MassStorageUsb* mass = ctx; mass_cur = mass; mass->dev = dev; @@ -283,7 +284,7 @@ static void usb_deinit(usbd_device* dev) { mass_cur = NULL; furi_assert(mass->thread); - osThreadFlagsSet(furi_thread_get_thread_id(mass->thread), EventExit); + furi_thread_flags_set(furi_thread_get_id(mass->thread), EventExit); furi_thread_join(mass->thread); furi_thread_free(mass->thread); mass->thread = NULL; @@ -296,18 +297,21 @@ static void usb_deinit(usbd_device* dev) { } static void usb_wakeup(usbd_device* dev) { + UNUSED(dev); } static void usb_suspend(usbd_device* dev) { MassStorageUsb* mass = mass_cur; if(!mass || mass->dev != dev) return; - osThreadFlagsSet(furi_thread_get_thread_id(mass->thread), EventReset); + furi_thread_flags_set(furi_thread_get_id(mass->thread), EventReset); } static void usb_rxtx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) { + UNUSED(event); + UNUSED(ep); MassStorageUsb* mass = mass_cur; if(!mass || mass->dev != dev) return; - osThreadFlagsSet(furi_thread_get_thread_id(mass->thread), EventRxTx); + furi_thread_flags_set(furi_thread_get_id(mass->thread), EventRxTx); } static usbd_respond usb_ep_config(usbd_device* dev, uint8_t cfg) { @@ -331,6 +335,7 @@ static usbd_respond usb_ep_config(usbd_device* dev, uint8_t cfg) { } static usbd_respond usb_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_callback* callback) { + UNUSED(callback); if(((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) != (USB_REQ_INTERFACE | USB_REQ_CLASS)) { return usbd_fail; @@ -345,7 +350,7 @@ static usbd_respond usb_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_cal case USB_MSC_BOT_RESET: { MassStorageUsb* mass = mass_cur; if(!mass || mass->dev != dev) return usbd_fail; - osThreadFlagsSet(furi_thread_get_thread_id(mass->thread), EventReset); + furi_thread_flags_set(furi_thread_get_id(mass->thread), EventReset); return usbd_ack; }; break; } diff --git a/applications/external/mass_storage/mass_storage_app.c b/applications/external/mass_storage/mass_storage_app.c index 48159730ff..f07c8aa6c9 100644 --- a/applications/external/mass_storage/mass_storage_app.c +++ b/applications/external/mass_storage/mass_storage_app.c @@ -40,19 +40,20 @@ MassStorageApp* mass_storage_app_alloc(char* arg) { memset(app, 0, sizeof(MassStorageApp)); if(arg != NULL) { - string_t filename; - string_init_set(filename, arg); - if(string_start_with_str_p(filename, MASS_STORAGE_APP_PATH_FOLDER)) { - string_right(filename, strlen(MASS_STORAGE_APP_PATH_FOLDER) + 1); + FuriString* filename = furi_string_alloc_set(arg); + if(furi_string_start_with_str(filename, MASS_STORAGE_APP_PATH_FOLDER)) { + furi_string_right(filename, strlen(MASS_STORAGE_APP_PATH_FOLDER) + 1); } - strncpy(app->file_name, string_get_cstr(filename), MASS_STORAGE_FILE_NAME_LEN); - string_clear(filename); + strlcpy(app->file_name, furi_string_get_cstr(filename), MASS_STORAGE_FILE_NAME_LEN); + furi_string_free(filename); } - app->gui = furi_record_open("gui"); - app->fs_api = furi_record_open("storage"); - app->notifications = furi_record_open("notification"); - app->dialogs = furi_record_open("dialogs"); + app->gui = furi_record_open(RECORD_GUI); + app->fs_api = furi_record_open(RECORD_STORAGE); + app->notifications = furi_record_open(RECORD_NOTIFICATION); + app->dialogs = furi_record_open(RECORD_DIALOGS); + + storage_simply_mkdir(app->fs_api, MASS_STORAGE_APP_PATH_FOLDER); app->view_dispatcher = view_dispatcher_alloc(); view_dispatcher_enable_queue(app->view_dispatcher); @@ -95,7 +96,6 @@ void mass_storage_app_free(MassStorageApp* app) { furi_assert(app); // Views - view_dispatcher_remove_view(app->view_dispatcher, MassStorageAppViewFileSelect); view_dispatcher_remove_view(app->view_dispatcher, MassStorageAppViewWork); mass_storage_free(app->mass_storage_view); @@ -108,10 +108,10 @@ void mass_storage_app_free(MassStorageApp* app) { scene_manager_free(app->scene_manager); // Close records - furi_record_close("gui"); - furi_record_close("storage"); - furi_record_close("notification"); - furi_record_close("dialogs"); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_STORAGE); + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_DIALOGS); free(app); } diff --git a/applications/external/mass_storage/mass_storage_app_i.h b/applications/external/mass_storage/mass_storage_app_i.h index e30b7b6288..7fc829abaf 100644 --- a/applications/external/mass_storage/mass_storage_app_i.h +++ b/applications/external/mass_storage/mass_storage_app_i.h @@ -29,11 +29,11 @@ struct MassStorageApp { DialogsApp* dialogs; Widget* widget; - char file_name[MASS_STORAGE_FILE_NAME_LEN + 1]; + char file_name[MASS_STORAGE_FILE_NAME_LEN]; File* file; MassStorage* mass_storage_view; - osMutexId_t usb_mutex; + FuriMutex* usb_mutex; MassStorageUsb* usb; }; diff --git a/applications/external/mass_storage/scenes/mass_storage_scene_error.c b/applications/external/mass_storage/scenes/mass_storage_scene_error.c index 998c7d1607..daef7ccd19 100644 --- a/applications/external/mass_storage/scenes/mass_storage_scene_error.c +++ b/applications/external/mass_storage/scenes/mass_storage_scene_error.c @@ -1,4 +1,5 @@ #include "../mass_storage_app_i.h" +#include typedef enum { SubghzCustomEventErrorBack, diff --git a/applications/external/mass_storage/scenes/mass_storage_scene_file_select.c b/applications/external/mass_storage/scenes/mass_storage_scene_file_select.c index ea1177a67f..36c8c4692b 100644 --- a/applications/external/mass_storage/scenes/mass_storage_scene_file_select.c +++ b/applications/external/mass_storage/scenes/mass_storage_scene_file_select.c @@ -4,14 +4,22 @@ static bool mass_storage_file_select(MassStorageApp* mass_storage) { furi_assert(mass_storage); - // Input events and views are managed by file_select - bool res = dialog_file_select_show( - mass_storage->dialogs, - MASS_STORAGE_APP_PATH_FOLDER, - "*", - mass_storage->file_name, - sizeof(mass_storage->file_name), - NULL); + FuriString* file_path = furi_string_alloc(); + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, "*", NULL); + browser_options.base_path = MASS_STORAGE_APP_PATH_FOLDER; + furi_string_set(file_path, MASS_STORAGE_APP_PATH_FOLDER); + + bool res = + dialog_file_browser_show(mass_storage->dialogs, file_path, file_path, &browser_options); + + if(res) { + strlcpy( + mass_storage->file_name, + furi_string_get_cstr(file_path), + sizeof(mass_storage->file_name)); + } + furi_string_free(file_path); return res; } @@ -27,10 +35,13 @@ void mass_storage_scene_file_select_on_enter(void* context) { } bool mass_storage_scene_file_select_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); // MassStorageApp* mass_storage = context; return false; } void mass_storage_scene_file_select_on_exit(void* context) { + UNUSED(context); // MassStorageApp* mass_storage = context; } diff --git a/applications/external/mass_storage/scenes/mass_storage_scene_work.c b/applications/external/mass_storage/scenes/mass_storage_scene_work.c index c3e9104b0c..4112931ead 100644 --- a/applications/external/mass_storage/scenes/mass_storage_scene_work.c +++ b/applications/external/mass_storage/scenes/mass_storage_scene_work.c @@ -27,7 +27,7 @@ static bool file_write(void* ctx, uint32_t lba, uint16_t count, uint8_t* buf, ui MassStorageApp* app = ctx; // FURI_LOG_I(TAG, "file_write lba=%08lx count=%04x len=%04x", lba, count, len); if(len != count * SCSI_BLOCK_SIZE) { - FURI_LOG_W(TAG, "bad write params count=%d len=%d", count, len); + FURI_LOG_W(TAG, "bad write params count=%d len=%ld", count, len); return false; } if(!storage_file_seek(app->file, lba * SCSI_BLOCK_SIZE, true)) { @@ -45,19 +45,19 @@ static uint32_t file_num_blocks(void* ctx) { static void file_eject(void* ctx) { MassStorageApp* app = ctx; FURI_LOG_I(TAG, "EJECT"); - furi_check(osMutexAcquire(app->usb_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(app->usb_mutex, FuriWaitForever) == FuriStatusOk); mass_storage_usb_stop(app->usb); app->usb = NULL; - furi_check(osMutexRelease(app->usb_mutex) == osOK); + furi_check(furi_mutex_release(app->usb_mutex) == FuriStatusOk); } bool mass_storage_scene_work_on_event(void* context, SceneManagerEvent event) { MassStorageApp* app = context; if(event.type == SceneManagerEventTypeTick) { bool ejected; - furi_check(osMutexAcquire(app->usb_mutex, osWaitForever) == osOK); + furi_check(furi_mutex_acquire(app->usb_mutex, FuriWaitForever) == FuriStatusOk); ejected = app->usb == NULL; - furi_check(osMutexRelease(app->usb_mutex) == osOK); + furi_check(furi_mutex_release(app->usb_mutex) == FuriStatusOk); if(ejected) scene_manager_previous_scene(app->scene_manager); } return false; @@ -66,17 +66,16 @@ bool mass_storage_scene_work_on_event(void* context, SceneManagerEvent event) { void mass_storage_scene_work_on_enter(void* context) { MassStorageApp* app = context; - app->usb_mutex = osMutexNew(NULL); + app->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - string_t file_name; - string_init(file_name); + FuriString* file_name = furi_string_alloc(); mass_storage_set_file_name(app->mass_storage_view, app->file_name); - string_printf(file_name, "%s/%s", MASS_STORAGE_APP_PATH_FOLDER, app->file_name); + furi_string_printf(file_name, "%s/%s", MASS_STORAGE_APP_PATH_FOLDER, app->file_name); app->file = storage_file_alloc(app->fs_api); furi_assert(storage_file_open( - app->file, string_get_cstr(file_name), FSAM_READ | FSAM_WRITE, FSOM_OPEN_EXISTING)); - string_clear(file_name); + app->file, furi_string_get_cstr(file_name), FSAM_READ | FSAM_WRITE, FSOM_OPEN_EXISTING)); + furi_string_free(file_name); SCSIDeviceFunc fn = { .ctx = app, @@ -93,7 +92,7 @@ void mass_storage_scene_work_on_enter(void* context) { void mass_storage_scene_work_on_exit(void* context) { MassStorageApp* app = context; - furi_assert(osMutexDelete(app->usb_mutex) == osOK); + furi_mutex_free(app->usb_mutex); if(app->usb) { mass_storage_usb_stop(app->usb); app->usb = NULL; diff --git a/applications/external/mass_storage/views/mass_storage_view.c b/applications/external/mass_storage/views/mass_storage_view.c index 7dc838f4f3..7cf0fa66c4 100644 --- a/applications/external/mass_storage/views/mass_storage_view.c +++ b/applications/external/mass_storage/views/mass_storage_view.c @@ -1,5 +1,6 @@ #include "mass_storage_view.h" #include +#include struct MassStorage { View* view; @@ -12,16 +13,15 @@ typedef struct { static void mass_storage_draw_callback(Canvas* canvas, void* _model) { MassStorageModel* model = _model; - string_t disp_str; - string_init_set_str(disp_str, model->file_name); + FuriString* disp_str = furi_string_alloc_set(model->file_name); elements_string_fit_width(canvas, disp_str, 128 - 2); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 8, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas_draw_str(canvas, 2, 8, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); canvas_draw_icon(canvas, 40, 20, &I_UsbTree_48x22); - string_clear(disp_str); + furi_string_free(disp_str); } MassStorage* mass_storage_alloc() { @@ -49,8 +49,5 @@ View* mass_storage_get_view(MassStorage* mass_storage) { void mass_storage_set_file_name(MassStorage* mass_storage, char* name) { furi_assert(name); with_view_model( - mass_storage->view, (MassStorageModel * model) { - model->file_name = name; - return true; - }); + mass_storage->view, MassStorageModel * model, { model->file_name = name; }, true); }