Skip to content
This repository has been archived by the owner on Jul 28, 2024. It is now read-only.

Commit

Permalink
Refactor mass storage to current flipper api (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
Willy-JL committed Jun 13, 2023
1 parent eb1e816 commit 40cff8a
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 58 deletions.
13 changes: 13 additions & 0 deletions applications/external/mass_storage/application.fam
Original file line number Diff line number Diff line change
@@ -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"],
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "mass_storage_scsi.h"

#include <furi/log.h>

#define TAG "MassStorageSCSI"

#define SCSI_TEST_UNIT_READY (0x00)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <furi.h>

#define SCSI_BLOCK_SIZE (0x200)
#define SCSI_BLOCK_SIZE (0x200u)

#define SCSI_SK_ILLEGAL_REQUEST (5)

Expand Down Expand Up @@ -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);
bool scsi_cmd_end(SCSISession* scsi);
21 changes: 13 additions & 8 deletions applications/external/mass_storage/helpers/mass_storage_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down
30 changes: 15 additions & 15 deletions applications/external/mass_storage/mass_storage_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand All @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions applications/external/mass_storage/mass_storage_app_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "../mass_storage_app_i.h"
#include <assets_icons.h>

typedef enum {
SubghzCustomEventErrorBack,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}
23 changes: 11 additions & 12 deletions applications/external/mass_storage/scenes/mass_storage_scene_work.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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;
Expand All @@ -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,
Expand All @@ -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;
Expand Down
15 changes: 6 additions & 9 deletions applications/external/mass_storage/views/mass_storage_view.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "mass_storage_view.h"
#include <gui/elements.h>
#include <assets_icons.h>

struct MassStorage {
View* view;
Expand All @@ -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() {
Expand Down Expand Up @@ -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);
}

0 comments on commit 40cff8a

Please sign in to comment.