diff --git a/.github/workflows/pvs_studio.yml b/.github/workflows/pvs_studio.yml index 7bd71de49..981575551 100644 --- a/.github/workflows/pvs_studio.yml +++ b/.github/workflows/pvs_studio.yml @@ -65,6 +65,7 @@ jobs: pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }} pvs-studio-analyzer analyze \ @.pvsoptions \ + --disableLicenseExpirationCheck \ -j$(grep -c processor /proc/cpuinfo) \ -f build/f7-firmware-DC/compile_commands.json \ -o PVS-Studio.log diff --git a/.vscode/example/launch.json b/.vscode/example/launch.json index 7cb2542de..f4df96592 100644 --- a/.vscode/example/launch.json +++ b/.vscode/example/launch.json @@ -28,13 +28,14 @@ "servertype": "openocd", "device": "stlink", "svdFile": "./debug/STM32WB55_CM4.svd", + // If you're debugging early in the boot process, before OS scheduler is running, + // you have to comment out the following line. "rtos": "FreeRTOS", "configFiles": [ "interface/stlink.cfg", "./debug/stm32wbx.cfg", ], "postAttachCommands": [ - // "attach 1", // "compare-sections", "source debug/flipperapps.py", // "source debug/FreeRTOS/FreeRTOS.py", diff --git a/applications/debug/bt_debug_app/views/bt_test.c b/applications/debug/bt_debug_app/views/bt_test.c index 70f57c12c..9588b667b 100644 --- a/applications/debug/bt_debug_app/views/bt_test.c +++ b/applications/debug/bt_debug_app/views/bt_test.c @@ -3,14 +3,13 @@ #include #include #include -#include #include #include struct BtTestParam { const char* label; uint8_t current_value_index; - string_t current_value_text; + FuriString* current_value_text; uint8_t values_count; BtTestParamChangeCallback change_callback; void* context; @@ -85,7 +84,8 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str(canvas, 50, param_text_y, "<"); } - canvas_draw_str(canvas, 61, param_text_y, string_get_cstr(param->current_value_text)); + canvas_draw_str( + canvas, 61, param_text_y, furi_string_get_cstr(param->current_value_text)); if(param->current_value_index < (param->values_count - 1)) { canvas_draw_str(canvas, 113, param_text_y, ">"); @@ -154,7 +154,9 @@ static bool bt_test_input_callback(InputEvent* event, void* context) { void bt_test_process_up(BtTest* bt_test) { with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { uint8_t params_on_screen = 3; if(model->position > 0) { model->position--; @@ -168,13 +170,15 @@ void bt_test_process_up(BtTest* bt_test) { model->window_position = model->position - (params_on_screen - 1); } } - return true; - }); + }, + true); } void bt_test_process_down(BtTest* bt_test) { with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { uint8_t params_on_screen = 3; if(model->position < (BtTestParamArray_size(model->params) - 1)) { model->position++; @@ -187,8 +191,8 @@ void bt_test_process_down(BtTest* bt_test) { model->position = 0; model->window_position = 0; } - return true; - }); + }, + true); } BtTestParam* bt_test_get_selected_param(BtTestModel* model) { @@ -213,7 +217,9 @@ BtTestParam* bt_test_get_selected_param(BtTestModel* model) { void bt_test_process_left(BtTest* bt_test) { BtTestParam* param; with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { param = bt_test_get_selected_param(model); if(param->current_value_index > 0) { param->current_value_index--; @@ -225,8 +231,8 @@ void bt_test_process_left(BtTest* bt_test) { model->packets_num_tx = 0; } } - return true; - }); + }, + true); if(param->change_callback) { param->change_callback(param); } @@ -235,7 +241,9 @@ void bt_test_process_left(BtTest* bt_test) { void bt_test_process_right(BtTest* bt_test) { BtTestParam* param; with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { param = bt_test_get_selected_param(model); if(param->current_value_index < (param->values_count - 1)) { param->current_value_index++; @@ -247,8 +255,8 @@ void bt_test_process_right(BtTest* bt_test) { model->packets_num_tx = 0; } } - return true; - }); + }, + true); if(param->change_callback) { param->change_callback(param); } @@ -257,7 +265,9 @@ void bt_test_process_right(BtTest* bt_test) { void bt_test_process_ok(BtTest* bt_test) { BtTestState state; with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { if(model->state == BtTestStateStarted) { model->state = BtTestStateStopped; model->message = BT_TEST_START_MESSAGE; @@ -269,8 +279,8 @@ void bt_test_process_ok(BtTest* bt_test) { model->message = BT_TEST_STOP_MESSAGE; } state = model->state; - return true; - }); + }, + true); if(bt_test->change_state_callback) { bt_test->change_state_callback(state, bt_test->context); } @@ -278,13 +288,15 @@ void bt_test_process_ok(BtTest* bt_test) { void bt_test_process_back(BtTest* bt_test) { with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { model->state = BtTestStateStopped; model->rssi = 0.0f; model->packets_num_rx = 0; model->packets_num_tx = 0; - return false; - }); + }, + false); if(bt_test->back_callback) { bt_test->back_callback(bt_test->context); } @@ -299,7 +311,9 @@ BtTest* bt_test_alloc() { view_set_input_callback(bt_test->view, bt_test_input_callback); with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { model->state = BtTestStateStopped; model->message = "Ok - Start"; BtTestParamArray_init(model->params); @@ -308,8 +322,8 @@ BtTest* bt_test_alloc() { model->rssi = 0.0f; model->packets_num_tx = 0; model->packets_num_rx = 0; - return true; - }); + }, + true); return bt_test; } @@ -318,15 +332,17 @@ void bt_test_free(BtTest* bt_test) { furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { BtTestParamArray_it_t it; for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it); BtTestParamArray_next(it)) { - string_clear(BtTestParamArray_ref(it)->current_value_text); + furi_string_free(BtTestParamArray_ref(it)->current_value_text); } BtTestParamArray_clear(model->params); - return false; - }); + }, + false); view_free(bt_test->view); free(bt_test); } @@ -347,16 +363,18 @@ BtTestParam* bt_test_param_add( furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { + bt_test->view, + BtTestModel * model, + { param = BtTestParamArray_push_new(model->params); param->label = label; param->values_count = values_count; param->change_callback = change_callback; param->context = context; param->current_value_index = 0; - string_init(param->current_value_text); - return true; - }); + param->current_value_text = furi_string_alloc(); + }, + true); return param; } @@ -364,28 +382,19 @@ BtTestParam* bt_test_param_add( void bt_test_set_rssi(BtTest* bt_test, float rssi) { furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { - model->rssi = rssi; - return true; - }); + bt_test->view, BtTestModel * model, { model->rssi = rssi; }, true); } void bt_test_set_packets_tx(BtTest* bt_test, uint32_t packets_num) { furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { - model->packets_num_tx = packets_num; - return true; - }); + bt_test->view, BtTestModel * model, { model->packets_num_tx = packets_num; }, true); } void bt_test_set_packets_rx(BtTest* bt_test, uint32_t packets_num) { furi_assert(bt_test); with_view_model( - bt_test->view, (BtTestModel * model) { - model->packets_num_rx = packets_num; - return true; - }); + bt_test->view, BtTestModel * model, { model->packets_num_rx = packets_num; }, true); } void bt_test_set_change_state_callback(BtTest* bt_test, BtTestChangeStateCallback callback) { @@ -410,7 +419,7 @@ void bt_test_set_current_value_index(BtTestParam* param, uint8_t current_value_i } void bt_test_set_current_value_text(BtTestParam* param, const char* current_value_text) { - string_set_str(param->current_value_text, current_value_text); + furi_string_set(param->current_value_text, current_value_text); } uint8_t bt_test_get_current_value_index(BtTestParam* param) { diff --git a/applications/debug/display_test/display_test.c b/applications/debug/display_test/display_test.c index 947e4dc8b..e7f366cbb 100644 --- a/applications/debug/display_test/display_test.c +++ b/applications/debug/display_test/display_test.c @@ -113,11 +113,11 @@ static void display_config_set_regulation_ratio(VariableItem* item) { static void display_config_set_contrast(VariableItem* item) { DisplayTest* instance = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - string_t temp; - string_init(temp); - string_cat_printf(temp, "%d", index); - variable_item_set_current_value_text(item, string_get_cstr(temp)); - string_clear(temp); + FuriString* temp; + temp = furi_string_alloc(); + furi_string_cat_printf(temp, "%d", index); + variable_item_set_current_value_text(item, furi_string_get_cstr(temp)); + furi_string_free(temp); instance->config_contrast = index; display_test_reload_config(instance); } diff --git a/applications/debug/display_test/view_display_test.c b/applications/debug/display_test/view_display_test.c index f00fe0094..b47c74c6c 100644 --- a/applications/debug/display_test/view_display_test.c +++ b/applications/debug/display_test/view_display_test.c @@ -110,7 +110,9 @@ static bool view_display_test_input_callback(InputEvent* event, void* context) { bool consumed = false; if(event->type == InputTypeShort || event->type == InputTypeRepeat) { with_view_model( - instance->view, (ViewDisplayTestModel * model) { + instance->view, + ViewDisplayTestModel * model, + { if(event->key == InputKeyLeft && model->test > 0) { model->test--; consumed = true; @@ -129,8 +131,8 @@ static bool view_display_test_input_callback(InputEvent* event, void* context) { model->flip_flop = !model->flip_flop; consumed = true; } - return consumed; - }); + }, + consumed); } return consumed; @@ -149,10 +151,7 @@ static void view_display_test_exit(void* context) { static void view_display_test_timer_callback(void* context) { ViewDisplayTest* instance = context; with_view_model( - instance->view, (ViewDisplayTestModel * model) { - model->counter++; - return true; - }); + instance->view, ViewDisplayTestModel * model, { model->counter++; }, true); } ViewDisplayTest* view_display_test_alloc() { diff --git a/applications/debug/file_browser_test/file_browser_app.c b/applications/debug/file_browser_test/file_browser_app.c index c7f461d40..5c7b93bcb 100644 --- a/applications/debug/file_browser_test/file_browser_app.c +++ b/applications/debug/file_browser_test/file_browser_app.c @@ -1,7 +1,6 @@ #include "assets_icons.h" #include "file_browser_app_i.h" #include "gui/modules/file_browser.h" -#include "m-string.h" #include #include #include @@ -47,7 +46,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) { app->widget = widget_alloc(); - string_init(app->file_path); + app->file_path = furi_string_alloc(); app->file_browser = file_browser_alloc(app->file_path); file_browser_configure(app->file_browser, "*", true, &I_badusb_10px, true); @@ -84,7 +83,7 @@ void file_browser_app_free(FileBrowserApp* app) { furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_DIALOGS); - string_clear(app->file_path); + furi_string_free(app->file_path); free(app); } diff --git a/applications/debug/file_browser_test/file_browser_app_i.h b/applications/debug/file_browser_test/file_browser_app_i.h index 6e8412c9b..20f4c3a03 100644 --- a/applications/debug/file_browser_test/file_browser_app_i.h +++ b/applications/debug/file_browser_test/file_browser_app_i.h @@ -22,7 +22,7 @@ struct FileBrowserApp { Widget* widget; FileBrowser* file_browser; - string_t file_path; + FuriString* file_path; }; typedef enum { diff --git a/applications/debug/file_browser_test/scenes/file_browser_scene_browser.c b/applications/debug/file_browser_test/scenes/file_browser_scene_browser.c index d9bd1ac53..0bf70e9c6 100644 --- a/applications/debug/file_browser_test/scenes/file_browser_scene_browser.c +++ b/applications/debug/file_browser_test/scenes/file_browser_scene_browser.c @@ -1,8 +1,5 @@ #include "../file_browser_app_i.h" -#include -#include -#include "furi_hal.h" -#include "m-string.h" +#include #define DEFAULT_PATH "/" #define EXTENSION "*" diff --git a/applications/debug/file_browser_test/scenes/file_browser_scene_result.c b/applications/debug/file_browser_test/scenes/file_browser_scene_result.c index 53576cef4..4c68d80f7 100644 --- a/applications/debug/file_browser_test/scenes/file_browser_scene_result.c +++ b/applications/debug/file_browser_test/scenes/file_browser_scene_result.c @@ -1,6 +1,5 @@ #include "../file_browser_app_i.h" -#include "furi_hal.h" -#include "m-string.h" +#include void file_browser_scene_result_ok_callback(InputType type, void* context) { furi_assert(context); @@ -24,7 +23,13 @@ void file_browser_scene_result_on_enter(void* context) { FileBrowserApp* app = context; widget_add_string_multiline_element( - app->widget, 64, 10, AlignCenter, AlignTop, FontSecondary, string_get_cstr(app->file_path)); + app->widget, + 64, + 10, + AlignCenter, + AlignTop, + FontSecondary, + furi_string_get_cstr(app->file_path)); view_dispatcher_switch_to_view(app->view_dispatcher, FileBrowserAppViewResult); } diff --git a/applications/debug/file_browser_test/scenes/file_browser_scene_start.c b/applications/debug/file_browser_test/scenes/file_browser_scene_start.c index b3381f0ad..9eb26944f 100644 --- a/applications/debug/file_browser_test/scenes/file_browser_scene_start.c +++ b/applications/debug/file_browser_test/scenes/file_browser_scene_start.c @@ -19,7 +19,7 @@ bool file_browser_scene_start_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - string_set_str(app->file_path, ANY_PATH("badusb/demo_windows.txt")); + furi_string_set(app->file_path, ANY_PATH("badusb/demo_windows.txt")); scene_manager_next_scene(app->scene_manager, FileBrowserSceneBrowser); consumed = true; } else if(event.type == SceneManagerEventTypeTick) { diff --git a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c index 38fe36036..fd221c4e9 100644 --- a/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c +++ b/applications/debug/lfrfid_debug/views/lfrfid_debug_view_tune.c @@ -52,23 +52,29 @@ static void lfrfid_debug_view_tune_draw_callback(Canvas* canvas, void* _model) { static void lfrfid_debug_view_tune_button_up(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { if(model->pos > 0) model->pos--; - return true; - }); + }, + true); } static void lfrfid_debug_view_tune_button_down(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { if(model->pos < 1) model->pos++; - return true; - }); + }, + true); } static void lfrfid_debug_view_tune_button_left(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { if(model->pos == 0) { if(model->fine) { model->ARR -= 1; @@ -84,13 +90,15 @@ static void lfrfid_debug_view_tune_button_left(LfRfidTuneView* tune_view) { } model->dirty = true; - return true; - }); + }, + true); } static void lfrfid_debug_view_tune_button_right(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { if(model->pos == 0) { if(model->fine) { model->ARR += 1; @@ -106,16 +114,13 @@ static void lfrfid_debug_view_tune_button_right(LfRfidTuneView* tune_view) { } model->dirty = true; - return true; - }); + }, + true); } static void lfrfid_debug_view_tune_button_ok(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { - model->fine = !model->fine; - return true; - }); + tune_view->view, LfRfidTuneViewModel * model, { model->fine = !model->fine; }, true); } static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* context) { @@ -158,14 +163,16 @@ LfRfidTuneView* lfrfid_debug_view_tune_alloc() { view_allocate_model(tune_view->view, ViewModelTypeLocking, sizeof(LfRfidTuneViewModel)); with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { model->dirty = true; model->fine = false; model->ARR = 511; model->CCR = 255; model->pos = 0; - return true; - }); + }, + true); view_set_draw_callback(tune_view->view, lfrfid_debug_view_tune_draw_callback); view_set_input_callback(tune_view->view, lfrfid_debug_view_tune_input_callback); @@ -184,24 +191,28 @@ View* lfrfid_debug_view_tune_get_view(LfRfidTuneView* tune_view) { void lfrfid_debug_view_tune_clean(LfRfidTuneView* tune_view) { with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { model->dirty = true; model->fine = false; model->ARR = 511; model->CCR = 255; model->pos = 0; - return true; - }); + }, + true); } bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view) { bool result = false; with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { + tune_view->view, + LfRfidTuneViewModel * model, + { result = model->dirty; model->dirty = false; - return false; - }); + }, + false); return result; } @@ -209,10 +220,7 @@ bool lfrfid_debug_view_tune_is_dirty(LfRfidTuneView* tune_view) { uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view) { uint32_t result = false; with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { - result = model->ARR; - return false; - }); + tune_view->view, LfRfidTuneViewModel * model, { result = model->ARR; }, false); return result; } @@ -220,10 +228,7 @@ uint32_t lfrfid_debug_view_tune_get_arr(LfRfidTuneView* tune_view) { uint32_t lfrfid_debug_view_tune_get_ccr(LfRfidTuneView* tune_view) { uint32_t result = false; with_view_model( - tune_view->view, (LfRfidTuneViewModel * model) { - result = model->CCR; - return false; - }); + tune_view->view, LfRfidTuneViewModel * model, { result = model->CCR; }, false); return result; } diff --git a/applications/debug/uart_echo/uart_echo.c b/applications/debug/uart_echo/uart_echo.c index 7a0f5c393..701e5325a 100644 --- a/applications/debug/uart_echo/uart_echo.c +++ b/applications/debug/uart_echo/uart_echo.c @@ -1,10 +1,8 @@ #include -#include #include #include #include #include -#include #include #include #include @@ -21,11 +19,11 @@ typedef struct { ViewDispatcher* view_dispatcher; View* view; FuriThread* worker_thread; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* rx_stream; } UartEchoApp; typedef struct { - string_t text; + FuriString* text; } ListElement; struct UartDumpModel { @@ -64,10 +62,11 @@ static void uart_echo_view_draw_callback(Canvas* canvas, void* _model) { canvas, 0, (i + 1) * (canvas_current_font_height(canvas) - 1), - string_get_cstr(model->list[i]->text)); + furi_string_get_cstr(model->list[i]->text)); if(i == model->line) { - uint8_t width = canvas_string_width(canvas, string_get_cstr(model->list[i]->text)); + uint8_t width = + canvas_string_width(canvas, furi_string_get_cstr(model->list[i]->text)); canvas_draw_box( canvas, @@ -92,13 +91,11 @@ static uint32_t uart_echo_exit(void* context) { static void uart_echo_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { furi_assert(context); - BaseType_t xHigherPriorityTaskWoken = pdFALSE; UartEchoApp* app = context; if(ev == UartIrqEventRXNE) { - xStreamBufferSendFromISR(app->rx_stream, &data, 1, &xHigherPriorityTaskWoken); + furi_stream_buffer_send(app->rx_stream, &data, 1, 0); furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventRx); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } @@ -113,7 +110,7 @@ static void uart_echo_push_to_list(UartDumpModel* model, const char data) { model->escape = true; } else if((data >= ' ' && data <= '~') || (data == '\n' || data == '\r')) { bool new_string_needed = false; - if(string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) { + if(furi_string_size(model->list[model->line]->text) >= COLUMNS_ON_SCREEN) { new_string_needed = true; } else if((data == '\n' || data == '\r')) { // pack line breaks @@ -132,13 +129,13 @@ static void uart_echo_push_to_list(UartDumpModel* model, const char data) { model->list[i - 1] = model->list[i]; } - string_reset(first->text); + furi_string_reset(first->text); model->list[model->line] = first; } } if(data != '\n' && data != '\r') { - string_push_back(model->list[model->line]->text, data); + furi_string_push_back(model->list[model->line]->text, data); } } model->last_char = data; @@ -158,25 +155,24 @@ static int32_t uart_echo_worker(void* context) { size_t length = 0; do { uint8_t data[64]; - length = xStreamBufferReceive(app->rx_stream, data, 64, 0); + length = furi_stream_buffer_receive(app->rx_stream, data, 64, 0); if(length > 0) { furi_hal_uart_tx(FuriHalUartIdUSART1, data, length); with_view_model( - app->view, (UartDumpModel * model) { + app->view, + UartDumpModel * model, + { for(size_t i = 0; i < length; i++) { uart_echo_push_to_list(model, data[i]); } - return false; - }); + }, + false); } } while(length > 0); notification_message(app->notification, &sequence_notification); with_view_model( - app->view, (UartDumpModel * model) { - UNUSED(model); - return true; - }); + app->view, UartDumpModel * model, { UNUSED(model); }, true); } } @@ -186,7 +182,7 @@ static int32_t uart_echo_worker(void* context) { static UartEchoApp* uart_echo_app_alloc() { UartEchoApp* app = malloc(sizeof(UartEchoApp)); - app->rx_stream = xStreamBufferCreate(2048, 1); + app->rx_stream = furi_stream_buffer_alloc(2048, 1); // Gui app->gui = furi_record_open(RECORD_GUI); @@ -203,15 +199,17 @@ static UartEchoApp* uart_echo_app_alloc() { view_set_input_callback(app->view, uart_echo_view_input_callback); view_allocate_model(app->view, ViewModelTypeLocking, sizeof(UartDumpModel)); with_view_model( - app->view, (UartDumpModel * model) { + app->view, + UartDumpModel * model, + { for(size_t i = 0; i < LINES_ON_SCREEN; i++) { model->line = 0; model->escape = false; model->list[i] = malloc(sizeof(ListElement)); - string_init(model->list[i]->text); + model->list[i]->text = furi_string_alloc(); } - return true; - }); + }, + true); view_set_previous_callback(app->view, uart_echo_exit); view_dispatcher_add_view(app->view_dispatcher, 0, app->view); @@ -245,13 +243,15 @@ static void uart_echo_app_free(UartEchoApp* app) { view_dispatcher_remove_view(app->view_dispatcher, 0); with_view_model( - app->view, (UartDumpModel * model) { + app->view, + UartDumpModel * model, + { for(size_t i = 0; i < LINES_ON_SCREEN; i++) { - string_clear(model->list[i]->text); + furi_string_free(model->list[i]->text); free(model->list[i]); } - return true; - }); + }, + true); view_free(app->view); view_dispatcher_free(app->view_dispatcher); @@ -260,7 +260,7 @@ static void uart_echo_app_free(UartEchoApp* app) { furi_record_close(RECORD_NOTIFICATION); app->gui = NULL; - vStreamBufferDelete(app->rx_stream); + furi_stream_buffer_free(app->rx_stream); // Free rest free(app); diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c index b22b333a3..920a22a43 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_string_test.c @@ -58,7 +58,7 @@ static const char* test_data_win = "Filetype: Flipper Format test\r\n" #define ARRAY_W_BSIZE(x) (x), (sizeof(x)) MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { - string_t tmpstr; + FuriString* tmpstr; uint32_t version; uint32_t uint32_data[COUNT_OF(test_uint_data)]; int32_t int32_data[COUNT_OF(test_int_data)]; @@ -101,14 +101,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { mu_assert_int_eq(position_before, stream_tell(flipper_format_get_raw_stream(flipper_format))); // read test - string_init(tmpstr); + tmpstr = furi_string_alloc(); mu_check(flipper_format_read_header(flipper_format, tmpstr, &version)); - mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr)); mu_assert_int_eq(test_version, version); mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr)); - mu_assert_string_eq(test_string_data, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_string_data, furi_string_get_cstr(tmpstr)); mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count)); mu_assert_int_eq(COUNT_OF(test_int_data), count); @@ -133,7 +133,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr)); - string_clear(tmpstr); + furi_string_free(tmpstr); // update data mu_check(flipper_format_rewind(flipper_format)); @@ -155,14 +155,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { uint8_t hex_updated_data[COUNT_OF(test_hex_updated_data)]; mu_check(flipper_format_rewind(flipper_format)); - string_init(tmpstr); + tmpstr = furi_string_alloc(); mu_check(flipper_format_read_header(flipper_format, tmpstr, &version)); - mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr)); mu_assert_int_eq(test_version, version); mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr)); - mu_assert_string_eq(test_string_updated_data, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_string_updated_data, furi_string_get_cstr(tmpstr)); mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count)); mu_assert_int_eq(COUNT_OF(test_int_updated_data), count); @@ -190,7 +190,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr)); - string_clear(tmpstr); + furi_string_free(tmpstr); // update data mu_check(flipper_format_rewind(flipper_format)); @@ -214,14 +214,14 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { uint8_t hex_new_data[COUNT_OF(test_hex_new_data)]; mu_check(flipper_format_rewind(flipper_format)); - string_init(tmpstr); + tmpstr = furi_string_alloc(); mu_check(flipper_format_read_header(flipper_format, tmpstr, &version)); - mu_assert_string_eq(test_filetype, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_filetype, furi_string_get_cstr(tmpstr)); mu_assert_int_eq(test_version, version); mu_check(flipper_format_read_string(flipper_format, test_string_key, tmpstr)); - mu_assert_string_eq(test_string_updated_2_data, string_get_cstr(tmpstr)); + mu_assert_string_eq(test_string_updated_2_data, furi_string_get_cstr(tmpstr)); mu_check(flipper_format_get_value_count(flipper_format, test_int_key, &count)); mu_assert_int_eq(COUNT_OF(test_int_updated_2_data), count); @@ -255,7 +255,7 @@ MU_TEST_1(flipper_format_read_and_update_test, FlipperFormat* flipper_format) { mu_check(!flipper_format_read_string(flipper_format, "Key that doesn't exist", tmpstr)); - string_clear(tmpstr); + furi_string_free(tmpstr); // delete key test mu_check(flipper_format_rewind(flipper_format)); diff --git a/applications/debug/unit_tests/flipper_format/flipper_format_test.c b/applications/debug/unit_tests/flipper_format/flipper_format_test.c index 86e2df21e..012e905b6 100644 --- a/applications/debug/unit_tests/flipper_format/flipper_format_test.c +++ b/applications/debug/unit_tests/flipper_format/flipper_format_test.c @@ -57,6 +57,23 @@ static const char* test_data_win = "Filetype: Flipper File test\r\n" "Hex data: DE AD BE"; #define READ_TEST_FLP "ff_flp.test" +#define READ_TEST_ODD "ff_oddities.test" +static const char* test_data_odd = "Filetype: Flipper File test\n" + // Tabs before newline + "Version: 666\t\t\n" + "# This is comment\n" + // Windows newline in a UNIX file + "String data: String\r\n" + // Trailing whitespace + "Int32 data: 1234 -6345 7813 0 \n" + // Extra whitespace + "Uint32 data: 1234 0 5678 9098 7654321 \n" + // Mixed whitespace + "Float data: 1.5\t \t1000.0\n" + // Leading tabs after key + "Bool data:\t\ttrue false\n" + // Mixed trailing whitespace + "Hex data: DE AD BE\t "; // data created by user on linux machine static const char* test_file_linux = TEST_DIR READ_TEST_NIX; @@ -64,6 +81,8 @@ static const char* test_file_linux = TEST_DIR READ_TEST_NIX; static const char* test_file_windows = TEST_DIR READ_TEST_WIN; // data created by flipper itself static const char* test_file_flipper = TEST_DIR READ_TEST_FLP; +// data containing odd user input +static const char* test_file_oddities = TEST_DIR READ_TEST_ODD; static bool storage_write_string(const char* path, const char* data) { Storage* storage = furi_record_open(RECORD_STORAGE); @@ -102,8 +121,8 @@ static bool test_read(const char* file_name) { bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); - string_t string_value; - string_init(string_value); + FuriString* string_value; + string_value = furi_string_alloc(); uint32_t uint32_value; void* scratchpad = malloc(512); @@ -111,11 +130,11 @@ static bool test_read(const char* file_name) { if(!flipper_format_file_open_existing(file, file_name)) break; if(!flipper_format_read_header(file, string_value, &uint32_value)) break; - if(string_cmp_str(string_value, test_filetype) != 0) break; + if(furi_string_cmp_str(string_value, test_filetype) != 0) break; if(uint32_value != test_version) break; if(!flipper_format_read_string(file, test_string_key, string_value)) break; - if(string_cmp_str(string_value, test_string_data) != 0) break; + if(furi_string_cmp_str(string_value, test_string_data) != 0) break; if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break; if(uint32_value != COUNT_OF(test_int_data)) break; @@ -150,7 +169,7 @@ static bool test_read(const char* file_name) { } while(false); free(scratchpad); - string_clear(string_value); + furi_string_free(string_value); flipper_format_free(file); @@ -164,8 +183,8 @@ static bool test_read_updated(const char* file_name) { bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); - string_t string_value; - string_init(string_value); + FuriString* string_value; + string_value = furi_string_alloc(); uint32_t uint32_value; void* scratchpad = malloc(512); @@ -173,11 +192,11 @@ static bool test_read_updated(const char* file_name) { if(!flipper_format_file_open_existing(file, file_name)) break; if(!flipper_format_read_header(file, string_value, &uint32_value)) break; - if(string_cmp_str(string_value, test_filetype) != 0) break; + if(furi_string_cmp_str(string_value, test_filetype) != 0) break; if(uint32_value != test_version) break; if(!flipper_format_read_string(file, test_string_key, string_value)) break; - if(string_cmp_str(string_value, test_string_updated_data) != 0) break; + if(furi_string_cmp_str(string_value, test_string_updated_data) != 0) break; if(!flipper_format_get_value_count(file, test_int_key, &uint32_value)) break; if(uint32_value != COUNT_OF(test_int_updated_data)) break; @@ -228,7 +247,7 @@ static bool test_read_updated(const char* file_name) { } while(false); free(scratchpad); - string_clear(string_value); + furi_string_free(string_value); flipper_format_free(file); @@ -401,14 +420,14 @@ static bool test_read_multikey(const char* file_name) { bool result = false; FlipperFormat* file = flipper_format_file_alloc(storage); - string_t string_value; - string_init(string_value); + FuriString* string_value; + string_value = furi_string_alloc(); uint32_t uint32_value; do { if(!flipper_format_file_open_existing(file, file_name)) break; if(!flipper_format_read_header(file, string_value, &uint32_value)) break; - if(string_cmp_str(string_value, test_filetype) != 0) break; + if(furi_string_cmp_str(string_value, test_filetype) != 0) break; if(uint32_value != test_version) break; bool error = false; @@ -429,7 +448,7 @@ static bool test_read_multikey(const char* file_name) { result = true; } while(false); - string_clear(string_value); + furi_string_free(string_value); flipper_format_free(file); furi_record_close(RECORD_STORAGE); @@ -503,6 +522,12 @@ MU_TEST(flipper_format_multikey_test) { mu_assert(test_read_multikey(TEST_DIR "ff_multiline.test"), "Multikey read test error"); } +MU_TEST(flipper_format_oddities_test) { + mu_assert( + storage_write_string(test_file_oddities, test_data_odd), "Write test error [Oddities]"); + mu_assert(test_read(test_file_linux), "Read test error [Oddities]"); +} + MU_TEST_SUITE(flipper_format) { tests_setup(); MU_RUN_TEST(flipper_format_write_test); @@ -516,6 +541,7 @@ MU_TEST_SUITE(flipper_format) { MU_RUN_TEST(flipper_format_update_2_test); MU_RUN_TEST(flipper_format_update_2_result_test); MU_RUN_TEST(flipper_format_multikey_test); + MU_RUN_TEST(flipper_format_oddities_test); tests_teardown(); } diff --git a/applications/debug/unit_tests/furi/furi_string_test.c b/applications/debug/unit_tests/furi/furi_string_test.c new file mode 100644 index 000000000..3ea95b92b --- /dev/null +++ b/applications/debug/unit_tests/furi/furi_string_test.c @@ -0,0 +1,469 @@ +#include +#include "../minunit.h" + +static void test_setup(void) { +} + +static void test_teardown(void) { +} + +static FuriString* furi_string_alloc_vprintf_test(const char format[], ...) { + va_list args; + va_start(args, format); + FuriString* string = furi_string_alloc_vprintf(format, args); + va_end(args); + return string; +} + +MU_TEST(mu_test_furi_string_alloc_free) { + FuriString* tmp; + FuriString* string; + + // test alloc and free + string = furi_string_alloc(); + mu_check(string != NULL); + mu_check(furi_string_empty(string)); + furi_string_free(string); + + // test furi_string_alloc_set_str and free + string = furi_string_alloc_set_str("test"); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "test") == 0); + furi_string_free(string); + + // test furi_string_alloc_set and free + tmp = furi_string_alloc_set("more"); + string = furi_string_alloc_set(tmp); + furi_string_free(tmp); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "more") == 0); + furi_string_free(string); + + // test alloc_printf and free + string = furi_string_alloc_printf("test %d %s %c 0x%02x", 1, "two", '3', 0x04); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "test 1 two 3 0x04") == 0); + furi_string_free(string); + + // test alloc_vprintf and free + string = furi_string_alloc_vprintf_test("test %d %s %c 0x%02x", 4, "five", '6', 0x07); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "test 4 five 6 0x07") == 0); + furi_string_free(string); + + // test alloc_move and free + tmp = furi_string_alloc_set("move"); + string = furi_string_alloc_move(tmp); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + mu_check(furi_string_cmp(string, "move") == 0); + furi_string_free(string); +} + +MU_TEST(mu_test_furi_string_mem) { + FuriString* string = furi_string_alloc_set("test"); + mu_check(string != NULL); + mu_check(!furi_string_empty(string)); + + // TODO: how to test furi_string_reserve? + + // test furi_string_reset + furi_string_reset(string); + mu_check(furi_string_empty(string)); + + // test furi_string_swap + furi_string_set(string, "test"); + FuriString* swap_string = furi_string_alloc_set("swap"); + furi_string_swap(string, swap_string); + mu_check(furi_string_cmp(string, "swap") == 0); + mu_check(furi_string_cmp(swap_string, "test") == 0); + furi_string_free(swap_string); + + // test furi_string_move + FuriString* move_string = furi_string_alloc_set("move"); + furi_string_move(string, move_string); + mu_check(furi_string_cmp(string, "move") == 0); + // move_string is now empty + // and tested by leaked memory check at the end of the tests + + furi_string_set(string, "abracadabra"); + + // test furi_string_hash + mu_assert_int_eq(0xc3bc16d7, furi_string_hash(string)); + + // test furi_string_size + mu_assert_int_eq(11, furi_string_size(string)); + + // test furi_string_empty + mu_check(!furi_string_empty(string)); + furi_string_reset(string); + mu_check(furi_string_empty(string)); + + furi_string_free(string); +} + +MU_TEST(mu_test_furi_string_getters) { + FuriString* string = furi_string_alloc_set("test"); + + // test furi_string_get_char + mu_check(furi_string_get_char(string, 0) == 't'); + mu_check(furi_string_get_char(string, 1) == 'e'); + mu_check(furi_string_get_char(string, 2) == 's'); + mu_check(furi_string_get_char(string, 3) == 't'); + + // test furi_string_get_cstr + mu_assert_string_eq("test", furi_string_get_cstr(string)); + furi_string_free(string); +} + +static FuriString* furi_string_vprintf_test(FuriString* string, const char format[], ...) { + va_list args; + va_start(args, format); + furi_string_vprintf(string, format, args); + va_end(args); + return string; +} + +MU_TEST(mu_test_furi_string_setters) { + FuriString* tmp; + FuriString* string = furi_string_alloc(); + + // test furi_string_set_str + furi_string_set_str(string, "test"); + mu_assert_string_eq("test", furi_string_get_cstr(string)); + + // test furi_string_set + tmp = furi_string_alloc_set("more"); + furi_string_set(string, tmp); + furi_string_free(tmp); + mu_assert_string_eq("more", furi_string_get_cstr(string)); + + // test furi_string_set_strn + furi_string_set_strn(string, "test", 2); + mu_assert_string_eq("te", furi_string_get_cstr(string)); + + // test furi_string_set_char + furi_string_set_char(string, 0, 'a'); + furi_string_set_char(string, 1, 'b'); + mu_assert_string_eq("ab", furi_string_get_cstr(string)); + + // test furi_string_set_n + tmp = furi_string_alloc_set("dodecahedron"); + furi_string_set_n(string, tmp, 4, 5); + furi_string_free(tmp); + mu_assert_string_eq("cahed", furi_string_get_cstr(string)); + + // test furi_string_printf + furi_string_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04); + mu_assert_string_eq("test 1 two 3 0x04", furi_string_get_cstr(string)); + + // test furi_string_vprintf + furi_string_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07); + mu_assert_string_eq("test 4 five 6 0x07", furi_string_get_cstr(string)); + + furi_string_free(string); +} + +static FuriString* furi_string_cat_vprintf_test(FuriString* string, const char format[], ...) { + va_list args; + va_start(args, format); + furi_string_cat_vprintf(string, format, args); + va_end(args); + return string; +} + +MU_TEST(mu_test_furi_string_appends) { + FuriString* tmp; + FuriString* string = furi_string_alloc(); + + // test furi_string_push_back + furi_string_push_back(string, 't'); + furi_string_push_back(string, 'e'); + furi_string_push_back(string, 's'); + furi_string_push_back(string, 't'); + mu_assert_string_eq("test", furi_string_get_cstr(string)); + furi_string_push_back(string, '!'); + mu_assert_string_eq("test!", furi_string_get_cstr(string)); + + // test furi_string_cat_str + furi_string_cat_str(string, "test"); + mu_assert_string_eq("test!test", furi_string_get_cstr(string)); + + // test furi_string_cat + tmp = furi_string_alloc_set("more"); + furi_string_cat(string, tmp); + furi_string_free(tmp); + mu_assert_string_eq("test!testmore", furi_string_get_cstr(string)); + + // test furi_string_cat_printf + furi_string_cat_printf(string, "test %d %s %c 0x%02x", 1, "two", '3', 0x04); + mu_assert_string_eq("test!testmoretest 1 two 3 0x04", furi_string_get_cstr(string)); + + // test furi_string_cat_vprintf + furi_string_cat_vprintf_test(string, "test %d %s %c 0x%02x", 4, "five", '6', 0x07); + mu_assert_string_eq( + "test!testmoretest 1 two 3 0x04test 4 five 6 0x07", furi_string_get_cstr(string)); + + furi_string_free(string); +} + +MU_TEST(mu_test_furi_string_compare) { + FuriString* string_1 = furi_string_alloc_set("string_1"); + FuriString* string_2 = furi_string_alloc_set("string_2"); + + // test furi_string_cmp + mu_assert_int_eq(0, furi_string_cmp(string_1, string_1)); + mu_assert_int_eq(0, furi_string_cmp(string_2, string_2)); + mu_assert_int_eq(-1, furi_string_cmp(string_1, string_2)); + mu_assert_int_eq(1, furi_string_cmp(string_2, string_1)); + + // test furi_string_cmp_str + mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string_1")); + mu_assert_int_eq(0, furi_string_cmp_str(string_2, "string_2")); + mu_assert_int_eq(-1, furi_string_cmp_str(string_1, "string_2")); + mu_assert_int_eq(1, furi_string_cmp_str(string_2, "string_1")); + + // test furi_string_cmpi + furi_string_set(string_1, "string"); + furi_string_set(string_2, "StrIng"); + mu_assert_int_eq(0, furi_string_cmpi(string_1, string_1)); + mu_assert_int_eq(0, furi_string_cmpi(string_2, string_2)); + mu_assert_int_eq(0, furi_string_cmpi(string_1, string_2)); + mu_assert_int_eq(0, furi_string_cmpi(string_2, string_1)); + furi_string_set(string_1, "string_1"); + furi_string_set(string_2, "StrIng_2"); + mu_assert_int_eq(32, furi_string_cmp(string_1, string_2)); + mu_assert_int_eq(-32, furi_string_cmp(string_2, string_1)); + mu_assert_int_eq(-1, furi_string_cmpi(string_1, string_2)); + mu_assert_int_eq(1, furi_string_cmpi(string_2, string_1)); + + // test furi_string_cmpi_str + furi_string_set(string_1, "string"); + mu_assert_int_eq(0, furi_string_cmp_str(string_1, "string")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "String")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STring")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRing")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRIng")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRINg")); + mu_assert_int_eq(32, furi_string_cmp_str(string_1, "STRING")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "string")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "String")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STring")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRing")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRIng")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRINg")); + mu_assert_int_eq(0, furi_string_cmpi_str(string_1, "STRING")); + + furi_string_free(string_1); + furi_string_free(string_2); +} + +MU_TEST(mu_test_furi_string_search) { + // 012345678901234567 + FuriString* haystack = furi_string_alloc_set("test321test123test"); + FuriString* needle = furi_string_alloc_set("test"); + + // test furi_string_search + mu_assert_int_eq(0, furi_string_search(haystack, needle)); + mu_assert_int_eq(7, furi_string_search(haystack, needle, 1)); + mu_assert_int_eq(14, furi_string_search(haystack, needle, 8)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, needle, 15)); + + FuriString* tmp = furi_string_alloc_set("testnone"); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search(haystack, tmp)); + furi_string_free(tmp); + + // test furi_string_search_str + mu_assert_int_eq(0, furi_string_search_str(haystack, "test")); + mu_assert_int_eq(7, furi_string_search_str(haystack, "test", 1)); + mu_assert_int_eq(14, furi_string_search_str(haystack, "test", 8)); + mu_assert_int_eq(4, furi_string_search_str(haystack, "321")); + mu_assert_int_eq(11, furi_string_search_str(haystack, "123")); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "testnone")); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_str(haystack, "test", 15)); + + // test furi_string_search_char + mu_assert_int_eq(0, furi_string_search_char(haystack, 't')); + mu_assert_int_eq(1, furi_string_search_char(haystack, 'e')); + mu_assert_int_eq(2, furi_string_search_char(haystack, 's')); + mu_assert_int_eq(3, furi_string_search_char(haystack, 't', 1)); + mu_assert_int_eq(7, furi_string_search_char(haystack, 't', 4)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_char(haystack, 'x')); + + // test furi_string_search_rchar + mu_assert_int_eq(17, furi_string_search_rchar(haystack, 't')); + mu_assert_int_eq(15, furi_string_search_rchar(haystack, 'e')); + mu_assert_int_eq(16, furi_string_search_rchar(haystack, 's')); + mu_assert_int_eq(13, furi_string_search_rchar(haystack, '3')); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, '3', 14)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_search_rchar(haystack, 'x')); + + furi_string_free(haystack); + furi_string_free(needle); +} + +MU_TEST(mu_test_furi_string_equality) { + FuriString* string = furi_string_alloc_set("test"); + FuriString* string_eq = furi_string_alloc_set("test"); + FuriString* string_neq = furi_string_alloc_set("test2"); + + // test furi_string_equal + mu_check(furi_string_equal(string, string_eq)); + mu_check(!furi_string_equal(string, string_neq)); + + // test furi_string_equal_str + mu_check(furi_string_equal_str(string, "test")); + mu_check(!furi_string_equal_str(string, "test2")); + mu_check(furi_string_equal_str(string_neq, "test2")); + mu_check(!furi_string_equal_str(string_neq, "test")); + + furi_string_free(string); + furi_string_free(string_eq); + furi_string_free(string_neq); +} + +MU_TEST(mu_test_furi_string_replace) { + FuriString* needle = furi_string_alloc_set("test"); + FuriString* replace = furi_string_alloc_set("replace"); + FuriString* string = furi_string_alloc_set("test123test"); + + // test furi_string_replace_at + furi_string_replace_at(string, 4, 3, "!biglongword!"); + mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string)); + + // test furi_string_replace + mu_assert_int_eq(17, furi_string_replace(string, needle, replace, 1)); + mu_assert_string_eq("test!biglongword!replace", furi_string_get_cstr(string)); + mu_assert_int_eq(0, furi_string_replace(string, needle, replace)); + mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace(string, needle, replace)); + mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string)); + + // test furi_string_replace_str + mu_assert_int_eq(20, furi_string_replace_str(string, "replace", "test", 1)); + mu_assert_string_eq("replace!biglongword!test", furi_string_get_cstr(string)); + mu_assert_int_eq(0, furi_string_replace_str(string, "replace", "test")); + mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string)); + mu_assert_int_eq(FURI_STRING_FAILURE, furi_string_replace_str(string, "replace", "test")); + mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string)); + + // test furi_string_replace_all + furi_string_replace_all(string, needle, replace); + mu_assert_string_eq("replace!biglongword!replace", furi_string_get_cstr(string)); + + // test furi_string_replace_all_str + furi_string_replace_all_str(string, "replace", "test"); + mu_assert_string_eq("test!biglongword!test", furi_string_get_cstr(string)); + + furi_string_free(string); + furi_string_free(needle); + furi_string_free(replace); +} + +MU_TEST(mu_test_furi_string_start_end) { + FuriString* string = furi_string_alloc_set("start_end"); + FuriString* start = furi_string_alloc_set("start"); + FuriString* end = furi_string_alloc_set("end"); + + // test furi_string_start_with + mu_check(furi_string_start_with(string, start)); + mu_check(!furi_string_start_with(string, end)); + + // test furi_string_start_with_str + mu_check(furi_string_start_with_str(string, "start")); + mu_check(!furi_string_start_with_str(string, "end")); + + // test furi_string_end_with + mu_check(furi_string_end_with(string, end)); + mu_check(!furi_string_end_with(string, start)); + + // test furi_string_end_with_str + mu_check(furi_string_end_with_str(string, "end")); + mu_check(!furi_string_end_with_str(string, "start")); + + furi_string_free(string); + furi_string_free(start); + furi_string_free(end); +} + +MU_TEST(mu_test_furi_string_trim) { + FuriString* string = furi_string_alloc_set("biglongstring"); + + // test furi_string_left + furi_string_left(string, 7); + mu_assert_string_eq("biglong", furi_string_get_cstr(string)); + + // test furi_string_right + furi_string_right(string, 3); + mu_assert_string_eq("long", furi_string_get_cstr(string)); + + // test furi_string_mid + furi_string_mid(string, 1, 2); + mu_assert_string_eq("on", furi_string_get_cstr(string)); + + // test furi_string_trim + furi_string_set(string, " \n\r\tbiglongstring \n\r\t "); + furi_string_trim(string); + mu_assert_string_eq("biglongstring", furi_string_get_cstr(string)); + furi_string_set(string, "aaaabaaaabbaaabaaaabbtestaaaaaabbaaabaababaa"); + furi_string_trim(string, "ab"); + mu_assert_string_eq("test", furi_string_get_cstr(string)); + + furi_string_free(string); +} + +MU_TEST(mu_test_furi_string_utf8) { + FuriString* utf8_string = furi_string_alloc_set("イルカ"); + + // test furi_string_utf8_length + mu_assert_int_eq(9, furi_string_size(utf8_string)); + mu_assert_int_eq(3, furi_string_utf8_length(utf8_string)); + + // test furi_string_utf8_decode + const uint8_t dolphin_emoji_array[4] = {0xF0, 0x9F, 0x90, 0xAC}; + FuriStringUTF8State state = FuriStringUTF8StateStarting; + FuriStringUnicodeValue value = 0; + furi_string_utf8_decode(dolphin_emoji_array[0], &state, &value); + mu_assert_int_eq(FuriStringUTF8StateDecoding3, state); + furi_string_utf8_decode(dolphin_emoji_array[1], &state, &value); + mu_assert_int_eq(FuriStringUTF8StateDecoding2, state); + furi_string_utf8_decode(dolphin_emoji_array[2], &state, &value); + mu_assert_int_eq(FuriStringUTF8StateDecoding1, state); + furi_string_utf8_decode(dolphin_emoji_array[3], &state, &value); + mu_assert_int_eq(FuriStringUTF8StateStarting, state); + mu_assert_int_eq(0x1F42C, value); + + // test furi_string_utf8_push + furi_string_set(utf8_string, ""); + furi_string_utf8_push(utf8_string, value); + mu_assert_string_eq("🐬", furi_string_get_cstr(utf8_string)); + + furi_string_free(utf8_string); +} + +MU_TEST_SUITE(test_suite) { + MU_SUITE_CONFIGURE(&test_setup, &test_teardown); + + MU_RUN_TEST(mu_test_furi_string_alloc_free); + MU_RUN_TEST(mu_test_furi_string_mem); + MU_RUN_TEST(mu_test_furi_string_getters); + MU_RUN_TEST(mu_test_furi_string_setters); + MU_RUN_TEST(mu_test_furi_string_appends); + MU_RUN_TEST(mu_test_furi_string_compare); + MU_RUN_TEST(mu_test_furi_string_search); + MU_RUN_TEST(mu_test_furi_string_equality); + MU_RUN_TEST(mu_test_furi_string_replace); + MU_RUN_TEST(mu_test_furi_string_start_end); + MU_RUN_TEST(mu_test_furi_string_trim); + MU_RUN_TEST(mu_test_furi_string_utf8); +} + +int run_minunit_test_furi_string() { + MU_RUN_SUITE(test_suite); + + return MU_EXIT_CODE; +} \ No newline at end of file diff --git a/applications/debug/unit_tests/infrared/infrared_test.c b/applications/debug/unit_tests/infrared/infrared_test.c index 32266c48e..8879c8fc8 100644 --- a/applications/debug/unit_tests/infrared/infrared_test.c +++ b/applications/debug/unit_tests/infrared/infrared_test.c @@ -11,7 +11,7 @@ typedef struct { InfraredDecoderHandler* decoder_handler; InfraredEncoderHandler* encoder_handler; - string_t file_path; + FuriString* file_path; FlipperFormat* ff; } InfraredTest; @@ -23,7 +23,7 @@ static void infrared_test_alloc() { test->decoder_handler = infrared_alloc_decoder(); test->encoder_handler = infrared_alloc_encoder(); test->ff = flipper_format_buffered_file_alloc(storage); - string_init(test->file_path); + test->file_path = furi_string_alloc(); } static void infrared_test_free() { @@ -31,18 +31,18 @@ static void infrared_test_free() { infrared_free_decoder(test->decoder_handler); infrared_free_encoder(test->encoder_handler); flipper_format_free(test->ff); - string_clear(test->file_path); + furi_string_free(test->file_path); furi_record_close(RECORD_STORAGE); free(test); test = NULL; } static bool infrared_test_prepare_file(const char* protocol_name) { - string_t file_type; - string_init(file_type); + FuriString* file_type; + file_type = furi_string_alloc(); bool success = false; - string_printf( + furi_string_printf( test->file_path, "%s%s%s%s", IR_TEST_FILES_DIR, @@ -52,14 +52,15 @@ static bool infrared_test_prepare_file(const char* protocol_name) { do { uint32_t format_version; - if(!flipper_format_buffered_file_open_existing(test->ff, string_get_cstr(test->file_path))) + if(!flipper_format_buffered_file_open_existing( + test->ff, furi_string_get_cstr(test->file_path))) break; if(!flipper_format_read_header(test->ff, file_type, &format_version)) break; - if(string_cmp_str(file_type, "IR tests file") || format_version != 1) break; + if(furi_string_cmp_str(file_type, "IR tests file") || format_version != 1) break; success = true; } while(false); - string_clear(file_type); + furi_string_free(file_type); return success; } @@ -68,18 +69,18 @@ static bool infrared_test_load_raw_signal( const char* signal_name, uint32_t** timings, uint32_t* timings_count) { - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); bool success = false; do { bool is_name_found = false; for(; !is_name_found && flipper_format_read_string(ff, "name", buf); - is_name_found = !string_cmp_str(buf, signal_name)) + is_name_found = !furi_string_cmp(buf, signal_name)) ; if(!is_name_found) break; - if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "raw")) break; + if(!flipper_format_read_string(ff, "type", buf) || furi_string_cmp_str(buf, "raw")) break; if(!flipper_format_get_value_count(ff, "data", timings_count)) break; if(!*timings_count) break; @@ -91,18 +92,18 @@ static bool infrared_test_load_raw_signal( success = true; } while(false); - string_clear(buf); + furi_string_free(buf); return success; } static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* message) { - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); bool success = false; do { if(!flipper_format_read_string(ff, "protocol", buf)) break; - message->protocol = infrared_get_protocol_by_name(string_get_cstr(buf)); + message->protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf)); if(!infrared_is_protocol_valid(message->protocol)) break; if(!flipper_format_read_hex(ff, "address", (uint8_t*)&message->address, sizeof(uint32_t))) break; @@ -112,7 +113,7 @@ static bool infrared_test_read_message(FlipperFormat* ff, InfraredMessage* messa success = true; } while(false); - string_clear(buf); + furi_string_free(buf); return success; } @@ -121,18 +122,19 @@ static bool infrared_test_load_messages( const char* signal_name, InfraredMessage** messages, uint32_t* messages_count) { - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); bool success = false; do { bool is_name_found = false; for(; !is_name_found && flipper_format_read_string(ff, "name", buf); - is_name_found = !string_cmp_str(buf, signal_name)) + is_name_found = !furi_string_cmp(buf, signal_name)) ; if(!is_name_found) break; - if(!flipper_format_read_string(ff, "type", buf) || string_cmp_str(buf, "parsed_array")) + if(!flipper_format_read_string(ff, "type", buf) || + furi_string_cmp_str(buf, "parsed_array")) break; if(!flipper_format_read_uint32(ff, "count", messages_count, 1)) break; if(!*messages_count) break; @@ -151,7 +153,7 @@ static bool infrared_test_load_messages( success = true; } while(false); - string_clear(buf); + furi_string_free(buf); return success; } @@ -213,26 +215,26 @@ static void infrared_test_run_encoder(InfraredProtocol protocol, uint32_t test_i InfraredMessage* input_messages; uint32_t input_messages_count; - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); const char* protocol_name = infrared_get_protocol_name(protocol); mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); - string_printf(buf, "encoder_input%d", test_index); + furi_string_printf(buf, "encoder_input%ld", test_index); mu_assert( infrared_test_load_messages( - test->ff, string_get_cstr(buf), &input_messages, &input_messages_count), + test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count), "Failed to load messages from file"); - string_printf(buf, "encoder_expected%d", test_index); + furi_string_printf(buf, "encoder_expected%ld", test_index); mu_assert( infrared_test_load_raw_signal( - test->ff, string_get_cstr(buf), &expected_timings, &expected_timings_count), + test->ff, furi_string_get_cstr(buf), &expected_timings, &expected_timings_count), "Failed to load raw signal from file"); flipper_format_buffered_file_close(test->ff); - string_clear(buf); + furi_string_free(buf); uint32_t j = 0; timings = malloc(sizeof(uint32_t) * timings_count); @@ -267,22 +269,22 @@ static void infrared_test_run_encoder_decoder(InfraredProtocol protocol, uint32_ uint32_t input_messages_count; bool level = false; - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); timings = malloc(sizeof(uint32_t) * timings_count); const char* protocol_name = infrared_get_protocol_name(protocol); mu_assert(infrared_test_prepare_file(protocol_name), "Failed to prepare test file"); - string_printf(buf, "encoder_decoder_input%d", test_index); + furi_string_printf(buf, "encoder_decoder_input%ld", test_index); mu_assert( infrared_test_load_messages( - test->ff, string_get_cstr(buf), &input_messages, &input_messages_count), + test->ff, furi_string_get_cstr(buf), &input_messages, &input_messages_count), "Failed to load messages from file"); flipper_format_buffered_file_close(test->ff); - string_clear(buf); + furi_string_free(buf); for(uint32_t message_counter = 0; message_counter < input_messages_count; ++message_counter) { const InfraredMessage* message_encoded = &input_messages[message_counter]; @@ -327,25 +329,27 @@ static void infrared_test_run_decoder(InfraredProtocol protocol, uint32_t test_i InfraredMessage* messages; uint32_t messages_count; - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); mu_assert( infrared_test_prepare_file(infrared_get_protocol_name(protocol)), "Failed to prepare test file"); - string_printf(buf, "decoder_input%d", test_index); + furi_string_printf(buf, "decoder_input%ld", test_index); mu_assert( - infrared_test_load_raw_signal(test->ff, string_get_cstr(buf), &timings, &timings_count), + infrared_test_load_raw_signal( + test->ff, furi_string_get_cstr(buf), &timings, &timings_count), "Failed to load raw signal from file"); - string_printf(buf, "decoder_expected%d", test_index); + furi_string_printf(buf, "decoder_expected%ld", test_index); mu_assert( - infrared_test_load_messages(test->ff, string_get_cstr(buf), &messages, &messages_count), + infrared_test_load_messages( + test->ff, furi_string_get_cstr(buf), &messages, &messages_count), "Failed to load messages from file"); flipper_format_buffered_file_close(test->ff); - string_clear(buf); + furi_string_free(buf); InfraredMessage message_decoded_check_local; bool level = 0; diff --git a/applications/debug/unit_tests/nfc/nfc_test.c b/applications/debug/unit_tests/nfc/nfc_test.c index 580943f24..f149508b0 100644 --- a/applications/debug/unit_tests/nfc/nfc_test.c +++ b/applications/debug/unit_tests/nfc/nfc_test.c @@ -53,14 +53,15 @@ static bool nfc_test_read_signal_from_file(const char* file_name) { bool success = false; FlipperFormat* file = flipper_format_file_alloc(nfc_test->storage); - string_t file_type; - string_init(file_type); + FuriString* file_type; + file_type = furi_string_alloc(); uint32_t file_version = 0; do { if(!flipper_format_file_open_existing(file, file_name)) break; if(!flipper_format_read_header(file, file_type, &file_version)) break; - if(string_cmp_str(file_type, nfc_test_file_type) || file_version != nfc_test_file_version) + if(furi_string_cmp_str(file_type, nfc_test_file_type) || + file_version != nfc_test_file_version) break; if(!flipper_format_read_uint32(file, "Data length", &nfc_test->test_data_len, 1)) break; if(nfc_test->test_data_len > NFC_TEST_DATA_MAX_LEN) break; @@ -76,7 +77,7 @@ static bool nfc_test_read_signal_from_file(const char* file_name) { success = true; } while(false); - string_clear(file_type); + furi_string_free(file_type); flipper_format_free(file); return success; @@ -111,7 +112,7 @@ static bool nfc_test_digital_signal_test_encode( // Check timings if(time > encode_max_time) { FURI_LOG_E( - TAG, "Encoding time: %d us while accepted value: %d us", time, encode_max_time); + TAG, "Encoding time: %ld us while accepted value: %ld us", time, encode_max_time); break; } @@ -131,7 +132,7 @@ static bool nfc_test_digital_signal_test_encode( ref_timings_sum += ref[i]; if(timings_diff > timing_tolerance) { FURI_LOG_E( - TAG, "Too big differece in %d timings. Ref: %d, DUT: %d", i, ref[i], dut[i]); + TAG, "Too big differece in %d timings. Ref: %ld, DUT: %ld", i, ref[i], dut[i]); timing_check_success = false; break; } @@ -142,16 +143,16 @@ static bool nfc_test_digital_signal_test_encode( if(sum_diff > timings_sum_tolerance) { FURI_LOG_E( TAG, - "Too big difference in timings sum. Ref: %d, DUT: %d", + "Too big difference in timings sum. Ref: %ld, DUT: %ld", ref_timings_sum, dut_timings_sum); break; } - FURI_LOG_I(TAG, "Encoding time: %d us. Acceptable time: %d us", time, encode_max_time); + FURI_LOG_I(TAG, "Encoding time: %ld us. Acceptable time: %ld us", time, encode_max_time); FURI_LOG_I( TAG, - "Timings sum difference: %d [1/64MHZ]. Acceptable difference: %d [1/64MHz]", + "Timings sum difference: %ld [1/64MHZ]. Acceptable difference: %ld [1/64MHz]", sum_diff, timings_sum_tolerance); success = true; @@ -174,8 +175,8 @@ MU_TEST(nfc_digital_signal_test) { MU_TEST(mf_classic_dict_test) { MfClassicDict* instance = NULL; uint64_t key = 0; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); instance = mf_classic_dict_alloc(MfClassicDictTypeUnitTest); mu_assert(instance != NULL, "mf_classic_dict_alloc\r\n"); @@ -184,7 +185,7 @@ MU_TEST(mf_classic_dict_test) { mf_classic_dict_get_total_keys(instance) == 0, "mf_classic_dict_get_total_keys == 0 assert failed\r\n"); - string_set(temp_str, "2196FAD8115B"); + furi_string_set(temp_str, "2196FAD8115B"); mu_assert( mf_classic_dict_add_key_str(instance, temp_str), "mf_classic_dict_add_key == true assert failed\r\n"); @@ -199,7 +200,7 @@ MU_TEST(mf_classic_dict_test) { mf_classic_dict_get_key_at_index_str(instance, temp_str, 0), "mf_classic_dict_get_key_at_index_str == true assert failed\r\n"); mu_assert( - string_cmp(temp_str, "2196FAD8115B") == 0, + furi_string_cmp(temp_str, "2196FAD8115B") == 0, "string_cmp(temp_str, \"2196FAD8115B\") == 0 assert failed\r\n"); mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n"); @@ -216,7 +217,7 @@ MU_TEST(mf_classic_dict_test) { "mf_classic_dict_delete_index == true assert failed\r\n"); mf_classic_dict_free(instance); - string_clear(temp_str); + furi_string_free(temp_str); } MU_TEST_SUITE(nfc) { diff --git a/applications/debug/unit_tests/rpc/rpc_test.c b/applications/debug/unit_tests/rpc/rpc_test.c index 6ee2aed65..5b52df2fa 100644 --- a/applications/debug/unit_tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/rpc/rpc_test.c @@ -10,7 +10,6 @@ #include #include "../minunit.h" #include -#include #include #include #include @@ -34,7 +33,7 @@ static uint32_t command_id = 0; typedef struct { RpcSession* session; - StreamBufferHandle_t output_stream; + FuriStreamBuffer* output_stream; SemaphoreHandle_t close_session_semaphore; SemaphoreHandle_t terminate_semaphore; TickType_t timeout; @@ -90,7 +89,7 @@ static void test_rpc_setup(void) { } furi_check(rpc_session[0].session); - rpc_session[0].output_stream = xStreamBufferCreate(1000, 1); + rpc_session[0].output_stream = furi_stream_buffer_alloc(1000, 1); rpc_session_set_send_bytes_callback(rpc_session[0].session, output_bytes_callback); rpc_session[0].close_session_semaphore = xSemaphoreCreateBinary(); rpc_session[0].terminate_semaphore = xSemaphoreCreateBinary(); @@ -110,7 +109,7 @@ static void test_rpc_setup_second_session(void) { } furi_check(rpc_session[1].session); - rpc_session[1].output_stream = xStreamBufferCreate(1000, 1); + rpc_session[1].output_stream = furi_stream_buffer_alloc(1000, 1); rpc_session_set_send_bytes_callback(rpc_session[1].session, output_bytes_callback); rpc_session[1].close_session_semaphore = xSemaphoreCreateBinary(); rpc_session[1].terminate_semaphore = xSemaphoreCreateBinary(); @@ -126,7 +125,7 @@ static void test_rpc_teardown(void) { rpc_session_close(rpc_session[0].session); furi_check(xSemaphoreTake(rpc_session[0].terminate_semaphore, portMAX_DELAY)); furi_record_close(RECORD_RPC); - vStreamBufferDelete(rpc_session[0].output_stream); + furi_stream_buffer_free(rpc_session[0].output_stream); vSemaphoreDelete(rpc_session[0].close_session_semaphore); vSemaphoreDelete(rpc_session[0].terminate_semaphore); ++command_id; @@ -141,7 +140,7 @@ static void test_rpc_teardown_second_session(void) { xSemaphoreTake(rpc_session[1].terminate_semaphore, 0); rpc_session_close(rpc_session[1].session); furi_check(xSemaphoreTake(rpc_session[1].terminate_semaphore, portMAX_DELAY)); - vStreamBufferDelete(rpc_session[1].output_stream); + furi_stream_buffer_free(rpc_session[1].output_stream); vSemaphoreDelete(rpc_session[1].close_session_semaphore); vSemaphoreDelete(rpc_session[1].terminate_semaphore); ++command_id; @@ -268,8 +267,8 @@ static PB_CommandStatus test_rpc_storage_get_file_error(File* file) { static void output_bytes_callback(void* ctx, uint8_t* got_bytes, size_t got_size) { RpcSessionContext* callbacks_context = ctx; - size_t bytes_sent = - xStreamBufferSend(callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever); + size_t bytes_sent = furi_stream_buffer_send( + callbacks_context->output_stream, got_bytes, got_size, FuriWaitForever); (void)bytes_sent; furi_check(bytes_sent == got_size); } @@ -534,7 +533,8 @@ static bool test_rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_ TickType_t now = xTaskGetTickCount(); int32_t time_left = session_context->timeout - now; time_left = MAX(time_left, 0); - bytes_received = xStreamBufferReceive(session_context->output_stream, buf, count, time_left); + bytes_received = + furi_stream_buffer_receive(session_context->output_stream, buf, count, time_left); return (count == bytes_received); } diff --git a/applications/debug/unit_tests/storage/dirwalk_test.c b/applications/debug/unit_tests/storage/dirwalk_test.c index db3d91a96..97aaa3580 100644 --- a/applications/debug/unit_tests/storage/dirwalk_test.c +++ b/applications/debug/unit_tests/storage/dirwalk_test.c @@ -75,7 +75,7 @@ typedef struct { bool visited; } StorageTestPath; -DICT_DEF2(StorageTestPathDict, string_t, STRING_OPLIST, StorageTestPath, M_POD_OPLIST) +DICT_DEF2(StorageTestPathDict, FuriString*, FURI_STRING_OPLIST, StorageTestPath, M_POD_OPLIST) static StorageTestPathDict_t* storage_test_paths_alloc(const StorageTestPathDesc paths[], size_t paths_count) { @@ -83,15 +83,15 @@ static StorageTestPathDict_t* StorageTestPathDict_init(*data); for(size_t i = 0; i < paths_count; i++) { - string_t key; - string_init_set(key, paths[i].path); + FuriString* key; + key = furi_string_alloc_set(paths[i].path); StorageTestPath value = { .is_dir = paths[i].is_dir, .visited = false, }; StorageTestPathDict_set_at(*data, key, value); - string_clear(key); + furi_string_free(key); } return data; @@ -102,7 +102,7 @@ static void storage_test_paths_free(StorageTestPathDict_t* data) { free(data); } -static bool storage_test_paths_mark(StorageTestPathDict_t* data, string_t path, bool is_dir) { +static bool storage_test_paths_mark(StorageTestPathDict_t* data, FuriString* path, bool is_dir) { bool found = false; StorageTestPath* record = StorageTestPathDict_get(*data, path); @@ -148,27 +148,27 @@ static bool write_file_13DA(Storage* storage, const char* path) { } static void storage_dirs_create(Storage* storage, const char* base) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); storage_common_mkdir(storage, base); for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_paths); i++) { - string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]); - storage_common_mkdir(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_test_dirwalk_paths[i]); + storage_common_mkdir(storage, furi_string_get_cstr(path)); } for(size_t i = 0; i < COUNT_OF(storage_test_dirwalk_files); i++) { - string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]); - write_file_13DA(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_test_dirwalk_files[i]); + write_file_13DA(storage, furi_string_get_cstr(path)); } - string_clear(path); + furi_string_free(path); } MU_TEST_1(test_dirwalk_full, Storage* storage) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); FileInfo fileinfo; StorageTestPathDict_t* paths = @@ -178,12 +178,12 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) { mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen(EXT_PATH("dirwalk/"))); + furi_string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } dir_walk_free(dir_walk); - string_clear(path); + furi_string_free(path); mu_check(storage_test_paths_check(paths) == false); @@ -191,8 +191,8 @@ MU_TEST_1(test_dirwalk_full, Storage* storage) { } MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); FileInfo fileinfo; StorageTestPathDict_t* paths = storage_test_paths_alloc( @@ -203,12 +203,12 @@ MU_TEST_1(test_dirwalk_no_recursive, Storage* storage) { mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen(EXT_PATH("dirwalk/"))); + furi_string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } dir_walk_free(dir_walk); - string_clear(path); + furi_string_free(path); mu_check(storage_test_paths_check(paths) == false); @@ -230,8 +230,8 @@ static bool test_dirwalk_filter_no_folder_ext(const char* name, FileInfo* filein } MU_TEST_1(test_dirwalk_filter, Storage* storage) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); FileInfo fileinfo; StorageTestPathDict_t* paths = storage_test_paths_alloc( @@ -242,12 +242,12 @@ MU_TEST_1(test_dirwalk_filter, Storage* storage) { mu_check(dir_walk_open(dir_walk, EXT_PATH("dirwalk"))); while(dir_walk_read(dir_walk, path, &fileinfo) == DirWalkOK) { - string_right(path, strlen(EXT_PATH("dirwalk/"))); + furi_string_right(path, strlen(EXT_PATH("dirwalk/"))); mu_check(storage_test_paths_mark(paths, path, (fileinfo.flags & FSF_DIRECTORY))); } dir_walk_free(dir_walk); - string_clear(path); + furi_string_free(path); mu_check(storage_test_paths_check(paths) == false); diff --git a/applications/debug/unit_tests/storage/storage_test.c b/applications/debug/unit_tests/storage/storage_test.c index c3628a4f9..7c1c669ff 100644 --- a/applications/debug/unit_tests/storage/storage_test.c +++ b/applications/debug/unit_tests/storage/storage_test.c @@ -58,7 +58,7 @@ MU_TEST(storage_file_open_lock) { storage_file_close(file); // file_locker thread stop - mu_check(furi_thread_join(locker_thread) == FuriStatusOk); + mu_check(furi_thread_join(locker_thread)); furi_thread_free(locker_thread); // clean data @@ -148,7 +148,7 @@ MU_TEST(storage_dir_open_lock) { storage_dir_close(file); // file_locker thread stop - mu_check(furi_thread_join(locker_thread) == FuriStatusOk); + mu_check(furi_thread_join(locker_thread)); furi_thread_free(locker_thread); // clean data @@ -211,22 +211,22 @@ static bool check_file_13DA(Storage* storage, const char* path) { } static void storage_dir_create(Storage* storage, const char* base) { - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); storage_common_mkdir(storage, base); for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) { - string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); - storage_common_mkdir(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); + storage_common_mkdir(storage, furi_string_get_cstr(path)); } for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) { - string_printf(path, "%s/%s", base, storage_copy_test_files[i]); - write_file_13DA(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_copy_test_files[i]); + write_file_13DA(storage, furi_string_get_cstr(path)); } - string_clear(path); + furi_string_free(path); } static void storage_dir_remove(Storage* storage, const char* base) { @@ -235,15 +235,15 @@ static void storage_dir_remove(Storage* storage, const char* base) { static bool storage_dir_rename_check(Storage* storage, const char* base) { bool result = false; - string_t path; - string_init(path); + FuriString* path; + path = furi_string_alloc(); result = (storage_common_stat(storage, base, NULL) == FSE_OK); if(result) { for(size_t i = 0; i < COUNT_OF(storage_copy_test_paths); i++) { - string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); - result = (storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK); + furi_string_printf(path, "%s/%s", base, storage_copy_test_paths[i]); + result = (storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK); if(!result) { break; } @@ -252,15 +252,15 @@ static bool storage_dir_rename_check(Storage* storage, const char* base) { if(result) { for(size_t i = 0; i < COUNT_OF(storage_copy_test_files); i++) { - string_printf(path, "%s/%s", base, storage_copy_test_files[i]); - result = check_file_13DA(storage, string_get_cstr(path)); + furi_string_printf(path, "%s/%s", base, storage_copy_test_files[i]); + result = check_file_13DA(storage, furi_string_get_cstr(path)); if(!result) { break; } } } - string_clear(path); + furi_string_free(path); return result; } diff --git a/applications/debug/unit_tests/stream/stream_test.c b/applications/debug/unit_tests/stream/stream_test.c index b5a2d3980..c04e119c6 100644 --- a/applications/debug/unit_tests/stream/stream_test.c +++ b/applications/debug/unit_tests/stream/stream_test.c @@ -18,8 +18,8 @@ static const char* stream_test_right_data = MU_TEST_1(stream_composite_subtest, Stream* stream) { const size_t data_size = 128; uint8_t data[data_size]; - string_t string_lee; - string_init_set(string_lee, "lee"); + FuriString* string_lee; + string_lee = furi_string_alloc_set("lee"); // test that stream is empty // "" -> "" @@ -267,7 +267,7 @@ MU_TEST_1(stream_composite_subtest, Stream* stream) { mu_assert_int_eq(9, stream_tell(stream)); mu_check(stream_eof(stream)); - string_clear(string_lee); + furi_string_free(string_lee); } MU_TEST(stream_composite_test) { @@ -416,10 +416,10 @@ MU_TEST(stream_buffered_write_after_read_test) { } MU_TEST(stream_buffered_large_file_test) { - string_t input_data; - string_t output_data; - string_init(input_data); - string_init(output_data); + FuriString* input_data; + FuriString* output_data; + input_data = furi_string_alloc(); + output_data = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); @@ -429,7 +429,7 @@ MU_TEST(stream_buffered_large_file_test) { const size_t rep_count = data_size / line_size + 1; for(size_t i = 0; i < rep_count; ++i) { - string_cat_printf(input_data, "%s\n", stream_test_data); + furi_string_cat_printf(input_data, "%s\n", stream_test_data); } // write test data to file @@ -437,8 +437,8 @@ MU_TEST(stream_buffered_large_file_test) { mu_check(buffered_file_stream_open( stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)); mu_assert_int_eq(0, stream_size(stream)); - mu_assert_int_eq(string_size(input_data), stream_write_string(stream, input_data)); - mu_assert_int_eq(string_size(input_data), stream_size(stream)); + mu_assert_int_eq(furi_string_size(input_data), stream_write_string(stream, input_data)); + mu_assert_int_eq(furi_string_size(input_data), stream_size(stream)); const size_t substr_start = 8; const size_t substr_len = 11; @@ -475,23 +475,23 @@ MU_TEST(stream_buffered_large_file_test) { // read the whole file mu_check(stream_rewind(stream)); - string_t tmp; - string_init(tmp); + FuriString* tmp; + tmp = furi_string_alloc(); while(stream_read_line(stream, tmp)) { - string_cat(output_data, tmp); + furi_string_cat(output_data, tmp); } - string_clear(tmp); + furi_string_free(tmp); // check against generated data - mu_assert_int_eq(string_size(input_data), string_size(output_data)); - mu_check(string_equal_p(input_data, output_data)); + mu_assert_int_eq(furi_string_size(input_data), furi_string_size(output_data)); + mu_check(furi_string_equal(input_data, output_data)); mu_check(stream_eof(stream)); stream_free(stream); furi_record_close(RECORD_STORAGE); - string_clear(input_data); - string_clear(output_data); + furi_string_free(input_data); + furi_string_free(output_data); } MU_TEST_SUITE(stream_suite) { diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index 36f5b94c2..210d3770f 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -28,12 +28,12 @@ static void subghz_test_rx_callback( void* context) { UNUSED(receiver); UNUSED(context); - string_t text; - string_init(text); + FuriString* text; + text = furi_string_alloc(); subghz_protocol_decoder_base_get_string(decoder_base, text); subghz_receiver_reset(receiver_handler); - FURI_LOG_T(TAG, "\r\n%s", string_get_cstr(text)); - string_clear(text); + FURI_LOG_T(TAG, "\r\n%s", furi_string_get_cstr(text)); + furi_string_free(text); subghz_test_decoder_count++; } @@ -141,8 +141,8 @@ static bool subghz_decode_random_test(const char* path) { static bool subghz_encoder_test(const char* path) { subghz_test_decoder_count = 0; uint32_t test_start = furi_get_tick(); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); bool file_load = false; Storage* storage = furi_record_open(RECORD_STORAGE); @@ -167,11 +167,11 @@ static bool subghz_encoder_test(const char* path) { } while(false); if(file_load) { SubGhzTransmitter* transmitter = - subghz_transmitter_alloc_init(environment_handler, string_get_cstr(temp_str)); + subghz_transmitter_alloc_init(environment_handler, furi_string_get_cstr(temp_str)); subghz_transmitter_deserialize(transmitter, fff_data_file); SubGhzProtocolDecoderBase* decoder = subghz_receiver_search_decoder_base_by_name( - receiver_handler, string_get_cstr(temp_str)); + receiver_handler, furi_string_get_cstr(temp_str)); if(decoder) { LevelDuration level_duration; @@ -192,10 +192,11 @@ static bool subghz_encoder_test(const char* path) { flipper_format_free(fff_data_file); FURI_LOG_T(TAG, "\r\n Decoder count parse \033[0;33m%d\033[0m ", subghz_test_decoder_count); if(furi_get_tick() - test_start > TEST_TIMEOUT) { - printf("\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", string_get_cstr(temp_str)); + printf( + "\033[0;31mTest encoder %s ERROR TimeOut\033[0m\r\n", furi_string_get_cstr(temp_str)); subghz_test_decoder_count = 0; } - string_clear(temp_str); + furi_string_free(temp_str); return subghz_test_decoder_count ? true : false; } diff --git a/applications/debug/unit_tests/test_index.c b/applications/debug/unit_tests/test_index.c index 81d891b2b..2009d4a5b 100644 --- a/applications/debug/unit_tests/test_index.c +++ b/applications/debug/unit_tests/test_index.c @@ -1,5 +1,3 @@ -#include "m-string.h" - #include #include #include @@ -11,6 +9,7 @@ #define TAG "UnitTests" int run_minunit_test_furi(); +int run_minunit_test_furi_string(); int run_minunit_test_infrared(); int run_minunit_test_rpc(); int run_minunit_test_flipper_format(); @@ -33,6 +32,7 @@ typedef struct { const UnitTest unit_tests[] = { {.name = "furi", .entry = run_minunit_test_furi}, + {.name = "furi_string", .entry = run_minunit_test_furi_string}, {.name = "storage", .entry = run_minunit_test_storage}, {.name = "stream", .entry = run_minunit_test_stream}, {.name = "dirwalk", .entry = run_minunit_test_dirwalk}, @@ -63,7 +63,7 @@ void minunit_print_fail(const char* str) { printf(FURI_LOG_CLR_E "%s\r\n" FURI_LOG_CLR_RESET, str); } -void unit_tests_cli(Cli* cli, string_t args, void* context) { +void unit_tests_cli(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); @@ -91,8 +91,8 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { break; } - if(string_size(args)) { - if(string_cmp_str(args, unit_tests[i].name) == 0) { + if(furi_string_size(args)) { + if(furi_string_cmp_str(args, unit_tests[i].name) == 0) { failed_tests += unit_tests[i].entry(); } else { printf("Skipping %s\r\n", unit_tests[i].name); diff --git a/applications/examples/application.fam b/applications/examples/application.fam new file mode 100644 index 000000000..16d240ccf --- /dev/null +++ b/applications/examples/application.fam @@ -0,0 +1,5 @@ +App( + appid="sample_apps", + name="Sample apps bundle", + apptype=FlipperAppType.METAPACKAGE, +) diff --git a/applications/examples/example_images/application.fam b/applications/examples/example_images/application.fam new file mode 100644 index 000000000..9a5f8e030 --- /dev/null +++ b/applications/examples/example_images/application.fam @@ -0,0 +1,10 @@ +App( + appid="example_images", + name="Example: Images", + apptype=FlipperAppType.EXTERNAL, + entry_point="example_images_main", + requires=["gui"], + stack_size=1 * 1024, + fap_category="Examples", + fap_icon_assets="images", +) diff --git a/applications/examples/example_images/example_images.c b/applications/examples/example_images/example_images.c new file mode 100644 index 000000000..48fa5e77e --- /dev/null +++ b/applications/examples/example_images/example_images.c @@ -0,0 +1,79 @@ +#include +#include + +#include +#include + +#include "example_images_icons.h" + +typedef struct { + uint8_t x, y; +} ImagePosition; + +static ImagePosition image_position = {.x = 0, .y = 0}; + +// Screen is 128x64 px +static void app_draw_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); + + canvas_clear(canvas); + canvas_draw_icon(canvas, image_position.x % 128, image_position.y % 64, &I_dolphin_71x25); +} + +static void app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + FuriMessageQueue* event_queue = ctx; + furi_message_queue_put(event_queue, input_event, FuriWaitForever); +} + +int32_t example_images_main(void* p) { + UNUSED(p); + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + // Configure view port + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, app_draw_callback, view_port); + view_port_input_callback_set(view_port, app_input_callback, event_queue); + + // Register view port in GUI + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + InputEvent event; + + bool running = true; + while(running) { + if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) { + if((event.type == InputTypePress) || (event.type == InputTypeRepeat)) { + switch(event.key) { + case InputKeyLeft: + image_position.x -= 2; + break; + case InputKeyRight: + image_position.x += 2; + break; + case InputKeyUp: + image_position.y -= 2; + break; + case InputKeyDown: + image_position.y += 2; + break; + default: + running = false; + break; + } + } + } + view_port_update(view_port); + } + + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_message_queue_free(event_queue); + + furi_record_close(RECORD_GUI); + + return 0; +} diff --git a/applications/examples/example_images/images/dolphin_71x25.png b/applications/examples/example_images/images/dolphin_71x25.png new file mode 100644 index 000000000..6b3f8aa59 Binary files /dev/null and b/applications/examples/example_images/images/dolphin_71x25.png differ diff --git a/applications/main/archive/archive.c b/applications/main/archive/archive.c index bbe532c8c..b8609cf2d 100644 --- a/applications/main/archive/archive.c +++ b/applications/main/archive/archive.c @@ -1,5 +1,4 @@ #include "archive_i.h" -#include "m-string.h" bool archive_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -18,7 +17,7 @@ ArchiveApp* archive_alloc() { archive->gui = furi_record_open(RECORD_GUI); archive->text_input = text_input_alloc(); - string_init(archive->fav_move_str); + archive->fav_move_str = furi_string_alloc(); archive->view_dispatcher = view_dispatcher_alloc(); archive->scene_manager = scene_manager_alloc(&archive_scene_handlers, archive); @@ -58,7 +57,7 @@ void archive_free(ArchiveApp* archive) { view_dispatcher_free(archive->view_dispatcher); scene_manager_free(archive->scene_manager); browser_free(archive->browser); - string_clear(archive->fav_move_str); + furi_string_free(archive->fav_move_str); text_input_free(archive->text_input); diff --git a/applications/main/archive/archive_i.h b/applications/main/archive/archive_i.h index 865e837dc..d444aef8f 100644 --- a/applications/main/archive/archive_i.h +++ b/applications/main/archive/archive_i.h @@ -28,7 +28,7 @@ struct ArchiveApp { TextInput* text_input; Widget* widget; FuriPubSubSubscription* loader_stop_subscription; - string_t fav_move_str; + FuriString* fav_move_str; char text_store[MAX_NAME_LEN]; char file_extension[MAX_EXT_LEN + 1]; }; diff --git a/applications/main/archive/helpers/archive_browser.c b/applications/main/archive/helpers/archive_browser.c index 00bb6b063..9689454ba 100644 --- a/applications/main/archive/helpers/archive_browser.c +++ b/applications/main/archive/helpers/archive_browser.c @@ -5,7 +5,7 @@ #include #include #include "gui/modules/file_browser_worker.h" -#include "m-string.h" +#include #include static void @@ -19,9 +19,11 @@ static void if((item_cnt == 0) && (archive_is_home(browser)) && (tab != ArchiveTabBrowser)) { archive_switch_tab(browser, browser->last_tab_switch_dir); - } else if(!string_start_with_str_p(browser->path, "/app:")) { + } else if(!furi_string_start_with_str(browser->path, "/app:")) { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_reset(model->files); model->item_cnt = item_cnt; model->item_idx = (file_idx > 0) ? file_idx : 0; @@ -31,8 +33,8 @@ static void model->list_offset = 0; model->list_loading = true; model->folder_loading = false; - return false; - }); + }, + false); archive_update_offset(browser); file_browser_worker_load(browser->worker, load_offset, FILE_LIST_BUF_LEN); @@ -44,25 +46,25 @@ static void archive_list_load_cb(void* context, uint32_t list_load_offset) { ArchiveBrowserView* browser = (ArchiveBrowserView*)context; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_reset(model->files); model->array_offset = list_load_offset; - return false; - }); + }, + false); } -static void archive_list_item_cb(void* context, string_t item_path, bool is_folder, bool is_last) { +static void + archive_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last) { furi_assert(context); ArchiveBrowserView* browser = (ArchiveBrowserView*)context; if(!is_last) { - archive_add_file_item(browser, is_folder, string_get_cstr(item_path)); + archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path)); } else { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - model->list_loading = false; - return true; - }); + browser->view, ArchiveBrowserViewModel * model, { model->list_loading = false; }, true); } } @@ -71,15 +73,12 @@ static void archive_long_load_cb(void* context) { ArchiveBrowserView* browser = (ArchiveBrowserView*)context; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - model->folder_loading = true; - return true; - }); + browser->view, ArchiveBrowserViewModel * model, { model->folder_loading = true; }, true); } static void archive_file_browser_set_path( ArchiveBrowserView* browser, - string_t path, + FuriString* path, const char* filter_ext, bool skip_assets) { furi_assert(browser); @@ -112,7 +111,9 @@ void archive_update_offset(ArchiveBrowserView* browser) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { uint16_t bounds = model->item_cnt > 3 ? 2 : model->item_cnt; if((model->item_cnt > 3u) && (model->item_idx >= ((int32_t)model->item_cnt - 1))) { @@ -124,33 +125,34 @@ void archive_update_offset(ArchiveBrowserView* browser) { model->list_offset = CLAMP(model->item_idx - 1, (int32_t)model->item_cnt - bounds, 0); } - - return true; - }); + }, + true); } void archive_update_focus(ArchiveBrowserView* browser, const char* target) { furi_assert(browser); furi_assert(target); - archive_get_items(browser, string_get_cstr(browser->path)); + archive_get_items(browser, furi_string_get_cstr(browser->path)); if(!archive_file_get_array_size(browser) && archive_is_home(browser)) { archive_switch_tab(browser, TAB_RIGHT); } else { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { uint16_t idx = 0; while(idx < files_array_size(model->files)) { ArchiveFile_t* current = files_array_get(model->files, idx); - if(!string_search(current->path, target)) { + if(!furi_string_search(current->path, target)) { model->item_idx = idx + model->array_offset; break; } ++idx; } - return false; - }); + }, + false); archive_update_offset(browser); } @@ -161,10 +163,10 @@ size_t archive_file_get_array_size(ArchiveBrowserView* browser) { uint16_t size = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - size = files_array_size(model->files); - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { size = files_array_size(model->files); }, + false); return size; } @@ -172,11 +174,13 @@ void archive_set_item_count(ArchiveBrowserView* browser, uint32_t count) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { model->item_cnt = count; model->item_idx = CLAMP(model->item_idx, (int32_t)model->item_cnt - 1, 0); - return false; - }); + }, + false); archive_update_offset(browser); } @@ -185,7 +189,9 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) { uint32_t items_cnt = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_remove_v( model->files, model->item_idx - model->array_offset, @@ -193,8 +199,8 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) { model->item_cnt--; model->item_idx = CLAMP(model->item_idx, (int32_t)model->item_cnt - 1, 0); items_cnt = model->item_cnt; - return false; - }); + }, + false); if((items_cnt == 0) && (archive_is_home(browser))) { archive_switch_tab(browser, TAB_RIGHT); @@ -207,7 +213,9 @@ void archive_file_array_swap(ArchiveBrowserView* browser, int8_t dir) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { ArchiveFile_t temp; size_t array_size = files_array_size(model->files) - 1; uint8_t swap_idx = CLAMP((size_t)(model->item_idx + dir), array_size, 0u); @@ -225,18 +233,18 @@ void archive_file_array_swap(ArchiveBrowserView* browser, int8_t dir) { } else { files_array_swap_at(model->files, model->item_idx, swap_idx); } - return false; - }); + }, + false); } void archive_file_array_rm_all(ArchiveBrowserView* browser) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - files_array_reset(model->files); - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { files_array_reset(model->files); }, + false); } void archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) { @@ -245,7 +253,9 @@ void archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) { int32_t offset_new = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { if(model->item_cnt > FILE_LIST_BUF_LEN) { if(dir < 0) { offset_new = model->item_idx - FILE_LIST_BUF_LEN / 4 * 3; @@ -261,8 +271,8 @@ void archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) { offset_new = 0; } } - return false; - }); + }, + false); file_browser_worker_load(browser->worker, offset_new, FILE_LIST_BUF_LEN); } @@ -272,12 +282,14 @@ ArchiveFile_t* archive_get_current_file(ArchiveBrowserView* browser) { ArchiveFile_t* selected = NULL; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { selected = files_array_size(model->files) ? files_array_get(model->files, model->item_idx - model->array_offset) : NULL; - return false; - }); + }, + false); return selected; } @@ -287,11 +299,13 @@ ArchiveFile_t* archive_get_file_at(ArchiveBrowserView* browser, size_t idx) { ArchiveFile_t* selected = NULL; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { idx = CLAMP(idx - model->array_offset, files_array_size(model->files), 0u); selected = files_array_size(model->files) ? files_array_get(model->files, idx) : NULL; - return false; - }); + }, + false); return selected; } @@ -300,10 +314,7 @@ ArchiveTabEnum archive_get_tab(ArchiveBrowserView* browser) { ArchiveTabEnum tab_id = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - tab_id = model->tab_idx; - return false; - }); + browser->view, ArchiveBrowserViewModel * model, { tab_id = model->tab_idx; }, false); return tab_id; } @@ -315,22 +326,19 @@ bool archive_is_home(ArchiveBrowserView* browser) { } const char* default_path = archive_get_default_path(archive_get_tab(browser)); - return (string_cmp_str(browser->path, default_path) == 0); + return (furi_string_cmp_str(browser->path, default_path) == 0); } const char* archive_get_name(ArchiveBrowserView* browser) { ArchiveFile_t* selected = archive_get_current_file(browser); - return string_get_cstr(selected->path); + return furi_string_get_cstr(selected->path); } void archive_set_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - model->tab_idx = tab; - return false; - }); + browser->view, ArchiveBrowserViewModel * model, { model->tab_idx = tab; }, false); } void archive_add_app_item(ArchiveBrowserView* browser, const char* name) { @@ -339,75 +347,92 @@ void archive_add_app_item(ArchiveBrowserView* browser, const char* name) { ArchiveFile_t item; ArchiveFile_t_init(&item); - string_set_str(item.path, name); + furi_string_set(item.path, name); archive_set_file_type(&item, name, false, true); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_push_back(model->files, item); model->item_cnt = files_array_size(model->files); - return false; - }); + }, + false); ArchiveFile_t_clear(&item); } +static bool archive_get_fap_meta(FuriString* file_path, FuriString* fap_name, uint8_t** icon_ptr) { + Storage* storage = furi_record_open(RECORD_STORAGE); + bool success = false; + if(fap_loader_load_name_and_icon(file_path, storage, icon_ptr, fap_name)) { + success = true; + } + furi_record_close(RECORD_STORAGE); + return success; +} + void archive_add_file_item(ArchiveBrowserView* browser, bool is_folder, const char* name) { furi_assert(browser); furi_assert(name); ArchiveFile_t item; - ArchiveFile_t_init(&item); - string_init_set_str(item.path, name); - archive_set_file_type(&item, string_get_cstr(browser->path), is_folder, false); + furi_string_set(item.path, name); + archive_set_file_type(&item, furi_string_get_cstr(browser->path), is_folder, false); + if(item.type == ArchiveFileTypeApplication) { + item.custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE); + if(!archive_get_fap_meta(item.path, item.custom_name, &item.custom_icon_data)) { + free(item.custom_icon_data); + item.custom_icon_data = NULL; + } + } with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - files_array_push_back(model->files, item); - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { files_array_push_back(model->files, item); }, + false); ArchiveFile_t_clear(&item); } void archive_show_file_menu(ArchiveBrowserView* browser, bool show) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { if(show) { if(archive_is_item_in_array(model, model->item_idx)) { model->menu = true; model->menu_idx = 0; ArchiveFile_t* selected = files_array_get(model->files, model->item_idx - model->array_offset); - selected->fav = archive_is_favorite("%s", string_get_cstr(selected->path)); + selected->fav = + archive_is_favorite("%s", furi_string_get_cstr(selected->path)); } } else { model->menu = false; model->menu_idx = 0; } - - return true; - }); + }, + true); } void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) { furi_assert(browser); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - model->move_fav = active; - return true; - }); + browser->view, ArchiveBrowserViewModel * model, { model->move_fav = active; }, true); } -static bool archive_is_dir_exists(string_t path) { - if(string_equal_str_p(path, STORAGE_ANY_PATH_PREFIX)) { +static bool archive_is_dir_exists(FuriString* path) { + if(furi_string_equal(path, STORAGE_ANY_PATH_PREFIX)) { return true; } bool state = false; FileInfo file_info; Storage* storage = furi_record_open(RECORD_STORAGE); - if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { + if(storage_common_stat(storage, furi_string_get_cstr(path), &file_info) == FSE_OK) { if(file_info.flags & FSF_DIRECTORY) { state = true; } @@ -431,16 +456,16 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { browser->is_root = true; archive_set_tab(browser, tab); - string_set_str(browser->path, archive_get_default_path(tab)); + furi_string_set(browser->path, archive_get_default_path(tab)); bool tab_empty = true; if(tab == ArchiveTabFavorites) { if(archive_favorites_count(browser) > 0) { tab_empty = false; } - } else if(string_start_with_str_p(browser->path, "/app:")) { - char* app_name = strchr(string_get_cstr(browser->path), ':'); + } else if(furi_string_start_with_str(browser->path, "/app:")) { + char* app_name = strchr(furi_string_get_cstr(browser->path), ':'); if(app_name != NULL) { - if(archive_app_is_available(browser, string_get_cstr(browser->path))) { + if(archive_app_is_available(browser, furi_string_get_cstr(browser->path))) { tab_empty = false; } } @@ -458,29 +483,28 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) { archive_switch_tab(browser, key); } else { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { model->item_idx = 0; model->array_offset = 0; - return false; - }); - archive_get_items(browser, string_get_cstr(browser->path)); + }, + false); + archive_get_items(browser, furi_string_get_cstr(browser->path)); archive_update_offset(browser); } } -void archive_enter_dir(ArchiveBrowserView* browser, string_t path) { +void archive_enter_dir(ArchiveBrowserView* browser, FuriString* path) { furi_assert(browser); furi_assert(path); int32_t idx_temp = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - idx_temp = model->item_idx; - return false; - }); + browser->view, ArchiveBrowserViewModel * model, { idx_temp = model->item_idx; }, false); - string_set(browser->path, path); + furi_string_set(browser->path, path); file_browser_worker_folder_enter(browser->worker, path, idx_temp); } @@ -496,9 +520,6 @@ void archive_refresh_dir(ArchiveBrowserView* browser) { int32_t idx_temp = 0; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - idx_temp = model->item_idx; - return false; - }); + browser->view, ArchiveBrowserViewModel * model, { idx_temp = model->item_idx; }, false); file_browser_worker_folder_refresh(browser->worker, idx_temp); } diff --git a/applications/main/archive/helpers/archive_browser.h b/applications/main/archive/helpers/archive_browser.h index ad64a9845..519a34a2d 100644 --- a/applications/main/archive/helpers/archive_browser.h +++ b/applications/main/archive/helpers/archive_browser.h @@ -16,6 +16,7 @@ static const char* tab_default_paths[] = { [ArchiveTabInfrared] = ANY_PATH("infrared"), [ArchiveTabBadUsb] = ANY_PATH("badusb"), [ArchiveTabU2f] = "/app:u2f", + [ArchiveTabApplications] = ANY_PATH("apps"), [ArchiveTabBrowser] = STORAGE_ANY_PATH_PREFIX, }; @@ -27,6 +28,7 @@ static const char* known_ext[] = { [ArchiveFileTypeInfrared] = ".ir", [ArchiveFileTypeBadUsb] = ".txt", [ArchiveFileTypeU2f] = "?", + [ArchiveFileTypeApplication] = ".fap", [ArchiveFileTypeUpdateManifest] = ".fuf", [ArchiveFileTypeFolder] = "?", [ArchiveFileTypeUnknown] = "*", @@ -41,6 +43,7 @@ static const ArchiveFileTypeEnum known_type[] = { [ArchiveTabInfrared] = ArchiveFileTypeInfrared, [ArchiveTabBadUsb] = ArchiveFileTypeBadUsb, [ArchiveTabU2f] = ArchiveFileTypeU2f, + [ArchiveTabApplications] = ArchiveFileTypeApplication, [ArchiveTabBrowser] = ArchiveFileTypeUnknown, }; @@ -84,6 +87,6 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show); void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active); void archive_switch_tab(ArchiveBrowserView* browser, InputKey key); -void archive_enter_dir(ArchiveBrowserView* browser, string_t name); +void archive_enter_dir(ArchiveBrowserView* browser, FuriString* name); void archive_leave_dir(ArchiveBrowserView* browser); void archive_refresh_dir(ArchiveBrowserView* browser); diff --git a/applications/main/archive/helpers/archive_favorites.c b/applications/main/archive/helpers/archive_favorites.c index 4d5b555f5..86a294f78 100644 --- a/applications/main/archive/helpers/archive_favorites.c +++ b/applications/main/archive/helpers/archive_favorites.c @@ -6,8 +6,8 @@ #define ARCHIVE_FAV_FILE_BUF_LEN 32 -static bool archive_favorites_read_line(File* file, string_t str_result) { - string_reset(str_result); +static bool archive_favorites_read_line(File* file, FuriString* str_result) { + furi_string_reset(str_result); uint8_t buffer[ARCHIVE_FAV_FILE_BUF_LEN]; bool result = false; @@ -34,7 +34,7 @@ static bool archive_favorites_read_line(File* file, string_t str_result) { result = true; break; } else { - string_push_back(str_result, buffer[i]); + furi_string_push_back(str_result, buffer[i]); } } @@ -52,8 +52,8 @@ uint16_t archive_favorites_count(void* context) { Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); uint16_t lines = 0; @@ -63,7 +63,7 @@ uint16_t archive_favorites_count(void* context) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; // Skip empty lines } ++lines; @@ -72,7 +72,7 @@ uint16_t archive_favorites_count(void* context) { storage_file_close(file); - string_clear(buffer); + furi_string_free(buffer); storage_file_free(file); furi_record_close(RECORD_STORAGE); @@ -80,8 +80,8 @@ uint16_t archive_favorites_count(void* context) { } static bool archive_favourites_rescan() { - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); @@ -91,23 +91,25 @@ static bool archive_favourites_rescan() { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } - if(string_search(buffer, "/app:") == 0) { - if(archive_app_is_available(NULL, string_get_cstr(buffer))) { - archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); + if(furi_string_search(buffer, "/app:") == 0) { + if(archive_app_is_available(NULL, furi_string_get_cstr(buffer))) { + archive_file_append( + ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer)); } } else { - if(storage_file_exists(storage, string_get_cstr(buffer))) { - archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); + if(storage_file_exists(storage, furi_string_get_cstr(buffer))) { + archive_file_append( + ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer)); } } } } - string_clear(buffer); + furi_string_free(buffer); storage_file_close(file); storage_common_remove(storage, ARCHIVE_FAV_PATH); @@ -127,9 +129,9 @@ bool archive_favorites_read(void* context) { Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); - string_t buffer; + FuriString* buffer; FileInfo file_info; - string_init(buffer); + buffer = furi_string_alloc(); bool need_refresh = false; uint16_t file_count = 0; @@ -143,33 +145,33 @@ bool archive_favorites_read(void* context) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } - if(string_search(buffer, "/app:") == 0) { - if(archive_app_is_available(browser, string_get_cstr(buffer))) { - archive_add_app_item(browser, string_get_cstr(buffer)); + if(furi_string_search(buffer, "/app:") == 0) { + if(archive_app_is_available(browser, furi_string_get_cstr(buffer))) { + archive_add_app_item(browser, furi_string_get_cstr(buffer)); file_count++; } else { need_refresh = true; } } else { - if(storage_file_exists(storage, string_get_cstr(buffer))) { - storage_common_stat(storage, string_get_cstr(buffer), &file_info); + if(storage_file_exists(storage, furi_string_get_cstr(buffer))) { + storage_common_stat(storage, furi_string_get_cstr(buffer), &file_info); archive_add_file_item( - browser, (file_info.flags & FSF_DIRECTORY), string_get_cstr(buffer)); + browser, (file_info.flags & FSF_DIRECTORY), furi_string_get_cstr(buffer)); file_count++; } else { need_refresh = true; } } - string_reset(buffer); + furi_string_reset(buffer); } } storage_file_close(file); - string_clear(buffer); + furi_string_free(buffer); storage_file_free(file); furi_record_close(RECORD_STORAGE); @@ -183,14 +185,14 @@ bool archive_favorites_read(void* context) { } bool archive_favorites_delete(const char* format, ...) { - string_t buffer; - string_t filename; + FuriString* buffer; + FuriString* filename; va_list args; va_start(args, format); - string_init_vprintf(filename, format, args); + filename = furi_string_alloc_vprintf(format, args); va_end(args); - string_init(buffer); + buffer = furi_string_alloc(); Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); @@ -201,18 +203,18 @@ bool archive_favorites_delete(const char* format, ...) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } - if(string_search(buffer, filename)) { - archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer)); + if(furi_string_search(buffer, filename)) { + archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(buffer)); } } } - string_clear(buffer); - string_clear(filename); + furi_string_free(buffer); + furi_string_free(filename); storage_file_close(file); storage_common_remove(fs_api, ARCHIVE_FAV_PATH); @@ -226,14 +228,14 @@ bool archive_favorites_delete(const char* format, ...) { } bool archive_is_favorite(const char* format, ...) { - string_t buffer; - string_t filename; + FuriString* buffer; + FuriString* filename; va_list args; va_start(args, format); - string_init_vprintf(filename, format, args); + filename = furi_string_alloc_vprintf(format, args); va_end(args); - string_init(buffer); + buffer = furi_string_alloc(); Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); @@ -245,10 +247,10 @@ bool archive_is_favorite(const char* format, ...) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } - if(!string_search(buffer, filename)) { + if(!furi_string_search(buffer, filename)) { found = true; break; } @@ -256,8 +258,8 @@ bool archive_is_favorite(const char* format, ...) { } storage_file_close(file); - string_clear(buffer); - string_clear(filename); + furi_string_free(buffer); + furi_string_free(filename); storage_file_free(file); furi_record_close(RECORD_STORAGE); @@ -271,13 +273,13 @@ bool archive_favorites_rename(const char* src, const char* dst) { Storage* fs_api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(fs_api); - string_t path; - string_t buffer; + FuriString* path; + FuriString* buffer; - string_init(buffer); - string_init(path); + buffer = furi_string_alloc(); + path = furi_string_alloc(); - string_printf(path, "%s", src); + furi_string_printf(path, "%s", src); bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); if(result) { @@ -285,19 +287,19 @@ bool archive_favorites_rename(const char* src, const char* dst) { if(!archive_favorites_read_line(file, buffer)) { break; } - if(!string_size(buffer)) { + if(!furi_string_size(buffer)) { continue; } archive_file_append( ARCHIVE_FAV_TEMP_PATH, "%s\n", - string_search(buffer, path) ? string_get_cstr(buffer) : dst); + furi_string_search(buffer, path) ? furi_string_get_cstr(buffer) : dst); } } - string_clear(buffer); - string_clear(path); + furi_string_free(buffer); + furi_string_free(path); storage_file_close(file); storage_common_remove(fs_api, ARCHIVE_FAV_PATH); @@ -325,7 +327,7 @@ void archive_favorites_save(void* context) { for(size_t i = 0; i < archive_file_get_array_size(browser); i++) { ArchiveFile_t* item = archive_get_file_at(browser, i); - archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(item->path)); + archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", furi_string_get_cstr(item->path)); } storage_common_remove(fs_api, ARCHIVE_FAV_PATH); diff --git a/applications/main/archive/helpers/archive_favorites.h b/applications/main/archive/helpers/archive_favorites.h index 29eedcdb6..db8943378 100644 --- a/applications/main/archive/helpers/archive_favorites.h +++ b/applications/main/archive/helpers/archive_favorites.h @@ -7,8 +7,8 @@ uint16_t archive_favorites_count(void* context); bool archive_favorites_read(void* context); -bool archive_favorites_delete(const char* format, ...); -bool archive_is_favorite(const char* format, ...); +bool archive_favorites_delete(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); +bool archive_is_favorite(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); bool archive_favorites_rename(const char* src, const char* dst); void archive_add_to_favorites(const char* file_path); void archive_favorites_save(void* context); diff --git a/applications/main/archive/helpers/archive_files.c b/applications/main/archive/helpers/archive_files.c index 9f8b4ee1b..87265a45d 100644 --- a/applications/main/archive/helpers/archive_files.c +++ b/applications/main/archive/helpers/archive_files.c @@ -15,10 +15,10 @@ void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder } else { for(size_t i = 0; i < COUNT_OF(known_ext); i++) { if((known_ext[i][0] == '?') || (known_ext[i][0] == '*')) continue; - if(string_search_str(file->path, known_ext[i], 0) != STRING_FAILURE) { + if(furi_string_search(file->path, known_ext[i], 0) != FURI_STRING_FAILURE) { if(i == ArchiveFileTypeBadUsb) { - if(string_search_str(file->path, archive_get_default_path(ArchiveTabBadUsb)) == - 0) { + if(furi_string_search( + file->path, archive_get_default_path(ArchiveTabBadUsb)) == 0) { file->type = i; return; // *.txt file is a BadUSB script only if it is in BadUSB folder } @@ -54,10 +54,10 @@ bool archive_get_items(void* context, const char* path) { void archive_file_append(const char* path, const char* format, ...) { furi_assert(path); - string_t string; + FuriString* string; va_list args; va_start(args, format); - string_init_vprintf(string, format, args); + string = furi_string_alloc_vprintf(format, args); va_end(args); Storage* fs_api = furi_record_open(RECORD_STORAGE); @@ -66,7 +66,7 @@ void archive_file_append(const char* path, const char* format, ...) { bool res = storage_file_open(file, path, FSAM_WRITE, FSOM_OPEN_APPEND); if(res) { - storage_file_write(file, string_get_cstr(string), string_size(string)); + storage_file_write(file, furi_string_get_cstr(string), furi_string_size(string)); } storage_file_close(file); @@ -77,35 +77,35 @@ void archive_file_append(const char* path, const char* format, ...) { void archive_delete_file(void* context, const char* format, ...) { furi_assert(context); - string_t filename; + FuriString* filename; va_list args; va_start(args, format); - string_init_vprintf(filename, format, args); + filename = furi_string_alloc_vprintf(format, args); va_end(args); ArchiveBrowserView* browser = context; Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo fileinfo; - storage_common_stat(fs_api, string_get_cstr(filename), &fileinfo); + storage_common_stat(fs_api, furi_string_get_cstr(filename), &fileinfo); bool res = false; if(fileinfo.flags & FSF_DIRECTORY) { - res = storage_simply_remove_recursive(fs_api, string_get_cstr(filename)); + res = storage_simply_remove_recursive(fs_api, furi_string_get_cstr(filename)); } else { - res = (storage_common_remove(fs_api, string_get_cstr(filename)) == FSE_OK); + res = (storage_common_remove(fs_api, furi_string_get_cstr(filename)) == FSE_OK); } furi_record_close(RECORD_STORAGE); - if(archive_is_favorite("%s", string_get_cstr(filename))) { - archive_favorites_delete("%s", string_get_cstr(filename)); + if(archive_is_favorite("%s", furi_string_get_cstr(filename))) { + archive_favorites_delete("%s", furi_string_get_cstr(filename)); } if(res) { archive_file_array_rm_selected(browser); } - string_clear(filename); + furi_string_free(filename); } diff --git a/applications/main/archive/helpers/archive_files.h b/applications/main/archive/helpers/archive_files.h index 84b7e24a6..1822befa3 100644 --- a/applications/main/archive/helpers/archive_files.h +++ b/applications/main/archive/helpers/archive_files.h @@ -1,9 +1,11 @@ #pragma once #include -#include +#include #include +#define FAP_MANIFEST_MAX_ICON_SIZE 32 + typedef enum { ArchiveFileTypeIButton, ArchiveFileTypeNFC, @@ -13,41 +15,65 @@ typedef enum { ArchiveFileTypeBadUsb, ArchiveFileTypeU2f, ArchiveFileTypeUpdateManifest, + ArchiveFileTypeApplication, ArchiveFileTypeFolder, ArchiveFileTypeUnknown, ArchiveFileTypeLoading, } ArchiveFileTypeEnum; typedef struct { - string_t path; + FuriString* path; ArchiveFileTypeEnum type; + uint8_t* custom_icon_data; + FuriString* custom_name; bool fav; bool is_app; } ArchiveFile_t; static void ArchiveFile_t_init(ArchiveFile_t* obj) { + obj->path = furi_string_alloc(); obj->type = ArchiveFileTypeUnknown; - obj->is_app = false; + obj->custom_icon_data = NULL; + obj->custom_name = furi_string_alloc(); obj->fav = false; - string_init(obj->path); + obj->is_app = false; } static void ArchiveFile_t_init_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { + obj->path = furi_string_alloc_set(src->path); obj->type = src->type; - obj->is_app = src->is_app; + if(src->custom_icon_data) { + obj->custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE); + memcpy(obj->custom_icon_data, src->custom_icon_data, FAP_MANIFEST_MAX_ICON_SIZE); + } else { + obj->custom_icon_data = NULL; + } + obj->custom_name = furi_string_alloc_set(src->custom_name); obj->fav = src->fav; - string_init_set(obj->path, src->path); + obj->is_app = src->is_app; } static void ArchiveFile_t_set(ArchiveFile_t* obj, const ArchiveFile_t* src) { + furi_string_set(obj->path, src->path); obj->type = src->type; - obj->is_app = src->is_app; + if(src->custom_icon_data) { + obj->custom_icon_data = malloc(FAP_MANIFEST_MAX_ICON_SIZE); + memcpy(obj->custom_icon_data, src->custom_icon_data, FAP_MANIFEST_MAX_ICON_SIZE); + } else { + obj->custom_icon_data = NULL; + } + furi_string_set(obj->custom_name, src->custom_name); obj->fav = src->fav; - string_set(obj->path, src->path); + obj->is_app = src->is_app; } static void ArchiveFile_t_clear(ArchiveFile_t* obj) { - string_clear(obj->path); + furi_string_free(obj->path); + if(obj->custom_icon_data) { + free(obj->custom_icon_data); + obj->custom_icon_data = NULL; + } + furi_string_free(obj->custom_name); } ARRAY_DEF( @@ -60,5 +86,7 @@ ARRAY_DEF( void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder, bool is_app); bool archive_get_items(void* context, const char* path); -void archive_file_append(const char* path, const char* format, ...); -void archive_delete_file(void* context, const char* format, ...); +void archive_file_append(const char* path, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); +void archive_delete_file(void* context, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); diff --git a/applications/main/archive/scenes/archive_scene_browser.c b/applications/main/archive/scenes/archive_scene_browser.c index e22ac792f..9dc671617 100644 --- a/applications/main/archive/scenes/archive_scene_browser.c +++ b/applications/main/archive/scenes/archive_scene_browser.c @@ -20,6 +20,7 @@ static const char* flipper_app_name[] = { [ArchiveFileTypeBadUsb] = "Bad USB", [ArchiveFileTypeU2f] = "U2F", [ArchiveFileTypeUpdateManifest] = "UpdaterApp", + [ArchiveFileTypeApplication] = "Applications", }; static void archive_loader_callback(const void* message, void* context) { @@ -40,14 +41,14 @@ static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selec LoaderStatus status; if(selected->is_app) { - char* param = strrchr(string_get_cstr(selected->path), '/'); + char* param = strrchr(furi_string_get_cstr(selected->path), '/'); if(param != NULL) { param++; } status = loader_start(loader, flipper_app_name[selected->type], param); } else { status = loader_start( - loader, flipper_app_name[selected->type], string_get_cstr(selected->path)); + loader, flipper_app_name[selected->type], furi_string_get_cstr(selected->path)); } if(status != LoaderStatusOk) { @@ -159,13 +160,13 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { consumed = true; break; case ArchiveBrowserEventEnterFavMove: - string_set(archive->fav_move_str, selected->path); + furi_string_set(archive->fav_move_str, selected->path); archive_show_file_menu(browser, false); archive_favorites_move_mode(archive->browser, true); consumed = true; break; case ArchiveBrowserEventExitFavMove: - archive_update_focus(browser, string_get_cstr(archive->fav_move_str)); + archive_update_focus(browser, furi_string_get_cstr(archive->fav_move_str)); archive_favorites_move_mode(archive->browser, false); consumed = true; break; diff --git a/applications/main/archive/scenes/archive_scene_delete.c b/applications/main/archive/scenes/archive_scene_delete.c index d882fd066..d3964d0fe 100644 --- a/applications/main/archive/scenes/archive_scene_delete.c +++ b/applications/main/archive/scenes/archive_scene_delete.c @@ -4,7 +4,6 @@ #include "../helpers/archive_apps.h" #include "../helpers/archive_browser.h" #include "toolbox/path.h" -#include "m-string.h" #define SCENE_DELETE_CUSTOM_EVENT (0UL) #define MAX_TEXT_INPUT_LEN 22 @@ -26,18 +25,18 @@ void archive_scene_delete_on_enter(void* context) { widget_add_button_element( app->widget, GuiButtonTypeRight, "Delete", archive_scene_delete_widget_callback, app); - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); ArchiveFile_t* current = archive_get_current_file(app->browser); path_extract_filename(current->path, filename, false); char delete_str[64]; - snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", string_get_cstr(filename)); + snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", furi_string_get_cstr(filename)); widget_add_text_box_element( app->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str, false); - string_clear(filename); + furi_string_free(filename); view_dispatcher_switch_to_view(app->view_dispatcher, ArchiveViewWidget); } diff --git a/applications/main/archive/scenes/archive_scene_rename.c b/applications/main/archive/scenes/archive_scene_rename.c index 293fa89af..1451428bd 100644 --- a/applications/main/archive/scenes/archive_scene_rename.c +++ b/applications/main/archive/scenes/archive_scene_rename.c @@ -19,10 +19,10 @@ void archive_scene_rename_on_enter(void* context) { TextInput* text_input = archive->text_input; ArchiveFile_t* current = archive_get_current_file(archive->browser); - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_filename(current->path, filename, true); - strlcpy(archive->text_store, string_get_cstr(filename), MAX_NAME_LEN); + strlcpy(archive->text_store, furi_string_get_cstr(filename), MAX_NAME_LEN); path_extract_extension(current->path, archive->file_extension, MAX_EXT_LEN); @@ -37,10 +37,10 @@ void archive_scene_rename_on_enter(void* context) { false); ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(archive->browser->path), archive->file_extension, ""); + furi_string_get_cstr(archive->browser->path), archive->file_extension, ""); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - string_clear(filename); + furi_string_free(filename); view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewTextInput); } @@ -56,19 +56,19 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { const char* path_src = archive_get_name(archive->browser); ArchiveFile_t* file = archive_get_current_file(archive->browser); - string_t path_dst; - string_init(path_dst); + FuriString* path_dst; + path_dst = furi_string_alloc(); path_extract_dirname(path_src, path_dst); - string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); + furi_string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); - storage_common_rename(fs_api, path_src, string_get_cstr(path_dst)); + storage_common_rename(fs_api, path_src, furi_string_get_cstr(path_dst)); furi_record_close(RECORD_STORAGE); if(file->fav) { - archive_favorites_rename(path_src, string_get_cstr(path_dst)); + archive_favorites_rename(path_src, furi_string_get_cstr(path_dst)); } - string_clear(path_dst); + furi_string_free(path_dst); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser); consumed = true; diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index ddd6637db..a2e219b95 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -14,6 +14,7 @@ static const char* ArchiveTabNames[] = { [ArchiveTabInfrared] = "Infrared", [ArchiveTabBadUsb] = "Bad USB", [ArchiveTabU2f] = "U2F", + [ArchiveTabApplications] = "Apps", [ArchiveTabBrowser] = "Browser", }; @@ -29,6 +30,7 @@ static const Icon* ArchiveItemIcons[] = { [ArchiveFileTypeFolder] = &I_dir_10px, [ArchiveFileTypeUnknown] = &I_unknown_10px, [ArchiveFileTypeLoading] = &I_loading_10px, + [ArchiveFileTypeApplication] = &I_unknown_10px, }; void archive_browser_set_callback( @@ -47,35 +49,35 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) { canvas_set_color(canvas, ColorBlack); elements_slightly_rounded_frame(canvas, 70, 16, 58, 48); - string_t menu[MENU_ITEMS]; + FuriString* menu[MENU_ITEMS]; - string_init_set_str(menu[0], "Run in app"); - string_init_set_str(menu[1], "Pin"); - string_init_set_str(menu[2], "Rename"); - string_init_set_str(menu[3], "Delete"); + menu[0] = furi_string_alloc_set("Run in app"); + menu[1] = furi_string_alloc_set("Pin"); + menu[2] = furi_string_alloc_set("Rename"); + menu[3] = furi_string_alloc_set("Delete"); ArchiveFile_t* selected = files_array_get(model->files, model->item_idx - model->array_offset); if((selected->fav) || (model->tab_idx == ArchiveTabFavorites)) { - string_set_str(menu[1], "Unpin"); + furi_string_set(menu[1], "Unpin"); } if(!archive_is_known_app(selected->type)) { - string_set_str(menu[0], "---"); - string_set_str(menu[1], "---"); - string_set_str(menu[2], "---"); + furi_string_set(menu[0], "---"); + furi_string_set(menu[1], "---"); + furi_string_set(menu[2], "---"); } else { if(model->tab_idx == ArchiveTabFavorites) { - string_set_str(menu[2], "Move"); - string_set_str(menu[3], "---"); + furi_string_set(menu[2], "Move"); + furi_string_set(menu[3], "---"); } else if(selected->is_app) { - string_set_str(menu[2], "---"); + furi_string_set(menu[2], "---"); } } for(size_t i = 0; i < MENU_ITEMS; i++) { - canvas_draw_str(canvas, 82, 27 + i * 11, string_get_cstr(menu[i])); - string_clear(menu[i]); + canvas_draw_str(canvas, 82, 27 + i * 11, furi_string_get_cstr(menu[i])); + furi_string_free(menu[i]); } canvas_draw_icon(canvas, 74, 20 + model->menu_idx * 11, &I_ButtonRight_4x7); @@ -118,20 +120,31 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { bool scrollbar = model->item_cnt > 4; for(uint32_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) { - string_t str_buf; - string_init(str_buf); + FuriString* str_buf; + str_buf = furi_string_alloc(); int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u); uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0; ArchiveFileTypeEnum file_type = ArchiveFileTypeLoading; + uint8_t* custom_icon_data = NULL; if(archive_is_item_in_array(model, idx)) { ArchiveFile_t* file = files_array_get( model->files, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0)); - path_extract_filename(file->path, str_buf, archive_is_known_app(file->type)); file_type = file->type; + if(file_type == ArchiveFileTypeApplication) { + if(file->custom_icon_data) { + custom_icon_data = file->custom_icon_data; + furi_string_set(str_buf, file->custom_name); + } else { + file_type = ArchiveFileTypeUnknown; + path_extract_filename(file->path, str_buf, archive_is_known_app(file->type)); + } + } else { + path_extract_filename(file->path, str_buf, archive_is_known_app(file->type)); + } } else { - string_set_str(str_buf, "---"); + furi_string_set(str_buf, "---"); } elements_string_fit_width( @@ -143,10 +156,17 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { canvas_set_color(canvas, ColorBlack); } - canvas_draw_icon(canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]); - canvas_draw_str(canvas, 15 + x_offset, 24 + i * FRAME_HEIGHT, string_get_cstr(str_buf)); + if(custom_icon_data) { + canvas_draw_bitmap( + canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, 11, 10, custom_icon_data); + } else { + canvas_draw_icon( + canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]); + } + canvas_draw_str( + canvas, 15 + x_offset, 24 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buf)); - string_clear(str_buf); + furi_string_free(str_buf); } if(scrollbar) { @@ -243,33 +263,37 @@ static bool archive_view_input(InputEvent* event, void* context) { bool in_menu; bool move_fav_mode; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { in_menu = model->menu; move_fav_mode = model->move_fav; - return false; - }); + }, + false); if(in_menu) { if(event->type == InputTypeShort) { if(event->key == InputKeyUp || event->key == InputKeyDown) { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { if(event->key == InputKeyUp) { model->menu_idx = ((model->menu_idx - 1) + MENU_ITEMS) % MENU_ITEMS; } else if(event->key == InputKeyDown) { model->menu_idx = (model->menu_idx + 1) % MENU_ITEMS; } - return true; - }); + }, + true); } if(event->key == InputKeyOk) { uint8_t idx; with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - idx = model->menu_idx; - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { idx = model->menu_idx; }, + false); browser->callback(file_menu_actions[idx], browser->context); } else if(event->key == InputKeyBack) { browser->callback(ArchiveBrowserEventFileMenuClose, browser->context); @@ -293,7 +317,9 @@ static bool archive_view_input(InputEvent* event, void* context) { if((event->key == InputKeyUp || event->key == InputKeyDown) && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { if(event->key == InputKeyUp) { model->item_idx = ((model->item_idx - 1) + model->item_cnt) % model->item_cnt; @@ -314,9 +340,8 @@ static bool archive_view_input(InputEvent* event, void* context) { browser->callback(ArchiveBrowserEventFavMoveDown, browser->context); } } - - return true; - }); + }, + true); archive_update_offset(browser); } @@ -361,14 +386,16 @@ ArchiveBrowserView* browser_alloc() { view_set_draw_callback(browser->view, archive_view_render); view_set_input_callback(browser->view, archive_view_input); - string_init_set_str(browser->path, archive_get_default_path(TAB_DEFAULT)); + browser->path = furi_string_alloc_set(archive_get_default_path(TAB_DEFAULT)); with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { + browser->view, + ArchiveBrowserViewModel * model, + { files_array_init(model->files); model->tab_idx = TAB_DEFAULT; - return true; - }); + }, + true); return browser; } @@ -381,12 +408,12 @@ void browser_free(ArchiveBrowserView* browser) { } with_view_model( - browser->view, (ArchiveBrowserViewModel * model) { - files_array_clear(model->files); - return false; - }); + browser->view, + ArchiveBrowserViewModel * model, + { files_array_clear(model->files); }, + false); - string_clear(browser->path); + furi_string_free(browser->path); view_free(browser->view); free(browser); diff --git a/applications/main/archive/views/archive_browser_view.h b/applications/main/archive/views/archive_browser_view.h index 5c649c389..308af4e4d 100644 --- a/applications/main/archive/views/archive_browser_view.h +++ b/applications/main/archive/views/archive_browser_view.h @@ -26,6 +26,7 @@ typedef enum { ArchiveTabIButton, ArchiveTabBadUsb, ArchiveTabU2f, + ArchiveTabApplications, ArchiveTabBrowser, ArchiveTabTotal, } ArchiveTabEnum; @@ -77,7 +78,7 @@ struct ArchiveBrowserView { bool worker_running; ArchiveBrowserViewCallback callback; void* context; - string_t path; + FuriString* path; InputKey last_tab_switch_dir; bool is_root; }; diff --git a/applications/main/bad_usb/bad_usb_app.c b/applications/main/bad_usb/bad_usb_app.c index 09d7d3468..6fd29cd70 100644 --- a/applications/main/bad_usb/bad_usb_app.c +++ b/applications/main/bad_usb/bad_usb_app.c @@ -1,5 +1,4 @@ #include "bad_usb_app_i.h" -#include "m-string.h" #include #include #include @@ -26,10 +25,10 @@ static void bad_usb_app_tick_event_callback(void* context) { BadUsbApp* bad_usb_app_alloc(char* arg) { BadUsbApp* app = malloc(sizeof(BadUsbApp)); - string_init(app->file_path); + app->file_path = furi_string_alloc(); if(arg && strlen(arg)) { - string_set_str(app->file_path, arg); + furi_string_set(app->file_path, arg); } app->gui = furi_record_open(RECORD_GUI); @@ -64,10 +63,10 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { app->error = BadUsbAppErrorCloseRpc; scene_manager_next_scene(app->scene_manager, BadUsbSceneError); } else { - if(!string_empty_p(app->file_path)) { + if(!furi_string_empty(app->file_path)) { scene_manager_next_scene(app->scene_manager, BadUsbSceneWork); } else { - string_set_str(app->file_path, BAD_USB_APP_PATH_FOLDER); + furi_string_set(app->file_path, BAD_USB_APP_PATH_FOLDER); scene_manager_next_scene(app->scene_manager, BadUsbSceneFileSelect); } } @@ -95,7 +94,7 @@ void bad_usb_app_free(BadUsbApp* app) { furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_DIALOGS); - string_clear(app->file_path); + furi_string_free(app->file_path); free(app); } diff --git a/applications/main/bad_usb/bad_usb_app_i.h b/applications/main/bad_usb/bad_usb_app_i.h index 6378bddfb..85fd56ff0 100644 --- a/applications/main/bad_usb/bad_usb_app_i.h +++ b/applications/main/bad_usb/bad_usb_app_i.h @@ -31,7 +31,7 @@ struct BadUsbApp { Widget* widget; BadUsbAppError error; - string_t file_path; + FuriString* file_path; BadUsb* bad_usb_view; BadUsbScript* bad_usb_script; }; diff --git a/applications/main/bad_usb/bad_usb_script.c b/applications/main/bad_usb/bad_usb_script.c index 9d9d3e397..78aba88ed 100644 --- a/applications/main/bad_usb/bad_usb_script.c +++ b/applications/main/bad_usb/bad_usb_script.c @@ -26,16 +26,16 @@ typedef enum { struct BadUsbScript { FuriHalUsbHidConfig hid_cfg; BadUsbState st; - string_t file_path; + FuriString* file_path; uint32_t defdelay; FuriThread* thread; uint8_t file_buf[FILE_BUFFER_LEN + 1]; uint8_t buf_start; uint8_t buf_len; bool file_end; - string_t line; + FuriString* line; - string_t line_prev; + FuriString* line_prev; uint32_t repeat_cnt; }; @@ -109,6 +109,7 @@ static const char ducky_cmd_string[] = {"STRING "}; static const char ducky_cmd_defdelay_1[] = {"DEFAULT_DELAY "}; static const char ducky_cmd_defdelay_2[] = {"DEFAULTDELAY "}; static const char ducky_cmd_repeat[] = {"REPEAT "}; +static const char ducky_cmd_sysrq[] = {"SYSRQ "}; static const char ducky_cmd_altchar[] = {"ALTCHAR "}; static const char ducky_cmd_altstr_1[] = {"ALTSTRING "}; @@ -230,9 +231,9 @@ static uint16_t ducky_get_keycode(const char* param, bool accept_chars) { return 0; } -static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) { - uint32_t line_len = string_size(line); - const char* line_tmp = string_get_cstr(line); +static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { + uint32_t line_len = furi_string_size(line); + const char* line_tmp = furi_string_get_cstr(line); bool state = false; for(uint32_t i = 0; i < line_len; i++) { @@ -292,6 +293,14 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) { line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; state = ducky_get_number(line_tmp, &bad_usb->repeat_cnt); return (state) ? (0) : SCRIPT_STATE_ERROR; + } else if(strncmp(line_tmp, ducky_cmd_sysrq, strlen(ducky_cmd_sysrq)) == 0) { + // SYSRQ + line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1]; + uint16_t key = ducky_get_keycode(line_tmp, true); + furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); + furi_hal_hid_kb_press(key); + furi_hal_hid_kb_release_all(); + return (0); } else { // Special keys + modifiers uint16_t key = ducky_get_keycode(line_tmp, false); @@ -323,7 +332,7 @@ static bool ducky_set_usb_id(BadUsbScript* bad_usb, const char* line) { } FURI_LOG_D( WORKER_TAG, - "set id: %04X:%04X mfr:%s product:%s", + "set id: %04lX:%04lX mfr:%s product:%s", bad_usb->hid_cfg.vid, bad_usb->hid_cfg.pid, bad_usb->hid_cfg.manuf, @@ -337,7 +346,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { uint8_t ret = 0; uint32_t line_len = 0; - string_reset(bad_usb->line); + furi_string_reset(bad_usb->line); do { ret = storage_file_read(script_file, bad_usb->file_buf, FILE_BUFFER_LEN); @@ -347,7 +356,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { line_len = 0; } else { if(bad_usb->st.line_nb == 0) { // Save first line - string_push_back(bad_usb->line, bad_usb->file_buf[i]); + furi_string_push_back(bad_usb->line, bad_usb->file_buf[i]); } line_len++; } @@ -360,7 +369,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { } } while(ret > 0); - const char* line_tmp = string_get_cstr(bad_usb->line); + const char* line_tmp = furi_string_get_cstr(bad_usb->line); bool id_set = false; // Looking for ID command at first line if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) { id_set = ducky_set_usb_id(bad_usb, &line_tmp[strlen(ducky_cmd_id) + 1]); @@ -373,7 +382,7 @@ static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) { } storage_file_seek(script_file, 0, true); - string_reset(bad_usb->line); + furi_string_reset(bad_usb->line); return true; } @@ -388,15 +397,15 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil return 0; } else if(delay_val < 0) { // Script error bad_usb->st.error_line = bad_usb->st.line_cur - 1; - FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur - 1); + FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur - 1); return SCRIPT_STATE_ERROR; } else { return (delay_val + bad_usb->defdelay); } } - string_set(bad_usb->line_prev, bad_usb->line); - string_reset(bad_usb->line); + furi_string_set(bad_usb->line_prev, bad_usb->line); + furi_string_reset(bad_usb->line); while(1) { if(bad_usb->buf_len == 0) { @@ -413,20 +422,20 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil if(bad_usb->buf_len == 0) return SCRIPT_STATE_END; } for(uint8_t i = bad_usb->buf_start; i < (bad_usb->buf_start + bad_usb->buf_len); i++) { - if(bad_usb->file_buf[i] == '\n' && string_size(bad_usb->line) > 0) { + if(bad_usb->file_buf[i] == '\n' && furi_string_size(bad_usb->line) > 0) { bad_usb->st.line_cur++; bad_usb->buf_len = bad_usb->buf_len + bad_usb->buf_start - (i + 1); bad_usb->buf_start = i + 1; delay_val = ducky_parse_line(bad_usb, bad_usb->line); if(delay_val < 0) { bad_usb->st.error_line = bad_usb->st.line_cur; - FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur); + FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur); return SCRIPT_STATE_ERROR; } else { return (delay_val + bad_usb->defdelay); } } else { - string_push_back(bad_usb->line, bad_usb->file_buf[i]); + furi_string_push_back(bad_usb->line, bad_usb->file_buf[i]); } } bad_usb->buf_len = 0; @@ -456,8 +465,8 @@ static int32_t bad_usb_worker(void* context) { FURI_LOG_I(WORKER_TAG, "Init"); File* script_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); - string_init(bad_usb->line); - string_init(bad_usb->line_prev); + bad_usb->line = furi_string_alloc(); + bad_usb->line_prev = furi_string_alloc(); furi_hal_hid_set_state_callback(bad_usb_hid_state_callback, bad_usb); @@ -465,7 +474,7 @@ static int32_t bad_usb_worker(void* context) { if(worker_state == BadUsbStateInit) { // State: initialization if(storage_file_open( script_file, - string_get_cstr(bad_usb->file_path), + furi_string_get_cstr(bad_usb->file_path), FSAM_READ, FSOM_OPEN_EXISTING)) { if((ducky_script_preload(bad_usb, script_file)) && (bad_usb->st.line_nb > 0)) { @@ -577,20 +586,20 @@ static int32_t bad_usb_worker(void* context) { storage_file_close(script_file); storage_file_free(script_file); - string_clear(bad_usb->line); - string_clear(bad_usb->line_prev); + furi_string_free(bad_usb->line); + furi_string_free(bad_usb->line_prev); FURI_LOG_I(WORKER_TAG, "End"); return 0; } -BadUsbScript* bad_usb_script_open(string_t file_path) { +BadUsbScript* bad_usb_script_open(FuriString* file_path) { furi_assert(file_path); BadUsbScript* bad_usb = malloc(sizeof(BadUsbScript)); - string_init(bad_usb->file_path); - string_set(bad_usb->file_path, file_path); + bad_usb->file_path = furi_string_alloc(); + furi_string_set(bad_usb->file_path, file_path); bad_usb->st.state = BadUsbStateInit; @@ -609,7 +618,7 @@ void bad_usb_script_close(BadUsbScript* bad_usb) { furi_thread_flags_set(furi_thread_get_id(bad_usb->thread), WorkerEvtEnd); furi_thread_join(bad_usb->thread); furi_thread_free(bad_usb->thread); - string_clear(bad_usb->file_path); + furi_string_free(bad_usb->file_path); free(bad_usb); } diff --git a/applications/main/bad_usb/bad_usb_script.h b/applications/main/bad_usb/bad_usb_script.h index 88921de38..5fee6505f 100644 --- a/applications/main/bad_usb/bad_usb_script.h +++ b/applications/main/bad_usb/bad_usb_script.h @@ -5,7 +5,6 @@ extern "C" { #endif #include -#include typedef struct BadUsbScript BadUsbScript; @@ -28,7 +27,7 @@ typedef struct { uint16_t error_line; } BadUsbState; -BadUsbScript* bad_usb_script_open(string_t file_path); +BadUsbScript* bad_usb_script_open(FuriString* file_path); void bad_usb_script_close(BadUsbScript* bad_usb); diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_work.c b/applications/main/bad_usb/scenes/bad_usb_scene_work.c index 516cbde3a..689f3b4ea 100644 --- a/applications/main/bad_usb/scenes/bad_usb_scene_work.c +++ b/applications/main/bad_usb/scenes/bad_usb_scene_work.c @@ -2,7 +2,6 @@ #include "../bad_usb_app_i.h" #include "../views/bad_usb_view.h" #include "furi_hal.h" -#include "m-string.h" #include "toolbox/path.h" void bad_usb_scene_work_ok_callback(InputType type, void* context) { @@ -27,14 +26,14 @@ bool bad_usb_scene_work_on_event(void* context, SceneManagerEvent event) { void bad_usb_scene_work_on_enter(void* context) { BadUsbApp* app = context; - string_t file_name; - string_init(file_name); + FuriString* file_name; + file_name = furi_string_alloc(); path_extract_filename(app->file_path, file_name, true); - bad_usb_set_file_name(app->bad_usb_view, string_get_cstr(file_name)); + bad_usb_set_file_name(app->bad_usb_view, furi_string_get_cstr(file_name)); app->bad_usb_script = bad_usb_script_open(app->file_path); - string_clear(file_name); + furi_string_free(file_name); bad_usb_set_state(app->bad_usb_view, bad_usb_script_get_state(app->bad_usb_script)); diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index 0679669f6..db10d01ee 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -19,12 +19,12 @@ typedef struct { static void bad_usb_draw_callback(Canvas* canvas, void* _model) { BadUsbModel* model = _model; - string_t disp_str; - string_init_set_str(disp_str, model->file_name); + FuriString* disp_str; + 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, 22, 20, &I_UsbTree_48x22); @@ -49,10 +49,10 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned(canvas, 127, 33, AlignRight, AlignBottom, "ERROR:"); canvas_set_font(canvas, FontSecondary); - string_printf(disp_str, "line %u", model->state.error_line); + furi_string_printf(disp_str, "line %u", model->state.error_line); canvas_draw_str_aligned( - canvas, 127, 46, AlignRight, AlignBottom, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); } else if(model->state.state == BadUsbStateIdle) { canvas_draw_icon(canvas, 4, 22, &I_Smile_18x18); canvas_set_font(canvas, FontBigNumbers); @@ -65,16 +65,17 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 4, 19, &I_EviSmile2_18x21); } canvas_set_font(canvas, FontBigNumbers); - string_printf(disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); + furi_string_printf( + disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); canvas_draw_str_aligned( - canvas, 114, 36, AlignRight, AlignBottom, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas, 114, 36, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 22, &I_Percent_10x14); } else if(model->state.state == BadUsbStateDone) { canvas_draw_icon(canvas, 4, 19, &I_EviSmile1_18x21); canvas_set_font(canvas, FontBigNumbers); canvas_draw_str_aligned(canvas, 114, 36, AlignRight, AlignBottom, "100"); - string_reset(disp_str); + furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 22, &I_Percent_10x14); } else if(model->state.state == BadUsbStateDelay) { if(model->anim_frame == 0) { @@ -83,21 +84,22 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 4, 19, &I_EviWaiting2_18x21); } canvas_set_font(canvas, FontBigNumbers); - string_printf(disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); + furi_string_printf( + disp_str, "%u", ((model->state.line_cur - 1) * 100) / model->state.line_nb); canvas_draw_str_aligned( - canvas, 114, 36, AlignRight, AlignBottom, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas, 114, 36, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); canvas_draw_icon(canvas, 117, 22, &I_Percent_10x14); canvas_set_font(canvas, FontSecondary); - string_printf(disp_str, "delay %us", model->state.delay_remain); + furi_string_printf(disp_str, "delay %lus", model->state.delay_remain); canvas_draw_str_aligned( - canvas, 127, 46, AlignRight, AlignBottom, string_get_cstr(disp_str)); - string_reset(disp_str); + canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str)); + furi_string_reset(disp_str); } else { canvas_draw_icon(canvas, 4, 22, &I_Clock_18x18); } - string_clear(disp_str); + furi_string_free(disp_str); } static bool bad_usb_input_callback(InputEvent* event, void* context) { @@ -143,29 +145,33 @@ void bad_usb_set_ok_callback(BadUsb* bad_usb, BadUsbOkCallback callback, void* c furi_assert(bad_usb); furi_assert(callback); with_view_model( - bad_usb->view, (BadUsbModel * model) { + bad_usb->view, + BadUsbModel * model, + { UNUSED(model); bad_usb->callback = callback; bad_usb->context = context; - return true; - }); + }, + true); } void bad_usb_set_file_name(BadUsb* bad_usb, const char* name) { furi_assert(name); with_view_model( - bad_usb->view, (BadUsbModel * model) { - strlcpy(model->file_name, name, MAX_NAME_LEN); - return true; - }); + bad_usb->view, + BadUsbModel * model, + { strlcpy(model->file_name, name, MAX_NAME_LEN); }, + true); } void bad_usb_set_state(BadUsb* bad_usb, BadUsbState* st) { furi_assert(st); with_view_model( - bad_usb->view, (BadUsbModel * model) { + bad_usb->view, + BadUsbModel * model, + { memcpy(&(model->state), st, sizeof(BadUsbState)); model->anim_frame ^= 1; - return true; - }); + }, + true); } diff --git a/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp b/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp index 17e2ba83f..f8adbf9d8 100644 --- a/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp +++ b/applications/main/fap_loader/elf_cpp/elf_hashtable.cpp @@ -31,7 +31,7 @@ bool elf_resolve_from_hashtable(const char* name, Elf32_Addr* address) { auto find_res = std::lower_bound(elf_api_table.cbegin(), elf_api_table.cend(), key); if((find_res == elf_api_table.cend() || (find_res->hash != gnu_sym_hash))) { - FURI_LOG_W(TAG, "Cant find symbol '%s' (hash %x)!", name, gnu_sym_hash); + FURI_LOG_W(TAG, "Cant find symbol '%s' (hash %lx)!", name, gnu_sym_hash); result = false; } else { result = true; diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index c0f60ceca..d2f6b1f41 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -1,34 +1,34 @@ #include #include #include -#include #include +#include #include -#include "elf_cpp/elf_hashtable.h" #include +#include "elf_cpp/elf_hashtable.h" +#include "fap_loader_app.h" #define TAG "fap_loader_app" -typedef struct { +struct FapLoader { FlipperApplication* app; Storage* storage; DialogsApp* dialogs; Gui* gui; - string_t fap_path; - + FuriString* fap_path; ViewDispatcher* view_dispatcher; Loading* loading; -} FapLoader; +}; -static bool - fap_loader_item_callback(string_t path, void* context, uint8_t** icon_ptr, string_t item_name) { - FapLoader* loader = context; - furi_assert(loader); - - FlipperApplication* app = flipper_application_alloc(loader->storage, &hashtable_api_interface); +bool fap_loader_load_name_and_icon( + FuriString* path, + Storage* storage, + uint8_t** icon_ptr, + FuriString* item_name) { + FlipperApplication* app = flipper_application_alloc(storage, &hashtable_api_interface); FlipperApplicationPreloadStatus preload_res = - flipper_application_preload_manifest(app, string_get_cstr(path)); + flipper_application_preload_manifest(app, furi_string_get_cstr(path)); bool load_success = false; @@ -37,10 +37,10 @@ static bool if(manifest->has_icon) { memcpy(*icon_ptr, manifest->icon, FAP_MANIFEST_MAX_ICON_SIZE); } - string_set_str(item_name, manifest->name); + furi_string_set(item_name, manifest->name); load_success = true; } else { - FURI_LOG_E(TAG, "FAP Loader failed to preload %s", string_get_cstr(path)); + FURI_LOG_E(TAG, "FAP Loader failed to preload %s", furi_string_get_cstr(path)); load_success = false; } @@ -48,30 +48,41 @@ static bool return load_success; } +static bool fap_loader_item_callback( + FuriString* path, + void* context, + uint8_t** icon_ptr, + FuriString* item_name) { + FapLoader* fap_loader = context; + furi_assert(fap_loader); + return fap_loader_load_name_and_icon(path, fap_loader->storage, icon_ptr, item_name); +} + static bool fap_loader_run_selected_app(FapLoader* loader) { furi_assert(loader); - string_t error_message; + FuriString* error_message; - string_init_set(error_message, "unknown error"); + error_message = furi_string_alloc_set("unknown error"); bool file_selected = false; bool show_error = true; do { file_selected = true; loader->app = flipper_application_alloc(loader->storage, &hashtable_api_interface); + size_t start = furi_get_tick(); - FURI_LOG_I(TAG, "FAP Loader is loading %s", string_get_cstr(loader->fap_path)); + FURI_LOG_I(TAG, "FAP Loader is loading %s", furi_string_get_cstr(loader->fap_path)); FlipperApplicationPreloadStatus preload_res = - flipper_application_preload(loader->app, string_get_cstr(loader->fap_path)); + flipper_application_preload(loader->app, furi_string_get_cstr(loader->fap_path)); if(preload_res != FlipperApplicationPreloadStatusSuccess) { const char* err_msg = flipper_application_preload_status_to_string(preload_res); - string_printf(error_message, "Preload failed: %s", err_msg); + furi_string_printf(error_message, "Preload failed: %s", err_msg); FURI_LOG_E( TAG, "FAP Loader failed to preload %s: %s", - string_get_cstr(loader->fap_path), + furi_string_get_cstr(loader->fap_path), err_msg); break; } @@ -80,15 +91,16 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { FlipperApplicationLoadStatus load_status = flipper_application_map_to_memory(loader->app); if(load_status != FlipperApplicationLoadStatusSuccess) { const char* err_msg = flipper_application_load_status_to_string(load_status); - string_printf(error_message, "Load failed: %s", err_msg); + furi_string_printf(error_message, "Load failed: %s", err_msg); FURI_LOG_E( TAG, "FAP Loader failed to map to memory %s: %s", - string_get_cstr(loader->fap_path), + furi_string_get_cstr(loader->fap_path), err_msg); break; } + FURI_LOG_I(TAG, "Loaded in %ums", (size_t)(furi_get_tick() - start)); FURI_LOG_I(TAG, "FAP Loader is staring app"); FuriThread* thread = flipper_application_spawn(loader->app, NULL); @@ -106,19 +118,19 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { dialog_message_set_header(message, "Error", 64, 0, AlignCenter, AlignTop); dialog_message_set_buttons(message, NULL, NULL, NULL); - string_t buffer; - string_init(buffer); - string_printf(buffer, "%s", string_get_cstr(error_message)); - string_replace_str(buffer, ":", "\n"); + FuriString* buffer; + buffer = furi_string_alloc(); + furi_string_printf(buffer, "%s", furi_string_get_cstr(error_message)); + furi_string_replace(buffer, ":", "\n"); dialog_message_set_text( - message, string_get_cstr(buffer), 64, 32, AlignCenter, AlignCenter); + message, furi_string_get_cstr(buffer), 64, 32, AlignCenter, AlignCenter); dialog_message_show(loader->dialogs, message); dialog_message_free(message); - string_clear(buffer); + furi_string_free(buffer); } - string_clear(error_message); + furi_string_free(error_message); if(file_selected) { flipper_application_free(loader->app); @@ -131,7 +143,7 @@ static bool fap_loader_select_app(FapLoader* loader) { const DialogsFileBrowserOptions browser_options = { .extension = ".fap", .skip_assets = true, - .icon = &I_badusb_10px, + .icon = &I_unknown_10px, .hide_ext = true, .item_loader_callback = fap_loader_item_callback, .item_loader_context = loader, @@ -141,39 +153,44 @@ static bool fap_loader_select_app(FapLoader* loader) { loader->dialogs, loader->fap_path, loader->fap_path, &browser_options); } -int32_t fap_loader_app(void* p) { +static FapLoader* fap_loader_alloc(const char* path) { FapLoader* loader = malloc(sizeof(FapLoader)); + loader->fap_path = furi_string_alloc_set(path); loader->storage = furi_record_open(RECORD_STORAGE); loader->dialogs = furi_record_open(RECORD_DIALOGS); loader->gui = furi_record_open(RECORD_GUI); - loader->view_dispatcher = view_dispatcher_alloc(); loader->loading = loading_alloc(); - view_dispatcher_attach_to_gui( loader->view_dispatcher, loader->gui, ViewDispatcherTypeFullscreen); view_dispatcher_add_view(loader->view_dispatcher, 0, loading_get_view(loader->loading)); + return loader; +} +static void fap_loader_free(FapLoader* loader) { + view_dispatcher_remove_view(loader->view_dispatcher, 0); + loading_free(loader->loading); + view_dispatcher_free(loader->view_dispatcher); + furi_string_free(loader->fap_path); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_DIALOGS); + furi_record_close(RECORD_STORAGE); + free(loader); +} + +int32_t fap_loader_app(void* p) { + FapLoader* loader; if(p) { - string_init_set(loader->fap_path, (const char*)p); + loader = fap_loader_alloc((const char*)p); fap_loader_run_selected_app(loader); } else { - string_init_set(loader->fap_path, EXT_PATH("apps")); - + loader = fap_loader_alloc(EXT_PATH("apps")); while(fap_loader_select_app(loader)) { view_dispatcher_switch_to_view(loader->view_dispatcher, 0); fap_loader_run_selected_app(loader); }; } - view_dispatcher_remove_view(loader->view_dispatcher, 0); - loading_free(loader->loading); - view_dispatcher_free(loader->view_dispatcher); - - string_clear(loader->fap_path); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_DIALOGS); - furi_record_close(RECORD_STORAGE); - free(loader); + fap_loader_free(loader); return 0; -} \ No newline at end of file +} diff --git a/applications/main/fap_loader/fap_loader_app.h b/applications/main/fap_loader/fap_loader_app.h new file mode 100644 index 000000000..9ed725efe --- /dev/null +++ b/applications/main/fap_loader/fap_loader_app.h @@ -0,0 +1,27 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FapLoader FapLoader; + +/** + * @brief Load name and icon from FAP file. + * + * @param path Path to FAP file. + * @param storage Storage instance. + * @param icon_ptr Icon pointer. + * @param item_name Application name. + * @return true if icon and name were loaded successfully. + */ +bool fap_loader_load_name_and_icon( + FuriString* path, + Storage* storage, + uint8_t** icon_ptr, + FuriString* item_name); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/applications/main/gpio/usb_uart_bridge.c b/applications/main/gpio/usb_uart_bridge.c index 02f58ed10..6e0bce736 100644 --- a/applications/main/gpio/usb_uart_bridge.c +++ b/applications/main/gpio/usb_uart_bridge.c @@ -1,6 +1,5 @@ #include "usb_uart_bridge.h" #include "furi_hal.h" -#include #include #include "usb_cdc.h" #include "cli/cli_vcp.h" @@ -43,7 +42,7 @@ struct UsbUartBridge { FuriThread* thread; FuriThread* tx_thread; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* rx_stream; FuriMutex* usb_mutex; @@ -74,12 +73,10 @@ static int32_t usb_uart_tx_thread(void* context); static void usb_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { UsbUartBridge* usb_uart = (UsbUartBridge*)context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; if(ev == UartIrqEventRXNE) { - xStreamBufferSendFromISR(usb_uart->rx_stream, &data, 1, &xHigherPriorityTaskWoken); + furi_stream_buffer_send(usb_uart->rx_stream, &data, 1, 0); furi_thread_flags_set(furi_thread_get_id(usb_uart->thread), WorkerEvtRxDone); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } @@ -156,7 +153,7 @@ static int32_t usb_uart_worker(void* context) { memcpy(&usb_uart->cfg, &usb_uart->cfg_new, sizeof(UsbUartConfig)); - usb_uart->rx_stream = xStreamBufferCreate(USB_UART_RX_BUF_SIZE, 1); + usb_uart->rx_stream = furi_stream_buffer_alloc(USB_UART_RX_BUF_SIZE, 1); usb_uart->tx_sem = furi_semaphore_alloc(1, 1); usb_uart->usb_mutex = furi_mutex_alloc(FuriMutexTypeNormal); @@ -189,8 +186,8 @@ static int32_t usb_uart_worker(void* context) { furi_check((events & FuriFlagError) == 0); if(events & WorkerEvtStop) break; if(events & WorkerEvtRxDone) { - size_t len = - xStreamBufferReceive(usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0); + size_t len = furi_stream_buffer_receive( + usb_uart->rx_stream, usb_uart->rx_buf, USB_CDC_PKT_LEN, 0); if(len > 0) { if(furi_semaphore_acquire(usb_uart->tx_sem, 100) == FuriStatusOk) { usb_uart->st.rx_cnt += len; @@ -199,7 +196,7 @@ static int32_t usb_uart_worker(void* context) { furi_hal_cdc_send(usb_uart->cfg.vcp_ch, usb_uart->rx_buf, len); furi_check(furi_mutex_release(usb_uart->usb_mutex) == FuriStatusOk); } else { - xStreamBufferReset(usb_uart->rx_stream); + furi_stream_buffer_reset(usb_uart->rx_stream); } } } @@ -270,7 +267,7 @@ static int32_t usb_uart_worker(void* context) { furi_thread_join(usb_uart->tx_thread); furi_thread_free(usb_uart->tx_thread); - vStreamBufferDelete(usb_uart->rx_stream); + furi_stream_buffer_free(usb_uart->rx_stream); furi_mutex_free(usb_uart->usb_mutex); furi_semaphore_free(usb_uart->tx_sem); diff --git a/applications/main/gpio/views/gpio_test.c b/applications/main/gpio/views/gpio_test.c index 89c09f864..69dc0f67b 100644 --- a/applications/main/gpio/views/gpio_test.c +++ b/applications/main/gpio/views/gpio_test.c @@ -48,23 +48,27 @@ static bool gpio_test_input_callback(InputEvent* event, void* context) { static bool gpio_test_process_left(GpioTest* gpio_test) { with_view_model( - gpio_test->view, (GpioTestModel * model) { + gpio_test->view, + GpioTestModel * model, + { if(model->pin_idx) { model->pin_idx--; } - return true; - }); + }, + true); return true; } static bool gpio_test_process_right(GpioTest* gpio_test) { with_view_model( - gpio_test->view, (GpioTestModel * model) { + gpio_test->view, + GpioTestModel * model, + { if(model->pin_idx < GPIO_ITEM_COUNT) { model->pin_idx++; } - return true; - }); + }, + true); return true; } @@ -72,7 +76,9 @@ static bool gpio_test_process_ok(GpioTest* gpio_test, InputEvent* event) { bool consumed = false; with_view_model( - gpio_test->view, (GpioTestModel * model) { + gpio_test->view, + GpioTestModel * model, + { if(event->type == InputTypePress) { if(model->pin_idx < GPIO_ITEM_COUNT) { gpio_item_set_pin(model->pin_idx, true); @@ -89,8 +95,8 @@ static bool gpio_test_process_ok(GpioTest* gpio_test, InputEvent* event) { consumed = true; } gpio_test->callback(event->type, gpio_test->context); - return true; - }); + }, + true); return consumed; } @@ -122,10 +128,12 @@ void gpio_test_set_ok_callback(GpioTest* gpio_test, GpioTestOkCallback callback, furi_assert(gpio_test); furi_assert(callback); with_view_model( - gpio_test->view, (GpioTestModel * model) { + gpio_test->view, + GpioTestModel * model, + { UNUSED(model); gpio_test->callback = callback; gpio_test->context = context; - return false; - }); + }, + false); } diff --git a/applications/main/gpio/views/gpio_usb_uart.c b/applications/main/gpio/views/gpio_usb_uart.c index d2d371b68..c7406d29b 100644 --- a/applications/main/gpio/views/gpio_usb_uart.c +++ b/applications/main/gpio/views/gpio_usb_uart.c @@ -54,7 +54,7 @@ static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 116, 24, AlignRight, AlignBottom, temp_str); } else { canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KB."); + canvas_draw_str_aligned(canvas, 127, 24, AlignRight, AlignBottom, "KiB."); canvas_set_font(canvas, FontKeyboard); snprintf(temp_str, 18, "%lu", model->tx_cnt / 1024); canvas_draw_str_aligned(canvas, 111, 24, AlignRight, AlignBottom, temp_str); @@ -68,7 +68,7 @@ static void gpio_usb_uart_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 116, 41, AlignRight, AlignBottom, temp_str); } else { canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KB."); + canvas_draw_str_aligned(canvas, 127, 41, AlignRight, AlignBottom, "KiB."); canvas_set_font(canvas, FontKeyboard); snprintf(temp_str, 18, "%lu", model->rx_cnt / 1024); canvas_draw_str_aligned(canvas, 111, 41, AlignRight, AlignBottom, temp_str); @@ -129,12 +129,14 @@ void gpio_usb_uart_set_callback(GpioUsbUart* usb_uart, GpioUsbUartCallback callb furi_assert(callback); with_view_model( - usb_uart->view, (GpioUsbUartModel * model) { + usb_uart->view, + GpioUsbUartModel * model, + { UNUSED(model); usb_uart->callback = callback; usb_uart->context = context; - return false; - }); + }, + false); } void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUartState* st) { @@ -143,7 +145,9 @@ void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUa furi_assert(st); with_view_model( - instance->view, (GpioUsbUartModel * model) { + instance->view, + GpioUsbUartModel * model, + { model->baudrate = st->baudrate_cur; model->vcp_port = cfg->vcp_ch; model->tx_pin = (cfg->uart_ch == 0) ? (13) : (15); @@ -152,6 +156,6 @@ void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUa model->rx_active = (model->rx_cnt != st->rx_cnt); model->tx_cnt = st->tx_cnt; model->rx_cnt = st->rx_cnt; - return true; - }); + }, + true); } diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index e9ec614ec..887fb3e75 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -2,7 +2,6 @@ #include "assets_icons.h" #include "ibutton_i.h" #include "ibutton/scenes/ibutton_scene.h" -#include "m-string.h" #include #include #include @@ -39,25 +38,25 @@ static void ibutton_make_app_folder(iButton* ibutton) { } } -bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog) { +bool ibutton_load_key_data(iButton* ibutton, FuriString* key_path, bool show_dialog) { FlipperFormat* file = flipper_format_file_alloc(ibutton->storage); bool result = false; - string_t data; - string_init(data); + FuriString* data; + data = furi_string_alloc(); do { - if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(key_path))) break; // header uint32_t version; if(!flipper_format_read_header(file, data, &version)) break; - if(string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break; + if(furi_string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break; if(version != 1) break; // key type iButtonKeyType type; if(!flipper_format_read_string(file, "Key type", data)) break; - if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break; + if(!ibutton_key_get_type_by_string(furi_string_get_cstr(data), &type)) break; // key data uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0}; @@ -71,7 +70,7 @@ bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog } while(false); flipper_format_free(file); - string_clear(data); + furi_string_free(data); if((!result) && (show_dialog)) { dialog_message_show_storage_error(ibutton->dialogs, "Cannot load\nkey file"); @@ -119,7 +118,7 @@ void ibutton_tick_event_callback(void* context) { iButton* ibutton_alloc() { iButton* ibutton = malloc(sizeof(iButton)); - string_init(ibutton->file_path); + ibutton->file_path = furi_string_alloc(); ibutton->scene_manager = scene_manager_alloc(&ibutton_scene_handlers, ibutton); @@ -210,7 +209,7 @@ void ibutton_free(iButton* ibutton) { ibutton_worker_free(ibutton->key_worker); ibutton_key_free(ibutton->key); - string_clear(ibutton->file_path); + furi_string_free(ibutton->file_path); free(ibutton); } @@ -240,19 +239,19 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) { do { // Check if we has old key - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { // First remove old key ibutton_delete_key(ibutton); // Remove old key name from path - size_t filename_start = string_search_rchar(ibutton->file_path, '/'); - string_left(ibutton->file_path, filename_start); + size_t filename_start = furi_string_search_rchar(ibutton->file_path, '/'); + furi_string_left(ibutton->file_path, filename_start); } - string_cat_printf(ibutton->file_path, "/%s%s", key_name, IBUTTON_APP_EXTENSION); + furi_string_cat_printf(ibutton->file_path, "/%s%s", key_name, IBUTTON_APP_EXTENSION); // Open file for write - if(!flipper_format_file_open_always(file, string_get_cstr(ibutton->file_path))) break; + if(!flipper_format_file_open_always(file, furi_string_get_cstr(ibutton->file_path))) break; // Write header if(!flipper_format_write_header_cstr(file, IBUTTON_APP_FILE_TYPE, 1)) break; @@ -286,7 +285,7 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) { bool ibutton_delete_key(iButton* ibutton) { bool result = false; - result = storage_simply_remove(ibutton->storage, string_get_cstr(ibutton->file_path)); + result = storage_simply_remove(ibutton->storage, furi_string_get_cstr(ibutton->file_path)); return result; } @@ -326,7 +325,7 @@ int32_t ibutton_app(void* p) { rpc_system_app_set_callback(ibutton->rpc_ctx, ibutton_rpc_command_callback, ibutton); rpc_system_app_send_started(ibutton->rpc_ctx); } else { - string_set_str(ibutton->file_path, (const char*)p); + furi_string_set(ibutton->file_path, (const char*)p); if(ibutton_load_key_data(ibutton, ibutton->file_path, true)) { key_loaded = true; // TODO: Display an error if the key from p could not be loaded diff --git a/applications/main/ibutton/ibutton_cli.c b/applications/main/ibutton/ibutton_cli.c index d36d3dffd..fab1ccf05 100644 --- a/applications/main/ibutton/ibutton_cli.c +++ b/applications/main/ibutton/ibutton_cli.c @@ -6,8 +6,8 @@ #include #include -static void ibutton_cli(Cli* cli, string_t args, void* context); -static void onewire_cli(Cli* cli, string_t args, void* context); +static void ibutton_cli(Cli* cli, FuriString* args, void* context); +static void onewire_cli(Cli* cli, FuriString* args, void* context); // app cli function void ibutton_on_system_start() { @@ -34,16 +34,16 @@ void ibutton_cli_print_usage() { printf("\t are hex-formatted\r\n"); }; -bool ibutton_cli_get_key_type(string_t data, iButtonKeyType* type) { +bool ibutton_cli_get_key_type(FuriString* data, iButtonKeyType* type) { bool result = false; - if(string_cmp_str(data, "Dallas") == 0 || string_cmp_str(data, "dallas") == 0) { + if(furi_string_cmp_str(data, "Dallas") == 0 || furi_string_cmp_str(data, "dallas") == 0) { result = true; *type = iButtonKeyDS1990; - } else if(string_cmp_str(data, "Cyfral") == 0 || string_cmp_str(data, "cyfral") == 0) { + } else if(furi_string_cmp_str(data, "Cyfral") == 0 || furi_string_cmp_str(data, "cyfral") == 0) { result = true; *type = iButtonKeyCyfral; - } else if(string_cmp_str(data, "Metakom") == 0 || string_cmp_str(data, "metakom") == 0) { + } else if(furi_string_cmp_str(data, "Metakom") == 0 || furi_string_cmp_str(data, "metakom") == 0) { result = true; *type = iButtonKeyMetakom; } @@ -123,17 +123,17 @@ static void ibutton_cli_worker_write_cb(void* context, iButtonWorkerWriteResult furi_event_flag_set(write_context->event, EVENT_FLAG_IBUTTON_COMPLETE); } -void ibutton_cli_write(Cli* cli, string_t args) { +void ibutton_cli_write(Cli* cli, FuriString* args) { iButtonKey* key = ibutton_key_alloc(); iButtonWorker* worker = ibutton_worker_alloc(); iButtonKeyType type; iButtonWriteContext write_context; uint8_t key_data[IBUTTON_KEY_DATA_SIZE]; - string_t data; + FuriString* data; write_context.event = furi_event_flag_alloc(); - string_init(data); + data = furi_string_alloc(); ibutton_worker_start_thread(worker); ibutton_worker_write_set_callback(worker, ibutton_cli_worker_write_cb, &write_context); @@ -186,7 +186,7 @@ void ibutton_cli_write(Cli* cli, string_t args) { ibutton_worker_stop(worker); } while(false); - string_clear(data); + furi_string_free(data); ibutton_worker_stop_thread(worker); ibutton_worker_free(worker); ibutton_key_free(key); @@ -194,14 +194,14 @@ void ibutton_cli_write(Cli* cli, string_t args) { furi_event_flag_free(write_context.event); }; -void ibutton_cli_emulate(Cli* cli, string_t args) { +void ibutton_cli_emulate(Cli* cli, FuriString* args) { iButtonKey* key = ibutton_key_alloc(); iButtonWorker* worker = ibutton_worker_alloc(); iButtonKeyType type; uint8_t key_data[IBUTTON_KEY_DATA_SIZE]; - string_t data; + FuriString* data; - string_init(data); + data = furi_string_alloc(); ibutton_worker_start_thread(worker); do { @@ -234,34 +234,34 @@ void ibutton_cli_emulate(Cli* cli, string_t args) { ibutton_worker_stop(worker); } while(false); - string_clear(data); + furi_string_free(data); ibutton_worker_stop_thread(worker); ibutton_worker_free(worker); ibutton_key_free(key); }; -static void ibutton_cli(Cli* cli, string_t args, void* context) { +static void ibutton_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); if(!args_read_string_and_trim(args, cmd)) { - string_clear(cmd); + furi_string_free(cmd); ibutton_cli_print_usage(); return; } - if(string_cmp_str(cmd, "read") == 0) { + if(furi_string_cmp_str(cmd, "read") == 0) { ibutton_cli_read(cli); - } else if(string_cmp_str(cmd, "write") == 0) { + } else if(furi_string_cmp_str(cmd, "write") == 0) { ibutton_cli_write(cli, args); - } else if(string_cmp_str(cmd, "emulate") == 0) { + } else if(furi_string_cmp_str(cmd, "emulate") == 0) { ibutton_cli_emulate(cli, args); } else { ibutton_cli_print_usage(); } - string_clear(cmd); + furi_string_free(cmd); } void onewire_cli_print_usage() { @@ -299,20 +299,20 @@ static void onewire_cli_search(Cli* cli) { onewire_host_free(onewire); } -void onewire_cli(Cli* cli, string_t args, void* context) { +void onewire_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); if(!args_read_string_and_trim(args, cmd)) { - string_clear(cmd); + furi_string_free(cmd); onewire_cli_print_usage(); return; } - if(string_cmp_str(cmd, "search") == 0) { + if(furi_string_cmp_str(cmd, "search") == 0) { onewire_cli_search(cli); } - string_clear(cmd); + furi_string_free(cmd); } diff --git a/applications/main/ibutton/ibutton_i.h b/applications/main/ibutton/ibutton_i.h index fd11b8c19..a9515195e 100644 --- a/applications/main/ibutton/ibutton_i.h +++ b/applications/main/ibutton/ibutton_i.h @@ -41,7 +41,7 @@ struct iButton { iButtonWorker* key_worker; iButtonKey* key; - string_t file_path; + FuriString* file_path; char text_store[IBUTTON_TEXT_STORE_SIZE + 1]; Submenu* submenu; @@ -78,7 +78,7 @@ typedef enum { } iButtonNotificationMessage; bool ibutton_file_select(iButton* ibutton); -bool ibutton_load_key_data(iButton* ibutton, string_t key_path, bool show_dialog); +bool ibutton_load_key_data(iButton* ibutton, FuriString* key_path, bool show_dialog); bool ibutton_save_key(iButton* ibutton, const char* key_name); bool ibutton_delete_key(iButton* ibutton); void ibutton_text_store_set(iButton* ibutton, const char* text, ...); diff --git a/applications/main/ibutton/scenes/ibutton_scene_add_type.c b/applications/main/ibutton/scenes/ibutton_scene_add_type.c index 9a0583a58..38373999c 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_add_type.c +++ b/applications/main/ibutton/scenes/ibutton_scene_add_type.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include "m-string.h" enum SubmenuIndex { SubmenuIndexCyfral, @@ -47,7 +46,7 @@ bool ibutton_scene_add_type_on_event(void* context, SceneManagerEvent event) { furi_crash("Unknown key type"); } - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); + furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER); ibutton_key_clear_data(key); scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddValue); } diff --git a/applications/main/ibutton/scenes/ibutton_scene_delete_confirm.c b/applications/main/ibutton/scenes/ibutton_scene_delete_confirm.c index 51f1f2794..3d609e833 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_delete_confirm.c +++ b/applications/main/ibutton/scenes/ibutton_scene_delete_confirm.c @@ -17,13 +17,13 @@ void ibutton_scene_delete_confirm_on_enter(void* context) { iButtonKey* key = ibutton->key; const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); + FuriString* key_name; + key_name = furi_string_alloc(); path_extract_filename(ibutton->file_path, key_name, true); - ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "\e#Delete %s?\e#", furi_string_get_cstr(key_name)); widget_add_text_box_element( - widget, 0, 0, 128, 27, AlignCenter, AlignCenter, ibutton->text_store, false); + widget, 0, 0, 128, 27, AlignCenter, AlignCenter, ibutton->text_store, true); widget_add_button_element( widget, GuiButtonTypeLeft, "Cancel", ibutton_scene_delete_confirm_widget_callback, ibutton); widget_add_button_element( @@ -47,28 +47,28 @@ void ibutton_scene_delete_confirm_on_enter(void* context) { key_data[6], key_data[7]); widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas"); + widget, 64, 34, AlignCenter, AlignBottom, FontSecondary, "Dallas"); break; case iButtonKeyCyfral: ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]); widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); + widget, 64, 34, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); break; case iButtonKeyMetakom: ibutton_text_store_set( ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); widget_add_string_element( - widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Metakom"); + widget, 64, 34, AlignCenter, AlignBottom, FontSecondary, "Metakom"); break; } widget_add_string_element( - widget, 64, 33, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store); + widget, 64, 46, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); - string_clear(key_name); + furi_string_free(key_name); } bool ibutton_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_emulate.c b/applications/main/ibutton/scenes/ibutton_scene_emulate.c index 3420f8471..b3bc38ead 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_emulate.c +++ b/applications/main/ibutton/scenes/ibutton_scene_emulate.c @@ -15,31 +15,29 @@ static void ibutton_scene_emulate_callback(void* context, bool emulated) { void ibutton_scene_emulate_on_enter(void* context) { iButton* ibutton = context; - Popup* popup = ibutton->popup; + Widget* widget = ibutton->widget; iButtonKey* key = ibutton->key; const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + FuriString* key_name; + key_name = furi_string_alloc(); + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { path_extract_filename(ibutton->file_path, key_name, true); } - uint8_t line_count = 2; DOLPHIN_DEED(DolphinDeedIbuttonEmulate); // check that stored key has name - if(!string_empty_p(key_name)) { - ibutton_text_store_set(ibutton, "emulating\n%s", string_get_cstr(key_name)); - line_count = 2; + if(!furi_string_empty(key_name)) { + ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name)); } else { // if not, show key data switch(ibutton_key_get_type(key)) { case iButtonKeyDS1990: ibutton_text_store_set( ibutton, - "emulating\n%02X %02X %02X %02X\n%02X %02X %02X %02X", + "%02X %02X %02X %02X\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], @@ -48,46 +46,30 @@ void ibutton_scene_emulate_on_enter(void* context) { key_data[5], key_data[6], key_data[7]); - line_count = 3; break; case iButtonKeyCyfral: - ibutton_text_store_set(ibutton, "emulating\n%02X %02X", key_data[0], key_data[1]); - line_count = 2; + ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]); break; case iButtonKeyMetakom: ibutton_text_store_set( - ibutton, - "emulating\n%02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3]); - line_count = 2; + ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); break; } } - switch(line_count) { - case 3: - popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom); - popup_set_text(popup, ibutton->text_store, 82, 22, AlignCenter, AlignTop); - break; + widget_add_string_multiline_element( + widget, 90, 10, AlignCenter, AlignTop, FontPrimary, "iButton\nemulating"); + widget_add_icon_element(widget, 3, 10, &I_iButtonKey_49x44); + widget_add_text_box_element( + widget, 54, 39, 75, 22, AlignCenter, AlignCenter, ibutton->text_store, true); - default: - popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom); - popup_set_text(popup, ibutton->text_store, 82, 28, AlignCenter, AlignTop); - break; - } - - popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); - - view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); ibutton_worker_emulate_set_callback( ibutton->key_worker, ibutton_scene_emulate_callback, ibutton); ibutton_worker_emulate_start(ibutton->key_worker, key); - string_clear(key_name); + furi_string_free(key_name); ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); } @@ -122,10 +104,7 @@ bool ibutton_scene_emulate_on_event(void* context, SceneManagerEvent event) { void ibutton_scene_emulate_on_exit(void* context) { iButton* ibutton = context; - Popup* popup = ibutton->popup; ibutton_worker_stop(ibutton->key_worker); - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); + widget_reset(ibutton->widget); ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop); } diff --git a/applications/main/ibutton/scenes/ibutton_scene_info.c b/applications/main/ibutton/scenes/ibutton_scene_info.c index bd364ada8..15648f6f2 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_info.c +++ b/applications/main/ibutton/scenes/ibutton_scene_info.c @@ -8,13 +8,13 @@ void ibutton_scene_info_on_enter(void* context) { const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); + FuriString* key_name; + key_name = furi_string_alloc(); path_extract_filename(ibutton->file_path, key_name, true); - ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name)); widget_add_text_box_element( - widget, 0, 0, 128, 28, AlignCenter, AlignCenter, ibutton->text_store, false); + widget, 0, 0, 128, 23, AlignCenter, AlignCenter, ibutton->text_store, true); switch(ibutton_key_get_type(key)) { case iButtonKeyDS1990: @@ -29,30 +29,28 @@ void ibutton_scene_info_on_enter(void* context) { key_data[5], key_data[6], key_data[7]); - widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Dallas"); + widget_add_string_element(widget, 64, 36, AlignCenter, AlignBottom, FontPrimary, "Dallas"); break; case iButtonKeyMetakom: ibutton_text_store_set( ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Metakom"); + widget, 64, 36, AlignCenter, AlignBottom, FontPrimary, "Metakom"); break; case iButtonKeyCyfral: ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]); - widget_add_string_element( - widget, 64, 51, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); + widget_add_string_element(widget, 64, 36, AlignCenter, AlignBottom, FontPrimary, "Cyfral"); break; } widget_add_string_element( - widget, 64, 35, AlignCenter, AlignBottom, FontPrimary, ibutton->text_store); + widget, 64, 50, AlignCenter, AlignBottom, FontSecondary, ibutton->text_store); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); - string_clear(key_name); + furi_string_free(key_name); } bool ibutton_scene_info_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_read.c b/applications/main/ibutton/scenes/ibutton_scene_read.c index 7af351f06..05920a0ad 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_read.c +++ b/applications/main/ibutton/scenes/ibutton_scene_read.c @@ -18,7 +18,7 @@ void ibutton_scene_read_on_enter(void* context) { popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); + furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER); ibutton_worker_read_set_callback(worker, ibutton_scene_read_callback, ibutton); ibutton_worker_read_start(worker, key); diff --git a/applications/main/ibutton/scenes/ibutton_scene_rpc.c b/applications/main/ibutton/scenes/ibutton_scene_rpc.c index 0755c8ff8..b25b1b8dd 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_rpc.c +++ b/applications/main/ibutton/scenes/ibutton_scene_rpc.c @@ -29,19 +29,19 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(event.event == iButtonCustomEventRpcLoad) { const char* arg = rpc_system_app_get_data(ibutton->rpc_ctx); bool result = false; - if(arg && (string_empty_p(ibutton->file_path))) { - string_set_str(ibutton->file_path, arg); + if(arg && (furi_string_empty(ibutton->file_path))) { + furi_string_set(ibutton->file_path, arg); if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) { ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key); - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + FuriString* key_name; + key_name = furi_string_alloc(); + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { path_extract_filename(ibutton->file_path, key_name, true); } - if(!string_empty_p(key_name)) { + if(!furi_string_empty(key_name)) { ibutton_text_store_set( - ibutton, "emulating\n%s", string_get_cstr(key_name)); + ibutton, "emulating\n%s", furi_string_get_cstr(key_name)); } else { ibutton_text_store_set(ibutton, "emulating"); } @@ -49,10 +49,10 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); - string_clear(key_name); + furi_string_free(key_name); result = true; } else { - string_reset(ibutton->file_path); + furi_string_reset(ibutton->file_path); } } rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventLoadFile, result); diff --git a/applications/main/ibutton/scenes/ibutton_scene_save_name.c b/applications/main/ibutton/scenes/ibutton_scene_save_name.c index be6403874..773b93e0c 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_save_name.c +++ b/applications/main/ibutton/scenes/ibutton_scene_save_name.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include "m-string.h" #include #include @@ -12,17 +11,17 @@ void ibutton_scene_save_name_on_enter(void* context) { iButton* ibutton = context; TextInput* text_input = ibutton->text_input; - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + FuriString* key_name; + key_name = furi_string_alloc(); + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { path_extract_filename(ibutton->file_path, key_name, true); } - const bool key_name_is_empty = string_empty_p(key_name); + const bool key_name_is_empty = furi_string_empty(key_name); if(key_name_is_empty) { set_random_name(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE); } else { - ibutton_text_store_set(ibutton, "%s", string_get_cstr(key_name)); + ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name)); } text_input_set_header_text(text_input, "Name the key"); @@ -34,19 +33,19 @@ void ibutton_scene_save_name_on_enter(void* context) { IBUTTON_KEY_NAME_SIZE, key_name_is_empty); - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - path_extract_dirname(string_get_cstr(ibutton->file_path), folder_path); + path_extract_dirname(furi_string_get_cstr(ibutton->file_path), folder_path); ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), IBUTTON_APP_EXTENSION, string_get_cstr(key_name)); + furi_string_get_cstr(folder_path), IBUTTON_APP_EXTENSION, furi_string_get_cstr(key_name)); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewTextInput); - string_clear(key_name); - string_clear(folder_path); + furi_string_free(key_name); + furi_string_free(folder_path); } bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_save_success.c b/applications/main/ibutton/scenes/ibutton_scene_save_success.c index 6c24a897c..43237f429 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_save_success.c +++ b/applications/main/ibutton/scenes/ibutton_scene_save_success.c @@ -29,10 +29,8 @@ bool ibutton_scene_save_success_on_event(void* context, SceneManagerEvent event) if(event.type == SceneManagerEventTypeCustom) { consumed = true; if(event.event == iButtonCustomEventBack) { - const uint32_t possible_scenes[] = { - iButtonSceneReadKeyMenu, iButtonSceneSavedKeyMenu, iButtonSceneAddType}; - scene_manager_search_and_switch_to_previous_scene_one_of( - ibutton->scene_manager, possible_scenes, COUNT_OF(possible_scenes)); + scene_manager_search_and_switch_to_another_scene( + ibutton->scene_manager, iButtonSceneSelectKey); } } diff --git a/applications/main/ibutton/scenes/ibutton_scene_start.c b/applications/main/ibutton/scenes/ibutton_scene_start.c index c2844cde9..dde224e15 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_start.c +++ b/applications/main/ibutton/scenes/ibutton_scene_start.c @@ -39,7 +39,7 @@ bool ibutton_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.event == SubmenuIndexRead) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneRead); } else if(event.event == SubmenuIndexSaved) { - string_set_str(ibutton->file_path, IBUTTON_APP_FOLDER); + furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER); scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSelectKey); } else if(event.event == SubmenuIndexAdd) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneAddType); diff --git a/applications/main/ibutton/scenes/ibutton_scene_write.c b/applications/main/ibutton/scenes/ibutton_scene_write.c index 195758d2c..cdea04db3 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_write.c +++ b/applications/main/ibutton/scenes/ibutton_scene_write.c @@ -1,5 +1,4 @@ #include "../ibutton_i.h" -#include "m-string.h" #include "toolbox/path.h" typedef enum { @@ -14,31 +13,28 @@ static void ibutton_scene_write_callback(void* context, iButtonWorkerWriteResult void ibutton_scene_write_on_enter(void* context) { iButton* ibutton = context; - Popup* popup = ibutton->popup; iButtonKey* key = ibutton->key; + Widget* widget = ibutton->widget; iButtonWorker* worker = ibutton->key_worker; const uint8_t* key_data = ibutton_key_get_data_p(key); - string_t key_name; - string_init(key_name); - if(string_end_with_str_p(ibutton->file_path, IBUTTON_APP_EXTENSION)) { + FuriString* key_name; + key_name = furi_string_alloc(); + if(furi_string_end_with(ibutton->file_path, IBUTTON_APP_EXTENSION)) { path_extract_filename(ibutton->file_path, key_name, true); } - uint8_t line_count = 2; - // check that stored key has name - if(!string_empty_p(key_name)) { - ibutton_text_store_set(ibutton, "writing\n%s", string_get_cstr(key_name)); - line_count = 2; + if(!furi_string_empty(key_name)) { + ibutton_text_store_set(ibutton, "%s", furi_string_get_cstr(key_name)); } else { // if not, show key data switch(ibutton_key_get_type(key)) { case iButtonKeyDS1990: ibutton_text_store_set( ibutton, - "writing\n%02X %02X %02X %02X\n%02X %02X %02X %02X", + "%02X %02X %02X %02X\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], @@ -47,45 +43,29 @@ void ibutton_scene_write_on_enter(void* context) { key_data[5], key_data[6], key_data[7]); - line_count = 3; break; case iButtonKeyCyfral: - ibutton_text_store_set(ibutton, "writing\n%02X %02X", key_data[0], key_data[1]); - line_count = 2; + ibutton_text_store_set(ibutton, "%02X %02X", key_data[0], key_data[1]); break; case iButtonKeyMetakom: ibutton_text_store_set( - ibutton, - "writing\n%02X %02X %02X %02X", - key_data[0], - key_data[1], - key_data[2], - key_data[3]); - line_count = 2; + ibutton, "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); break; } } - switch(line_count) { - case 3: - popup_set_header(popup, "iButton", 82, 18, AlignCenter, AlignBottom); - popup_set_text(popup, ibutton->text_store, 82, 22, AlignCenter, AlignTop); - break; + widget_add_string_multiline_element( + widget, 90, 10, AlignCenter, AlignTop, FontPrimary, "iButton\nwriting"); + widget_add_icon_element(widget, 3, 10, &I_iButtonKey_49x44); + widget_add_text_box_element( + widget, 54, 39, 75, 22, AlignCenter, AlignCenter, ibutton->text_store, true); - default: - popup_set_header(popup, "iButton", 82, 24, AlignCenter, AlignBottom); - popup_set_text(popup, ibutton->text_store, 82, 28, AlignCenter, AlignTop); - break; - } - - popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); - - view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewWidget); ibutton_worker_write_set_callback(worker, ibutton_scene_write_callback, ibutton); ibutton_worker_write_start(worker, key); - string_clear(key_name); + furi_string_free(key_name); ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); } @@ -114,11 +94,8 @@ bool ibutton_scene_write_on_event(void* context, SceneManagerEvent event) { void ibutton_scene_write_on_exit(void* context) { iButton* ibutton = context; - Popup* popup = ibutton->popup; ibutton_worker_stop(ibutton->key_worker); - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); + widget_reset(ibutton->widget); ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop); } diff --git a/applications/main/infrared/infrared.c b/applications/main/infrared/infrared.c index 60809e787..f62db14c1 100644 --- a/applications/main/infrared/infrared.c +++ b/applications/main/infrared/infrared.c @@ -65,51 +65,52 @@ static void infrared_rpc_command_callback(RpcAppSystemEvent event, void* context } } -static void infrared_find_vacant_remote_name(string_t name, const char* path) { +static void infrared_find_vacant_remote_name(FuriString* name, const char* path) { Storage* storage = furi_record_open(RECORD_STORAGE); - string_t base_path; - string_init_set_str(base_path, path); + FuriString* base_path; + base_path = furi_string_alloc_set(path); - if(string_end_with_str_p(base_path, INFRARED_APP_EXTENSION)) { - size_t filename_start = string_search_rchar(base_path, '/'); - string_left(base_path, filename_start); + if(furi_string_end_with(base_path, INFRARED_APP_EXTENSION)) { + size_t filename_start = furi_string_search_rchar(base_path, '/'); + furi_string_left(base_path, filename_start); } - string_printf(base_path, "%s/%s%s", path, string_get_cstr(name), INFRARED_APP_EXTENSION); + furi_string_printf( + base_path, "%s/%s%s", path, furi_string_get_cstr(name), INFRARED_APP_EXTENSION); - FS_Error status = storage_common_stat(storage, string_get_cstr(base_path), NULL); + FS_Error status = storage_common_stat(storage, furi_string_get_cstr(base_path), NULL); if(status == FSE_OK) { /* If the suggested name is occupied, try another one (name2, name3, etc) */ - size_t dot = string_search_rchar(base_path, '.'); - string_left(base_path, dot); + size_t dot = furi_string_search_rchar(base_path, '.'); + furi_string_left(base_path, dot); - string_t path_temp; - string_init(path_temp); + FuriString* path_temp; + path_temp = furi_string_alloc(); uint32_t i = 1; do { - string_printf( - path_temp, "%s%u%s", string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION); - status = storage_common_stat(storage, string_get_cstr(path_temp), NULL); + furi_string_printf( + path_temp, "%s%lu%s", furi_string_get_cstr(base_path), ++i, INFRARED_APP_EXTENSION); + status = storage_common_stat(storage, furi_string_get_cstr(path_temp), NULL); } while(status == FSE_OK); - string_clear(path_temp); + furi_string_free(path_temp); if(status == FSE_NOT_EXIST) { - string_cat_printf(name, "%u", i); + furi_string_cat_printf(name, "%lu", i); } } - string_clear(base_path); + furi_string_free(base_path); furi_record_close(RECORD_STORAGE); } static Infrared* infrared_alloc() { Infrared* infrared = malloc(sizeof(Infrared)); - string_init(infrared->file_path); + infrared->file_path = furi_string_alloc(); InfraredAppState* app_state = &infrared->app_state; app_state->is_learning_new_remote = false; @@ -232,7 +233,7 @@ static void infrared_free(Infrared* infrared) { furi_record_close(RECORD_GUI); infrared->gui = NULL; - string_clear(infrared->file_path); + furi_string_free(infrared->file_path); free(infrared); } @@ -243,19 +244,20 @@ bool infrared_add_remote_with_button( InfraredSignal* signal) { InfraredRemote* remote = infrared->remote; - string_t new_name, new_path; - string_init_set_str(new_name, INFRARED_DEFAULT_REMOTE_NAME); - string_init_set_str(new_path, INFRARED_APP_FOLDER); + FuriString *new_name, *new_path; + new_name = furi_string_alloc_set(INFRARED_DEFAULT_REMOTE_NAME); + new_path = furi_string_alloc_set(INFRARED_APP_FOLDER); - infrared_find_vacant_remote_name(new_name, string_get_cstr(new_path)); - string_cat_printf(new_path, "/%s%s", string_get_cstr(new_name), INFRARED_APP_EXTENSION); + infrared_find_vacant_remote_name(new_name, furi_string_get_cstr(new_path)); + furi_string_cat_printf( + new_path, "/%s%s", furi_string_get_cstr(new_name), INFRARED_APP_EXTENSION); infrared_remote_reset(remote); - infrared_remote_set_name(remote, string_get_cstr(new_name)); - infrared_remote_set_path(remote, string_get_cstr(new_path)); + infrared_remote_set_name(remote, furi_string_get_cstr(new_name)); + infrared_remote_set_path(remote, furi_string_get_cstr(new_path)); - string_clear(new_name); - string_clear(new_path); + furi_string_free(new_name); + furi_string_free(new_path); return infrared_remote_add_button(remote, button_name, signal); } @@ -267,28 +269,29 @@ bool infrared_rename_current_remote(Infrared* infrared, const char* name) { return true; } - string_t new_name; - string_init_set_str(new_name, name); + FuriString* new_name; + new_name = furi_string_alloc_set(name); infrared_find_vacant_remote_name(new_name, remote_path); - string_t new_path; - string_init_set(new_path, infrared_remote_get_path(remote)); - if(string_end_with_str_p(new_path, INFRARED_APP_EXTENSION)) { - size_t filename_start = string_search_rchar(new_path, '/'); - string_left(new_path, filename_start); + FuriString* new_path; + new_path = furi_string_alloc_set(infrared_remote_get_path(remote)); + if(furi_string_end_with(new_path, INFRARED_APP_EXTENSION)) { + size_t filename_start = furi_string_search_rchar(new_path, '/'); + furi_string_left(new_path, filename_start); } - string_cat_printf(new_path, "/%s%s", string_get_cstr(new_name), INFRARED_APP_EXTENSION); + furi_string_cat_printf( + new_path, "/%s%s", furi_string_get_cstr(new_name), INFRARED_APP_EXTENSION); Storage* storage = furi_record_open(RECORD_STORAGE); FS_Error status = storage_common_rename( - storage, infrared_remote_get_path(remote), string_get_cstr(new_path)); - infrared_remote_set_name(remote, string_get_cstr(new_name)); - infrared_remote_set_path(remote, string_get_cstr(new_path)); + storage, infrared_remote_get_path(remote), furi_string_get_cstr(new_path)); + infrared_remote_set_name(remote, furi_string_get_cstr(new_name)); + infrared_remote_set_path(remote, furi_string_get_cstr(new_path)); - string_clear(new_name); - string_clear(new_path); + furi_string_free(new_name); + furi_string_free(new_path); furi_record_close(RECORD_STORAGE); return (status == FSE_OK || status == FSE_EXIST); @@ -435,7 +438,7 @@ int32_t infrared_app(void* p) { rpc_system_app_send_started(infrared->rpc_ctx); is_rpc_mode = true; } else { - string_set_str(infrared->file_path, (const char*)p); + furi_string_set(infrared->file_path, (const char*)p); is_remote_loaded = infrared_remote_load(infrared->remote, infrared->file_path); if(!is_remote_loaded) { dialog_message_show_storage_error( diff --git a/applications/main/infrared/infrared_brute_force.c b/applications/main/infrared/infrared_brute_force.c index 0edc5f742..3f426f1dc 100644 --- a/applications/main/infrared/infrared_brute_force.c +++ b/applications/main/infrared/infrared_brute_force.c @@ -2,7 +2,6 @@ #include #include -#include #include #include "infrared_signal.h" @@ -14,15 +13,15 @@ typedef struct { DICT_DEF2( InfraredBruteForceRecordDict, - string_t, - STRING_OPLIST, + FuriString*, + FURI_STRING_OPLIST, InfraredBruteForceRecord, M_POD_OPLIST); struct InfraredBruteForce { FlipperFormat* ff; const char* db_filename; - string_t current_record_name; + FuriString* current_record_name; InfraredSignal* current_signal; InfraredBruteForceRecordDict_t records; bool is_started; @@ -34,7 +33,7 @@ InfraredBruteForce* infrared_brute_force_alloc() { brute_force->db_filename = NULL; brute_force->current_signal = NULL; brute_force->is_started = false; - string_init(brute_force->current_record_name); + brute_force->current_record_name = furi_string_alloc(); InfraredBruteForceRecordDict_init(brute_force->records); return brute_force; } @@ -42,7 +41,7 @@ InfraredBruteForce* infrared_brute_force_alloc() { void infrared_brute_force_free(InfraredBruteForce* brute_force) { furi_assert(!brute_force->is_started); InfraredBruteForceRecordDict_clear(brute_force->records); - string_clear(brute_force->current_record_name); + furi_string_free(brute_force->current_record_name); free(brute_force); } @@ -61,8 +60,8 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { success = flipper_format_buffered_file_open_existing(ff, brute_force->db_filename); if(success) { - string_t signal_name; - string_init(signal_name); + FuriString* signal_name; + signal_name = furi_string_alloc(); while(flipper_format_read_string(ff, "name", signal_name)) { InfraredBruteForceRecord* record = InfraredBruteForceRecordDict_get(brute_force->records, signal_name); @@ -70,7 +69,7 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) { ++(record->count); } } - string_clear(signal_name); + furi_string_free(signal_name); } flipper_format_free(ff); @@ -94,7 +93,7 @@ bool infrared_brute_force_start( if(record->value.index == index) { *record_count = record->value.count; if(*record_count) { - string_set(brute_force->current_record_name, record->key); + furi_string_set(brute_force->current_record_name, record->key); } break; } @@ -118,7 +117,7 @@ bool infrared_brute_force_is_started(InfraredBruteForce* brute_force) { void infrared_brute_force_stop(InfraredBruteForce* brute_force) { furi_assert(brute_force->is_started); - string_reset(brute_force->current_record_name); + furi_string_reset(brute_force->current_record_name); infrared_signal_free(brute_force->current_signal); flipper_format_free(brute_force->ff); brute_force->current_signal = NULL; @@ -142,10 +141,10 @@ void infrared_brute_force_add_record( uint32_t index, const char* name) { InfraredBruteForceRecord value = {.index = index, .count = 0}; - string_t key; - string_init_set_str(key, name); + FuriString* key; + key = furi_string_alloc_set(name); InfraredBruteForceRecordDict_set_at(brute_force->records, key, value); - string_clear(key); + furi_string_free(key); } void infrared_brute_force_reset(InfraredBruteForce* brute_force) { diff --git a/applications/main/infrared/infrared_cli.c b/applications/main/infrared/infrared_cli.c index 693e191ee..5ec57c757 100644 --- a/applications/main/infrared/infrared_cli.c +++ b/applications/main/infrared/infrared_cli.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -10,13 +9,13 @@ #define INFRARED_CLI_BUF_SIZE 10 -static void infrared_cli_start_ir_rx(Cli* cli, string_t args); -static void infrared_cli_start_ir_tx(Cli* cli, string_t args); -static void infrared_cli_process_decode(Cli* cli, string_t args); +static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args); +static void infrared_cli_start_ir_tx(Cli* cli, FuriString* args); +static void infrared_cli_process_decode(Cli* cli, FuriString* args); static const struct { const char* cmd; - void (*process_function)(Cli* cli, string_t args); + void (*process_function)(Cli* cli, FuriString* args); } infrared_cli_commands[] = { {.cmd = "rx", .process_function = infrared_cli_start_ir_rx}, {.cmd = "tx", .process_function = infrared_cli_start_ir_tx}, @@ -58,7 +57,7 @@ static void signal_received_callback(void* context, InfraredWorkerSignal* receiv } } -static void infrared_cli_start_ir_rx(Cli* cli, string_t args) { +static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); InfraredWorker* worker = infrared_worker_alloc(); @@ -151,9 +150,9 @@ static bool infrared_cli_parse_raw(const char* str, InfraredSignal* signal) { return infrared_signal_is_valid(signal); } -static void infrared_cli_start_ir_tx(Cli* cli, string_t args) { +static void infrared_cli_start_ir_tx(Cli* cli, FuriString* args) { UNUSED(cli); - const char* str = string_get_cstr(args); + const char* str = furi_string_get_cstr(args); InfraredSignal* signal = infrared_signal_alloc(); bool success = infrared_cli_parse_message(str, signal) || infrared_cli_parse_raw(str, signal); @@ -231,8 +230,8 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o InfraredSignal* signal = infrared_signal_alloc(); InfraredDecoderHandler* decoder = infrared_alloc_decoder(); - string_t tmp; - string_init(tmp); + FuriString* tmp; + tmp = furi_string_alloc(); while(infrared_signal_read(signal, input_file, tmp)) { ret = false; @@ -242,7 +241,7 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o } if(!infrared_signal_is_raw(signal)) { if(output_file && - !infrared_cli_save_signal(signal, output_file, string_get_cstr(tmp))) { + !infrared_cli_save_signal(signal, output_file, furi_string_get_cstr(tmp))) { break; } else { printf("Skipping decoded signal\r\n"); @@ -250,31 +249,33 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o } } InfraredRawSignal* raw_signal = infrared_signal_get_raw_signal(signal); - printf("Raw signal: %s, %u samples\r\n", string_get_cstr(tmp), raw_signal->timings_size); - if(!infrared_cli_decode_raw_signal(raw_signal, decoder, output_file, string_get_cstr(tmp))) + printf( + "Raw signal: %s, %u samples\r\n", furi_string_get_cstr(tmp), raw_signal->timings_size); + if(!infrared_cli_decode_raw_signal( + raw_signal, decoder, output_file, furi_string_get_cstr(tmp))) break; ret = true; } infrared_free_decoder(decoder); infrared_signal_free(signal); - string_clear(tmp); + furi_string_free(tmp); return ret; } -static void infrared_cli_process_decode(Cli* cli, string_t args) { +static void infrared_cli_process_decode(Cli* cli, FuriString* args) { UNUSED(cli); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* input_file = flipper_format_buffered_file_alloc(storage); FlipperFormat* output_file = NULL; uint32_t version; - string_t tmp, header, input_path, output_path; - string_init(tmp); - string_init(header); - string_init(input_path); - string_init(output_path); + FuriString *tmp, *header, *input_path, *output_path; + tmp = furi_string_alloc(); + header = furi_string_alloc(); + input_path = furi_string_alloc(); + output_path = furi_string_alloc(); do { if(!args_read_probably_quoted_string_and_trim(args, input_path)) { @@ -283,26 +284,32 @@ static void infrared_cli_process_decode(Cli* cli, string_t args) { break; } args_read_probably_quoted_string_and_trim(args, output_path); - if(!flipper_format_buffered_file_open_existing(input_file, string_get_cstr(input_path))) { - printf("Failed to open file for reading: \"%s\"\r\n", string_get_cstr(input_path)); + if(!flipper_format_buffered_file_open_existing( + input_file, furi_string_get_cstr(input_path))) { + printf( + "Failed to open file for reading: \"%s\"\r\n", furi_string_get_cstr(input_path)); break; } if(!flipper_format_read_header(input_file, header, &version) || - (!string_start_with_str_p(header, "IR")) || version != 1) { - printf("Invalid or corrupted input file: \"%s\"\r\n", string_get_cstr(input_path)); + (!furi_string_start_with_str(header, "IR")) || version != 1) { + printf( + "Invalid or corrupted input file: \"%s\"\r\n", furi_string_get_cstr(input_path)); break; } - if(!string_empty_p(output_path)) { - printf("Writing output to file: \"%s\"\r\n", string_get_cstr(output_path)); + if(!furi_string_empty(output_path)) { + printf("Writing output to file: \"%s\"\r\n", furi_string_get_cstr(output_path)); output_file = flipper_format_file_alloc(storage); } if(output_file && - !flipper_format_file_open_always(output_file, string_get_cstr(output_path))) { - printf("Failed to open file for writing: \"%s\"\r\n", string_get_cstr(output_path)); + !flipper_format_file_open_always(output_file, furi_string_get_cstr(output_path))) { + printf( + "Failed to open file for writing: \"%s\"\r\n", furi_string_get_cstr(output_path)); break; } if(output_file && !flipper_format_write_header(output_file, header, version)) { - printf("Failed to write to the output file: \"%s\"\r\n", string_get_cstr(output_path)); + printf( + "Failed to write to the output file: \"%s\"\r\n", + furi_string_get_cstr(output_path)); break; } if(!infrared_cli_decode_file(input_file, output_file)) { @@ -311,31 +318,31 @@ static void infrared_cli_process_decode(Cli* cli, string_t args) { printf("File successfully decoded.\r\n"); } while(false); - string_clear(tmp); - string_clear(header); - string_clear(input_path); - string_clear(output_path); + furi_string_free(tmp); + furi_string_free(header); + furi_string_free(input_path); + furi_string_free(output_path); flipper_format_free(input_file); if(output_file) flipper_format_free(output_file); furi_record_close(RECORD_STORAGE); } -static void infrared_cli_start_ir(Cli* cli, string_t args, void* context) { +static void infrared_cli_start_ir(Cli* cli, FuriString* args, void* context) { UNUSED(context); if(furi_hal_infrared_is_busy()) { printf("INFRARED is busy. Exiting."); return; } - string_t command; - string_init(command); + FuriString* command; + command = furi_string_alloc(); args_read_string_and_trim(args, command); size_t i = 0; for(; i < COUNT_OF(infrared_cli_commands); ++i) { size_t cmd_len = strlen(infrared_cli_commands[i].cmd); - if(!strncmp(string_get_cstr(command), infrared_cli_commands[i].cmd, cmd_len)) { + if(!strncmp(furi_string_get_cstr(command), infrared_cli_commands[i].cmd, cmd_len)) { break; } } @@ -346,7 +353,7 @@ static void infrared_cli_start_ir(Cli* cli, string_t args, void* context) { infrared_cli_print_usage(); } - string_clear(command); + furi_string_free(command); } void infrared_on_system_start() { #ifdef SRV_CLI diff --git a/applications/main/infrared/infrared_i.h b/applications/main/infrared/infrared_i.h index 952152587..6d25d1609 100644 --- a/applications/main/infrared/infrared_i.h +++ b/applications/main/infrared/infrared_i.h @@ -96,7 +96,7 @@ struct Infrared { Loading* loading; InfraredProgressView* progress; - string_t file_path; + FuriString* file_path; char text_store[INFRARED_TEXT_STORE_NUM][INFRARED_TEXT_STORE_SIZE + 1]; InfraredAppState app_state; diff --git a/applications/main/infrared/infrared_remote.c b/applications/main/infrared/infrared_remote.c index 4417c3c73..3a528a656 100644 --- a/applications/main/infrared/infrared_remote.c +++ b/applications/main/infrared/infrared_remote.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -15,8 +14,8 @@ ARRAY_DEF(InfraredButtonArray, InfraredRemoteButton*, M_PTR_OPLIST); struct InfraredRemote { InfraredButtonArray_t buttons; - string_t name; - string_t path; + FuriString* name; + FuriString* path; }; static void infrared_remote_clear_buttons(InfraredRemote* remote) { @@ -31,39 +30,39 @@ static void infrared_remote_clear_buttons(InfraredRemote* remote) { InfraredRemote* infrared_remote_alloc() { InfraredRemote* remote = malloc(sizeof(InfraredRemote)); InfraredButtonArray_init(remote->buttons); - string_init(remote->name); - string_init(remote->path); + remote->name = furi_string_alloc(); + remote->path = furi_string_alloc(); return remote; } void infrared_remote_free(InfraredRemote* remote) { infrared_remote_clear_buttons(remote); InfraredButtonArray_clear(remote->buttons); - string_clear(remote->path); - string_clear(remote->name); + furi_string_free(remote->path); + furi_string_free(remote->name); free(remote); } void infrared_remote_reset(InfraredRemote* remote) { infrared_remote_clear_buttons(remote); - string_reset(remote->name); - string_reset(remote->path); + furi_string_reset(remote->name); + furi_string_reset(remote->path); } void infrared_remote_set_name(InfraredRemote* remote, const char* name) { - string_set_str(remote->name, name); + furi_string_set(remote->name, name); } const char* infrared_remote_get_name(InfraredRemote* remote) { - return string_get_cstr(remote->name); + return furi_string_get_cstr(remote->name); } void infrared_remote_set_path(InfraredRemote* remote, const char* path) { - string_set_str(remote->path, path); + furi_string_set(remote->path, path); } const char* infrared_remote_get_path(InfraredRemote* remote) { - return string_get_cstr(remote->path); + return furi_string_get_cstr(remote->path); } size_t infrared_remote_get_button_count(InfraredRemote* remote) { @@ -112,7 +111,7 @@ bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) { bool infrared_remote_store(InfraredRemote* remote) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_file_alloc(storage); - const char* path = string_get_cstr(remote->path); + const char* path = furi_string_get_cstr(remote->path); FURI_LOG_I(TAG, "store file: \'%s\'", path); @@ -138,33 +137,33 @@ bool infrared_remote_store(InfraredRemote* remote) { return success; } -bool infrared_remote_load(InfraredRemote* remote, string_t path) { +bool infrared_remote_load(InfraredRemote* remote, FuriString* path) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_buffered_file_alloc(storage); - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); - FURI_LOG_I(TAG, "load file: \'%s\'", string_get_cstr(path)); - bool success = flipper_format_buffered_file_open_existing(ff, string_get_cstr(path)); + FURI_LOG_I(TAG, "load file: \'%s\'", furi_string_get_cstr(path)); + bool success = flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(path)); if(success) { uint32_t version; success = flipper_format_read_header(ff, buf, &version) && - !string_cmp_str(buf, "IR signals file") && (version == 1); + !furi_string_cmp(buf, "IR signals file") && (version == 1); } if(success) { path_extract_filename(path, buf, true); infrared_remote_clear_buttons(remote); - infrared_remote_set_name(remote, string_get_cstr(buf)); - infrared_remote_set_path(remote, string_get_cstr(path)); + infrared_remote_set_name(remote, furi_string_get_cstr(buf)); + infrared_remote_set_path(remote, furi_string_get_cstr(path)); for(bool can_read = true; can_read;) { InfraredRemoteButton* button = infrared_remote_button_alloc(); can_read = infrared_signal_read(infrared_remote_button_get_signal(button), ff, buf); if(can_read) { - infrared_remote_button_set_name(button, string_get_cstr(buf)); + infrared_remote_button_set_name(button, furi_string_get_cstr(buf)); InfraredButtonArray_push_back(remote->buttons, button); } else { infrared_remote_button_free(button); @@ -172,7 +171,7 @@ bool infrared_remote_load(InfraredRemote* remote, string_t path) { } } - string_clear(buf); + furi_string_free(buf); flipper_format_free(ff); furi_record_close(RECORD_STORAGE); return success; @@ -181,7 +180,7 @@ bool infrared_remote_load(InfraredRemote* remote, string_t path) { bool infrared_remote_remove(InfraredRemote* remote) { Storage* storage = furi_record_open(RECORD_STORAGE); - FS_Error status = storage_common_remove(storage, string_get_cstr(remote->path)); + FS_Error status = storage_common_remove(storage, furi_string_get_cstr(remote->path)); infrared_remote_reset(remote); furi_record_close(RECORD_STORAGE); diff --git a/applications/main/infrared/infrared_remote.h b/applications/main/infrared/infrared_remote.h index b6f63a198..6eac193d3 100644 --- a/applications/main/infrared/infrared_remote.h +++ b/applications/main/infrared/infrared_remote.h @@ -25,5 +25,5 @@ bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, bool infrared_remote_delete_button(InfraredRemote* remote, size_t index); bool infrared_remote_store(InfraredRemote* remote); -bool infrared_remote_load(InfraredRemote* remote, string_t path); +bool infrared_remote_load(InfraredRemote* remote, FuriString* path); bool infrared_remote_remove(InfraredRemote* remote); diff --git a/applications/main/infrared/infrared_remote_button.c b/applications/main/infrared/infrared_remote_button.c index 7525ce48f..1f6315ec5 100644 --- a/applications/main/infrared/infrared_remote_button.c +++ b/applications/main/infrared/infrared_remote_button.c @@ -1,32 +1,31 @@ #include "infrared_remote_button.h" #include -#include struct InfraredRemoteButton { - string_t name; + FuriString* name; InfraredSignal* signal; }; InfraredRemoteButton* infrared_remote_button_alloc() { InfraredRemoteButton* button = malloc(sizeof(InfraredRemoteButton)); - string_init(button->name); + button->name = furi_string_alloc(); button->signal = infrared_signal_alloc(); return button; } void infrared_remote_button_free(InfraredRemoteButton* button) { - string_clear(button->name); + furi_string_free(button->name); infrared_signal_free(button->signal); free(button); } void infrared_remote_button_set_name(InfraredRemoteButton* button, const char* name) { - string_set_str(button->name, name); + furi_string_set(button->name, name); } const char* infrared_remote_button_get_name(InfraredRemoteButton* button) { - return string_get_cstr(button->name); + return furi_string_get_cstr(button->name); } void infrared_remote_button_set_signal(InfraredRemoteButton* button, InfraredSignal* signal) { diff --git a/applications/main/infrared/infrared_signal.c b/applications/main/infrared/infrared_signal.c index f2e359c8a..d399b9587 100644 --- a/applications/main/infrared/infrared_signal.c +++ b/applications/main/infrared/infrared_signal.c @@ -61,7 +61,7 @@ static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) { if((raw->frequency > INFRARED_MAX_FREQUENCY) || (raw->frequency < INFRARED_MIN_FREQUENCY)) { FURI_LOG_E( TAG, - "Frequency is out of range (%lX - %lX): %lX", + "Frequency is out of range (%X - %X): %lX", INFRARED_MIN_FREQUENCY, INFRARED_MAX_FREQUENCY, raw->frequency); @@ -74,7 +74,7 @@ static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) { } else if((raw->timings_size <= 0) || (raw->timings_size > MAX_TIMINGS_AMOUNT)) { FURI_LOG_E( TAG, - "Timings amount is out of range (0 - %lX): %lX", + "Timings amount is out of range (0 - %X): %X", MAX_TIMINGS_AMOUNT, raw->timings_size); return false; @@ -100,15 +100,15 @@ static inline bool infrared_signal_save_raw(InfraredRawSignal* raw, FlipperForma } static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperFormat* ff) { - string_t buf; - string_init(buf); + FuriString* buf; + buf = furi_string_alloc(); bool success = false; do { if(!flipper_format_read_string(ff, "protocol", buf)) break; InfraredMessage message; - message.protocol = infrared_get_protocol_by_name(string_get_cstr(buf)); + message.protocol = infrared_get_protocol_by_name(furi_string_get_cstr(buf)); success = flipper_format_read_hex(ff, "address", (uint8_t*)&message.address, 4) && flipper_format_read_hex(ff, "command", (uint8_t*)&message.command, 4) && @@ -119,7 +119,7 @@ static inline bool infrared_signal_read_message(InfraredSignal* signal, FlipperF infrared_signal_set_message(signal, &message); } while(0); - string_clear(buf); + furi_string_free(buf); return success; } @@ -147,22 +147,22 @@ static inline bool infrared_signal_read_raw(InfraredSignal* signal, FlipperForma } static bool infrared_signal_read_body(InfraredSignal* signal, FlipperFormat* ff) { - string_t tmp; - string_init(tmp); + FuriString* tmp = furi_string_alloc(); + bool success = false; do { if(!flipper_format_read_string(ff, "type", tmp)) break; - if(string_equal_p(tmp, "raw")) { + if(furi_string_equal(tmp, "raw")) { success = infrared_signal_read_raw(signal, ff); - } else if(string_equal_p(tmp, "parsed")) { + } else if(furi_string_equal(tmp, "parsed")) { success = infrared_signal_read_message(signal, ff); } else { FURI_LOG_E(TAG, "Unknown signal type"); } } while(false); - string_clear(tmp); + furi_string_free(tmp); return success; } @@ -246,34 +246,33 @@ bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* } } -bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, string_t name) { - string_t tmp; - string_init(tmp); +bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name) { + FuriString* tmp = furi_string_alloc(); + bool success = false; do { if(!flipper_format_read_string(ff, "name", tmp)) break; - string_set(name, tmp); + furi_string_set(name, tmp); if(!infrared_signal_read_body(signal, ff)) break; success = true; } while(0); - string_clear(tmp); + furi_string_free(tmp); return success; } bool infrared_signal_search_and_read( InfraredSignal* signal, FlipperFormat* ff, - const string_t name) { + const FuriString* name) { bool success = false; - string_t tmp; - string_init(tmp); + FuriString* tmp = furi_string_alloc(); do { bool is_name_found = false; while(flipper_format_read_string(ff, "name", tmp)) { - is_name_found = string_equal_p(name, tmp); + is_name_found = furi_string_equal(name, tmp); if(is_name_found) break; } if(!is_name_found) break; @@ -281,7 +280,7 @@ bool infrared_signal_search_and_read( success = true; } while(false); - string_clear(tmp); + furi_string_free(tmp); return success; } diff --git a/applications/main/infrared/infrared_signal.h b/applications/main/infrared/infrared_signal.h index ad2f5d57a..29c661938 100644 --- a/applications/main/infrared/infrared_signal.h +++ b/applications/main/infrared/infrared_signal.h @@ -36,10 +36,10 @@ void infrared_signal_set_message(InfraredSignal* signal, const InfraredMessage* InfraredMessage* infrared_signal_get_message(InfraredSignal* signal); bool infrared_signal_save(InfraredSignal* signal, FlipperFormat* ff, const char* name); -bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, string_t name); +bool infrared_signal_read(InfraredSignal* signal, FlipperFormat* ff, FuriString* name); bool infrared_signal_search_and_read( InfraredSignal* signal, FlipperFormat* ff, - const string_t name); + const FuriString* name); void infrared_signal_transmit(InfraredSignal* signal); diff --git a/applications/main/infrared/scenes/infrared_scene_edit_rename.c b/applications/main/infrared/scenes/infrared_scene_edit_rename.c index ebe7c2a96..a2199215d 100644 --- a/applications/main/infrared/scenes/infrared_scene_edit_rename.c +++ b/applications/main/infrared/scenes/infrared_scene_edit_rename.c @@ -29,20 +29,20 @@ void infrared_scene_edit_rename_on_enter(void* context) { enter_name_length = INFRARED_MAX_REMOTE_NAME_LENGTH; strncpy(infrared->text_store[0], infrared_remote_get_name(remote), enter_name_length); - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - if(string_end_with_str_p(infrared->file_path, INFRARED_APP_EXTENSION)) { - path_extract_dirname(string_get_cstr(infrared->file_path), folder_path); + if(furi_string_end_with(infrared->file_path, INFRARED_APP_EXTENSION)) { + path_extract_dirname(furi_string_get_cstr(infrared->file_path), folder_path); } ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), + furi_string_get_cstr(folder_path), INFRARED_APP_EXTENSION, infrared_remote_get_name(remote)); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - string_clear(folder_path); + furi_string_free(folder_path); } else { furi_assert(0); } diff --git a/applications/main/infrared/scenes/infrared_scene_learn_enter_name.c b/applications/main/infrared/scenes/infrared_scene_learn_enter_name.c index b7f4179ea..b6a7eac0d 100644 --- a/applications/main/infrared/scenes/infrared_scene_learn_enter_name.c +++ b/applications/main/infrared/scenes/infrared_scene_learn_enter_name.c @@ -50,8 +50,10 @@ bool infrared_scene_learn_enter_name_on_event(void* context, SceneManagerEvent e if(success) { scene_manager_next_scene(scene_manager, InfraredSceneLearnDone); } else { - scene_manager_search_and_switch_to_previous_scene( - scene_manager, InfraredSceneRemoteList); + dialog_message_show_storage_error(infrared->dialogs, "Failed to save file"); + const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart}; + scene_manager_search_and_switch_to_previous_scene_one_of( + scene_manager, possible_scenes, COUNT_OF(possible_scenes)); } consumed = true; } diff --git a/applications/main/infrared/scenes/infrared_scene_rpc.c b/applications/main/infrared/scenes/infrared_scene_rpc.c index ca7bbd8df..8044e8318 100644 --- a/applications/main/infrared/scenes/infrared_scene_rpc.c +++ b/applications/main/infrared/scenes/infrared_scene_rpc.c @@ -42,7 +42,7 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool result = false; const char* arg = rpc_system_app_get_data(infrared->rpc_ctx); if(arg && (state == InfraredRpcStateIdle)) { - string_set_str(infrared->file_path, arg); + furi_string_set(infrared->file_path, arg); result = infrared_remote_load(infrared->remote, infrared->file_path); if(result) { scene_manager_set_scene_state( diff --git a/applications/main/infrared/scenes/infrared_scene_start.c b/applications/main/infrared/scenes/infrared_scene_start.c index d188a6c36..c7df0f45b 100644 --- a/applications/main/infrared/scenes/infrared_scene_start.c +++ b/applications/main/infrared/scenes/infrared_scene_start.c @@ -66,7 +66,7 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(scene_manager, InfraredSceneLearn); consumed = true; } else if(submenu_index == SubmenuIndexSavedRemotes) { - string_set_str(infrared->file_path, INFRARED_APP_FOLDER); + furi_string_set(infrared->file_path, INFRARED_APP_FOLDER); scene_manager_next_scene(scene_manager, InfraredSceneRemoteList); consumed = true; } else if(submenu_index == SubmenuIndexDebug) { diff --git a/applications/main/infrared/views/infrared_progress_view.c b/applications/main/infrared/views/infrared_progress_view.c index 5c84ce0d9..3c50f89e4 100644 --- a/applications/main/infrared/views/infrared_progress_view.c +++ b/applications/main/infrared/views/infrared_progress_view.c @@ -4,7 +4,6 @@ #include "gui/canvas.h" #include "gui/view.h" #include "input/input.h" -#include "m-string.h" #include #include #include "infrared_progress_view.h" diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index dbed9f3af..b0f989374 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -36,9 +36,9 @@ static LfRfid* lfrfid_alloc() { lfrfid->storage = furi_record_open(RECORD_STORAGE); lfrfid->dialogs = furi_record_open(RECORD_DIALOGS); - string_init(lfrfid->file_name); - string_init(lfrfid->raw_file_name); - string_init_set_str(lfrfid->file_path, LFRFID_APP_FOLDER); + lfrfid->file_name = furi_string_alloc(); + lfrfid->raw_file_name = furi_string_alloc(); + lfrfid->file_path = furi_string_alloc_set(LFRFID_APP_FOLDER); lfrfid->dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); @@ -104,9 +104,9 @@ static LfRfid* lfrfid_alloc() { static void lfrfid_free(LfRfid* lfrfid) { furi_assert(lfrfid); - string_clear(lfrfid->raw_file_name); - string_clear(lfrfid->file_name); - string_clear(lfrfid->file_path); + furi_string_free(lfrfid->raw_file_name); + furi_string_free(lfrfid->file_name); + furi_string_free(lfrfid->file_path); protocol_dict_free(lfrfid->dict); lfrfid_worker_free(lfrfid->lfworker); @@ -183,7 +183,7 @@ int32_t lfrfid_app(void* p) { app->view_dispatcher, app->gui, ViewDispatcherTypeDesktop); scene_manager_next_scene(app->scene_manager, LfRfidSceneRpc); } else { - string_set_str(app->file_path, args); + furi_string_set(app->file_path, args); lfrfid_load_key_data(app, app->file_path, true); view_dispatcher_attach_to_gui( app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); @@ -210,13 +210,13 @@ bool lfrfid_save_key(LfRfid* app) { lfrfid_make_app_folder(app); - if(string_end_with_str_p(app->file_path, LFRFID_APP_EXTENSION)) { - size_t filename_start = string_search_rchar(app->file_path, '/'); - string_left(app->file_path, filename_start); + if(furi_string_end_with(app->file_path, LFRFID_APP_EXTENSION)) { + size_t filename_start = furi_string_search_rchar(app->file_path, '/'); + furi_string_left(app->file_path, filename_start); } - string_cat_printf( - app->file_path, "/%s%s", string_get_cstr(app->file_name), LFRFID_APP_EXTENSION); + furi_string_cat_printf( + app->file_path, "/%s%s", furi_string_get_cstr(app->file_name), LFRFID_APP_EXTENSION); result = lfrfid_save_key_data(app, app->file_path); return result; @@ -242,14 +242,14 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) { bool lfrfid_delete_key(LfRfid* app) { furi_assert(app); - return storage_simply_remove(app->storage, string_get_cstr(app->file_path)); + return storage_simply_remove(app->storage, furi_string_get_cstr(app->file_path)); } -bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog) { +bool lfrfid_load_key_data(LfRfid* app, FuriString* path, bool show_dialog) { bool result = false; do { - app->protocol_id = lfrfid_dict_file_load(app->dict, string_get_cstr(path)); + app->protocol_id = lfrfid_dict_file_load(app->dict, furi_string_get_cstr(path)); if(app->protocol_id == PROTOCOL_NO) break; path_extract_filename(path, app->file_name, true); @@ -263,8 +263,8 @@ bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog) { return result; } -bool lfrfid_save_key_data(LfRfid* app, string_t path) { - bool result = lfrfid_dict_file_save(app->dict, app->protocol_id, string_get_cstr(path)); +bool lfrfid_save_key_data(LfRfid* app, FuriString* path) { + bool result = lfrfid_dict_file_save(app->dict, app->protocol_id, furi_string_get_cstr(path)); if(!result) { dialog_message_show_storage_error(app->dialogs, "Cannot save\nkey file"); diff --git a/applications/main/lfrfid/lfrfid_cli.c b/applications/main/lfrfid/lfrfid_cli.c index 281a0e963..640274529 100644 --- a/applications/main/lfrfid/lfrfid_cli.c +++ b/applications/main/lfrfid/lfrfid_cli.c @@ -14,7 +14,7 @@ #include #include -static void lfrfid_cli(Cli* cli, string_t args, void* context); +static void lfrfid_cli(Cli* cli, FuriString* args, void* context); // app cli function void lfrfid_on_system_start() { @@ -46,27 +46,28 @@ static void lfrfid_cli_read_callback(LFRFIDWorkerReadResult result, ProtocolId p furi_event_flag_set(context->event, 1 << result); } -static void lfrfid_cli_read(Cli* cli, string_t args) { - string_t type_string; - string_init(type_string); +static void lfrfid_cli_read(Cli* cli, FuriString* args) { + FuriString* type_string; + type_string = furi_string_alloc(); LFRFIDWorkerReadType type = LFRFIDWorkerReadTypeAuto; if(args_read_string_and_trim(args, type_string)) { - if(string_cmp_str(type_string, "normal") == 0 || string_cmp_str(type_string, "ask") == 0) { + if(furi_string_cmp_str(type_string, "normal") == 0 || + furi_string_cmp_str(type_string, "ask") == 0) { // ask type = LFRFIDWorkerReadTypeASKOnly; } else if( - string_cmp_str(type_string, "indala") == 0 || - string_cmp_str(type_string, "psk") == 0) { + furi_string_cmp_str(type_string, "indala") == 0 || + furi_string_cmp_str(type_string, "psk") == 0) { // psk type = LFRFIDWorkerReadTypePSKOnly; } else { lfrfid_cli_print_usage(); - string_clear(type_string); + furi_string_free(type_string); return; } } - string_clear(type_string); + furi_string_free(type_string); ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); LFRFIDWorker* worker = lfrfid_worker_alloc(dict); @@ -111,13 +112,13 @@ static void lfrfid_cli_read(Cli* cli, string_t args) { printf("\r\n"); free(data); - string_t info; - string_init(info); + FuriString* info; + info = furi_string_alloc(); protocol_dict_render_data(dict, info, context.protocol); - if(!string_empty_p(info)) { - printf("%s\r\n", string_get_cstr(info)); + if(!furi_string_empty(info)) { + printf("%s\r\n", furi_string_get_cstr(info)); } - string_clear(info); + furi_string_free(info); } printf("Reading stopped\r\n"); @@ -126,11 +127,11 @@ static void lfrfid_cli_read(Cli* cli, string_t args) { furi_event_flag_free(context.event); } -static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId* protocol) { +static bool lfrfid_cli_parse_args(FuriString* args, ProtocolDict* dict, ProtocolId* protocol) { bool result = false; - string_t protocol_name, data_text; - string_init(protocol_name); - string_init(data_text); + FuriString *protocol_name, *data_text; + protocol_name = furi_string_alloc(); + data_text = furi_string_alloc(); size_t data_size = protocol_dict_get_max_data_size(dict); uint8_t* data = malloc(data_size); @@ -143,12 +144,12 @@ static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId* } // check protocol arg - *protocol = protocol_dict_get_protocol_by_name(dict, string_get_cstr(protocol_name)); + *protocol = protocol_dict_get_protocol_by_name(dict, furi_string_get_cstr(protocol_name)); if(*protocol == PROTOCOL_NO) { printf( "Unknown protocol: %s\r\n" "Available protocols:\r\n", - string_get_cstr(protocol_name)); + furi_string_get_cstr(protocol_name)); for(ProtocolId i = 0; i < LFRFIDProtocolMax; i++) { printf( @@ -177,8 +178,8 @@ static bool lfrfid_cli_parse_args(string_t args, ProtocolDict* dict, ProtocolId* } while(false); free(data); - string_clear(protocol_name); - string_clear(data_text); + furi_string_free(protocol_name); + furi_string_free(data_text); return result; } @@ -188,7 +189,7 @@ static void lfrfid_cli_write_callback(LFRFIDWorkerWriteResult result, void* ctx) furi_event_flag_set(events, 1 << result); } -static void lfrfid_cli_write(Cli* cli, string_t args) { +static void lfrfid_cli_write(Cli* cli, FuriString* args) { ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); ProtocolId protocol; @@ -235,7 +236,7 @@ static void lfrfid_cli_write(Cli* cli, string_t args) { furi_event_flag_free(event); } -static void lfrfid_cli_emulate(Cli* cli, string_t args) { +static void lfrfid_cli_emulate(Cli* cli, FuriString* args) { ProtocolDict* dict = protocol_dict_alloc(lfrfid_protocols, LFRFIDProtocolMax); ProtocolId protocol; @@ -261,11 +262,11 @@ static void lfrfid_cli_emulate(Cli* cli, string_t args) { protocol_dict_free(dict); } -static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { +static void lfrfid_cli_raw_analyze(Cli* cli, FuriString* args) { UNUSED(cli); - string_t filepath, info_string; - string_init(filepath); - string_init(info_string); + FuriString *filepath, *info_string; + filepath = furi_string_alloc(); + info_string = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage); @@ -278,7 +279,7 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { break; } - if(!lfrfid_raw_file_open_read(file, string_get_cstr(filepath))) { + if(!lfrfid_raw_file_open_read(file, furi_string_get_cstr(filepath))) { printf("Failed to open file\r\n"); break; } @@ -308,10 +309,10 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { warn = true; } - string_printf(info_string, "[%ld %ld]", pulse, duration); - printf("%-16s", string_get_cstr(info_string)); - string_printf(info_string, "[%ld %ld]", pulse, duration - pulse); - printf("%-16s", string_get_cstr(info_string)); + furi_string_printf(info_string, "[%ld %ld]", pulse, duration); + printf("%-16s", furi_string_get_cstr(info_string)); + furi_string_printf(info_string, "[%ld %ld]", pulse, duration - pulse); + printf("%-16s", furi_string_get_cstr(info_string)); if(warn) { printf(" <<----"); @@ -366,7 +367,7 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { printf("]\r\n"); protocol_dict_render_data(dict, info_string, total_protocol); - printf("%s\r\n", string_get_cstr(info_string)); + printf("%s\r\n", furi_string_get_cstr(info_string)); free(data); } else { @@ -376,8 +377,8 @@ static void lfrfid_cli_raw_analyze(Cli* cli, string_t args) { protocol_dict_free(dict); } while(false); - string_clear(filepath); - string_clear(info_string); + furi_string_free(filepath); + furi_string_free(info_string); lfrfid_raw_file_free(file); furi_record_close(RECORD_STORAGE); } @@ -388,23 +389,23 @@ static void lfrfid_cli_raw_read_callback(LFRFIDWorkerReadRawResult result, void* furi_event_flag_set(event, 1 << result); } -static void lfrfid_cli_raw_read(Cli* cli, string_t args) { +static void lfrfid_cli_raw_read(Cli* cli, FuriString* args) { UNUSED(cli); - string_t filepath, type_string; - string_init(filepath); - string_init(type_string); + FuriString *filepath, *type_string; + filepath = furi_string_alloc(); + type_string = furi_string_alloc(); LFRFIDWorkerReadType type = LFRFIDWorkerReadTypeAuto; do { if(args_read_string_and_trim(args, type_string)) { - if(string_cmp_str(type_string, "normal") == 0 || - string_cmp_str(type_string, "ask") == 0) { + if(furi_string_cmp_str(type_string, "normal") == 0 || + furi_string_cmp_str(type_string, "ask") == 0) { // ask type = LFRFIDWorkerReadTypeASKOnly; } else if( - string_cmp_str(type_string, "indala") == 0 || - string_cmp_str(type_string, "psk") == 0) { + furi_string_cmp_str(type_string, "indala") == 0 || + furi_string_cmp_str(type_string, "psk") == 0) { // psk type = LFRFIDWorkerReadTypePSKOnly; } else { @@ -430,7 +431,7 @@ static void lfrfid_cli_raw_read(Cli* cli, string_t args) { (1 << LFRFIDWorkerReadRawOverrun); lfrfid_worker_read_raw_start( - worker, string_get_cstr(filepath), type, lfrfid_cli_raw_read_callback, event); + worker, furi_string_get_cstr(filepath), type, lfrfid_cli_raw_read_callback, event); while(true) { uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100); @@ -465,8 +466,8 @@ static void lfrfid_cli_raw_read(Cli* cli, string_t args) { } while(false); - string_clear(filepath); - string_clear(type_string); + furi_string_free(filepath); + furi_string_free(type_string); } static void lfrfid_cli_raw_emulate_callback(LFRFIDWorkerEmulateRawResult result, void* context) { @@ -475,11 +476,11 @@ static void lfrfid_cli_raw_emulate_callback(LFRFIDWorkerEmulateRawResult result, furi_event_flag_set(event, 1 << result); } -static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) { +static void lfrfid_cli_raw_emulate(Cli* cli, FuriString* args) { UNUSED(cli); - string_t filepath; - string_init(filepath); + FuriString* filepath; + filepath = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); do { @@ -488,8 +489,8 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) { break; } - if(!storage_file_exists(storage, string_get_cstr(filepath))) { - printf("File not found: \"%s\"\r\n", string_get_cstr(filepath)); + if(!storage_file_exists(storage, furi_string_get_cstr(filepath))) { + printf("File not found: \"%s\"\r\n", furi_string_get_cstr(filepath)); break; } @@ -505,7 +506,7 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) { (1 << LFRFIDWorkerEmulateRawOverrun); lfrfid_worker_emulate_raw_start( - worker, string_get_cstr(filepath), lfrfid_cli_raw_emulate_callback, event); + worker, furi_string_get_cstr(filepath), lfrfid_cli_raw_emulate_callback, event); while(true) { uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100); @@ -541,35 +542,35 @@ static void lfrfid_cli_raw_emulate(Cli* cli, string_t args) { } while(false); furi_record_close(RECORD_STORAGE); - string_clear(filepath); + furi_string_free(filepath); } -static void lfrfid_cli(Cli* cli, string_t args, void* context) { +static void lfrfid_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); if(!args_read_string_and_trim(args, cmd)) { - string_clear(cmd); + furi_string_free(cmd); lfrfid_cli_print_usage(); return; } - if(string_cmp_str(cmd, "read") == 0) { + if(furi_string_cmp_str(cmd, "read") == 0) { lfrfid_cli_read(cli, args); - } else if(string_cmp_str(cmd, "write") == 0) { + } else if(furi_string_cmp_str(cmd, "write") == 0) { lfrfid_cli_write(cli, args); - } else if(string_cmp_str(cmd, "emulate") == 0) { + } else if(furi_string_cmp_str(cmd, "emulate") == 0) { lfrfid_cli_emulate(cli, args); - } else if(string_cmp_str(cmd, "raw_read") == 0) { + } else if(furi_string_cmp_str(cmd, "raw_read") == 0) { lfrfid_cli_raw_read(cli, args); - } else if(string_cmp_str(cmd, "raw_emulate") == 0) { + } else if(furi_string_cmp_str(cmd, "raw_emulate") == 0) { lfrfid_cli_raw_emulate(cli, args); - } else if(string_cmp_str(cmd, "raw_analyze") == 0) { + } else if(furi_string_cmp_str(cmd, "raw_analyze") == 0) { lfrfid_cli_raw_analyze(cli, args); } else { lfrfid_cli_print_usage(); } - string_clear(cmd); + furi_string_free(cmd); } \ No newline at end of file diff --git a/applications/main/lfrfid/lfrfid_i.h b/applications/main/lfrfid/lfrfid_i.h index 77e872527..71917c0c2 100644 --- a/applications/main/lfrfid/lfrfid_i.h +++ b/applications/main/lfrfid/lfrfid_i.h @@ -1,7 +1,5 @@ #pragma once -#include "m-string.h" - #include #include @@ -86,9 +84,9 @@ struct LfRfid { Widget* widget; char text_store[LFRFID_TEXT_STORE_SIZE + 1]; - string_t file_path; - string_t file_name; - string_t raw_file_name; + FuriString* file_path; + FuriString* file_name; + FuriString* raw_file_name; ProtocolDict* dict; ProtocolId protocol_id; @@ -128,9 +126,9 @@ bool lfrfid_load_key_from_file_select(LfRfid* app); bool lfrfid_delete_key(LfRfid* app); -bool lfrfid_load_key_data(LfRfid* app, string_t path, bool show_dialog); +bool lfrfid_load_key_data(LfRfid* app, FuriString* path, bool show_dialog); -bool lfrfid_save_key_data(LfRfid* app, string_t path); +bool lfrfid_save_key_data(LfRfid* app, FuriString* path); void lfrfid_make_app_folder(LfRfid* app); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c b/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c index dc1c3df26..b7702e269 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c @@ -4,31 +4,31 @@ void lfrfid_scene_delete_confirm_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - string_t tmp_string; - string_init(tmp_string); + FuriString* tmp_string; + tmp_string = furi_string_alloc(); widget_add_button_element(widget, GuiButtonTypeLeft, "Back", lfrfid_widget_callback, app); widget_add_button_element(widget, GuiButtonTypeRight, "Delete", lfrfid_widget_callback, app); - string_printf(tmp_string, "Delete %s?", string_get_cstr(app->file_name)); + furi_string_printf(tmp_string, "Delete %s?", furi_string_get_cstr(app->file_name)); widget_add_string_element( - widget, 64, 0, AlignCenter, AlignTop, FontPrimary, string_get_cstr(tmp_string)); + widget, 64, 0, AlignCenter, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string)); - string_reset(tmp_string); + furi_string_reset(tmp_string); size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); uint8_t* data = (uint8_t*)malloc(size); protocol_dict_get_data(app->dict, app->protocol_id, data, size); for(uint8_t i = 0; i < MIN(size, (size_t)8); i++) { if(i != 0) { - string_cat_printf(tmp_string, " "); + furi_string_cat_printf(tmp_string, " "); } - string_cat_printf(tmp_string, "%02X", data[i]); + furi_string_cat_printf(tmp_string, "%02X", data[i]); } free(data); widget_add_string_element( - widget, 64, 19, AlignCenter, AlignTop, FontSecondary, string_get_cstr(tmp_string)); + widget, 64, 19, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); widget_add_string_element( widget, 64, @@ -39,7 +39,7 @@ void lfrfid_scene_delete_confirm_on_enter(void* context) { protocol_dict_get_name(app->dict, app->protocol_id)); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - string_clear(tmp_string); + furi_string_free(tmp_string); } bool lfrfid_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c index 70cc2418c..2725982f0 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c @@ -8,8 +8,8 @@ void lfrfid_scene_emulate_on_enter(void* context) { DOLPHIN_DEED(DolphinDeedRfidEmulate); popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop); - if(!string_empty_p(app->file_name)) { - popup_set_text(popup, string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); + if(!furi_string_empty(app->file_name)) { + popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); } else { popup_set_text( popup, diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c index 43e3de99e..d7fd93e19 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c @@ -42,7 +42,7 @@ void lfrfid_scene_extra_actions_on_enter(void* context) { submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneExtraActions)); // clear key - string_reset(app->file_name); + furi_string_reset(app->file_name); app->protocol_id = PROTOCOL_NO; app->read_type = LFRFIDWorkerReadTypeAuto; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c index f60dd6243..e5193521d 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c @@ -4,8 +4,8 @@ void lfrfid_scene_raw_info_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - // string_t tmp_string; - // string_init(tmp_string); + // FuriString* tmp_string; + // tmp_string = furi_string_alloc(); bool sd_exist = storage_sd_status(app->storage) == FSE_OK; if(!sd_exist) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c index 512f9ee4c..3e09dbf08 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c @@ -4,9 +4,9 @@ void lfrfid_scene_raw_name_on_enter(void* context) { LfRfid* app = context; TextInput* text_input = app->text_input; - const char* key_name = string_get_cstr(app->raw_file_name); + const char* key_name = furi_string_get_cstr(app->raw_file_name); - bool key_name_is_empty = string_empty_p(app->file_name); + bool key_name_is_empty = furi_string_empty(app->file_name); if(key_name_is_empty) { lfrfid_text_store_set(app, "RfidRecord"); } else { @@ -38,7 +38,7 @@ bool lfrfid_scene_raw_name_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == LfRfidEventNext) { consumed = true; - string_set_str(app->raw_file_name, app->text_store); + furi_string_set(app->raw_file_name, app->text_store); scene_manager_next_scene(scene_manager, LfRfidSceneRawInfo); } } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c index d0c03ffa9..b2c7c364e 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c @@ -3,7 +3,7 @@ #define RAW_READ_TIME 5000 typedef struct { - string_t string_file_name; + FuriString* string_file_name; FuriTimer* timer; bool is_psk; bool error; @@ -31,7 +31,7 @@ void lfrfid_scene_raw_read_on_enter(void* context) { LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState)); scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state); - string_init(state->string_file_name); + state->string_file_name = furi_string_alloc(); popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); @@ -40,16 +40,16 @@ void lfrfid_scene_raw_read_on_enter(void* context) { state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, app); furi_timer_start(state->timer, RAW_READ_TIME); - string_printf( + furi_string_printf( state->string_file_name, "%s/%s%s", LFRFID_SD_FOLDER, - string_get_cstr(app->raw_file_name), + furi_string_get_cstr(app->raw_file_name), LFRFID_APP_RAW_ASK_EXTENSION); popup_set_header(popup, "Reading\nRAW RFID\nASK", 89, 30, AlignCenter, AlignTop); lfrfid_worker_read_raw_start( app->lfworker, - string_get_cstr(state->string_file_name), + furi_string_get_cstr(state->string_file_name), LFRFIDWorkerReadTypeASKOnly, lfrfid_read_callback, app); @@ -88,15 +88,15 @@ bool lfrfid_scene_raw_read_on_event(void* context, SceneManagerEvent event) { popup, "Reading\nRAW RFID\nPSK", 89, 30, AlignCenter, AlignTop); notification_message(app->notifications, &sequence_blink_start_yellow); lfrfid_worker_stop(app->lfworker); - string_printf( + furi_string_printf( state->string_file_name, "%s/%s%s", LFRFID_SD_FOLDER, - string_get_cstr(app->raw_file_name), + furi_string_get_cstr(app->raw_file_name), LFRFID_APP_RAW_PSK_EXTENSION); lfrfid_worker_read_raw_start( app->lfworker, - string_get_cstr(state->string_file_name), + furi_string_get_cstr(state->string_file_name), LFRFIDWorkerReadTypePSKOnly, lfrfid_read_callback, app); @@ -121,6 +121,6 @@ void lfrfid_scene_raw_read_on_exit(void* context) { lfrfid_worker_stop_thread(app->lfworker); furi_timer_free(state->timer); - string_clear(state->string_file_name); + furi_string_free(state->string_file_name); free(state); } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read.c b/applications/main/lfrfid/scenes/lfrfid_scene_read.c index 661680381..4bdb215d1 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read.c @@ -81,7 +81,7 @@ bool lfrfid_scene_read_on_event(void* context, SceneManagerEvent event) { app->protocol_id = app->protocol_id_next; DOLPHIN_DEED(DolphinDeedRfidReadSuccess); notification_message(app->notifications, &sequence_success); - string_reset(app->file_name); + furi_string_reset(app->file_name); scene_manager_next_scene(app->scene_manager, LfRfidSceneReadSuccess); consumed = true; } else if(event.event == LfRfidEventReadStartPSK) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c b/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c index 221cc0084..7480304b6 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c @@ -38,7 +38,7 @@ bool lfrfid_scene_read_key_menu_on_event(void* context, SceneManagerEvent event) scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite); consumed = true; } else if(event.event == SubmenuIndexSave) { - string_reset(app->file_name); + furi_string_reset(app->file_name); scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveName); consumed = true; } else if(event.event == SubmenuIndexEmulate) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c index 5ae6f0f1a..b83ef4a39 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c @@ -4,51 +4,51 @@ void lfrfid_scene_read_success_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - string_t tmp_string; - string_init(tmp_string); + FuriString* tmp_string; + tmp_string = furi_string_alloc(); widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app); widget_add_button_element(widget, GuiButtonTypeRight, "More", lfrfid_widget_callback, app); - string_printf( + furi_string_printf( tmp_string, "%s[%s]", protocol_dict_get_name(app->dict, app->protocol_id), protocol_dict_get_manufacturer(app->dict, app->protocol_id)); widget_add_string_element( - widget, 0, 2, AlignLeft, AlignTop, FontPrimary, string_get_cstr(tmp_string)); + widget, 0, 2, AlignLeft, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string)); - string_reset(tmp_string); + furi_string_reset(tmp_string); size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); uint8_t* data = (uint8_t*)malloc(size); protocol_dict_get_data(app->dict, app->protocol_id, data, size); for(uint8_t i = 0; i < size; i++) { if(i >= 9) { - string_cat_printf(tmp_string, ".."); + furi_string_cat_printf(tmp_string, ".."); break; } else { if(i != 0) { - string_cat_printf(tmp_string, " "); + furi_string_cat_printf(tmp_string, " "); } - string_cat_printf(tmp_string, "%02X", data[i]); + furi_string_cat_printf(tmp_string, "%02X", data[i]); } } free(data); - string_t render_data; - string_init(render_data); + FuriString* render_data; + render_data = furi_string_alloc(); protocol_dict_render_brief_data(app->dict, render_data, app->protocol_id); - string_cat_printf(tmp_string, "\r\n%s", string_get_cstr(render_data)); - string_clear(render_data); + furi_string_cat_printf(tmp_string, "\r\n%s", furi_string_get_cstr(render_data)); + furi_string_free(render_data); widget_add_string_multiline_element( - widget, 0, 16, AlignLeft, AlignTop, FontSecondary, string_get_cstr(tmp_string)); + widget, 0, 16, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); notification_message_block(app->notifications, &sequence_set_green_255); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - string_clear(tmp_string); + furi_string_free(tmp_string); } bool lfrfid_scene_read_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c index a69d6453a..156dd97af 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c @@ -34,13 +34,14 @@ bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) { const char* arg = rpc_system_app_get_data(app->rpc_ctx); bool result = false; if(arg && (app->rpc_state == LfRfidRpcStateIdle)) { - string_set_str(app->file_path, arg); + furi_string_set(app->file_path, arg); if(lfrfid_load_key_data(app, app->file_path, false)) { lfrfid_worker_start_thread(app->lfworker); lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); app->rpc_state = LfRfidRpcStateEmulating; - lfrfid_text_store_set(app, "emulating\n%s", string_get_cstr(app->file_name)); + lfrfid_text_store_set( + app, "emulating\n%s", furi_string_get_cstr(app->file_name)); popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop); notification_message(app->notifications, &sequence_blink_start_magenta); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c index 2ca1bb433..6c5ea2f2d 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_data.c @@ -9,14 +9,11 @@ void lfrfid_scene_save_data_on_enter(void* context) { bool need_restore = scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveData); - if(need_restore) { - protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size); - } else { + if(!need_restore) { protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size); + protocol_dict_get_data(app->dict, app->protocol_id, app->new_key_data, size); } - protocol_dict_get_data(app->dict, app->protocol_id, app->new_key_data, size); - byte_input_set_header_text(byte_input, "Enter the data in hex"); byte_input_set_result_callback( @@ -41,6 +38,8 @@ bool lfrfid_scene_save_data_on_event(void* context, SceneManagerEvent event) { } } else if(event.type == SceneManagerEventTypeBack) { scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 0); + size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); + protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size); } return consumed; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c index febf30a41..ca9a52de0 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c @@ -1,21 +1,20 @@ -#include "m-string.h" #include #include "../lfrfid_i.h" void lfrfid_scene_save_name_on_enter(void* context) { LfRfid* app = context; TextInput* text_input = app->text_input; - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - bool key_name_is_empty = string_empty_p(app->file_name); + bool key_name_is_empty = furi_string_empty(app->file_name); if(key_name_is_empty) { - string_set_str(app->file_path, LFRFID_APP_FOLDER); + furi_string_set(app->file_path, LFRFID_APP_FOLDER); set_random_name(app->text_store, LFRFID_TEXT_STORE_SIZE); - string_set_str(folder_path, LFRFID_APP_FOLDER); + furi_string_set(folder_path, LFRFID_APP_FOLDER); } else { - lfrfid_text_store_set(app, "%s", string_get_cstr(app->file_name)); - path_extract_dirname(string_get_cstr(app->file_path), folder_path); + lfrfid_text_store_set(app, "%s", furi_string_get_cstr(app->file_name)); + path_extract_dirname(furi_string_get_cstr(app->file_path), folder_path); } text_input_set_header_text(text_input, "Name the card"); @@ -27,13 +26,15 @@ void lfrfid_scene_save_name_on_enter(void* context) { LFRFID_KEY_NAME_SIZE, key_name_is_empty); - FURI_LOG_I("", "%s %s", string_get_cstr(folder_path), app->text_store); + FURI_LOG_I("", "%s %s", furi_string_get_cstr(folder_path), app->text_store); ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), LFRFID_APP_EXTENSION, string_get_cstr(app->file_name)); + furi_string_get_cstr(folder_path), + LFRFID_APP_EXTENSION, + furi_string_get_cstr(app->file_name)); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - string_clear(folder_path); + furi_string_free(folder_path); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewTextInput); } @@ -46,11 +47,11 @@ bool lfrfid_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == LfRfidEventNext) { consumed = true; - if(!string_empty_p(app->file_name)) { + if(!furi_string_empty(app->file_name)) { lfrfid_delete_key(app); } - string_set_str(app->file_name, app->text_store); + furi_string_set(app->file_name, app->text_store); if(lfrfid_save_key(app)) { scene_manager_next_scene(scene_manager, LfRfidSceneSaveSuccess); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c index 830ef3368..e91ad04e3 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c @@ -5,6 +5,9 @@ void lfrfid_scene_save_success_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; + // Clear state of data enter scene + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveData, 0); + DOLPHIN_DEED(DolphinDeedRfidSave); popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_type.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_type.c index 4c1116007..0ba51f066 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_type.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_type.c @@ -1,7 +1,7 @@ #include "../lfrfid_i.h" typedef struct { - string_t menu_item_name[LFRFIDProtocolMax]; + FuriString* menu_item_name[LFRFIDProtocolMax]; uint32_t line_sel; } SaveTypeCtx; @@ -20,18 +20,17 @@ void lfrfid_scene_save_type_on_enter(void* context) { if(strcmp( protocol_dict_get_manufacturer(app->dict, i), protocol_dict_get_name(app->dict, i)) != 0) { - string_init_printf( - state->menu_item_name[i], + state->menu_item_name[i] = furi_string_alloc_printf( "%s %s", protocol_dict_get_manufacturer(app->dict, i), protocol_dict_get_name(app->dict, i)); } else { - string_init_printf( - state->menu_item_name[i], "%s", protocol_dict_get_name(app->dict, i)); + state->menu_item_name[i] = + furi_string_alloc_printf("%s", protocol_dict_get_name(app->dict, i)); } submenu_add_item( submenu, - string_get_cstr(state->menu_item_name[i]), + furi_string_get_cstr(state->menu_item_name[i]), i, lfrfid_scene_save_type_submenu_callback, app); @@ -43,7 +42,7 @@ void lfrfid_scene_save_type_on_enter(void* context) { scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveType, (uint32_t)state); // clear key name - string_reset(app->file_name); + furi_string_reset(app->file_name); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu); } @@ -75,7 +74,7 @@ void lfrfid_scene_save_type_on_exit(void* context) { submenu_reset(app->submenu); for(uint8_t i = 0; i < LFRFIDProtocolMax; i++) { - string_clear(state->menu_item_name[i]); + furi_string_free(state->menu_item_name[i]); } uint32_t line_sel = state->line_sel; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c b/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c index 1496c6b4b..3f1c2d400 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c @@ -4,13 +4,13 @@ void lfrfid_scene_saved_info_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - string_t tmp_string; - string_init(tmp_string); + FuriString* tmp_string; + tmp_string = furi_string_alloc(); - string_printf( + furi_string_printf( tmp_string, "%s [%s]\r\n", - string_get_cstr(app->file_name), + furi_string_get_cstr(app->file_name), protocol_dict_get_name(app->dict, app->protocol_id)); size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); @@ -18,24 +18,24 @@ void lfrfid_scene_saved_info_on_enter(void* context) { protocol_dict_get_data(app->dict, app->protocol_id, data, size); for(uint8_t i = 0; i < size; i++) { if(i != 0) { - string_cat_printf(tmp_string, " "); + furi_string_cat_printf(tmp_string, " "); } - string_cat_printf(tmp_string, "%02X", data[i]); + furi_string_cat_printf(tmp_string, "%02X", data[i]); } free(data); - string_t render_data; - string_init(render_data); + FuriString* render_data; + render_data = furi_string_alloc(); protocol_dict_render_data(app->dict, render_data, app->protocol_id); - string_cat_printf(tmp_string, "\r\n%s", string_get_cstr(render_data)); - string_clear(render_data); + furi_string_cat_printf(tmp_string, "\r\n%s", furi_string_get_cstr(render_data)); + furi_string_free(render_data); widget_add_string_multiline_element( - widget, 0, 1, AlignLeft, AlignTop, FontSecondary, string_get_cstr(tmp_string)); + widget, 0, 1, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - string_clear(tmp_string); + furi_string_free(tmp_string); } bool lfrfid_scene_saved_info_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_start.c b/applications/main/lfrfid/scenes/lfrfid_scene_start.c index 9074e859b..d6d87f441 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_start.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_start.c @@ -33,7 +33,7 @@ void lfrfid_scene_start_on_enter(void* context) { submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneStart)); // clear key - string_reset(app->file_name); + furi_string_reset(app->file_name); app->protocol_id = PROTOCOL_NO; app->read_type = LFRFIDWorkerReadTypeAuto; @@ -49,7 +49,7 @@ bool lfrfid_scene_start_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(app->scene_manager, LfRfidSceneRead); consumed = true; } else if(event.event == SubmenuIndexSaved) { - string_set_str(app->file_path, LFRFID_APP_FOLDER); + furi_string_set(app->file_path, LFRFID_APP_FOLDER); scene_manager_next_scene(app->scene_manager, LfRfidSceneSelectKey); consumed = true; } else if(event.event == SubmenuIndexAddManually) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_write.c b/applications/main/lfrfid/scenes/lfrfid_scene_write.c index 4b03bac15..b7faed69f 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_write.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_write.c @@ -22,8 +22,8 @@ void lfrfid_scene_write_on_enter(void* context) { Popup* popup = app->popup; popup_set_header(popup, "Writing", 89, 30, AlignCenter, AlignTop); - if(!string_empty_p(app->file_name)) { - popup_set_text(popup, string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); + if(!furi_string_empty(app->file_name)) { + popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); } else { popup_set_text( popup, @@ -38,7 +38,6 @@ void lfrfid_scene_write_on_enter(void* context) { view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); - app->old_key_data = (uint8_t*)malloc(size); protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size); lfrfid_worker_start_thread(app->lfworker); @@ -92,5 +91,4 @@ void lfrfid_scene_write_on_exit(void* context) { size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size); - free(app->old_key_data); } diff --git a/applications/main/lfrfid/views/lfrfid_view_read.c b/applications/main/lfrfid/views/lfrfid_view_read.c index 66caf8df7..0d4db6178 100644 --- a/applications/main/lfrfid/views/lfrfid_view_read.c +++ b/applications/main/lfrfid/views/lfrfid_view_read.c @@ -56,19 +56,13 @@ static void lfrfid_view_read_draw_callback(Canvas* canvas, void* _model) { void lfrfid_view_read_enter(void* context) { LfRfidReadView* read_view = context; with_view_model( - read_view->view, (LfRfidReadViewModel * model) { - icon_animation_start(model->icon); - return true; - }); + read_view->view, LfRfidReadViewModel * model, { icon_animation_start(model->icon); }, true); } void lfrfid_view_read_exit(void* context) { LfRfidReadView* read_view = context; with_view_model( - read_view->view, (LfRfidReadViewModel * model) { - icon_animation_stop(model->icon); - return false; - }); + read_view->view, LfRfidReadViewModel * model, { icon_animation_stop(model->icon); }, false); } LfRfidReadView* lfrfid_view_read_alloc() { @@ -78,11 +72,13 @@ LfRfidReadView* lfrfid_view_read_alloc() { view_allocate_model(read_view->view, ViewModelTypeLocking, sizeof(LfRfidReadViewModel)); with_view_model( - read_view->view, (LfRfidReadViewModel * model) { + read_view->view, + LfRfidReadViewModel * model, + { model->icon = icon_animation_alloc(&A_Round_loader_8x8); view_tie_icon_animation(read_view->view, model->icon); - return false; - }); + }, + false); view_set_draw_callback(read_view->view, lfrfid_view_read_draw_callback); view_set_enter_callback(read_view->view, lfrfid_view_read_enter); @@ -93,10 +89,7 @@ LfRfidReadView* lfrfid_view_read_alloc() { void lfrfid_view_read_free(LfRfidReadView* read_view) { with_view_model( - read_view->view, (LfRfidReadViewModel * model) { - icon_animation_free(model->icon); - return false; - }); + read_view->view, LfRfidReadViewModel * model, { icon_animation_free(model->icon); }, false); view_free(read_view->view); free(read_view); @@ -108,10 +101,12 @@ View* lfrfid_view_read_get_view(LfRfidReadView* read_view) { void lfrfid_view_read_set_read_mode(LfRfidReadView* read_view, LfRfidReadViewMode mode) { with_view_model( - read_view->view, (LfRfidReadViewModel * model) { + read_view->view, + LfRfidReadViewModel * model, + { icon_animation_stop(model->icon); icon_animation_start(model->icon); model->read_mode = mode; - return true; - }); + }, + true); } diff --git a/applications/main/nfc/helpers/nfc_emv_parser.c b/applications/main/nfc/helpers/nfc_emv_parser.c index 0d7cb5a33..30e102405 100644 --- a/applications/main/nfc/helpers/nfc_emv_parser.c +++ b/applications/main/nfc/helpers/nfc_emv_parser.c @@ -7,12 +7,12 @@ static const uint32_t nfc_resources_file_version = 1; static bool nfc_emv_parser_search_data( Storage* storage, const char* file_name, - string_t key, - string_t data) { + FuriString* key, + FuriString* data) { bool parsed = false; FlipperFormat* file = flipper_format_file_alloc(storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { // Open file @@ -20,14 +20,14 @@ static bool nfc_emv_parser_search_data( // Read file header and version uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, nfc_resources_header) || + if(furi_string_cmp_str(temp_str, nfc_resources_header) || (version != nfc_resources_file_version)) break; - if(!flipper_format_read_string(file, string_get_cstr(key), data)) break; + if(!flipper_format_read_string(file, furi_string_get_cstr(key), data)) break; parsed = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return parsed; } @@ -36,47 +36,47 @@ bool nfc_emv_parser_get_aid_name( Storage* storage, uint8_t* aid, uint8_t aid_len, - string_t aid_name) { + FuriString* aid_name) { furi_assert(storage); bool parsed = false; - string_t key; - string_init(key); + FuriString* key; + key = furi_string_alloc(); for(uint8_t i = 0; i < aid_len; i++) { - string_cat_printf(key, "%02X", aid[i]); + furi_string_cat_printf(key, "%02X", aid[i]); } if(nfc_emv_parser_search_data(storage, EXT_PATH("nfc/assets/aid.nfc"), key, aid_name)) { parsed = true; } - string_clear(key); + furi_string_free(key); return parsed; } bool nfc_emv_parser_get_country_name( Storage* storage, uint16_t country_code, - string_t country_name) { + FuriString* country_name) { bool parsed = false; - string_t key; - string_init_printf(key, "%04X", country_code); + FuriString* key; + key = furi_string_alloc_printf("%04X", country_code); if(nfc_emv_parser_search_data( storage, EXT_PATH("nfc/assets/country_code.nfc"), key, country_name)) { parsed = true; } - string_clear(key); + furi_string_free(key); return parsed; } bool nfc_emv_parser_get_currency_name( Storage* storage, uint16_t currency_code, - string_t currency_name) { + FuriString* currency_name) { bool parsed = false; - string_t key; - string_init_printf(key, "%04X", currency_code); + FuriString* key; + key = furi_string_alloc_printf("%04X", currency_code); if(nfc_emv_parser_search_data( storage, EXT_PATH("nfc/assets/currency_code.nfc"), key, currency_name)) { parsed = true; } - string_clear(key); + furi_string_free(key); return parsed; } diff --git a/applications/main/nfc/helpers/nfc_emv_parser.h b/applications/main/nfc/helpers/nfc_emv_parser.h index 5948ed340..abe57f470 100644 --- a/applications/main/nfc/helpers/nfc_emv_parser.h +++ b/applications/main/nfc/helpers/nfc_emv_parser.h @@ -2,7 +2,6 @@ #include #include -#include #include /** Get EMV application name by number @@ -16,7 +15,7 @@ bool nfc_emv_parser_get_aid_name( Storage* storage, uint8_t* aid, uint8_t aid_len, - string_t aid_name); + FuriString* aid_name); /** Get country name by country code * @param storage Storage instance @@ -27,7 +26,7 @@ bool nfc_emv_parser_get_aid_name( bool nfc_emv_parser_get_country_name( Storage* storage, uint16_t country_code, - string_t country_name); + FuriString* country_name); /** Get currency name by currency code * @param storage Storage instance @@ -38,4 +37,4 @@ bool nfc_emv_parser_get_country_name( bool nfc_emv_parser_get_currency_name( Storage* storage, uint16_t currency_code, - string_t currency_name); + FuriString* currency_name); diff --git a/applications/main/nfc/nfc.c b/applications/main/nfc/nfc.c index c1350be3a..c2f8b6b1b 100644 --- a/applications/main/nfc/nfc.c +++ b/applications/main/nfc/nfc.c @@ -83,7 +83,7 @@ Nfc* nfc_alloc() { nfc->text_box = text_box_alloc(); view_dispatcher_add_view( nfc->view_dispatcher, NfcViewTextBox, text_box_get_view(nfc->text_box)); - string_init(nfc->text_box_store); + nfc->text_box_store = furi_string_alloc(); // Variable Item List nfc->variable_item_list = variable_item_list_alloc(); @@ -160,7 +160,7 @@ void nfc_free(Nfc* nfc) { // TextBox view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewTextBox); text_box_free(nfc->text_box); - string_clear(nfc->text_box_store); + furi_string_free(nfc->text_box_store); // Variable Item List view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewVarItemList); @@ -288,6 +288,8 @@ int32_t nfc_app(void* p) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); + } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); } diff --git a/applications/main/nfc/nfc_cli.c b/applications/main/nfc/nfc_cli.c index 4ac95f043..a6475ca68 100644 --- a/applications/main/nfc/nfc_cli.c +++ b/applications/main/nfc/nfc_cli.c @@ -17,7 +17,7 @@ static void nfc_cli_print_usage() { } } -static void nfc_cli_detect(Cli* cli, string_t args) { +static void nfc_cli_detect(Cli* cli, FuriString* args) { UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { @@ -46,7 +46,7 @@ static void nfc_cli_detect(Cli* cli, string_t args) { furi_hal_nfc_sleep(); } -static void nfc_cli_emulate(Cli* cli, string_t args) { +static void nfc_cli_emulate(Cli* cli, FuriString* args) { UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { @@ -76,7 +76,7 @@ static void nfc_cli_emulate(Cli* cli, string_t args) { furi_hal_nfc_sleep(); } -static void nfc_cli_field(Cli* cli, string_t args) { +static void nfc_cli_field(Cli* cli, FuriString* args) { UNUSED(args); // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { @@ -98,27 +98,27 @@ static void nfc_cli_field(Cli* cli, string_t args) { furi_hal_nfc_sleep(); } -static void nfc_cli(Cli* cli, string_t args, void* context) { +static void nfc_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { nfc_cli_print_usage(); break; } - if(string_cmp_str(cmd, "detect") == 0) { + if(furi_string_cmp_str(cmd, "detect") == 0) { nfc_cli_detect(cli, args); break; } - if(string_cmp_str(cmd, "emulate") == 0) { + if(furi_string_cmp_str(cmd, "emulate") == 0) { nfc_cli_emulate(cli, args); break; } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - if(string_cmp_str(cmd, "field") == 0) { + if(furi_string_cmp_str(cmd, "field") == 0) { nfc_cli_field(cli, args); break; } @@ -127,7 +127,7 @@ static void nfc_cli(Cli* cli, string_t args, void* context) { nfc_cli_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } void nfc_on_system_start() { diff --git a/applications/main/nfc/nfc_i.h b/applications/main/nfc/nfc_i.h index b005cf7f1..677fd19c6 100644 --- a/applications/main/nfc/nfc_i.h +++ b/applications/main/nfc/nfc_i.h @@ -63,7 +63,7 @@ struct Nfc { FuriHalNfcDevData dev_edit_data; char text_store[NFC_TEXT_STORE_SIZE + 1]; - string_t text_box_store; + FuriString* text_box_store; uint8_t byte_input_store[6]; MfClassicUserKeys_t mfc_key_strs; // Used in MFC key listing diff --git a/applications/main/nfc/scenes/nfc_scene_delete.c b/applications/main/nfc/scenes/nfc_scene_delete.c index 987927e19..cbb52bfd0 100644 --- a/applications/main/nfc/scenes/nfc_scene_delete.c +++ b/applications/main/nfc/scenes/nfc_scene_delete.c @@ -12,40 +12,40 @@ void nfc_scene_delete_on_enter(void* context) { FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data; // Setup Custom Widget view - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); - string_printf(temp_str, "\e#Delete %s?\e#", nfc->dev->dev_name); + furi_string_printf(temp_str, "\e#Delete %s?\e#", nfc->dev->dev_name); widget_add_text_box_element( - nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, string_get_cstr(temp_str), false); + nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, furi_string_get_cstr(temp_str), false); widget_add_button_element( nfc->widget, GuiButtonTypeLeft, "Cancel", nfc_scene_delete_widget_callback, nfc); widget_add_button_element( nfc->widget, GuiButtonTypeRight, "Delete", nfc_scene_delete_widget_callback, nfc); - string_set_str(temp_str, "UID:"); + furi_string_set(temp_str, "UID:"); for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); } widget_add_string_element( - nfc->widget, 64, 24, AlignCenter, AlignTop, FontSecondary, string_get_cstr(temp_str)); + nfc->widget, 64, 24, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); NfcProtocol protocol = nfc->dev->dev_data.protocol; if(protocol == NfcDeviceProtocolEMV) { - string_set_str(temp_str, "EMV bank card"); + furi_string_set(temp_str, "EMV bank card"); } else if(protocol == NfcDeviceProtocolMifareUl) { - string_set_str(temp_str, nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, true)); + furi_string_set(temp_str, nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, true)); } else if(protocol == NfcDeviceProtocolMifareClassic) { - string_set_str(temp_str, nfc_mf_classic_type(nfc->dev->dev_data.mf_classic_data.type)); + furi_string_set(temp_str, nfc_mf_classic_type(nfc->dev->dev_data.mf_classic_data.type)); } else if(protocol == NfcDeviceProtocolMifareDesfire) { - string_set_str(temp_str, "MIFARE DESFire"); + furi_string_set(temp_str, "MIFARE DESFire"); } else { - string_set_str(temp_str, "Unknown ISO tag"); + furi_string_set(temp_str, "Unknown ISO tag"); } widget_add_string_element( - nfc->widget, 64, 34, AlignCenter, AlignTop, FontSecondary, string_get_cstr(temp_str)); + nfc->widget, 64, 34, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); widget_add_string_element(nfc->widget, 64, 44, AlignCenter, AlignTop, FontSecondary, "NFC-A"); - string_clear(temp_str); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_detect_reader.c b/applications/main/nfc/scenes/nfc_scene_detect_reader.c index 5f4582d8e..e8c2b5ee8 100644 --- a/applications/main/nfc/scenes/nfc_scene_detect_reader.c +++ b/applications/main/nfc/scenes/nfc_scene_detect_reader.c @@ -1,6 +1,15 @@ #include "../nfc_i.h" #include +#define NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX (10U) + +static const NotificationSequence sequence_detect_reader = { + &message_green_255, + &message_blue_255, + &message_do_not_reset, + NULL, +}; + bool nfc_detect_reader_worker_callback(NfcWorkerEvent event, void* context) { UNUSED(event); furi_assert(context); @@ -20,21 +29,26 @@ void nfc_scene_detect_reader_on_enter(void* context) { DOLPHIN_DEED(DolphinDeedNfcEmulate); detect_reader_set_callback(nfc->detect_reader, nfc_scene_detect_reader_callback, nfc); + detect_reader_set_nonces_max(nfc->detect_reader, NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX); + + // Store number of collected nonces in scene state + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDetectReader, 0); + notification_message(nfc->notifications, &sequence_detect_reader); + nfc_worker_start( nfc->worker, NfcWorkerStateAnalyzeReader, &nfc->dev->dev_data, nfc_detect_reader_worker_callback, nfc); - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDetectReader); - - nfc_blink_read_start(nfc); } bool nfc_scene_detect_reader_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; bool consumed = false; + uint32_t nonces_collected = + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDetectReader); if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventViewExit) { @@ -42,8 +56,29 @@ bool nfc_scene_detect_reader_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfkeyNoncesInfo); consumed = true; } else if(event.event == NfcWorkerEventDetectReaderMfkeyCollected) { - detect_reader_inc_nonce_cnt(nfc->detect_reader); + nonces_collected += 2; + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneDetectReader, nonces_collected); + detect_reader_set_nonces_collected(nfc->detect_reader, nonces_collected); + if(nonces_collected >= NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) { + detect_reader_set_state(nfc->detect_reader, DetectReaderStateDone); + nfc_blink_stop(nfc); + notification_message(nfc->notifications, &sequence_single_vibro); + notification_message(nfc->notifications, &sequence_set_green_255); + nfc_worker_stop(nfc->worker); + } consumed = true; + } else if(event.event == NfcWorkerEventDetectReaderDetected) { + if(nonces_collected < NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) { + notification_message(nfc->notifications, &sequence_blink_start_cyan); + detect_reader_set_state(nfc->detect_reader, DetectReaderStateReaderDetected); + } + } else if(event.event == NfcWorkerEventDetectReaderLost) { + if(nonces_collected < NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) { + nfc_blink_stop(nfc); + notification_message(nfc->notifications, &sequence_detect_reader); + detect_reader_set_state(nfc->detect_reader, DetectReaderStateReaderLost); + } } } @@ -59,5 +94,7 @@ void nfc_scene_detect_reader_on_exit(void* context) { // Clear view detect_reader_reset(nfc->detect_reader); + // Stop notifications nfc_blink_stop(nfc); + notification_message(nfc->notifications, &sequence_reset_green); } diff --git a/applications/main/nfc/scenes/nfc_scene_device_info.c b/applications/main/nfc/scenes/nfc_scene_device_info.c index 245aea5c5..9780ffe41 100644 --- a/applications/main/nfc/scenes/nfc_scene_device_info.c +++ b/applications/main/nfc/scenes/nfc_scene_device_info.c @@ -12,49 +12,52 @@ void nfc_scene_device_info_on_enter(void* context) { Nfc* nfc = context; NfcDeviceData* dev_data = &nfc->dev->dev_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); if(dev_data->protocol == NfcDeviceProtocolEMV) { EmvData* emv_data = &dev_data->emv_data; - string_printf(temp_str, "\e#%s\n", emv_data->name); + furi_string_printf(temp_str, "\e#%s\n", emv_data->name); for(uint8_t i = 0; i < emv_data->number_len; i += 2) { - string_cat_printf(temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); + furi_string_cat_printf( + temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); } - string_strim(temp_str); + furi_string_trim(temp_str); // Add expiration date if(emv_data->exp_mon) { - string_cat_printf(temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year); + furi_string_cat_printf( + temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year); } // Parse currency code if((emv_data->currency_code)) { - string_t currency_name; - string_init(currency_name); + FuriString* currency_name; + currency_name = furi_string_alloc(); if(nfc_emv_parser_get_currency_name( nfc->dev->storage, emv_data->currency_code, currency_name)) { - string_cat_printf(temp_str, "\nCur: %s ", string_get_cstr(currency_name)); + furi_string_cat_printf( + temp_str, "\nCur: %s ", furi_string_get_cstr(currency_name)); } - string_clear(currency_name); + furi_string_free(currency_name); } // Parse country code if((emv_data->country_code)) { - string_t country_name; - string_init(country_name); + FuriString* country_name; + country_name = furi_string_alloc(); if(nfc_emv_parser_get_country_name( nfc->dev->storage, emv_data->country_code, country_name)) { - string_cat_printf(temp_str, "Reg: %s", string_get_cstr(country_name)); + furi_string_cat_printf(temp_str, "Reg: %s", furi_string_get_cstr(country_name)); } - string_clear(country_name); + furi_string_free(country_name); } } else if( dev_data->protocol == NfcDeviceProtocolMifareClassic || dev_data->protocol == NfcDeviceProtocolMifareUl) { - string_set(temp_str, nfc->dev->dev_data.parsed_data); + furi_string_set(temp_str, nfc->dev->dev_data.parsed_data); } - widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); widget_add_button_element( nfc->widget, GuiButtonTypeRight, "More", nfc_scene_device_info_widget_callback, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c index f64023010..8bb207960 100644 --- a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c @@ -35,22 +35,22 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; widget_reset(widget); - string_t info_str; - string_init(info_str); + FuriString* info_str; + info_str = furi_string_alloc(); widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61); widget_add_string_element(widget, 89, 32, AlignCenter, AlignTop, FontPrimary, "Emulating UID"); if(strcmp(nfc->dev->dev_name, "")) { - string_printf(info_str, "%s", nfc->dev->dev_name); + furi_string_printf(info_str, "%s", nfc->dev->dev_name); } else { for(uint8_t i = 0; i < data->uid_len; i++) { - string_cat_printf(info_str, "%02X ", data->uid[i]); + furi_string_cat_printf(info_str, "%02X ", data->uid[i]); } } - string_strim(info_str); + furi_string_trim(info_str); widget_add_text_box_element( - widget, 56, 43, 70, 21, AlignCenter, AlignTop, string_get_cstr(info_str), true); - string_clear(info_str); + widget, 56, 43, 70, 21, AlignCenter, AlignTop, furi_string_get_cstr(info_str), true); + furi_string_free(info_str); if(data_received) { widget_add_button_element( widget, GuiButtonTypeCenter, "Log", nfc_scene_emulate_uid_widget_callback, nfc); @@ -67,7 +67,7 @@ void nfc_scene_emulate_uid_on_enter(void* context) { TextBox* text_box = nfc->text_box; text_box_set_font(text_box, TextBoxFontHex); text_box_set_focus(text_box, TextBoxFocusEnd); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); // Set Widget state and view scene_manager_set_scene_state( @@ -94,17 +94,17 @@ bool nfc_scene_emulate_uid_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventWorkerExit) { // Add data button to widget if data is received for the first time - if(!string_size(nfc->text_box_store)) { + if(!furi_string_size(nfc->text_box_store)) { nfc_scene_emulate_uid_widget_config(nfc, true); } // Update TextBox data - if(string_size(nfc->text_box_store) < NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX) { - string_cat_printf(nfc->text_box_store, "R:"); + if(furi_string_size(nfc->text_box_store) < NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX) { + furi_string_cat_printf(nfc->text_box_store, "R:"); for(uint16_t i = 0; i < reader_data->size; i++) { - string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]); + furi_string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]); } - string_push_back(nfc->text_box_store, '\n'); - text_box_set_text(nfc->text_box, string_get_cstr(nfc->text_box_store)); + furi_string_push_back(nfc->text_box_store, '\n'); + text_box_set_text(nfc->text_box, furi_string_get_cstr(nfc->text_box_store)); } memset(reader_data, 0, sizeof(NfcReaderRequestData)); consumed = true; @@ -140,7 +140,7 @@ void nfc_scene_emulate_uid_on_exit(void* context) { // Clear view widget_reset(nfc->widget); text_box_reset(nfc->text_box); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); nfc_blink_stop(nfc); } diff --git a/applications/main/nfc/scenes/nfc_scene_emv_read_success.c b/applications/main/nfc/scenes/nfc_scene_emv_read_success.c index a40b4c1c9..8b6ab160e 100644 --- a/applications/main/nfc/scenes/nfc_scene_emv_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_emv_read_success.c @@ -23,42 +23,44 @@ void nfc_scene_emv_read_success_on_enter(void* context) { widget_add_button_element( nfc->widget, GuiButtonTypeRight, "More", nfc_scene_emv_read_success_widget_callback, nfc); - string_t temp_str; - string_init_printf(temp_str, "\e#%s\n", emv_data->name); + FuriString* temp_str; + temp_str = furi_string_alloc_printf("\e#%s\n", emv_data->name); for(uint8_t i = 0; i < emv_data->number_len; i += 2) { - string_cat_printf(temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); + furi_string_cat_printf( + temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]); } - string_strim(temp_str); + furi_string_trim(temp_str); // Add expiration date if(emv_data->exp_mon) { - string_cat_printf(temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year); + furi_string_cat_printf( + temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year); } // Parse currency code if((emv_data->currency_code)) { - string_t currency_name; - string_init(currency_name); + FuriString* currency_name; + currency_name = furi_string_alloc(); if(nfc_emv_parser_get_currency_name( nfc->dev->storage, emv_data->currency_code, currency_name)) { - string_cat_printf(temp_str, "\nCur: %s ", string_get_cstr(currency_name)); + furi_string_cat_printf(temp_str, "\nCur: %s ", furi_string_get_cstr(currency_name)); } - string_clear(currency_name); + furi_string_free(currency_name); } // Parse country code if((emv_data->country_code)) { - string_t country_name; - string_init(country_name); + FuriString* country_name; + country_name = furi_string_alloc(); if(nfc_emv_parser_get_country_name( nfc->dev->storage, emv_data->country_code, country_name)) { - string_cat_printf(temp_str, "Reg: %s", string_get_cstr(country_name)); + furi_string_cat_printf(temp_str, "Reg: %s", furi_string_get_cstr(country_name)); } - string_clear(country_name); + furi_string_free(country_name); } notification_message_block(nfc->notifications, &sequence_set_green_255); - widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_generate_info.c b/applications/main/nfc/scenes/nfc_scene_generate_info.c index 7fb7eb942..66900767e 100644 --- a/applications/main/nfc/scenes/nfc_scene_generate_info.c +++ b/applications/main/nfc/scenes/nfc_scene_generate_info.c @@ -16,15 +16,15 @@ void nfc_scene_generate_info_on_enter(void* context) { dialog_ex_set_right_button_text(dialog_ex, "More"); // Create info text - string_t info_str; - string_init_printf( - info_str, "%s\n%s\nUID:", nfc->generator->name, nfc_get_dev_type(data->type)); + FuriString* info_str = furi_string_alloc_printf( + "%s\n%s\nUID:", nfc->generator->name, nfc_get_dev_type(data->type)); + // Append UID for(int i = 0; i < data->uid_len; ++i) { - string_cat_printf(info_str, " %02X", data->uid[i]); + furi_string_cat_printf(info_str, " %02X", data->uid[i]); } - nfc_text_store_set(nfc, string_get_cstr(info_str)); - string_clear(info_str); + nfc_text_store_set(nfc, furi_string_get_cstr(info_str)); + furi_string_free(info_str); dialog_ex_set_text(dialog_ex, nfc->text_store, 0, 0, AlignLeft, AlignTop); dialog_ex_set_context(dialog_ex, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c index b23f4b8f1..813546905 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c @@ -91,6 +91,7 @@ void nfc_scene_mf_classic_dict_attack_on_enter(void* context) { nfc_scene_mf_classic_dict_attack_prepare_view(nfc, DictAttackStateIdle); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDictAttack); nfc_blink_read_start(nfc); + notification_message(nfc->notifications, &sequence_display_backlight_enforce_on); } bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent event) { @@ -167,4 +168,5 @@ void nfc_scene_mf_classic_dict_attack_on_exit(void* context) { } dict_attack_reset(nfc->dict_attack); nfc_blink_stop(nfc); + notification_message(nfc->notifications, &sequence_display_backlight_enforce_auto); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_delete.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_delete.c index 16a189da6..0ea3f59a4 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_delete.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_delete.c @@ -16,8 +16,8 @@ void nfc_scene_mf_classic_keys_delete_on_enter(void* context) { uint32_t key_index = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicKeysDelete); // Setup Custom Widget view - string_t key_str; - string_init(key_str); + FuriString* key_str; + key_str = furi_string_alloc(); widget_add_string_element( nfc->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Delete this key?"); @@ -36,9 +36,15 @@ void nfc_scene_mf_classic_keys_delete_on_enter(void* context) { mf_classic_dict_get_key_at_index_str(dict, key_str, key_index); widget_add_string_element( - nfc->widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(key_str)); + nfc->widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + furi_string_get_cstr(key_str)); - string_clear(key_str); + furi_string_free(key_str); mf_classic_dict_free(dict); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c index 6670ae132..19d2f556f 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_list.c @@ -19,19 +19,19 @@ void nfc_scene_mf_classic_keys_list_popup_callback(void* context) { void nfc_scene_mf_classic_keys_list_prepare(Nfc* nfc, MfClassicDict* dict) { Submenu* submenu = nfc->submenu; uint32_t index = 0; - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); submenu_set_header(submenu, "Select key to delete:"); while(mf_classic_dict_get_next_key_str(dict, temp_key)) { char* current_key = (char*)malloc(sizeof(char) * 13); - strncpy(current_key, string_get_cstr(temp_key), 12); + strncpy(current_key, furi_string_get_cstr(temp_key), 12); MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); - FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); + FURI_LOG_D("ListKeys", "Key %ld: %s", index, current_key); submenu_add_item( submenu, current_key, index++, nfc_scene_mf_classic_keys_list_submenu_callback, nfc); } - string_clear(temp_key); + furi_string_free(temp_key); } void nfc_scene_mf_classic_keys_list_on_enter(void* context) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c index 3ca24416a..0cdb86464 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_read_success.c @@ -27,26 +27,26 @@ void nfc_scene_mf_classic_read_success_on_enter(void* context) { widget_add_button_element( widget, GuiButtonTypeRight, "More", nfc_scene_mf_classic_read_success_widget_callback, nfc); - string_t temp_str; - if(string_size(nfc->dev->dev_data.parsed_data)) { - string_init_set(temp_str, nfc->dev->dev_data.parsed_data); + FuriString* temp_str; + if(furi_string_size(nfc->dev->dev_data.parsed_data)) { + temp_str = furi_string_alloc_set(nfc->dev->dev_data.parsed_data); } else { - string_init_printf(temp_str, "\e#%s\n", nfc_mf_classic_type(mf_data->type)); - string_cat_printf(temp_str, "UID:"); + temp_str = furi_string_alloc_printf("\e#%s\n", nfc_mf_classic_type(mf_data->type)); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < dev_data->nfc_data.uid_len; i++) { - string_cat_printf(temp_str, " %02X", dev_data->nfc_data.uid[i]); + furi_string_cat_printf(temp_str, " %02X", dev_data->nfc_data.uid[i]); } uint8_t sectors_total = mf_classic_get_total_sectors_num(mf_data->type); uint8_t keys_total = sectors_total * 2; uint8_t keys_found = 0; uint8_t sectors_read = 0; mf_classic_get_read_sectors_and_keys(mf_data, §ors_read, &keys_found); - string_cat_printf(temp_str, "\nKeys Found: %d/%d", keys_found, keys_total); - string_cat_printf(temp_str, "\nSectors Read: %d/%d", sectors_read, sectors_total); + furi_string_cat_printf(temp_str, "\nKeys Found: %d/%d", keys_found, keys_total); + furi_string_cat_printf(temp_str, "\nSectors Read: %d/%d", sectors_read, sectors_total); } - widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); notification_message_block(nfc->notifications, &sequence_set_green_255); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c index dd8424641..afc5f0dee 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_app.c @@ -84,7 +84,7 @@ bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) { } else { MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); TextBox* text_box = nfc->text_box; - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); if(event.event == SubmenuIndexAppInfo) { mf_df_cat_application_info(app, nfc->text_box_store); } else { @@ -98,7 +98,7 @@ bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) { } mf_df_cat_file(file, nfc->text_box_store); } - text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); + text_box_set_text(text_box, furi_string_get_cstr(nfc->text_box_store)); scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); consumed = true; @@ -120,6 +120,6 @@ void nfc_scene_mf_desfire_app_on_exit(void* context) { // Clear views popup_reset(nfc->popup); text_box_reset(nfc->text_box); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); submenu_reset(nfc->submenu); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c index 0019a0846..e619d0377 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_data.c @@ -67,10 +67,10 @@ bool nfc_scene_mf_desfire_data_on_event(void* context, SceneManagerEvent event) if(event.type == SceneManagerEventTypeCustom) { TextBox* text_box = nfc->text_box; - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); if(event.event == SubmenuIndexCardInfo) { mf_df_cat_card_info(data, nfc->text_box_store); - text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); + text_box_set_text(text_box, furi_string_get_cstr(nfc->text_box_store)); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); scene_manager_set_scene_state( nfc->scene_manager, @@ -102,6 +102,6 @@ void nfc_scene_mf_desfire_data_on_exit(void* context) { // Clear views text_box_reset(nfc->text_box); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); submenu_reset(nfc->submenu); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c index 12047c15a..2ab0355ca 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_desfire_read_success.c @@ -20,20 +20,19 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) { Widget* widget = nfc->widget; // Prepare string for data display - string_t temp_str; - string_init_printf(temp_str, "\e#MIFARE DESfire\n"); - string_cat_printf(temp_str, "UID:"); + FuriString* temp_str = furi_string_alloc_printf("\e#MIFARE DESfire\n"); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); } uint32_t bytes_total = 1 << (data->version.sw_storage >> 1); uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - string_cat_printf(temp_str, "\n%d", bytes_total); + furi_string_cat_printf(temp_str, "\n%ld", bytes_total); if(data->version.sw_storage & 1) { - string_push_back(temp_str, '+'); + furi_string_push_back(temp_str, '+'); } - string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); + furi_string_cat_printf(temp_str, " bytes, %ld bytes free\n", bytes_free); uint16_t n_apps = 0; uint16_t n_files = 0; @@ -43,20 +42,20 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) { n_files++; } } - string_cat_printf(temp_str, "%d Application", n_apps); + furi_string_cat_printf(temp_str, "%d Application", n_apps); if(n_apps != 1) { - string_push_back(temp_str, 's'); + furi_string_push_back(temp_str, 's'); } - string_cat_printf(temp_str, ", %d file", n_files); + furi_string_cat_printf(temp_str, ", %d file", n_files); if(n_files != 1) { - string_push_back(temp_str, 's'); + furi_string_push_back(temp_str, 's'); } notification_message_block(nfc->notifications, &sequence_set_green_255); // Add text scroll element - widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); // Add button elements widget_add_button_element( diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_data.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_data.c index d4184a6b4..8cd223ee6 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_data.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_data.c @@ -8,11 +8,11 @@ void nfc_scene_mf_ultralight_data_on_enter(void* context) { text_box_set_font(text_box, TextBoxFontHex); for(uint16_t i = 0; i < data->data_size; i += 2) { if(!(i % 8) && i) { - string_push_back(nfc->text_box_store, '\n'); + furi_string_push_back(nfc->text_box_store, '\n'); } - string_cat_printf(nfc->text_box_store, "%02X%02X ", data->data[i], data->data[i + 1]); + furi_string_cat_printf(nfc->text_box_store, "%02X%02X ", data->data[i], data->data[i + 1]); } - text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); + text_box_set_text(text_box, furi_string_get_cstr(nfc->text_box_store)); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); } @@ -28,5 +28,5 @@ void nfc_scene_mf_ultralight_data_on_exit(void* context) { // Clean view text_box_reset(nfc->text_box); - string_reset(nfc->text_box_store); + furi_string_reset(nfc->text_box_store); } \ No newline at end of file diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c index b94215455..f0c53c9ba 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_auth_result.c @@ -21,8 +21,8 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { MfUltralightData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; MfUltralightConfigPages* config_pages = mf_ultralight_get_config_pages(mf_ul_data); Widget* widget = nfc->widget; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); if((mf_ul_data->data_read == mf_ul_data->data_size) && (mf_ul_data->data_read > 0)) { widget_add_string_element( @@ -31,14 +31,14 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { widget_add_string_element( widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Not all pages unlocked!"); } - string_set_str(temp_str, "UID:"); + furi_string_set(temp_str, "UID:"); for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); } widget_add_string_element( - widget, 0, 17, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); + widget, 0, 17, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); if(mf_ul_data->auth_success) { - string_printf( + furi_string_printf( temp_str, "Password: %02X %02X %02X %02X", config_pages->auth_data.pwd.raw[0], @@ -46,19 +46,19 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { config_pages->auth_data.pwd.raw[2], config_pages->auth_data.pwd.raw[3]); widget_add_string_element( - widget, 0, 28, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); - string_printf( + widget, 0, 28, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); + furi_string_printf( temp_str, "PACK: %02X %02X", config_pages->auth_data.pack.raw[0], config_pages->auth_data.pack.raw[1]); widget_add_string_element( - widget, 0, 39, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); + widget, 0, 39, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); } - string_printf( + furi_string_printf( temp_str, "Pages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4); widget_add_string_element( - widget, 0, 50, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); + widget, 0, 50, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); widget_add_button_element( widget, GuiButtonTypeRight, @@ -66,7 +66,7 @@ void nfc_scene_mf_ultralight_read_auth_result_on_enter(void* context) { nfc_scene_mf_ultralight_read_auth_result_widget_callback, nfc); - string_clear(temp_str); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c index f6dc5984e..77034ea80 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_read_success.c @@ -33,23 +33,23 @@ void nfc_scene_mf_ultralight_read_success_on_enter(void* context) { nfc_scene_mf_ultralight_read_success_widget_callback, nfc); - string_t temp_str; - if(string_size(nfc->dev->dev_data.parsed_data)) { - string_init_set(temp_str, nfc->dev->dev_data.parsed_data); + FuriString* temp_str; + if(furi_string_size(nfc->dev->dev_data.parsed_data)) { + temp_str = furi_string_alloc_set(nfc->dev->dev_data.parsed_data); } else { - string_init_printf(temp_str, "\e#%s\n", nfc_mf_ul_type(mf_ul_data->type, true)); - string_cat_printf(temp_str, "UID:"); + temp_str = furi_string_alloc_printf("\e#%s\n", nfc_mf_ul_type(mf_ul_data->type, true)); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", data->uid[i]); } - string_cat_printf( + furi_string_cat_printf( temp_str, "\nPages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4); if(mf_ul_data->data_read != mf_ul_data->data_size) { - string_cat_printf(temp_str, "\nPassword-protected pages!"); + furi_string_cat_printf(temp_str, "\nPassword-protected pages!"); } } - widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); notification_message_block(nfc->notifications, &sequence_set_green_255); diff --git a/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c b/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c index b45b690d3..6d9852f3e 100644 --- a/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c +++ b/applications/main/nfc/scenes/nfc_scene_mfkey_nonces_info.c @@ -11,21 +11,21 @@ void nfc_scene_mfkey_nonces_info_callback(GuiButtonType result, InputType type, void nfc_scene_mfkey_nonces_info_on_enter(void* context) { Nfc* nfc = context; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint16_t nonces_saved = mfkey32_get_auth_sectors(temp_str); - widget_add_text_scroll_element(nfc->widget, 0, 22, 128, 42, string_get_cstr(temp_str)); - string_printf(temp_str, "Nonces saved %d", nonces_saved); + widget_add_text_scroll_element(nfc->widget, 0, 22, 128, 42, furi_string_get_cstr(temp_str)); + furi_string_printf(temp_str, "Nonce pairs saved: %d", nonces_saved); widget_add_string_element( - nfc->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, string_get_cstr(temp_str)); + nfc->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, furi_string_get_cstr(temp_str)); widget_add_string_element( nfc->widget, 0, 12, AlignLeft, AlignTop, FontSecondary, "Authenticated sectors:"); widget_add_button_element( - nfc->widget, GuiButtonTypeRight, "Next", nfc_scene_mfkey_nonces_info_callback, nfc); + nfc->widget, GuiButtonTypeCenter, "OK", nfc_scene_mfkey_nonces_info_callback, nfc); - string_clear(temp_str); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } @@ -35,7 +35,7 @@ bool nfc_scene_mfkey_nonces_info_on_event(void* context, SceneManagerEvent event bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeRight) { + if(event.event == GuiButtonTypeCenter) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfkeyComplete); consumed = true; } diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index c1c486a8a..a7ed8eb37 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -22,49 +22,50 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { text_scroll_height = 64; } - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); // Set name if present if(nfc->dev->dev_name[0] != '\0') { - string_printf(temp_str, "\ec%s\n", nfc->dev->dev_name); + furi_string_printf(temp_str, "\ec%s\n", nfc->dev->dev_name); } // Set tag type if(protocol == NfcDeviceProtocolEMV) { - string_cat_printf(temp_str, "\e#EMV Bank Card\n"); + furi_string_cat_printf(temp_str, "\e#EMV Bank Card\n"); } else if(protocol == NfcDeviceProtocolMRTD) { - string_cat_printf(temp_str, "\e#Passport/ID\n"); + furi_string_cat_printf(temp_str, "\e#Passport/ID\n"); } else if(protocol == NfcDeviceProtocolMifareUl) { - string_cat_printf(temp_str, "\e#%s\n", nfc_mf_ul_type(dev_data->mf_ul_data.type, true)); + furi_string_cat_printf( + temp_str, "\e#%s\n", nfc_mf_ul_type(dev_data->mf_ul_data.type, true)); } else if(protocol == NfcDeviceProtocolMifareClassic) { - string_cat_printf( + furi_string_cat_printf( temp_str, "\e#%s\n", nfc_mf_classic_type(dev_data->mf_classic_data.type)); } else if(protocol == NfcDeviceProtocolMifareDesfire) { - string_cat_printf(temp_str, "\e#MIFARE DESfire\n"); + furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n"); } else { - string_cat_printf(temp_str, "\e#Unknown ISO tag\n"); + furi_string_cat_printf(temp_str, "\e#Unknown ISO tag\n"); } // Set tag iso data char iso_type = FURI_BIT(nfc_data->sak, 5) ? '4' : '3'; - string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); - string_cat_printf(temp_str, "UID:"); + furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < nfc_data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); } - string_cat_printf(temp_str, "\nATQA: %02X %02X ", nfc_data->atqa[1], nfc_data->atqa[0]); - string_cat_printf(temp_str, " SAK: %02X", nfc_data->sak); + furi_string_cat_printf(temp_str, "\nATQA: %02X %02X ", nfc_data->atqa[1], nfc_data->atqa[0]); + furi_string_cat_printf(temp_str, " SAK: %02X", nfc_data->sak); // Set application specific data if(protocol == NfcDeviceProtocolMifareDesfire) { MifareDesfireData* data = &dev_data->mf_df_data; uint32_t bytes_total = 1 << (data->version.sw_storage >> 1); uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0; - string_cat_printf(temp_str, "\n%d", bytes_total); + furi_string_cat_printf(temp_str, "\n%ld", bytes_total); if(data->version.sw_storage & 1) { - string_push_back(temp_str, '+'); + furi_string_push_back(temp_str, '+'); } - string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free); + furi_string_cat_printf(temp_str, " bytes, %ld bytes free\n", bytes_free); uint16_t n_apps = 0; uint16_t n_files = 0; @@ -74,20 +75,20 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { n_files++; } } - string_cat_printf(temp_str, "%d Application", n_apps); + furi_string_cat_printf(temp_str, "%d Application", n_apps); if(n_apps != 1) { - string_push_back(temp_str, 's'); + furi_string_push_back(temp_str, 's'); } - string_cat_printf(temp_str, ", %d file", n_files); + furi_string_cat_printf(temp_str, ", %d file", n_files); if(n_files != 1) { - string_push_back(temp_str, 's'); + furi_string_push_back(temp_str, 's'); } } else if(protocol == NfcDeviceProtocolMifareUl) { MfUltralightData* data = &dev_data->mf_ul_data; - string_cat_printf( + furi_string_cat_printf( temp_str, "\nPages Read %d/%d", data->data_read / 4, data->data_size / 4); if(data->data_size > data->data_read) { - string_cat_printf(temp_str, "\nPassword-protected"); + furi_string_cat_printf(temp_str, "\nPassword-protected"); } } else if(protocol == NfcDeviceProtocolMifareClassic) { MfClassicData* data = &dev_data->mf_classic_data; @@ -96,14 +97,14 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { uint8_t keys_found = 0; uint8_t sectors_read = 0; mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found); - string_cat_printf(temp_str, "\nKeys Found %d/%d", keys_found, keys_total); - string_cat_printf(temp_str, "\nSectors Read %d/%d", sectors_read, sectors_total); + furi_string_cat_printf(temp_str, "\nKeys Found %d/%d", keys_found, keys_total); + furi_string_cat_printf(temp_str, "\nSectors Read %d/%d", sectors_read, sectors_total); } // Add text scroll widget widget_add_text_scroll_element( - widget, 0, 0, 128, text_scroll_height, string_get_cstr(temp_str)); - string_clear(temp_str); + widget, 0, 0, 128, text_scroll_height, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_nfca_read_success.c b/applications/main/nfc/scenes/nfc_scene_nfca_read_success.c index c695da247..2ea7c9921 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfca_read_success.c +++ b/applications/main/nfc/scenes/nfc_scene_nfca_read_success.c @@ -22,22 +22,22 @@ void nfc_scene_nfca_read_success_on_enter(void* context) { FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; - string_t temp_str; - string_init_set_str(temp_str, "\e#Unknown ISO tag\n"); + FuriString* temp_str; + temp_str = furi_string_alloc_set("\e#Unknown ISO tag\n"); notification_message_block(nfc->notifications, &sequence_set_green_255); char iso_type = FURI_BIT(data->sak, 5) ? '4' : '3'; - string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); - string_cat_printf(temp_str, "UID:"); + furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type); + furi_string_cat_printf(temp_str, "UID:"); for(size_t i = 0; i < data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", data->uid[i]); } - string_cat_printf(temp_str, "\nATQA: %02X %02X ", data->atqa[1], data->atqa[0]); - string_cat_printf(temp_str, " SAK: %02X", data->sak); + furi_string_cat_printf(temp_str, "\nATQA: %02X %02X ", data->atqa[1], data->atqa[0]); + furi_string_cat_printf(temp_str, " SAK: %02X", data->sak); - widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str)); - string_clear(temp_str); + widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); widget_add_button_element( widget, GuiButtonTypeLeft, "Retry", nfc_scene_nfca_read_success_widget_callback, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_read_card_success.c b/applications/main/nfc/scenes/nfc_scene_read_card_success.c index 0cb38cbdf..352cb4a7e 100644 --- a/applications/main/nfc/scenes/nfc_scene_read_card_success.c +++ b/applications/main/nfc/scenes/nfc_scene_read_card_success.c @@ -16,26 +16,26 @@ void nfc_scene_read_card_success_widget_callback( void nfc_scene_read_card_success_on_enter(void* context) { Nfc* nfc = context; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); // Setup view FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; - string_set_str(temp_str, nfc_get_dev_type(data->type)); + furi_string_set(temp_str, nfc_get_dev_type(data->type)); widget_add_string_element( - widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, string_get_cstr(temp_str)); - string_set_str(temp_str, "UID:"); + widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, furi_string_get_cstr(temp_str)); + furi_string_set(temp_str, "UID:"); for(uint8_t i = 0; i < data->uid_len; i++) { - string_cat_printf(temp_str, " %02X", data->uid[i]); + furi_string_cat_printf(temp_str, " %02X", data->uid[i]); } widget_add_string_element( - widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(temp_str)); + widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(temp_str)); widget_add_button_element( widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_card_success_widget_callback, nfc); - string_clear(temp_str); + furi_string_free(temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } diff --git a/applications/main/nfc/scenes/nfc_scene_save_name.c b/applications/main/nfc/scenes/nfc_scene_save_name.c index d5e05472a..736eab7de 100644 --- a/applications/main/nfc/scenes/nfc_scene_save_name.c +++ b/applications/main/nfc/scenes/nfc_scene_save_name.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "m-string.h" #include #include #include @@ -31,22 +30,22 @@ void nfc_scene_save_name_on_enter(void* context) { NFC_DEV_NAME_MAX_LEN, dev_name_empty); - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - if(string_end_with_str_p(nfc->dev->load_path, NFC_APP_EXTENSION)) { - path_extract_dirname(string_get_cstr(nfc->dev->load_path), folder_path); + if(furi_string_end_with(nfc->dev->load_path, NFC_APP_EXTENSION)) { + path_extract_dirname(furi_string_get_cstr(nfc->dev->load_path), folder_path); } else { - string_set_str(folder_path, NFC_APP_FOLDER); + furi_string_set(folder_path, NFC_APP_FOLDER); } ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), NFC_APP_EXTENSION, nfc->dev->dev_name); + furi_string_get_cstr(folder_path), NFC_APP_EXTENSION, nfc->dev->dev_name); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); - string_clear(folder_path); + furi_string_free(folder_path); } bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_saved_menu.c b/applications/main/nfc/scenes/nfc_scene_saved_menu.c index c1043b3a7..fe65b5b8a 100644 --- a/applications/main/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_saved_menu.c @@ -20,8 +20,7 @@ void nfc_scene_saved_menu_on_enter(void* context) { Submenu* submenu = nfc->submenu; if(nfc->dev->format == NfcDeviceSaveFormatUid || - nfc->dev->format == NfcDeviceSaveFormatMifareDesfire || - nfc->dev->format == NfcDeviceSaveFormatBankCard) { + nfc->dev->format == NfcDeviceSaveFormatMifareDesfire) { submenu_add_item( submenu, "Emulate UID", diff --git a/applications/main/nfc/scenes/nfc_scene_set_type.c b/applications/main/nfc/scenes/nfc_scene_set_type.c index ec6d11447..3e08aeb3f 100644 --- a/applications/main/nfc/scenes/nfc_scene_set_type.c +++ b/applications/main/nfc/scenes/nfc_scene_set_type.c @@ -1,5 +1,4 @@ #include "../nfc_i.h" -#include "m-string.h" #include "../helpers/nfc_generators.h" enum SubmenuIndex { @@ -19,7 +18,7 @@ void nfc_scene_set_type_on_enter(void* context) { Submenu* submenu = nfc->submenu; // Clear device name nfc_device_set_name(nfc->dev, ""); - string_set_str(nfc->dev->load_path, ""); + furi_string_set(nfc->dev->load_path, ""); submenu_add_item( submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc); submenu_add_item( diff --git a/applications/main/nfc/views/detect_reader.c b/applications/main/nfc/views/detect_reader.c index 177c13f75..2dbb4338b 100644 --- a/applications/main/nfc/views/detect_reader.c +++ b/applications/main/nfc/views/detect_reader.c @@ -10,29 +10,50 @@ struct DetectReader { typedef struct { uint16_t nonces; + uint16_t nonces_max; + DetectReaderState state; } DetectReaderViewModel; static void detect_reader_draw_callback(Canvas* canvas, void* model) { DetectReaderViewModel* m = model; char text[32] = {}; - snprintf(text, sizeof(text), "Tap the reader several times"); - canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, "Tap the reader several times"); + // Draw header and icon + canvas_draw_icon(canvas, 0, 16, &I_Modern_reader_18x34); + if(m->state == DetectReaderStateStart) { + snprintf(text, sizeof(text), "Touch the reader"); + canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39); + } else if(m->state == DetectReaderStateReaderDetected) { + snprintf(text, sizeof(text), "Move the Flipper away"); + canvas_draw_icon(canvas, 24, 25, &I_Release_arrow_18x15); + } else if(m->state == DetectReaderStateReaderLost) { + snprintf(text, sizeof(text), "Touch the reader again"); + canvas_draw_icon(canvas, 21, 13, &I_Move_flipper_26x39); + } - if(m->nonces == 0) { + canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, text); + + // Draw collected nonces + if(m->state == DetectReaderStateStart) { canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 52, 22, AlignLeft, AlignTop, "Emulating..."); + canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Emulating..."); canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 52, 35, AlignLeft, AlignTop, "MIFARE Classic"); - canvas_draw_icon(canvas, 0, 13, &I_Tap_reader_36x38); + canvas_draw_str_aligned(canvas, 51, 35, AlignLeft, AlignTop, "MIFARE MFkey32"); } else { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 54, 22, AlignLeft, AlignTop, "Collecting..."); + if(m->state == DetectReaderStateDone) { + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Completed!"); + } else { + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas, 51, 22, AlignLeft, AlignTop, "Collecting..."); + } canvas_set_font(canvas, FontSecondary); - snprintf(text, sizeof(text), "Nonces: %d", m->nonces); - canvas_draw_str_aligned(canvas, 54, 35, AlignLeft, AlignTop, text); - elements_button_right(canvas, "Next"); - canvas_draw_icon(canvas, 6, 15, &I_ArrowC_1_36x36); + snprintf(text, sizeof(text), "Nonce pairs: %d/%d", m->nonces, m->nonces_max); + canvas_draw_str_aligned(canvas, 51, 35, AlignLeft, AlignTop, text); + } + // Draw button + if(m->nonces > 0) { + elements_button_center(canvas, "Done"); } } @@ -43,13 +64,10 @@ static bool detect_reader_input_callback(InputEvent* event, void* context) { uint8_t nonces = 0; with_view_model( - detect_reader->view, (DetectReaderViewModel * model) { - nonces = model->nonces; - return false; - }); + detect_reader->view, DetectReaderViewModel * model, { nonces = model->nonces; }, false); if(event->type == InputTypeShort) { - if(event->key == InputKeyRight) { + if(event->key == InputKeyOk) { if(nonces > 0) { detect_reader->callback(detect_reader->context); consumed = true; @@ -82,10 +100,14 @@ void detect_reader_reset(DetectReader* detect_reader) { furi_assert(detect_reader); with_view_model( - detect_reader->view, (DetectReaderViewModel * model) { + detect_reader->view, + DetectReaderViewModel * model, + { model->nonces = 0; - return false; - }); + model->nonces_max = 0; + model->state = DetectReaderStateStart; + }, + false); } View* detect_reader_get_view(DetectReader* detect_reader) { @@ -105,11 +127,28 @@ void detect_reader_set_callback( detect_reader->context = context; } -void detect_reader_inc_nonce_cnt(DetectReader* detect_reader) { +void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_max) { + furi_assert(detect_reader); + + with_view_model( + detect_reader->view, + DetectReaderViewModel * model, + { model->nonces_max = nonces_max; }, + false); +} + +void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected) { + furi_assert(detect_reader); + + with_view_model( + detect_reader->view, + DetectReaderViewModel * model, + { model->nonces = nonces_collected; }, + false); +} + +void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state) { furi_assert(detect_reader); with_view_model( - detect_reader->view, (DetectReaderViewModel * model) { - model->nonces++; - return false; - }); + detect_reader->view, DetectReaderViewModel * model, { model->state = state; }, true); } diff --git a/applications/main/nfc/views/detect_reader.h b/applications/main/nfc/views/detect_reader.h index 12cd03db4..aabdd7c87 100644 --- a/applications/main/nfc/views/detect_reader.h +++ b/applications/main/nfc/views/detect_reader.h @@ -5,6 +5,13 @@ typedef struct DetectReader DetectReader; +typedef enum { + DetectReaderStateStart, + DetectReaderStateReaderDetected, + DetectReaderStateReaderLost, + DetectReaderStateDone, +} DetectReaderState; + typedef void (*DetectReaderDoneCallback)(void* context); DetectReader* detect_reader_alloc(); @@ -20,4 +27,8 @@ void detect_reader_set_callback( DetectReaderDoneCallback callback, void* context); -void detect_reader_inc_nonce_cnt(DetectReader* detect_reader); +void detect_reader_set_nonces_max(DetectReader* detect_reader, uint16_t nonces_max); + +void detect_reader_set_nonces_collected(DetectReader* detect_reader, uint16_t nonces_collected); + +void detect_reader_set_state(DetectReader* detect_reader, DetectReaderState state); diff --git a/applications/main/nfc/views/dict_attack.c b/applications/main/nfc/views/dict_attack.c index b4674fd31..c5f55ae76 100644 --- a/applications/main/nfc/views/dict_attack.c +++ b/applications/main/nfc/views/dict_attack.c @@ -1,6 +1,5 @@ #include "dict_attack.h" -#include #include typedef enum { @@ -17,7 +16,7 @@ struct DictAttack { typedef struct { DictAttackState state; MfClassicType type; - string_t header; + FuriString* header; uint8_t sectors_total; uint8_t sectors_read; uint8_t sector_current; @@ -38,7 +37,8 @@ static void dict_attack_draw_callback(Canvas* canvas, void* model) { } else if(m->state == DictAttackStateRead) { char draw_str[32] = {}; canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 2, AlignCenter, AlignTop, string_get_cstr(m->header)); + canvas_draw_str_aligned( + canvas, 64, 2, AlignCenter, AlignTop, furi_string_get_cstr(m->header)); canvas_set_font(canvas, FontSecondary); float dict_progress = m->dict_keys_total == 0 ? 0 : @@ -80,20 +80,20 @@ DictAttack* dict_attack_alloc() { view_set_input_callback(dict_attack->view, dict_attack_input_callback); view_set_context(dict_attack->view, dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - string_init(model->header); - return false; - }); + dict_attack->view, + DictAttackViewModel * model, + { model->header = furi_string_alloc(); }, + false); return dict_attack; } void dict_attack_free(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - string_clear(model->header); - return false; - }); + dict_attack->view, + DictAttackViewModel * model, + { furi_string_free(model->header); }, + false); view_free(dict_attack->view); free(dict_attack); } @@ -101,7 +101,9 @@ void dict_attack_free(DictAttack* dict_attack) { void dict_attack_reset(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { model->state = DictAttackStateRead; model->type = MfClassicType1k; model->sectors_total = 0; @@ -111,9 +113,9 @@ void dict_attack_reset(DictAttack* dict_attack) { model->keys_found = 0; model->dict_keys_total = 0; model->dict_keys_current = 0; - string_reset(model->header); - return false; - }); + furi_string_reset(model->header); + }, + false); } View* dict_attack_get_view(DictAttack* dict_attack) { @@ -133,99 +135,103 @@ void dict_attack_set_header(DictAttack* dict_attack, const char* header) { furi_assert(header); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - string_set_str(model->header, header); - return true; - }); + dict_attack->view, + DictAttackViewModel * model, + { furi_string_set(model->header, header); }, + true); } void dict_attack_set_card_detected(DictAttack* dict_attack, MfClassicType type) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { model->state = DictAttackStateRead; model->sectors_total = mf_classic_get_total_sectors_num(type); model->keys_total = model->sectors_total * 2; - return true; - }); + }, + true); } void dict_attack_set_card_removed(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->state = DictAttackStateCardRemoved; - return true; - }); + dict_attack->view, + DictAttackViewModel * model, + { model->state = DictAttackStateCardRemoved; }, + true); } void dict_attack_set_sector_read(DictAttack* dict_attack, uint8_t sec_read) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->sectors_read = sec_read; - return true; - }); + dict_attack->view, DictAttackViewModel * model, { model->sectors_read = sec_read; }, true); } void dict_attack_set_keys_found(DictAttack* dict_attack, uint8_t keys_found) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->keys_found = keys_found; - return true; - }); + dict_attack->view, DictAttackViewModel * model, { model->keys_found = keys_found; }, true); } void dict_attack_set_current_sector(DictAttack* dict_attack, uint8_t curr_sec) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { model->sector_current = curr_sec; model->dict_keys_current = 0; - return true; - }); + }, + true); } void dict_attack_inc_current_sector(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { if(model->sector_current < model->sectors_total) { model->sector_current++; model->dict_keys_current = 0; } - return true; - }); + }, + true); } void dict_attack_inc_keys_found(DictAttack* dict_attack) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { if(model->keys_found < model->keys_total) { model->keys_found++; } - return true; - }); + }, + true); } void dict_attack_set_total_dict_keys(DictAttack* dict_attack, uint16_t dict_keys_total) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { - model->dict_keys_total = dict_keys_total; - return true; - }); + dict_attack->view, + DictAttackViewModel * model, + { model->dict_keys_total = dict_keys_total; }, + true); } void dict_attack_inc_current_dict_key(DictAttack* dict_attack, uint16_t keys_tried) { furi_assert(dict_attack); with_view_model( - dict_attack->view, (DictAttackViewModel * model) { + dict_attack->view, + DictAttackViewModel * model, + { if(model->dict_keys_current + keys_tried < model->dict_keys_total) { model->dict_keys_current += keys_tried; } - return true; - }); + }, + true); } diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c index 10c5a9ea8..0341990d8 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.c @@ -71,6 +71,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { .frequency_coarse = 0, .rssi_coarse = 0, .frequency_fine = 0, .rssi_fine = 0}; float rssi = 0; uint32_t frequency = 0; + float rssi_temp = 0; + uint32_t frequency_temp = 0; CC1101Status status; //Start CC1101 @@ -147,7 +149,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { FURI_LOG_T( TAG, - "RSSI: avg %f, max %f at %u, min %f", + "RSSI: avg %f, max %f at %lu, min %f", (double)(rssi_avg / rssi_avg_samples), (double)frequency_rssi.rssi_coarse, frequency_rssi.frequency_coarse, @@ -178,7 +180,7 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { rssi = furi_hal_subghz_get_rssi(); - FURI_LOG_T(TAG, "#:%u:%f", frequency, (double)rssi); + FURI_LOG_T(TAG, "#:%lu:%f", frequency, (double)rssi); if(frequency_rssi.rssi_fine < rssi) { frequency_rssi.rssi_fine = rssi; @@ -191,9 +193,12 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { // Deliver results fine if(frequency_rssi.rssi_fine > SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD) { FURI_LOG_D( - TAG, "=:%u:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); + TAG, "=:%lu:%f", frequency_rssi.frequency_fine, (double)frequency_rssi.rssi_fine); instance->sample_hold_counter = 20; + rssi_temp = frequency_rssi.rssi_fine; + frequency_temp = frequency_rssi.frequency_fine; + if(instance->filVal) { frequency_rssi.frequency_fine = subghz_frequency_analyzer_worker_expRunningAverageAdaptive( @@ -202,18 +207,23 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { // Deliver callback if(instance->pair_callback) { instance->pair_callback( - instance->context, frequency_rssi.frequency_fine, frequency_rssi.rssi_fine); + instance->context, + frequency_rssi.frequency_fine, + frequency_rssi.rssi_fine, + true); } } else if( // Deliver results coarse (frequency_rssi.rssi_coarse > SUBGHZ_FREQUENCY_ANALYZER_THRESHOLD) && (instance->sample_hold_counter < 10)) { FURI_LOG_D( TAG, - "~:%u:%f", + "~:%lu:%f", frequency_rssi.frequency_coarse, (double)frequency_rssi.rssi_coarse); instance->sample_hold_counter = 20; + rssi_temp = frequency_rssi.rssi_coarse; + frequency_temp = frequency_rssi.frequency_coarse; if(instance->filVal) { frequency_rssi.frequency_coarse = subghz_frequency_analyzer_worker_expRunningAverageAdaptive( @@ -224,14 +234,22 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) { instance->pair_callback( instance->context, frequency_rssi.frequency_coarse, - frequency_rssi.rssi_coarse); + frequency_rssi.rssi_coarse, + true); } } else { if(instance->sample_hold_counter > 0) { instance->sample_hold_counter--; + if(instance->sample_hold_counter == 18) { + if(instance->pair_callback) { + instance->pair_callback( + instance->context, frequency_temp, rssi_temp, false); + } + } } else { instance->filVal = 0; - if(instance->pair_callback) instance->pair_callback(instance->context, 0, 0); + if(instance->pair_callback) + instance->pair_callback(instance->context, 0, 0, false); } } } diff --git a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h index 50687c76d..8bd1addc4 100644 --- a/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h +++ b/applications/main/subghz/helpers/subghz_frequency_analyzer_worker.h @@ -5,8 +5,11 @@ typedef struct SubGhzFrequencyAnalyzerWorker SubGhzFrequencyAnalyzerWorker; -typedef void ( - *SubGhzFrequencyAnalyzerWorkerPairCallback)(void* context, uint32_t frequency, float rssi); +typedef void (*SubGhzFrequencyAnalyzerWorkerPairCallback)( + void* context, + uint32_t frequency, + float rssi, + bool signal); typedef struct { uint32_t frequency_coarse; diff --git a/applications/main/subghz/helpers/subghz_types.h b/applications/main/subghz/helpers/subghz_types.h index 7fe1e7ce7..023fb4b6f 100644 --- a/applications/main/subghz/helpers/subghz_types.h +++ b/applications/main/subghz/helpers/subghz_types.h @@ -1,6 +1,5 @@ #pragma once -#include "m-string.h" #include #include @@ -72,7 +71,7 @@ typedef enum { } SubGhzViewId; struct SubGhzPresetDefinition { - string_t name; + FuriString* name; uint32_t frequency; uint8_t* data; size_t data_size; diff --git a/applications/main/subghz/scenes/subghz_scene_delete.c b/applications/main/subghz/scenes/subghz_scene_delete.c index 43151de20..94814b143 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete.c +++ b/applications/main/subghz/scenes/subghz_scene_delete.c @@ -11,17 +11,23 @@ void subghz_scene_delete_callback(GuiButtonType result, InputType type, void* co void subghz_scene_delete_on_enter(void* context) { SubGhz* subghz = context; - string_t frequency_str; - string_t modulation_str; - string_t text; + FuriString* frequency_str; + FuriString* modulation_str; + FuriString* text; - string_init(frequency_str); - string_init(modulation_str); - string_init(text); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); + text = furi_string_alloc(); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); widget_add_string_element( - subghz->widget, 78, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(frequency_str)); + subghz->widget, + 78, + 0, + AlignLeft, + AlignTop, + FontSecondary, + furi_string_get_cstr(frequency_str)); widget_add_string_element( subghz->widget, @@ -30,14 +36,14 @@ void subghz_scene_delete_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - string_get_cstr(modulation_str)); + furi_string_get_cstr(modulation_str)); subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, text); widget_add_string_multiline_element( - subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(text)); + subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(text)); - string_clear(frequency_str); - string_clear(modulation_str); - string_clear(text); + furi_string_free(frequency_str); + furi_string_free(modulation_str); + furi_string_free(text); widget_add_button_element( subghz->widget, GuiButtonTypeRight, "Delete", subghz_scene_delete_callback, subghz); @@ -49,7 +55,7 @@ bool subghz_scene_delete_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneDelete) { - string_set(subghz->file_path_tmp, subghz->file_path); + furi_string_set(subghz->file_path_tmp, subghz->file_path); if(subghz_delete_file(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); } else { diff --git a/applications/main/subghz/scenes/subghz_scene_delete_raw.c b/applications/main/subghz/scenes/subghz_scene_delete_raw.c index a20968d5b..fa4fc6f64 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_delete_raw.c @@ -15,18 +15,18 @@ void subghz_scene_delete_raw_callback(GuiButtonType result, InputType type, void void subghz_scene_delete_raw_on_enter(void* context) { SubGhz* subghz = context; - string_t frequency_str; - string_t modulation_str; + FuriString* frequency_str; + FuriString* modulation_str; - string_init(frequency_str); - string_init(modulation_str); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); char delete_str[SUBGHZ_MAX_LEN_NAME + 16]; - string_t file_name; - string_init(file_name); + FuriString* file_name; + file_name = furi_string_alloc(); path_extract_filename(subghz->file_path, file_name, true); - snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", string_get_cstr(file_name)); - string_clear(file_name); + snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", furi_string_get_cstr(file_name)); + furi_string_free(file_name); widget_add_text_box_element( subghz->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str, false); @@ -35,7 +35,13 @@ void subghz_scene_delete_raw_on_enter(void* context) { subghz->widget, 38, 25, AlignLeft, AlignTop, FontSecondary, "RAW signal"); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); widget_add_string_element( - subghz->widget, 35, 37, AlignLeft, AlignTop, FontSecondary, string_get_cstr(frequency_str)); + subghz->widget, + 35, + 37, + AlignLeft, + AlignTop, + FontSecondary, + furi_string_get_cstr(frequency_str)); widget_add_string_element( subghz->widget, @@ -44,10 +50,10 @@ void subghz_scene_delete_raw_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - string_get_cstr(modulation_str)); + furi_string_get_cstr(modulation_str)); - string_clear(frequency_str); - string_clear(modulation_str); + furi_string_free(frequency_str); + furi_string_free(modulation_str); widget_add_button_element( subghz->widget, GuiButtonTypeRight, "Delete", subghz_scene_delete_raw_callback, subghz); @@ -61,7 +67,7 @@ bool subghz_scene_delete_raw_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneDeleteRAW) { - string_set(subghz->file_path_tmp, subghz->file_path); + furi_string_set(subghz->file_path_tmp, subghz->file_path); if(subghz_delete_file(subghz)) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); } else { diff --git a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c index b42acd4d2..9595c61be 100644 --- a/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c +++ b/applications/main/subghz/scenes/subghz_scene_frequency_analyzer.c @@ -21,6 +21,8 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneAnalyzerLock) { notification_message(subghz->notifications, &sequence_set_green_255); + notification_message(subghz->notifications, &sequence_single_vibro); + notification_message(subghz->notifications, &sequence_display_backlight_on); return true; } else if(event.event == SubGhzCustomEventSceneAnalyzerUnlock) { notification_message(subghz->notifications, &sequence_reset_rgb); diff --git a/applications/main/subghz/scenes/subghz_scene_more_raw.c b/applications/main/subghz/scenes/subghz_scene_more_raw.c index a5bade927..d75ab13c7 100644 --- a/applications/main/subghz/scenes/subghz_scene_more_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_more_raw.c @@ -45,7 +45,7 @@ bool subghz_scene_more_raw_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteRAW); return true; } else if(event.event == SubmenuIndexEdit) { - string_reset(subghz->file_path_tmp); + furi_string_reset(subghz->file_path_tmp); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneMoreRAW, SubmenuIndexEdit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 38b73e07d..5dacefd66 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -10,8 +10,8 @@ bool subghz_scene_read_raw_update_filename(SubGhz* subghz) { bool ret = false; //set the path to read the file - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { if(!flipper_format_rewind(subghz->txrx->fff_data)) { FURI_LOG_E(TAG, "Rewind error"); @@ -23,12 +23,12 @@ bool subghz_scene_read_raw_update_filename(SubGhz* subghz) { break; } - string_set(subghz->file_path, temp_str); + furi_string_set(subghz->file_path, temp_str); ret = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return ret; } @@ -36,18 +36,20 @@ static void subghz_scene_read_raw_update_statusbar(void* context) { furi_assert(context); SubGhz* subghz = context; - string_t frequency_str; - string_t modulation_str; + FuriString* frequency_str; + FuriString* modulation_str; - string_init(frequency_str); - string_init(modulation_str); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); subghz_read_raw_add_data_statusbar( - subghz->subghz_read_raw, string_get_cstr(frequency_str), string_get_cstr(modulation_str)); + subghz->subghz_read_raw, + furi_string_get_cstr(frequency_str), + furi_string_get_cstr(modulation_str)); - string_clear(frequency_str); - string_clear(modulation_str); + furi_string_free(frequency_str); + furi_string_free(modulation_str); } void subghz_scene_read_raw_callback(SubGhzCustomEvent event, void* context) { @@ -65,8 +67,8 @@ void subghz_scene_read_raw_callback_end_tx(void* context) { void subghz_scene_read_raw_on_enter(void* context) { SubGhz* subghz = context; - string_t file_name; - string_init(file_name); + FuriString* file_name; + file_name = furi_string_alloc(); switch(subghz->txrx->rx_key_state) { case SubGhzRxKeyStateBack: @@ -75,13 +77,15 @@ void subghz_scene_read_raw_on_enter(void* context) { case SubGhzRxKeyStateRAWLoad: path_extract_filename(subghz->file_path, file_name, true); subghz_read_raw_set_status( - subghz->subghz_read_raw, SubGhzReadRAWStatusLoadKeyTX, string_get_cstr(file_name)); + subghz->subghz_read_raw, + SubGhzReadRAWStatusLoadKeyTX, + furi_string_get_cstr(file_name)); subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; break; case SubGhzRxKeyStateRAWSave: path_extract_filename(subghz->file_path, file_name, true); subghz_read_raw_set_status( - subghz->subghz_read_raw, SubGhzReadRAWStatusSaveKey, string_get_cstr(file_name)); + subghz->subghz_read_raw, SubGhzReadRAWStatusSaveKey, furi_string_get_cstr(file_name)); subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; break; default: @@ -89,7 +93,7 @@ void subghz_scene_read_raw_on_enter(void* context) { subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; break; } - string_clear(file_name); + furi_string_free(file_name); subghz_scene_read_raw_update_statusbar(subghz); //set callback view raw @@ -174,7 +178,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { case SubGhzCustomEventViewReadRAWErase: if(subghz->txrx->rx_key_state == SubGhzRxKeyStateAddKey) { if(subghz_scene_read_raw_update_filename(subghz)) { - string_set(subghz->file_path_tmp, subghz->file_path); + furi_string_set(subghz->file_path_tmp, subghz->file_path); subghz_delete_file(subghz); } } @@ -245,12 +249,13 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz_protocol_raw_save_to_file_stop( (SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result); - string_t temp_str; - string_init(temp_str); - string_printf( + FuriString* temp_str; + temp_str = furi_string_alloc(); + furi_string_printf( temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, RAW_FILE_NAME, SUBGHZ_APP_EXTENSION); - subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, string_get_cstr(temp_str)); - string_clear(temp_str); + subghz_protocol_raw_gen_fff_data( + subghz->txrx->fff_data, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); if(spl_count > 0) { notification_message(subghz->notifications, &sequence_set_green_255); @@ -279,13 +284,14 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz_begin( subghz, subghz_setting_get_preset_data_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz->setting, + furi_string_get_cstr(subghz->txrx->preset->name))); subghz_rx(subghz, subghz->txrx->preset->frequency); } subghz->state_notifications = SubGhzNotificationStateRx; subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } else { - string_set_str(subghz->error_str, "Function requires\nan SD card."); + furi_string_set(subghz->error_str, "Function requires\nan SD card."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } } diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 7c1f016d0..77a921457 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -33,31 +33,31 @@ static const NotificationSequence subghs_sequence_rx_locked = { static void subghz_scene_receiver_update_statusbar(void* context) { SubGhz* subghz = context; - string_t history_stat_str; - string_init(history_stat_str); + FuriString* history_stat_str; + history_stat_str = furi_string_alloc(); if(!subghz_history_get_text_space_left(subghz->txrx->history, history_stat_str)) { - string_t frequency_str; - string_t modulation_str; + FuriString* frequency_str; + FuriString* modulation_str; - string_init(frequency_str); - string_init(modulation_str); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); subghz_view_receiver_add_data_statusbar( subghz->subghz_receiver, - string_get_cstr(frequency_str), - string_get_cstr(modulation_str), - string_get_cstr(history_stat_str)); + furi_string_get_cstr(frequency_str), + furi_string_get_cstr(modulation_str), + furi_string_get_cstr(history_stat_str)); - string_clear(frequency_str); - string_clear(modulation_str); + furi_string_free(frequency_str); + furi_string_free(modulation_str); } else { subghz_view_receiver_add_data_statusbar( - subghz->subghz_receiver, string_get_cstr(history_stat_str), "", ""); + subghz->subghz_receiver, furi_string_get_cstr(history_stat_str), "", ""); subghz->state_notifications = SubGhzNotificationStateIDLE; } - string_clear(history_stat_str); + furi_string_free(history_stat_str); } void subghz_scene_receiver_callback(SubGhzCustomEvent event, void* context) { @@ -72,11 +72,11 @@ static void subghz_scene_add_to_history_callback( void* context) { furi_assert(context); SubGhz* subghz = context; - string_t str_buff; - string_init(str_buff); + FuriString* str_buff; + str_buff = furi_string_alloc(); if(subghz_history_add_to_history(subghz->txrx->history, decoder_base, subghz->txrx->preset)) { - string_reset(str_buff); + furi_string_reset(str_buff); subghz->state_notifications = SubGhzNotificationStateRxDone; @@ -84,22 +84,22 @@ static void subghz_scene_add_to_history_callback( subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, - string_get_cstr(str_buff), + furi_string_get_cstr(str_buff), subghz_history_get_type_protocol( subghz->txrx->history, subghz_history_get_item(subghz->txrx->history) - 1)); subghz_scene_receiver_update_statusbar(subghz); } subghz_receiver_reset(receiver); - string_clear(str_buff); + furi_string_free(str_buff); subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } void subghz_scene_receiver_on_enter(void* context) { SubGhz* subghz = context; - string_t str_buff; - string_init(str_buff); + FuriString* str_buff; + str_buff = furi_string_alloc(); if(subghz->txrx->rx_key_state == SubGhzRxKeyStateIDLE) { subghz_preset_init( @@ -113,15 +113,15 @@ void subghz_scene_receiver_on_enter(void* context) { //Load history to receiver subghz_view_receiver_exit(subghz->subghz_receiver); for(uint8_t i = 0; i < subghz_history_get_item(subghz->txrx->history); i++) { - string_reset(str_buff); + furi_string_reset(str_buff); subghz_history_get_text_item_menu(subghz->txrx->history, str_buff, i); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, - string_get_cstr(str_buff), + furi_string_get_cstr(str_buff), subghz_history_get_type_protocol(subghz->txrx->history, i)); subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } - string_clear(str_buff); + furi_string_free(str_buff); subghz_scene_receiver_update_statusbar(subghz); subghz_view_receiver_set_callback( subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); @@ -137,7 +137,7 @@ void subghz_scene_receiver_on_enter(void* context) { subghz_begin( subghz, subghz_setting_get_preset_data_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); subghz_rx(subghz, subghz->txrx->preset->frequency); } subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index 541ec0e0d..5f022d6e1 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -191,7 +191,7 @@ void subghz_scene_receiver_config_on_enter(void* context) { subghz_scene_receiver_config_set_preset, subghz); value_index = subghz_scene_receiver_config_next_preset( - string_get_cstr(subghz->txrx->preset->name), subghz); + furi_string_get_cstr(subghz->txrx->preset->name), subghz); variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text( item, subghz_setting_get_preset_name(subghz->setting, value_index)); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_info.c b/applications/main/subghz/scenes/subghz_scene_receiver_info.c index 6f3e6fd1f..2e833edd1 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_info.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_info.c @@ -32,7 +32,7 @@ static bool subghz_scene_receiver_info_update_parser(void* context) { subghz_history_get_preset_def(subghz->txrx->history, subghz->txrx->idx_menu_chosen); subghz_preset_init( subghz, - string_get_cstr(preset->name), + furi_string_get_cstr(preset->name), preset->frequency, preset->data, preset->data_size); @@ -47,13 +47,13 @@ void subghz_scene_receiver_info_on_enter(void* context) { DOLPHIN_DEED(DolphinDeedSubGhzReceiverInfo); if(subghz_scene_receiver_info_update_parser(subghz)) { - string_t frequency_str; - string_t modulation_str; - string_t text; + FuriString* frequency_str; + FuriString* modulation_str; + FuriString* text; - string_init(frequency_str); - string_init(modulation_str); - string_init(text); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); + text = furi_string_alloc(); subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); widget_add_string_element( @@ -63,7 +63,7 @@ void subghz_scene_receiver_info_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - string_get_cstr(frequency_str)); + furi_string_get_cstr(frequency_str)); widget_add_string_element( subghz->widget, @@ -72,14 +72,14 @@ void subghz_scene_receiver_info_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - string_get_cstr(modulation_str)); + furi_string_get_cstr(modulation_str)); subghz_protocol_decoder_base_get_string(subghz->txrx->decoder_result, text); widget_add_string_multiline_element( - subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, string_get_cstr(text)); + subghz->widget, 0, 0, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(text)); - string_clear(frequency_str); - string_clear(modulation_str); - string_clear(text); + furi_string_free(frequency_str); + furi_string_free(modulation_str); + furi_string_free(text); if((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Save) == SubGhzProtocolFlag_Save) { @@ -146,7 +146,7 @@ bool subghz_scene_receiver_info_on_event(void* context, SceneManagerEvent event) subghz_begin( subghz, subghz_setting_get_preset_data_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); subghz_rx(subghz, subghz->txrx->preset->frequency); } if(subghz->txrx->hopper_state == SubGhzHopperStatePause) { diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index 652499d05..1f06f4f9e 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -61,20 +61,20 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { if(subghz_key_load(subghz, arg, false)) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateLoaded); - string_set_str(subghz->file_path, arg); + furi_string_set(subghz->file_path, arg); result = true; - string_t file_name; - string_init(file_name); + FuriString* file_name; + file_name = furi_string_alloc(); path_extract_filename(subghz->file_path, file_name, true); snprintf( subghz->file_name_tmp, SUBGHZ_MAX_LEN_NAME, "loaded\n%s", - string_get_cstr(file_name)); + furi_string_get_cstr(file_name)); popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop); - string_clear(file_name); + furi_string_free(file_name); } } rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventLoadFile, result); diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 12ec98681..dfcb65865 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -1,5 +1,4 @@ #include "../subghz_i.h" -#include "m-string.h" #include "subghz/types.h" #include #include "../helpers/subghz_custom_event.h" @@ -14,6 +13,20 @@ void subghz_scene_save_name_text_input_callback(void* context) { view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneSaveName); } +void subghz_scene_save_name_get_timefilename(FuriString* name) { + FuriHalRtcDateTime datetime = {0}; + furi_hal_rtc_get_datetime(&datetime); + furi_string_printf( + name, + "RAW-%.4d%.2d%.2d-%.2d%.2d%.2d", + datetime.year, + datetime.month, + datetime.day, + datetime.hour, + datetime.minute, + datetime.second); +} + void subghz_scene_save_name_on_enter(void* context) { SubGhz* subghz = context; @@ -21,35 +34,34 @@ void subghz_scene_save_name_on_enter(void* context) { TextInput* text_input = subghz->text_input; bool dev_name_empty = false; - string_t file_name; - string_t dir_name; - string_init(file_name); - string_init(dir_name); + FuriString* file_name; + FuriString* dir_name; + file_name = furi_string_alloc(); + dir_name = furi_string_alloc(); if(!subghz_path_is_file(subghz->file_path)) { char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; set_random_name(file_name_buf, SUBGHZ_MAX_LEN_NAME); - string_set_str(file_name, file_name_buf); - string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); + furi_string_set(file_name, file_name_buf); + furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); //highlighting the entire filename by default dev_name_empty = true; } else { - string_set(subghz->file_path_tmp, subghz->file_path); - path_extract_dirname(string_get_cstr(subghz->file_path), dir_name); + furi_string_set(subghz->file_path_tmp, subghz->file_path); + path_extract_dirname(furi_string_get_cstr(subghz->file_path), dir_name); path_extract_filename(subghz->file_path, file_name, true); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == SubGhzCustomEventManagerSetRAW) { dev_name_empty = true; - subghz_get_next_name_file(subghz, SUBGHZ_MAX_LEN_NAME); + subghz_scene_save_name_get_timefilename(file_name); } - path_extract_filename(subghz->file_path, file_name, true); } - string_set(subghz->file_path, dir_name); + furi_string_set(subghz->file_path, dir_name); } - strncpy(subghz->file_name_tmp, string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); + strncpy(subghz->file_name_tmp, furi_string_get_cstr(file_name), SUBGHZ_MAX_LEN_NAME); text_input_set_header_text(text_input, "Name signal"); text_input_set_result_callback( text_input, @@ -59,12 +71,12 @@ void subghz_scene_save_name_on_enter(void* context) { MAX_TEXT_INPUT_LEN, // buffer size dev_name_empty); - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(string_get_cstr(subghz->file_path), SUBGHZ_APP_EXTENSION, ""); + ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( + furi_string_get_cstr(subghz->file_path), SUBGHZ_APP_EXTENSION, ""); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - string_clear(file_name); - string_clear(dir_name); + furi_string_free(file_name); + furi_string_free(dir_name); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTextInput); } @@ -75,14 +87,14 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(!strcmp(subghz->file_name_tmp, "") || scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { - string_set(subghz->file_path, subghz->file_path_tmp); + furi_string_set(subghz->file_path, subghz->file_path_tmp); } scene_manager_previous_scene(subghz->scene_manager); return true; } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneSaveName) { if(strcmp(subghz->file_name_tmp, "")) { - string_cat_printf( + furi_string_cat_printf( subghz->file_path, "/%s%s", subghz->file_name_tmp, SUBGHZ_APP_EXTENSION); if(subghz_path_is_file(subghz->file_path_tmp)) { if(!subghz_rename_file(subghz)) { @@ -92,7 +104,9 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneSetType) != SubGhzCustomEventManagerNoSet) { subghz_save_protocol_to_file( - subghz, subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + subghz, + subghz->txrx->fff_data, + furi_string_get_cstr(subghz->file_path)); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneSetType, @@ -102,14 +116,14 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { subghz, subghz_history_get_raw_data( subghz->txrx->history, subghz->txrx->idx_menu_chosen), - string_get_cstr(subghz->file_path)); + furi_string_get_cstr(subghz->file_path)); } } if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != SubGhzCustomEventManagerNoSet) { subghz_protocol_raw_gen_fff_data( - subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + subghz->txrx->fff_data, furi_string_get_cstr(subghz->file_path)); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet); } else { @@ -119,7 +133,7 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveSuccess); return true; } else { - string_set_str(subghz->error_str, "No name file"); + furi_string_set(subghz->error_str, "No name file"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); return true; } diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 1a359542e..1e7a7474b 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -27,7 +27,7 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( subghz_receiver_search_decoder_base_by_name(subghz->txrx->receiver, protocol_name); if(subghz->txrx->decoder_result == NULL) { - string_set_str(subghz->error_str, "Protocol not\nfound!"); + furi_string_set(subghz->error_str, "Protocol not\nfound!"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); return false; } @@ -261,7 +261,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { } subghz_transmitter_free(subghz->txrx->transmitter); if(!generated_protocol) { - string_set_str( + furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } @@ -285,7 +285,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { } subghz_transmitter_free(subghz->txrx->transmitter); if(!generated_protocol) { - string_set_str( + furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); } diff --git a/applications/main/subghz/scenes/subghz_scene_show_error.c b/applications/main/subghz/scenes/subghz_scene_show_error.c index 5632a859e..eadfb2114 100644 --- a/applications/main/subghz/scenes/subghz_scene_show_error.c +++ b/applications/main/subghz/scenes/subghz_scene_show_error.c @@ -33,7 +33,7 @@ void subghz_scene_show_error_on_enter(void* context) { AlignCenter, AlignCenter, FontSecondary, - string_get_cstr(subghz->error_str)); + furi_string_get_cstr(subghz->error_str)); if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneShowError) == SubGhzCustomEventManagerSet) { widget_add_button_element( @@ -89,6 +89,6 @@ void subghz_scene_show_error_on_exit(void* context) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneShowError, SubGhzCustomEventManagerNoSet); widget_reset(subghz->widget); - string_reset(subghz->error_str); + furi_string_reset(subghz->error_str); notification_message(subghz->notifications, &sequence_reset_rgb); } diff --git a/applications/main/subghz/scenes/subghz_scene_show_error_sub.c b/applications/main/subghz/scenes/subghz_scene_show_error_sub.c index 74e034323..2720b2b94 100644 --- a/applications/main/subghz/scenes/subghz_scene_show_error_sub.c +++ b/applications/main/subghz/scenes/subghz_scene_show_error_sub.c @@ -12,7 +12,7 @@ void subghz_scene_show_error_sub_on_enter(void* context) { // Setup view Popup* popup = subghz->popup; popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48); - popup_set_header(popup, string_get_cstr(subghz->error_str), 14, 15, AlignLeft, AlignTop); + popup_set_header(popup, furi_string_get_cstr(subghz->error_str), 14, 15, AlignLeft, AlignTop); popup_set_timeout(popup, 1500); popup_set_context(popup, subghz); popup_set_callback(popup, subghz_scene_show_error_sub_popup_callback); @@ -46,7 +46,7 @@ void subghz_scene_show_error_sub_on_exit(void* context) { popup_set_context(popup, NULL); popup_set_timeout(popup, 0); popup_disable_timeout(popup); - string_reset(subghz->error_str); + furi_string_reset(subghz->error_str); notification_message(subghz->notifications, &sequence_reset_rgb); } diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index b3f8d0799..5da6f4300 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -13,13 +13,13 @@ bool subghz_scene_transmitter_update_data_show(void* context) { SubGhz* subghz = context; if(subghz->txrx->decoder_result) { - string_t key_str; - string_t frequency_str; - string_t modulation_str; + FuriString* key_str; + FuriString* frequency_str; + FuriString* modulation_str; - string_init(key_str); - string_init(frequency_str); - string_init(modulation_str); + key_str = furi_string_alloc(); + frequency_str = furi_string_alloc(); + modulation_str = furi_string_alloc(); uint8_t show_button = 0; subghz_protocol_decoder_base_deserialize( @@ -34,14 +34,14 @@ bool subghz_scene_transmitter_update_data_show(void* context) { subghz_get_frequency_modulation(subghz, frequency_str, modulation_str); subghz_view_transmitter_add_data_to_show( subghz->subghz_transmitter, - string_get_cstr(key_str), - string_get_cstr(frequency_str), - string_get_cstr(modulation_str), + furi_string_get_cstr(key_str), + furi_string_get_cstr(frequency_str), + furi_string_get_cstr(modulation_str), show_button); - string_clear(frequency_str); - string_clear(modulation_str); - string_clear(key_str); + furi_string_free(frequency_str); + furi_string_free(modulation_str); + furi_string_free(key_str); return true; } @@ -94,7 +94,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart); return true; } else if(event.event == SubGhzCustomEventViewTransmitterError) { - string_set_str(subghz->error_str, "Protocol not\nfound!"); + furi_string_set(subghz->error_str, "Protocol not\nfound!"); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowErrorSub); } } else if(event.type == SceneManagerEventTypeTick) { diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 61960218b..71c6bc2cd 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -1,6 +1,5 @@ /* Abandon hope, all ye who enter here. */ -#include "m-string.h" #include "subghz/types.h" #include "subghz_i.h" #include @@ -62,8 +61,8 @@ void subghz_blink_stop(SubGhz* instance) { SubGhz* subghz_alloc() { SubGhz* subghz = malloc(sizeof(SubGhz)); - string_init(subghz->file_path); - string_init(subghz->file_path_tmp); + subghz->file_path = furi_string_alloc(); + subghz->file_path_tmp = furi_string_alloc(); // GUI subghz->gui = furi_record_open(RECORD_GUI); @@ -171,7 +170,7 @@ SubGhz* subghz_alloc() { subghz->lock = SubGhzLockOff; subghz->txrx = malloc(sizeof(SubGhzTxRx)); subghz->txrx->preset = malloc(sizeof(SubGhzPresetDefinition)); - string_init(subghz->txrx->preset->name); + subghz->txrx->preset->name = furi_string_alloc(); subghz_preset_init( subghz, "AM650", subghz_setting_get_default_frequency(subghz->setting), NULL, 0); @@ -197,7 +196,7 @@ SubGhz* subghz_alloc() { subghz_worker_set_context(subghz->txrx->worker, subghz->txrx->receiver); //Init Error_str - string_init(subghz->error_str); + subghz->error_str = furi_string_alloc(); return subghz; } @@ -282,20 +281,20 @@ void subghz_free(SubGhz* subghz) { subghz_worker_free(subghz->txrx->worker); flipper_format_free(subghz->txrx->fff_data); subghz_history_free(subghz->txrx->history); - string_clear(subghz->txrx->preset->name); + furi_string_free(subghz->txrx->preset->name); free(subghz->txrx->preset); free(subghz->txrx); //Error string - string_clear(subghz->error_str); + furi_string_free(subghz->error_str); // Notifications furi_record_close(RECORD_NOTIFICATION); subghz->notifications = NULL; // Path strings - string_clear(subghz->file_path); - string_clear(subghz->file_path_tmp); + furi_string_free(subghz->file_path); + furi_string_free(subghz->file_path_tmp); // The rest free(subghz); @@ -329,7 +328,7 @@ int32_t subghz_app(void* p) { view_dispatcher_attach_to_gui( subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); if(subghz_key_load(subghz, p, true)) { - string_set_str(subghz->file_path, p); + furi_string_set(subghz->file_path, (const char*)p); if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) { //Load Raw TX @@ -348,13 +347,13 @@ int32_t subghz_app(void* p) { } else { view_dispatcher_attach_to_gui( subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); - string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); + furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); if(load_database) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); } else { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneShowError, SubGhzCustomEventManagerSet); - string_set_str( + furi_string_set( subghz->error_str, "No SD card or\ndatabase found.\nSome app function\nmay be reduced."); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError); diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index d921979f0..a1474885e 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -24,15 +23,15 @@ #define SUBGHZ_REGION_FILENAME "/int/.region_data" -void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { +void subghz_cli_command_tx_carrier(Cli* cli, FuriString* args, void* context) { UNUSED(context); uint32_t frequency = 433920000; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(furi_string_size(args)) { + int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); if(ret != 1) { printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); - cli_print_usage("subghz tx_carrier", "", string_get_cstr(args)); + cli_print_usage("subghz tx_carrier", "", furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -68,15 +67,15 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { furi_hal_power_suppress_charge_exit(); } -void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { +void subghz_cli_command_rx_carrier(Cli* cli, FuriString* args, void* context) { UNUSED(context); uint32_t frequency = 433920000; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(furi_string_size(args)) { + int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); if(ret != 1) { printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); - cli_print_usage("subghz rx_carrier", "", string_get_cstr(args)); + cli_print_usage("subghz rx_carrier", "", furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -109,15 +108,16 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { furi_hal_subghz_sleep(); } -void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { +void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { UNUSED(context); uint32_t frequency = 433920000; uint32_t key = 0x0074BADE; uint32_t repeat = 10; uint32_t te = 403; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lx %lu %lu %lu", &key, &frequency, &te, &repeat); + if(furi_string_size(args)) { + int ret = + sscanf(furi_string_get_cstr(args), "%lx %lu %lu %lu", &key, &frequency, &te, &repeat); if(ret != 4) { printf( "sscanf returned %d, key: %lx, frequency: %lu, te:%lu, repeat: %lu\r\n", @@ -129,7 +129,7 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { cli_print_usage( "subghz tx", "<3 Byte Key: in hex> ", - string_get_cstr(args)); + furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -147,14 +147,12 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { te, repeat); - string_t flipper_format_string; - string_init_printf( - flipper_format_string, + FuriString* flipper_format_string = furi_string_alloc_printf( "Protocol: Princeton\n" "Bit: 24\n" "Key: 00 00 00 00 00 %02X %02X %02X\n" - "TE: %d\n" - "Repeat: %d\n", + "TE: %ld\n" + "Repeat: %ld\n", (uint8_t)((key >> 16) & 0xFF), (uint8_t)((key >> 8) & 0xFF), (uint8_t)(key & 0xFF), @@ -163,7 +161,7 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { FlipperFormat* flipper_format = flipper_format_string_alloc(); Stream* stream = flipper_format_get_raw_stream(flipper_format); stream_clean(stream); - stream_write_cstring(stream, string_get_cstr(flipper_format_string)); + stream_write_cstring(stream, furi_string_get_cstr(flipper_format_string)); SubGhzEnvironment* environment = subghz_environment_alloc(); @@ -195,23 +193,21 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { typedef struct { volatile bool overrun; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; size_t packet_count; } SubGhzCliCommandRx; static void subghz_cli_command_rx_capture_callback(bool level, uint32_t duration, void* context) { SubGhzCliCommandRx* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; LevelDuration level_duration = level_duration_make(level, duration); if(instance->overrun) { instance->overrun = false; level_duration = level_duration_reset(); } - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); if(sizeof(LevelDuration) != ret) instance->overrun = true; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } static void subghz_cli_command_rx_callback( @@ -221,23 +217,23 @@ static void subghz_cli_command_rx_callback( SubGhzCliCommandRx* instance = context; instance->packet_count++; - string_t text; - string_init(text); + FuriString* text; + text = furi_string_alloc(); subghz_protocol_decoder_base_get_string(decoder_base, text); subghz_receiver_reset(receiver); - printf("%s", string_get_cstr(text)); - string_clear(text); + printf("%s", furi_string_get_cstr(text)); + furi_string_free(text); } -void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { +void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { UNUSED(context); uint32_t frequency = 433920000; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(furi_string_size(args)) { + int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); if(ret != 1) { printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); - cli_print_usage("subghz rx", "", string_get_cstr(args)); + cli_print_usage("subghz rx", "", furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -250,7 +246,8 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { // Allocate context and buffers SubGhzCliCommandRx* instance = malloc(sizeof(SubGhzCliCommandRx)); - instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); + instance->stream = + furi_stream_buffer_alloc(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); furi_check(instance->stream); SubGhzEnvironment* environment = subghz_environment_alloc(); @@ -280,8 +277,8 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { printf("Listening at %lu. Press CTRL+C to stop\r\n", frequency); LevelDuration level_duration; while(!cli_cmd_interrupt_received(cli)) { - int ret = - xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 10); + int ret = furi_stream_buffer_receive( + instance->stream, &level_duration, sizeof(LevelDuration), 10); if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { printf("."); @@ -305,36 +302,36 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { // Cleanup subghz_receiver_free(receiver); subghz_environment_free(environment); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); free(instance); } -void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { +void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t file_name; - string_init(file_name); - string_set_str(file_name, ANY_PATH("subghz/test.sub")); + FuriString* file_name; + file_name = furi_string_alloc(); + furi_string_set(file_name, ANY_PATH("subghz/test.sub")); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t temp_data32; bool check_file = false; do { - if(string_size(args)) { + if(furi_string_size(args)) { if(!args_read_string_and_trim(args, file_name)) { cli_print_usage( - "subghz decode_raw", "", string_get_cstr(args)); + "subghz decode_raw", "", furi_string_get_cstr(args)); break; } } - if(!flipper_format_file_open_existing(fff_data_file, string_get_cstr(file_name))) { + if(!flipper_format_file_open_existing(fff_data_file, furi_string_get_cstr(file_name))) { printf( "subghz decode_raw \033[0;31mError open file\033[0m %s\r\n", - string_get_cstr(file_name)); + furi_string_get_cstr(file_name)); break; } @@ -343,7 +340,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { break; } - if(!strcmp(string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE) && + if(!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE) && temp_data32 == SUBGHZ_KEY_FILE_VERSION) { } else { printf("subghz decode_raw \033[0;31mType or version mismatch\033[0m\r\n"); @@ -353,7 +350,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { check_file = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); @@ -385,14 +382,14 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { subghz_receiver_set_rx_callback(receiver, subghz_cli_command_rx_callback, instance); SubGhzFileEncoderWorker* file_worker_encoder = subghz_file_encoder_worker_alloc(); - if(subghz_file_encoder_worker_start(file_worker_encoder, string_get_cstr(file_name))) { + if(subghz_file_encoder_worker_start(file_worker_encoder, furi_string_get_cstr(file_name))) { //the worker needs a file in order to open and read part of the file furi_delay_ms(100); } printf( "Listening at \033[0;33m%s\033[0m.\r\n\r\nPress CTRL+C to stop\r\n\r\n", - string_get_cstr(file_name)); + furi_string_get_cstr(file_name)); LevelDuration level_duration; while(!cli_cmd_interrupt_received(cli)) { @@ -419,7 +416,7 @@ void subghz_cli_command_decode_raw(Cli* cli, string_t args, void* context) { subghz_file_encoder_worker_free(file_worker_encoder); free(instance); } - string_clear(file_name); + furi_string_free(file_name); } static void subghz_cli_command_print_usage() { @@ -445,14 +442,14 @@ static void subghz_cli_command_print_usage() { } } -static void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { +static void subghz_cli_command_encrypt_keeloq(Cli* cli, FuriString* args) { UNUSED(cli); uint8_t iv[16]; - string_t source; - string_t destination; - string_init(source); - string_init(destination); + FuriString* source; + FuriString* destination; + source = furi_string_alloc(); + destination = furi_string_alloc(); SubGhzKeystore* keystore = subghz_keystore_alloc(); @@ -472,30 +469,30 @@ static void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { break; } - if(!subghz_keystore_load(keystore, string_get_cstr(source))) { + if(!subghz_keystore_load(keystore, furi_string_get_cstr(source))) { printf("Failed to load Keystore"); break; } - if(!subghz_keystore_save(keystore, string_get_cstr(destination), iv)) { + if(!subghz_keystore_save(keystore, furi_string_get_cstr(destination), iv)) { printf("Failed to save Keystore"); break; } } while(false); subghz_keystore_free(keystore); - string_clear(destination); - string_clear(source); + furi_string_free(destination); + furi_string_free(source); } -static void subghz_cli_command_encrypt_raw(Cli* cli, string_t args) { +static void subghz_cli_command_encrypt_raw(Cli* cli, FuriString* args) { UNUSED(cli); uint8_t iv[16]; - string_t source; - string_t destination; - string_init(source); - string_init(destination); + FuriString* source; + FuriString* destination; + source = furi_string_alloc(); + destination = furi_string_alloc(); do { if(!args_read_string_and_trim(args, source)) { @@ -514,25 +511,25 @@ static void subghz_cli_command_encrypt_raw(Cli* cli, string_t args) { } if(!subghz_keystore_raw_encrypted_save( - string_get_cstr(source), string_get_cstr(destination), iv)) { + furi_string_get_cstr(source), furi_string_get_cstr(destination), iv)) { printf("Failed to save Keystore"); break; } } while(false); - string_clear(destination); - string_clear(source); + furi_string_free(destination); + furi_string_free(source); } -static void subghz_cli_command_chat(Cli* cli, string_t args) { +static void subghz_cli_command_chat(Cli* cli, FuriString* args) { uint32_t frequency = 433920000; - if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(furi_string_size(args)) { + int ret = sscanf(furi_string_get_cstr(args), "%lu", &frequency); if(ret != 1) { printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); - cli_print_usage("subghz chat", "", string_get_cstr(args)); + cli_print_usage("subghz chat", "", furi_string_get_cstr(args)); return; } if(!furi_hal_subghz_is_frequency_valid(frequency)) { @@ -568,22 +565,22 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { size_t message_max_len = 64; uint8_t message[64] = {0}; - string_t input; - string_init(input); - string_t name; - string_init(name); - string_t output; - string_init(output); - string_t sysmsg; - string_init(sysmsg); + FuriString* input; + input = furi_string_alloc(); + FuriString* name; + name = furi_string_alloc(); + FuriString* output; + output = furi_string_alloc(); + FuriString* sysmsg; + sysmsg = furi_string_alloc(); bool exit = false; SubGhzChatEvent chat_event; NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - string_printf(name, "\033[0;33m%s\033[0m: ", furi_hal_version_get_name_ptr()); - string_set(input, name); - printf("%s", string_get_cstr(input)); + furi_string_printf(name, "\033[0;33m%s\033[0m: ", furi_hal_version_get_name_ptr()); + furi_string_set(input, name); + printf("%s", furi_string_get_cstr(input)); fflush(stdout); while(!exit) { @@ -597,63 +594,63 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { break; } else if( (chat_event.c == CliSymbolAsciiBackspace) || (chat_event.c == CliSymbolAsciiDel)) { - size_t len = string_length_u(input); - if(len > string_length_u(name)) { + size_t len = furi_string_utf8_length(input); + if(len > furi_string_utf8_length(name)) { printf("%s", "\e[D\e[1P"); fflush(stdout); //delete 1 char UTF - const char* str = string_get_cstr(input); + const char* str = furi_string_get_cstr(input); size_t size = 0; - m_str1ng_utf8_state_e s = M_STRING_UTF8_STARTING; - string_unicode_t u = 0; - string_reset(sysmsg); + FuriStringUTF8State s = FuriStringUTF8StateStarting; + FuriStringUnicodeValue u = 0; + furi_string_reset(sysmsg); while(*str) { - m_str1ng_utf8_decode(*str, &s, &u); - if((s == M_STRING_UTF8_ERROR) || s == M_STRING_UTF8_STARTING) { - string_push_u(sysmsg, u); + furi_string_utf8_decode(*str, &s, &u); + if((s == FuriStringUTF8StateError) || s == FuriStringUTF8StateStarting) { + furi_string_utf8_push(sysmsg, u); if(++size >= len - 1) break; - s = M_STRING_UTF8_STARTING; + s = FuriStringUTF8StateStarting; } str++; } - string_set(input, sysmsg); + furi_string_set(input, sysmsg); } } else if(chat_event.c == CliSymbolAsciiCR) { printf("\r\n"); - string_push_back(input, '\r'); - string_push_back(input, '\n'); + furi_string_push_back(input, '\r'); + furi_string_push_back(input, '\n'); while(!subghz_chat_worker_write( subghz_chat, - (uint8_t*)string_get_cstr(input), - strlen(string_get_cstr(input)))) { + (uint8_t*)furi_string_get_cstr(input), + strlen(furi_string_get_cstr(input)))) { furi_delay_ms(10); } - string_printf(input, "%s", string_get_cstr(name)); - printf("%s", string_get_cstr(input)); + furi_string_printf(input, "%s", furi_string_get_cstr(name)); + printf("%s", furi_string_get_cstr(input)); fflush(stdout); } else if(chat_event.c == CliSymbolAsciiLF) { //cut out the symbol \n } else { putc(chat_event.c, stdout); fflush(stdout); - string_push_back(input, chat_event.c); + furi_string_push_back(input, chat_event.c); break; case SubGhzChatEventRXData: do { memset(message, 0x00, message_max_len); size_t len = subghz_chat_worker_read(subghz_chat, message, message_max_len); for(size_t i = 0; i < len; i++) { - string_push_back(output, message[i]); + furi_string_push_back(output, message[i]); if(message[i] == '\n') { printf("\r"); for(uint8_t i = 0; i < 80; i++) { printf(" "); } - printf("\r %s", string_get_cstr(output)); - printf("%s", string_get_cstr(input)); + printf("\r %s", furi_string_get_cstr(output)); + printf("%s", furi_string_get_cstr(input)); fflush(stdout); - string_reset(output); + furi_string_reset(output); } } } while(subghz_chat_worker_available(subghz_chat)); @@ -662,22 +659,22 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { notification_message(notification, &sequence_single_vibro); break; case SubGhzChatEventUserEntrance: - string_printf( + furi_string_printf( sysmsg, "\033[0;34m%s joined chat.\033[0m\r\n", furi_hal_version_get_name_ptr()); subghz_chat_worker_write( subghz_chat, - (uint8_t*)string_get_cstr(sysmsg), - strlen(string_get_cstr(sysmsg))); + (uint8_t*)furi_string_get_cstr(sysmsg), + strlen(furi_string_get_cstr(sysmsg))); break; case SubGhzChatEventUserExit: - string_printf( + furi_string_printf( sysmsg, "\033[0;31m%s left chat.\033[0m\r\n", furi_hal_version_get_name_ptr()); subghz_chat_worker_write( subghz_chat, - (uint8_t*)string_get_cstr(sysmsg), - strlen(string_get_cstr(sysmsg))); + (uint8_t*)furi_string_get_cstr(sysmsg), + strlen(furi_string_get_cstr(sysmsg))); furi_delay_ms(10); exit = true; break; @@ -693,10 +690,10 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { } } - string_clear(input); - string_clear(name); - string_clear(output); - string_clear(sysmsg); + furi_string_free(input); + furi_string_free(name); + furi_string_free(output); + furi_string_free(sysmsg); furi_hal_power_suppress_charge_exit(); furi_record_close(RECORD_NOTIFICATION); @@ -707,9 +704,9 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { printf("\r\nExit chat\r\n"); } -static void subghz_cli_command(Cli* cli, string_t args, void* context) { - string_t cmd; - string_init(cmd); +static void subghz_cli_command(Cli* cli, FuriString* args, void* context) { + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -717,43 +714,43 @@ static void subghz_cli_command(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "chat") == 0) { + if(furi_string_cmp_str(cmd, "chat") == 0) { subghz_cli_command_chat(cli, args); break; } - if(string_cmp_str(cmd, "tx") == 0) { + if(furi_string_cmp_str(cmd, "tx") == 0) { subghz_cli_command_tx(cli, args, context); break; } - if(string_cmp_str(cmd, "rx") == 0) { + if(furi_string_cmp_str(cmd, "rx") == 0) { subghz_cli_command_rx(cli, args, context); break; } - if(string_cmp_str(cmd, "decode_raw") == 0) { + if(furi_string_cmp_str(cmd, "decode_raw") == 0) { subghz_cli_command_decode_raw(cli, args, context); break; } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - if(string_cmp_str(cmd, "encrypt_keeloq") == 0) { + if(furi_string_cmp_str(cmd, "encrypt_keeloq") == 0) { subghz_cli_command_encrypt_keeloq(cli, args); break; } - if(string_cmp_str(cmd, "encrypt_raw") == 0) { + if(furi_string_cmp_str(cmd, "encrypt_raw") == 0) { subghz_cli_command_encrypt_raw(cli, args); break; } - if(string_cmp_str(cmd, "tx_carrier") == 0) { + if(furi_string_cmp_str(cmd, "tx_carrier") == 0) { subghz_cli_command_tx_carrier(cli, args, context); break; } - if(string_cmp_str(cmd, "rx_carrier") == 0) { + if(furi_string_cmp_str(cmd, "rx_carrier") == 0) { subghz_cli_command_rx_carrier(cli, args, context); break; } @@ -762,7 +759,7 @@ static void subghz_cli_command(Cli* cli, string_t args, void* context) { subghz_cli_command_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } static bool @@ -797,7 +794,7 @@ static bool subghz_on_system_start_istream_decode_band( FURI_LOG_I( "SubGhzOnStart", - "Add allowed band: start %dHz, stop %dHz, power_limit %ddBm, duty_cycle %d%%", + "Add allowed band: start %ldHz, stop %ldHz, power_limit %ddBm, duty_cycle %d%%", band.start, band.end, band.power_limit, diff --git a/applications/main/subghz/subghz_history.c b/applications/main/subghz/subghz_history.c index 820a13d14..0f67b4fc9 100644 --- a/applications/main/subghz/subghz_history.c +++ b/applications/main/subghz/subghz_history.c @@ -3,13 +3,12 @@ #include #include -#include #define SUBGHZ_HISTORY_MAX 50 #define TAG "SubGhzHistory" typedef struct { - string_t item_str; + FuriString* item_str; FlipperFormat* flipper_string; uint8_t type; SubGhzPresetDefinition* preset; @@ -27,13 +26,13 @@ struct SubGhzHistory { uint32_t last_update_timestamp; uint16_t last_index_write; uint8_t code_last_hash_data; - string_t tmp_string; + FuriString* tmp_string; SubGhzHistoryStruct* history; }; SubGhzHistory* subghz_history_alloc(void) { SubGhzHistory* instance = malloc(sizeof(SubGhzHistory)); - string_init(instance->tmp_string); + instance->tmp_string = furi_string_alloc(); instance->history = malloc(sizeof(SubGhzHistoryStruct)); SubGhzHistoryItemArray_init(instance->history->data); return instance; @@ -41,11 +40,11 @@ SubGhzHistory* subghz_history_alloc(void) { void subghz_history_free(SubGhzHistory* instance) { furi_assert(instance); - string_clear(instance->tmp_string); + furi_string_free(instance->tmp_string); for M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) { - string_clear(item->item_str); - string_clear(item->preset->name); + furi_string_free(item->item_str); + furi_string_free(item->preset->name); free(item->preset); flipper_format_free(item->flipper_string); item->type = 0; @@ -70,16 +69,16 @@ SubGhzPresetDefinition* subghz_history_get_preset_def(SubGhzHistory* instance, u const char* subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx) { furi_assert(instance); SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); - return string_get_cstr(item->preset->name); + return furi_string_get_cstr(item->preset->name); } void subghz_history_reset(SubGhzHistory* instance) { furi_assert(instance); - string_reset(instance->tmp_string); + furi_string_reset(instance->tmp_string); for M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) { - string_clear(item->item_str); - string_clear(item->preset->name); + furi_string_free(item->item_str); + furi_string_free(item->preset->name); free(item->preset); flipper_format_free(item->flipper_string); item->type = 0; @@ -106,9 +105,9 @@ const char* subghz_history_get_protocol_name(SubGhzHistory* instance, uint16_t i flipper_format_rewind(item->flipper_string); if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) { FURI_LOG_E(TAG, "Missing Protocol"); - string_reset(instance->tmp_string); + furi_string_reset(instance->tmp_string); } - return string_get_cstr(instance->tmp_string); + return furi_string_get_cstr(instance->tmp_string); } FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx) { @@ -120,20 +119,20 @@ FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx return NULL; } } -bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output) { +bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output) { furi_assert(instance); if(instance->last_index_write == SUBGHZ_HISTORY_MAX) { - if(output != NULL) string_printf(output, "Memory is FULL"); + if(output != NULL) furi_string_printf(output, "Memory is FULL"); return true; } if(output != NULL) - string_printf(output, "%02u/%02u", instance->last_index_write, SUBGHZ_HISTORY_MAX); + furi_string_printf(output, "%02u/%02u", instance->last_index_write, SUBGHZ_HISTORY_MAX); return false; } -void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx) { +void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx) { SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); - string_set(output, item->item_str); + furi_string_set(output, item->item_str); } bool subghz_history_add_to_history( @@ -156,18 +155,18 @@ bool subghz_history_add_to_history( instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); instance->last_update_timestamp = furi_get_tick(); - string_t text; - string_init(text); + FuriString* text; + text = furi_string_alloc(); SubGhzHistoryItem* item = SubGhzHistoryItemArray_push_raw(instance->history->data); item->preset = malloc(sizeof(SubGhzPresetDefinition)); item->type = decoder_base->protocol->type; item->preset->frequency = preset->frequency; - string_init(item->preset->name); - string_set(item->preset->name, preset->name); + item->preset->name = furi_string_alloc(); + furi_string_set(item->preset->name, preset->name); item->preset->data = preset->data; item->preset->data_size = preset->data_size; - string_init(item->item_str); + item->item_str = furi_string_alloc(); item->flipper_string = flipper_format_string_alloc(); subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset); @@ -180,20 +179,20 @@ bool subghz_history_add_to_history( FURI_LOG_E(TAG, "Missing Protocol"); break; } - if(!strcmp(string_get_cstr(instance->tmp_string), "KeeLoq")) { - string_set_str(instance->tmp_string, "KL "); + if(!strcmp(furi_string_get_cstr(instance->tmp_string), "KeeLoq")) { + furi_string_set(instance->tmp_string, "KL "); if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) { FURI_LOG_E(TAG, "Missing Protocol"); break; } - string_cat(instance->tmp_string, text); - } else if(!strcmp(string_get_cstr(instance->tmp_string), "Star Line")) { - string_set_str(instance->tmp_string, "SL "); + furi_string_cat(instance->tmp_string, text); + } else if(!strcmp(furi_string_get_cstr(instance->tmp_string), "Star Line")) { + furi_string_set(instance->tmp_string, "SL "); if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) { FURI_LOG_E(TAG, "Missing Protocol"); break; } - string_cat(instance->tmp_string, text); + furi_string_cat(instance->tmp_string, text); } if(!flipper_format_rewind(item->flipper_string)) { FURI_LOG_E(TAG, "Rewind error"); @@ -209,22 +208,22 @@ bool subghz_history_add_to_history( data = (data << 8) | key_data[i]; } if(!(uint32_t)(data >> 32)) { - string_printf( + furi_string_printf( item->item_str, "%s %lX", - string_get_cstr(instance->tmp_string), + furi_string_get_cstr(instance->tmp_string), (uint32_t)(data & 0xFFFFFFFF)); } else { - string_printf( + furi_string_printf( item->item_str, "%s %lX%08lX", - string_get_cstr(instance->tmp_string), + furi_string_get_cstr(instance->tmp_string), (uint32_t)(data >> 32), (uint32_t)(data & 0xFFFFFFFF)); } } while(false); - string_clear(text); + furi_string_free(text); instance->last_index_write++; return true; } diff --git a/applications/main/subghz/subghz_history.h b/applications/main/subghz/subghz_history.h index adbcfc18a..7bff3df5e 100644 --- a/applications/main/subghz/subghz_history.h +++ b/applications/main/subghz/subghz_history.h @@ -71,18 +71,18 @@ const char* subghz_history_get_protocol_name(SubGhzHistory* instance, uint16_t i /** Get string item menu to history[idx] * * @param instance - SubGhzHistory instance - * @param output - string_t output + * @param output - FuriString* output * @param idx - record index */ -void subghz_history_get_text_item_menu(SubGhzHistory* instance, string_t output, uint16_t idx); +void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx); /** Get string the remaining number of records to history * * @param instance - SubGhzHistory instance - * @param output - string_t output + * @param output - FuriString* output * @return bool - is FUUL */ -bool subghz_history_get_text_space_left(SubGhzHistory* instance, string_t output); +bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output); /** Add protocol to history * diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 6ed8fd539..ac1036d05 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -26,7 +26,7 @@ void subghz_preset_init( size_t preset_data_size) { furi_assert(context); SubGhz* subghz = context; - string_set(subghz->txrx->preset->name, preset_name); + furi_string_set(subghz->txrx->preset->name, preset_name); subghz->txrx->preset->frequency = frequency; subghz->txrx->preset->data = preset_data; subghz->txrx->preset->data_size = preset_data_size; @@ -34,15 +34,15 @@ void subghz_preset_init( bool subghz_set_preset(SubGhz* subghz, const char* preset) { if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { - string_set(subghz->txrx->preset->name, "AM270"); + furi_string_set(subghz->txrx->preset->name, "AM270"); } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { - string_set(subghz->txrx->preset->name, "AM650"); + furi_string_set(subghz->txrx->preset->name, "AM650"); } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { - string_set(subghz->txrx->preset->name, "FM238"); + furi_string_set(subghz->txrx->preset->name, "FM238"); } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { - string_set(subghz->txrx->preset->name, "FM476"); + furi_string_set(subghz->txrx->preset->name, "FM476"); } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { - string_set(subghz->txrx->preset->name, "CUSTOM"); + furi_string_set(subghz->txrx->preset->name, "CUSTOM"); } else { FURI_LOG_E(TAG, "Unknown preset"); return false; @@ -50,17 +50,17 @@ bool subghz_set_preset(SubGhz* subghz, const char* preset) { return true; } -void subghz_get_frequency_modulation(SubGhz* subghz, string_t frequency, string_t modulation) { +void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, FuriString* modulation) { furi_assert(subghz); if(frequency != NULL) { - string_printf( + furi_string_printf( frequency, "%03ld.%02ld", subghz->txrx->preset->frequency / 1000000 % 1000, subghz->txrx->preset->frequency / 10000 % 100); } if(modulation != NULL) { - string_printf(modulation, "%0.2s", string_get_cstr(subghz->txrx->preset->name)); + furi_string_printf(modulation, "%.2s", furi_string_get_cstr(subghz->txrx->preset->name)); } } @@ -137,8 +137,8 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) { furi_assert(subghz); bool ret = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t repeat = 200; do { if(!flipper_format_rewind(flipper_format)) { @@ -155,21 +155,21 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) { break; } - subghz->txrx->transmitter = - subghz_transmitter_alloc_init(subghz->txrx->environment, string_get_cstr(temp_str)); + subghz->txrx->transmitter = subghz_transmitter_alloc_init( + subghz->txrx->environment, furi_string_get_cstr(temp_str)); if(subghz->txrx->transmitter) { if(subghz_transmitter_deserialize(subghz->txrx->transmitter, flipper_format)) { - if(strcmp(string_get_cstr(subghz->txrx->preset->name), "")) { + if(strcmp(furi_string_get_cstr(subghz->txrx->preset->name), "")) { subghz_begin( subghz, subghz_setting_get_preset_data_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name))); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name))); } else { FURI_LOG_E( TAG, "Unknown name preset \" %s \"", - string_get_cstr(subghz->txrx->preset->name)); + furi_string_get_cstr(subghz->txrx->preset->name)); subghz_begin( subghz, subghz_setting_get_preset_data_by_name(subghz->setting, "AM650")); } @@ -193,7 +193,7 @@ bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format) { } } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return ret; } @@ -209,7 +209,7 @@ void subghz_tx_stop(SubGhz* subghz) { if((subghz->txrx->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) && (subghz_path_is_file(subghz->file_path))) { subghz_save_protocol_to_file( - subghz, subghz->txrx->fff_data, string_get_cstr(subghz->file_path)); + subghz, subghz->txrx->fff_data, furi_string_get_cstr(subghz->file_path)); } subghz_idle(subghz); notification_message(subghz->notifications, &sequence_reset_red); @@ -244,8 +244,8 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { Stream* fff_data_stream = flipper_format_get_raw_stream(subghz->txrx->fff_data); SubGhzLoadKeyState load_key_state = SubGhzLoadKeyStateParseErr; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t temp_data32; do { @@ -260,8 +260,8 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { break; } - if(((!strcmp(string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) || - (!strcmp(string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) && + if(((!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) || + (!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) && temp_data32 == SUBGHZ_KEY_FILE_VERSION) { } else { FURI_LOG_E(TAG, "Type or version mismatch"); @@ -285,27 +285,29 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { break; } - if(!subghz_set_preset(subghz, string_get_cstr(temp_str))) { + if(!subghz_set_preset(subghz, furi_string_get_cstr(temp_str))) { break; } - if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { //Todo add Custom_preset_module //delete preset if it already exists subghz_setting_delete_custom_preset( - subghz->setting, string_get_cstr(subghz->txrx->preset->name)); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name)); //load custom preset from file if(!subghz_setting_load_custom_preset( - subghz->setting, string_get_cstr(subghz->txrx->preset->name), fff_data_file)) { + subghz->setting, + furi_string_get_cstr(subghz->txrx->preset->name), + fff_data_file)) { FURI_LOG_E(TAG, "Missing Custom preset"); break; } } size_t preset_index = subghz_setting_get_inx_preset_by_name( - subghz->setting, string_get_cstr(subghz->txrx->preset->name)); + subghz->setting, furi_string_get_cstr(subghz->txrx->preset->name)); subghz_preset_init( subghz, - string_get_cstr(subghz->txrx->preset->name), + furi_string_get_cstr(subghz->txrx->preset->name), subghz->txrx->preset->frequency, subghz_setting_get_preset_data(subghz->setting, preset_index), subghz_setting_get_preset_data_size(subghz->setting, preset_index)); @@ -314,7 +316,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { FURI_LOG_E(TAG, "Missing Protocol"); break; } - if(!strcmp(string_get_cstr(temp_str), "RAW")) { + if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) { //if RAW subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, file_path); } else { @@ -324,7 +326,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { } subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name( - subghz->txrx->receiver, string_get_cstr(temp_str)); + subghz->txrx->receiver, furi_string_get_cstr(temp_str)); if(subghz->txrx->decoder_result) { if(!subghz_protocol_decoder_base_deserialize( subghz->txrx->decoder_result, subghz->txrx->fff_data)) { @@ -338,7 +340,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) { load_key_state = SubGhzLoadKeyStateOK; } while(0); - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); @@ -362,42 +364,42 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { furi_assert(subghz); Storage* storage = furi_record_open(RECORD_STORAGE); - string_t temp_str; - string_t file_name; - string_t file_path; + FuriString* temp_str; + FuriString* file_name; + FuriString* file_path; - string_init(temp_str); - string_init(file_name); - string_init(file_path); + temp_str = furi_string_alloc(); + file_name = furi_string_alloc(); + file_path = furi_string_alloc(); bool res = false; if(subghz_path_is_file(subghz->file_path)) { //get the name of the next free file path_extract_filename(subghz->file_path, file_name, true); - path_extract_dirname(string_get_cstr(subghz->file_path), file_path); + path_extract_dirname(furi_string_get_cstr(subghz->file_path), file_path); storage_get_next_filename( storage, - string_get_cstr(file_path), - string_get_cstr(file_name), + furi_string_get_cstr(file_path), + furi_string_get_cstr(file_name), SUBGHZ_APP_EXTENSION, file_name, max_len); - string_printf( + furi_string_printf( temp_str, "%s/%s%s", - string_get_cstr(file_path), - string_get_cstr(file_name), + furi_string_get_cstr(file_path), + furi_string_get_cstr(file_name), SUBGHZ_APP_EXTENSION); - string_set(subghz->file_path, temp_str); + furi_string_set(subghz->file_path, temp_str); res = true; } - string_clear(temp_str); - string_clear(file_path); - string_clear(file_name); + furi_string_free(temp_str); + furi_string_free(file_path); + furi_string_free(file_name); furi_record_close(RECORD_STORAGE); return res; @@ -415,8 +417,8 @@ bool subghz_save_protocol_to_file( Stream* flipper_format_stream = flipper_format_get_raw_stream(flipper_format); bool saved = false; - string_t file_dir; - string_init(file_dir); + FuriString* file_dir; + file_dir = furi_string_alloc(); path_extract_dirname(dev_file_name, file_dir); do { @@ -425,7 +427,7 @@ bool subghz_save_protocol_to_file( flipper_format_delete_key(flipper_format, "Manufacture"); // Create subghz folder directory if necessary - if(!storage_simply_mkdir(storage, string_get_cstr(file_dir))) { + if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) { dialog_message_show_storage_error(subghz->dialogs, "Cannot create\nfolder"); break; } @@ -439,7 +441,7 @@ bool subghz_save_protocol_to_file( saved = true; } while(0); - string_clear(file_dir); + furi_string_free(file_dir); furi_record_close(RECORD_STORAGE); return saved; } @@ -447,8 +449,8 @@ bool subghz_save_protocol_to_file( bool subghz_load_protocol_from_file(SubGhz* subghz) { furi_assert(subghz); - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px); @@ -458,10 +460,10 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { subghz->dialogs, subghz->file_path, subghz->file_path, &browser_options); if(res) { - res = subghz_key_load(subghz, string_get_cstr(subghz->file_path), true); + res = subghz_key_load(subghz, furi_string_get_cstr(subghz->file_path), true); } - string_clear(file_path); + furi_string_free(file_path); return res; } @@ -472,9 +474,11 @@ bool subghz_rename_file(SubGhz* subghz) { Storage* storage = furi_record_open(RECORD_STORAGE); - if(string_cmp(subghz->file_path_tmp, subghz->file_path)) { + if(furi_string_cmp(subghz->file_path_tmp, subghz->file_path)) { FS_Error fs_result = storage_common_rename( - storage, string_get_cstr(subghz->file_path_tmp), string_get_cstr(subghz->file_path)); + storage, + furi_string_get_cstr(subghz->file_path_tmp), + furi_string_get_cstr(subghz->file_path)); if(fs_result != FSE_OK) { dialog_message_show_storage_error(subghz->dialogs, "Cannot rename\n file/directory"); @@ -490,7 +494,7 @@ bool subghz_delete_file(SubGhz* subghz) { furi_assert(subghz); Storage* storage = furi_record_open(RECORD_STORAGE); - bool result = storage_simply_remove(storage, string_get_cstr(subghz->file_path_tmp)); + bool result = storage_simply_remove(storage, furi_string_get_cstr(subghz->file_path_tmp)); furi_record_close(RECORD_STORAGE); subghz_file_name_clear(subghz); @@ -500,12 +504,12 @@ bool subghz_delete_file(SubGhz* subghz) { void subghz_file_name_clear(SubGhz* subghz) { furi_assert(subghz); - string_set_str(subghz->file_path, SUBGHZ_APP_FOLDER); - string_reset(subghz->file_path_tmp); + furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); + furi_string_reset(subghz->file_path_tmp); } -bool subghz_path_is_file(string_t path) { - return string_end_with_str_p(path, SUBGHZ_APP_EXTENSION); +bool subghz_path_is_file(FuriString* path) { + return furi_string_end_with(path, SUBGHZ_APP_EXTENSION); } uint32_t subghz_random_serial(void) { diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 99a0f8a28..58d307170 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -75,8 +75,8 @@ struct SubGhz { TextInput* text_input; Widget* widget; DialogsApp* dialogs; - string_t file_path; - string_t file_path_tmp; + FuriString* file_path; + FuriString* file_path_tmp; char file_name_tmp[SUBGHZ_MAX_LEN_NAME]; SubGhzNotificationState state_notifications; @@ -89,7 +89,7 @@ struct SubGhz { SubGhzTestStatic* subghz_test_static; SubGhzTestCarrier* subghz_test_carrier; SubGhzTestPacket* subghz_test_packet; - string_t error_str; + FuriString* error_str; SubGhzSetting* setting; SubGhzLock lock; @@ -103,7 +103,7 @@ void subghz_preset_init( uint8_t* preset_data, size_t preset_data_size); bool subghz_set_preset(SubGhz* subghz, const char* preset); -void subghz_get_frequency_modulation(SubGhz* subghz, string_t frequency, string_t modulation); +void subghz_get_frequency_modulation(SubGhz* subghz, FuriString* frequency, FuriString* modulation); void subghz_begin(SubGhz* subghz, uint8_t* preset_data); uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency); void subghz_rx_end(SubGhz* subghz); @@ -125,6 +125,6 @@ bool subghz_load_protocol_from_file(SubGhz* subghz); bool subghz_rename_file(SubGhz* subghz); bool subghz_delete_file(SubGhz* subghz); void subghz_file_name_clear(SubGhz* subghz); -bool subghz_path_is_file(string_t path); +bool subghz_path_is_file(FuriString* path); uint32_t subghz_random_serial(void); void subghz_hopper_update(SubGhz* subghz); diff --git a/applications/main/subghz/subghz_setting.c b/applications/main/subghz/subghz_setting.c index b7c143cd5..e0322f6a9 100644 --- a/applications/main/subghz/subghz_setting.c +++ b/applications/main/subghz/subghz_setting.c @@ -158,7 +158,7 @@ static const uint32_t subghz_hopper_frequency_list_region_jp[] = { }; typedef struct { - string_t custom_preset_name; + FuriString* custom_preset_name; uint8_t* custom_preset_data; size_t custom_preset_data_size; } SubGhzSettingCustomPresetItem; @@ -194,7 +194,7 @@ SubGhzSetting* subghz_setting_alloc(void) { static void subghz_setting_preset_reset(SubGhzSetting* instance) { for M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - string_clear(item->custom_preset_name); + furi_string_free(item->custom_preset_name); free(item->custom_preset_data); } SubGhzSettingCustomPresetItemArray_reset(instance->preset->data); @@ -206,7 +206,7 @@ void subghz_setting_free(SubGhzSetting* instance) { FrequencyList_clear(instance->hopper_frequencies); for M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - string_clear(item->custom_preset_name); + furi_string_free(item->custom_preset_name); free(item->custom_preset_data); } SubGhzSettingCustomPresetItemArray_clear(instance->preset->data); @@ -225,8 +225,8 @@ static void subghz_setting_load_default_preset( SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_push_raw(instance->preset->data); - string_init(item->custom_preset_name); - string_set(item->custom_preset_name, preset_name); + item->custom_preset_name = furi_string_alloc(); + furi_string_set(item->custom_preset_name, preset_name); while(preset_data[preset_data_count]) { preset_data_count += 2; @@ -314,8 +314,8 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t temp_data32; bool temp_bool; @@ -333,7 +333,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { break; } - if((!strcmp(string_get_cstr(temp_str), SUBGHZ_SETTING_FILE_TYPE)) && + if((!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_SETTING_FILE_TYPE)) && temp_data32 == SUBGHZ_SETTING_FILE_VERSION) { } else { FURI_LOG_E(TAG, "Type or version mismatch"); @@ -402,15 +402,15 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { break; } while(flipper_format_read_string(fff_data_file, "Custom_preset_name", temp_str)) { - FURI_LOG_I(TAG, "Custom preset loaded %s", string_get_cstr(temp_str)); + FURI_LOG_I(TAG, "Custom preset loaded %s", furi_string_get_cstr(temp_str)); subghz_setting_load_custom_preset( - instance, string_get_cstr(temp_str), fff_data_file); + instance, furi_string_get_cstr(temp_str), fff_data_file); } } while(false); } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(fff_data_file); furi_record_close(RECORD_STORAGE); @@ -440,7 +440,7 @@ const char* subghz_setting_get_preset_name(SubGhzSetting* instance, size_t idx) furi_assert(instance); SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); - return string_get_cstr(item->custom_preset_name); + return furi_string_get_cstr(item->custom_preset_name); } int subghz_setting_get_inx_preset_by_name(SubGhzSetting* instance, const char* preset_name) { @@ -448,7 +448,7 @@ int subghz_setting_get_inx_preset_by_name(SubGhzSetting* instance, const char* p size_t idx = 0; for M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - if(strcmp(string_get_cstr(item->custom_preset_name), preset_name) == 0) { + if(strcmp(furi_string_get_cstr(item->custom_preset_name), preset_name) == 0) { return idx; } idx++; @@ -466,8 +466,8 @@ bool subghz_setting_load_custom_preset( uint32_t temp_data32; SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_push_raw(instance->preset->data); - string_init(item->custom_preset_name); - string_set(item->custom_preset_name, preset_name); + item->custom_preset_name = furi_string_alloc(); + furi_string_set(item->custom_preset_name, preset_name); do { if(!flipper_format_get_value_count(fff_data_file, "Custom_preset_data", &temp_data32)) break; @@ -497,8 +497,8 @@ bool subghz_setting_delete_custom_preset(SubGhzSetting* instance, const char* pr SubGhzSettingCustomPresetItemArray_it_last(it, instance->preset->data); while(!SubGhzSettingCustomPresetItemArray_end_p(it)) { SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_ref(it); - if(strcmp(string_get_cstr(item->custom_preset_name), preset_name) == 0) { - string_clear(item->custom_preset_name); + if(strcmp(furi_string_get_cstr(item->custom_preset_name), preset_name) == 0) { + furi_string_free(item->custom_preset_name); free(item->custom_preset_data); SubGhzSettingCustomPresetItemArray_remove(instance->preset->data, it); return true; diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index c28c33636..cdebc6320 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #define FRAME_HEIGHT 12 @@ -14,7 +13,7 @@ #define UNLOCK_CNT 3 typedef struct { - string_t item_str; + FuriString* item_str; uint8_t type; } SubGhzReceiverMenuItem; @@ -52,9 +51,9 @@ struct SubGhzViewReceiver { }; typedef struct { - string_t frequency_str; - string_t preset_str; - string_t history_stat_str; + FuriString* frequency_str; + FuriString* preset_str; + FuriString* history_stat_str; SubGhzReceiverHistory* history; uint16_t idx; uint16_t list_offset; @@ -68,17 +67,17 @@ void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLo if(lock == SubGhzLockOn) { subghz_receiver->lock = lock; with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowLock; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowLock; }, + true); furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(1000)); } else { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowDefault; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowDefault; }, + true); } } @@ -96,7 +95,9 @@ static void subghz_view_receiver_update_offset(SubGhzViewReceiver* subghz_receiv furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { size_t history_item = model->history_item; uint16_t bounds = history_item > 3 ? 2 : history_item; @@ -108,8 +109,8 @@ static void subghz_view_receiver_update_offset(SubGhzViewReceiver* subghz_receiv } else if(model->list_offset > model->idx - bounds) { model->list_offset = CLAMP(model->idx - 1, (int16_t)(history_item - bounds), 0); } - return true; - }); + }, + true); } void subghz_view_receiver_add_item_to_menu( @@ -118,10 +119,12 @@ void subghz_view_receiver_add_item_to_menu( uint8_t type) { furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { SubGhzReceiverMenuItem* item_menu = SubGhzReceiverMenuItemArray_push_raw(model->history->data); - string_init_set_str(item_menu->item_str, name); + item_menu->item_str = furi_string_alloc_set(name); item_menu->type = type; if((model->idx == model->history_item - 1)) { model->history_item++; @@ -129,9 +132,8 @@ void subghz_view_receiver_add_item_to_menu( } else { model->history_item++; } - - return true; - }); + }, + true); subghz_view_receiver_update_offset(subghz_receiver); } @@ -142,12 +144,14 @@ void subghz_view_receiver_add_data_statusbar( const char* history_stat_str) { furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); - string_set_str(model->history_stat_str, history_stat_str); - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { + furi_string_set(model->frequency_str, frequency_str); + furi_string_set(model->preset_str, preset_str); + furi_string_set(model->history_stat_str, history_stat_str); + }, + true); } static void subghz_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { @@ -173,15 +177,15 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_line(canvas, 46, 51, 125, 51); bool scrollbar = model->history_item > 4; - string_t str_buff; - string_init(str_buff); + FuriString* str_buff; + str_buff = furi_string_alloc(); SubGhzReceiverMenuItem* item_menu; for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0); item_menu = SubGhzReceiverMenuItemArray_get(model->history->data, idx); - string_set(str_buff, item_menu->item_str); + furi_string_set(str_buff, item_menu->item_str); elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX); if(model->idx == idx) { subghz_view_receiver_draw_frame(canvas, i, scrollbar); @@ -189,13 +193,13 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_set_color(canvas, ColorBlack); } canvas_draw_icon(canvas, 1, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]); - canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, string_get_cstr(str_buff)); - string_reset(str_buff); + canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff)); + furi_string_reset(str_buff); } if(scrollbar) { elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item); } - string_clear(str_buff); + furi_string_free(str_buff); canvas_set_color(canvas, ColorBlack); @@ -213,9 +217,9 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_str(canvas, 74, 62, "Locked"); break; case SubGhzViewReceiverBarShowToUnlockPress: - canvas_draw_str(canvas, 44, 62, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, string_get_cstr(model->history_stat_str)); + canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); + canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); canvas_set_font(canvas, FontSecondary); elements_bold_rounded_frame(canvas, 14, 8, 99, 48); elements_multiline_text(canvas, 65, 26, "To unlock\npress:"); @@ -230,9 +234,9 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_str(canvas, 74, 62, "Unlocked"); break; default: - canvas_draw_str(canvas, 44, 62, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 79, 62, string_get_cstr(model->preset_str)); - canvas_draw_str(canvas, 96, 62, string_get_cstr(model->history_stat_str)); + canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str)); + canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); break; } } @@ -241,10 +245,10 @@ static void subghz_view_receiver_timer_callback(void* context) { furi_assert(context); SubGhzViewReceiver* subghz_receiver = context; with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowDefault; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowDefault; }, + true); if(subghz_receiver->lock_count < UNLOCK_CNT) { subghz_receiver->callback( SubGhzCustomEventViewReceiverOffDisplay, subghz_receiver->context); @@ -261,10 +265,10 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { if(subghz_receiver->lock == SubGhzLockOn) { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowToUnlockPress; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowToUnlockPress; }, + true); if(subghz_receiver->lock_count == 0) { furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(1000)); } @@ -275,10 +279,10 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { // subghz_receiver->callback( // SubGhzCustomEventViewReceiverUnlock, subghz_receiver->context); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - model->bar_show = SubGhzViewReceiverBarShowUnlock; - return true; - }); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->bar_show = SubGhzViewReceiverBarShowUnlock; }, + true); //subghz_receiver->lock = SubGhzLockOff; furi_timer_start(subghz_receiver->timer, pdMS_TO_TICKS(650)); } @@ -292,29 +296,35 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { event->key == InputKeyUp && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { if(model->idx != 0) model->idx--; - return true; - }); + }, + true); } else if( event->key == InputKeyDown && (event->type == InputTypeShort || event->type == InputTypeRepeat)) { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { if(model->idx != model->history_item - 1) model->idx++; - return true; - }); + }, + true); } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { subghz_receiver->callback(SubGhzCustomEventViewReceiverConfig, subghz_receiver->context); } else if(event->key == InputKeyOk && event->type == InputTypeShort) { with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { if(model->history_item != 0) { subghz_receiver->callback( SubGhzCustomEventViewReceiverOK, subghz_receiver->context); } - return false; - }); + }, + false); } subghz_view_receiver_update_offset(subghz_receiver); @@ -330,21 +340,23 @@ void subghz_view_receiver_exit(void* context) { furi_assert(context); SubGhzViewReceiver* subghz_receiver = context; with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_reset(model->frequency_str); - string_reset(model->preset_str); - string_reset(model->history_stat_str); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { + furi_string_reset(model->frequency_str); + furi_string_reset(model->preset_str); + furi_string_reset(model->history_stat_str); for M_EACH(item_menu, model->history->data, SubGhzReceiverMenuItemArray_t) { - string_clear(item_menu->item_str); + furi_string_free(item_menu->item_str); item_menu->type = 0; } SubGhzReceiverMenuItemArray_reset(model->history->data); model->idx = 0; model->list_offset = 0; model->history_item = 0; - return false; - }); + }, + false); furi_timer_stop(subghz_receiver->timer); } @@ -365,15 +377,17 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() { view_set_exit_callback(subghz_receiver->view, subghz_view_receiver_exit); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_init(model->frequency_str); - string_init(model->preset_str); - string_init(model->history_stat_str); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { + model->frequency_str = furi_string_alloc(); + model->preset_str = furi_string_alloc(); + model->history_stat_str = furi_string_alloc(); model->bar_show = SubGhzViewReceiverBarShowDefault; model->history = malloc(sizeof(SubGhzReceiverHistory)); SubGhzReceiverMenuItemArray_init(model->history->data); - return true; - }); + }, + true); subghz_receiver->timer = furi_timer_alloc(subghz_view_receiver_timer_callback, FuriTimerTypeOnce, subghz_receiver); return subghz_receiver; @@ -383,19 +397,21 @@ void subghz_view_receiver_free(SubGhzViewReceiver* subghz_receiver) { furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - string_clear(model->frequency_str); - string_clear(model->preset_str); - string_clear(model->history_stat_str); + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { + furi_string_free(model->frequency_str); + furi_string_free(model->preset_str); + furi_string_free(model->history_stat_str); for M_EACH(item_menu, model->history->data, SubGhzReceiverMenuItemArray_t) { - string_clear(item_menu->item_str); + furi_string_free(item_menu->item_str); item_menu->type = 0; } SubGhzReceiverMenuItemArray_clear(model->history->data); free(model->history); - return false; - }); + }, + false); furi_timer_free(subghz_receiver->timer); view_free(subghz_receiver->view); free(subghz_receiver); @@ -410,20 +426,19 @@ uint16_t subghz_view_receiver_get_idx_menu(SubGhzViewReceiver* subghz_receiver) furi_assert(subghz_receiver); uint32_t idx = 0; with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { - idx = model->idx; - return false; - }); + subghz_receiver->view, SubGhzViewReceiverModel * model, { idx = model->idx; }, false); return idx; } void subghz_view_receiver_set_idx_menu(SubGhzViewReceiver* subghz_receiver, uint16_t idx) { furi_assert(subghz_receiver); with_view_model( - subghz_receiver->view, (SubGhzViewReceiverModel * model) { + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->idx = idx; if(model->idx > 2) model->list_offset = idx - 2; - return true; - }); + }, + true); subghz_view_receiver_update_offset(subghz_receiver); } diff --git a/applications/main/subghz/views/subghz_frequency_analyzer.c b/applications/main/subghz/views/subghz_frequency_analyzer.c index d3f773159..c169f3611 100644 --- a/applications/main/subghz/views/subghz_frequency_analyzer.c +++ b/applications/main/subghz/views/subghz_frequency_analyzer.c @@ -25,6 +25,8 @@ struct SubGhzFrequencyAnalyzer { typedef struct { uint32_t frequency; float rssi; + uint32_t history_frequency[3]; + bool signal; } SubGhzFrequencyAnalyzerModel; void subghz_frequency_analyzer_set_callback( @@ -38,8 +40,8 @@ void subghz_frequency_analyzer_set_callback( } void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, float rssi) { - uint8_t x = 48; - uint8_t y = 56; + uint8_t x = 20; + uint8_t y = 64; uint8_t column_number = 0; if(rssi) { rssi = (rssi + 90) / 3; @@ -53,6 +55,31 @@ void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, float rssi) { } } +static void subghz_frequency_analyzer_history_frequency_draw( + Canvas* canvas, + SubGhzFrequencyAnalyzerModel* model) { + char buffer[64]; + uint8_t x = 66; + uint8_t y = 43; + + canvas_set_font(canvas, FontKeyboard); + for(uint8_t i = 0; i < 3; i++) { + if(model->history_frequency[i]) { + snprintf( + buffer, + sizeof(buffer), + "%03ld.%03ld", + model->history_frequency[i] / 1000000 % 1000, + model->history_frequency[i] / 1000 % 1000); + canvas_draw_str(canvas, x, y + i * 10, buffer); + } else { + canvas_draw_str(canvas, x, y + i * 10, "---.---"); + } + canvas_draw_str(canvas, x + 44, y + i * 10, "MHz"); + } + canvas_set_font(canvas, FontSecondary); +} + void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel* model) { char buffer[64]; @@ -60,9 +87,11 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 20, 8, "Frequency Analyzer"); - canvas_draw_str(canvas, 28, 60, "RSSI"); + canvas_draw_str(canvas, 0, 64, "RSSI"); subghz_frequency_analyzer_draw_rssi(canvas, model->rssi); + subghz_frequency_analyzer_history_frequency_draw(canvas, model); + //Frequency canvas_set_font(canvas, FontBigNumbers); snprintf( @@ -71,8 +100,14 @@ void subghz_frequency_analyzer_draw(Canvas* canvas, SubGhzFrequencyAnalyzerModel "%03ld.%03ld", model->frequency / 1000000 % 1000, model->frequency / 1000 % 1000); - canvas_draw_str(canvas, 8, 35, buffer); - canvas_draw_icon(canvas, 96, 24, &I_MHz_25x11); + if(model->signal) { + canvas_draw_box(canvas, 4, 12, 121, 22); + canvas_set_color(canvas, ColorWhite); + } else { + } + + canvas_draw_str(canvas, 8, 30, buffer); + canvas_draw_icon(canvas, 96, 19, &I_MHz_25x11); } bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { @@ -85,12 +120,26 @@ bool subghz_frequency_analyzer_input(InputEvent* event, void* context) { return true; } -void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, float rssi) { +void subghz_frequency_analyzer_pair_callback( + void* context, + uint32_t frequency, + float rssi, + bool signal) { SubGhzFrequencyAnalyzer* instance = context; if((rssi == 0.f) && (instance->locked)) { if(instance->callback) { instance->callback(SubGhzCustomEventSceneAnalyzerUnlock, instance->context); } + //update history + with_view_model( + instance->view, + SubGhzFrequencyAnalyzerModel * model, + { + model->history_frequency[2] = model->history_frequency[1]; + model->history_frequency[1] = model->history_frequency[0]; + model->history_frequency[0] = model->frequency; + }, + false); } else if((rssi != 0.f) && (!instance->locked)) { if(instance->callback) { instance->callback(SubGhzCustomEventSceneAnalyzerLock, instance->context); @@ -99,11 +148,14 @@ void subghz_frequency_analyzer_pair_callback(void* context, uint32_t frequency, instance->locked = (rssi != 0.f); with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { + instance->view, + SubGhzFrequencyAnalyzerModel * model, + { model->rssi = rssi; model->frequency = frequency; - return true; - }); + model->signal = signal; + }, + true); } void subghz_frequency_analyzer_enter(void* context) { @@ -121,11 +173,16 @@ void subghz_frequency_analyzer_enter(void* context) { subghz_frequency_analyzer_worker_start(instance->worker); with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { + instance->view, + SubGhzFrequencyAnalyzerModel * model, + { model->rssi = 0; model->frequency = 0; - return true; - }); + model->history_frequency[2] = 0; + model->history_frequency[1] = 0; + model->history_frequency[0] = 0; + }, + true); } void subghz_frequency_analyzer_exit(void* context) { @@ -139,10 +196,7 @@ void subghz_frequency_analyzer_exit(void* context) { subghz_frequency_analyzer_worker_free(instance->worker); with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { - model->rssi = 0; - return true; - }); + instance->view, SubGhzFrequencyAnalyzerModel * model, { model->rssi = 0; }, true); } SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc() { @@ -159,10 +213,7 @@ SubGhzFrequencyAnalyzer* subghz_frequency_analyzer_alloc() { view_set_exit_callback(instance->view, subghz_frequency_analyzer_exit); with_view_model( - instance->view, (SubGhzFrequencyAnalyzerModel * model) { - model->rssi = 0; - return true; - }); + instance->view, SubGhzFrequencyAnalyzerModel * model, { model->rssi = 0; }, true); return instance; } diff --git a/applications/main/subghz/views/subghz_read_raw.c b/applications/main/subghz/views/subghz_read_raw.c index ccffaf42f..2d951b11a 100644 --- a/applications/main/subghz/views/subghz_read_raw.c +++ b/applications/main/subghz/views/subghz_read_raw.c @@ -18,10 +18,10 @@ struct SubGhzReadRAW { }; typedef struct { - string_t frequency_str; - string_t preset_str; - string_t sample_write; - string_t file_name; + FuriString* frequency_str; + FuriString* preset_str; + FuriString* sample_write; + FuriString* file_name; uint8_t* rssi_history; bool rssi_history_end; uint8_t ind_write; @@ -45,11 +45,13 @@ void subghz_read_raw_add_data_statusbar( const char* preset_str) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); - return true; - }); + instance->view, + SubGhzReadRAWModel * model, + { + furi_string_set(model->frequency_str, frequency_str); + furi_string_set(model->preset_str, preset_str); + }, + true); } void subghz_read_raw_add_data_rssi(SubGhzReadRAW* instance, float rssi) { @@ -63,31 +65,35 @@ void subghz_read_raw_add_data_rssi(SubGhzReadRAW* instance, float rssi) { } with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->rssi_history[model->ind_write++] = u_rssi; if(model->ind_write > SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE) { model->rssi_history_end = true; model->ind_write = 0; } - return true; - }); + }, + true); } void subghz_read_raw_update_sample_write(SubGhzReadRAW* instance, size_t sample) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - string_printf(model->sample_write, "%d spl.", sample); - return false; - }); + instance->view, + SubGhzReadRAWModel * model, + { furi_string_printf(model->sample_write, "%d spl.", sample); }, + false); } void subghz_read_raw_stop_send(SubGhzReadRAW* instance) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { switch(model->status) { case SubGhzReadRAWStatusTXRepeat: case SubGhzReadRAWStatusLoadKeyTXRepeat: @@ -105,19 +111,21 @@ void subghz_read_raw_stop_send(SubGhzReadRAW* instance) { model->status = SubGhzReadRAWStatusIDLE; break; } - return true; - }); + }, + true); } void subghz_read_raw_update_sin(SubGhzReadRAW* instance) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->ind_sin++ > 62) { model->ind_sin = 0; } - return true; - }); + }, + true); } static int8_t subghz_read_raw_tab_sin(uint8_t x) { @@ -216,10 +224,10 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) { uint8_t graphics_mode = 1; canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 5, 7, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 40, 7, string_get_cstr(model->preset_str)); + canvas_draw_str(canvas, 5, 7, furi_string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 40, 7, furi_string_get_cstr(model->preset_str)); canvas_draw_str_aligned( - canvas, 126, 0, AlignRight, AlignTop, string_get_cstr(model->sample_write)); + canvas, 126, 0, AlignRight, AlignTop, furi_string_get_cstr(model->sample_write)); canvas_draw_line(canvas, 0, 14, 115, 14); canvas_draw_line(canvas, 0, 48, 115, 48); @@ -243,7 +251,7 @@ void subghz_read_raw_draw(Canvas* canvas, SubGhzReadRAWModel* model) { 30, AlignCenter, AlignCenter, - string_get_cstr(model->file_name), + furi_string_get_cstr(model->file_name), true); break; @@ -286,9 +294,11 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { //further check of events is not needed, we exit return false; } else if(event->key == InputKeyOk && event->type == InputTypePress) { + uint8_t ret = false; with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - uint8_t ret = false; + instance->view, + SubGhzReadRAWModel * model, + { switch(model->status) { case SubGhzReadRAWStatusIDLE: // Start TX @@ -314,11 +324,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { default: break; } - return ret; - }); + }, + ret); } else if(event->key == InputKeyOk && event->type == InputTypeRelease) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status == SubGhzReadRAWStatusTXRepeat) { // Stop repeat TX model->status = SubGhzReadRAWStatusTX; @@ -326,11 +338,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { // Stop repeat TX model->status = SubGhzReadRAWStatusLoadKeyTX; } - return false; - }); + }, + false); } else if(event->key == InputKeyBack && event->type == InputTypeShort) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { switch(model->status) { case SubGhzReadRAWStatusREC: //Stop REC @@ -357,11 +371,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { instance->callback(SubGhzCustomEventViewReadRAWBack, instance->context); break; } - return true; - }); + }, + true); } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status == SubGhzReadRAWStatusStart) { //Config instance->callback(SubGhzCustomEventViewReadRAWConfig, instance->context); @@ -372,15 +388,17 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { model->status = SubGhzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; - string_set_str(model->sample_write, "0 spl."); - string_reset(model->file_name); + furi_string_set(model->sample_write, "0 spl."); + furi_string_reset(model->file_name); instance->callback(SubGhzCustomEventViewReadRAWErase, instance->context); } - return true; - }); + }, + true); } else if(event->key == InputKeyRight && event->type == InputTypeShort) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status == SubGhzReadRAWStatusIDLE) { //Save instance->callback(SubGhzCustomEventViewReadRAWSave, instance->context); @@ -388,11 +406,13 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { //More instance->callback(SubGhzCustomEventViewReadRAWMore, instance->context); } - return true; - }); + }, + true); } else if(event->key == InputKeyOk && event->type == InputTypeShort) { with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status == SubGhzReadRAWStatusStart) { //Record instance->callback(SubGhzCustomEventViewReadRAWREC, instance->context); @@ -404,8 +424,8 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { instance->callback(SubGhzCustomEventViewReadRAWIDLE, instance->context); model->status = SubGhzReadRAWStatusIDLE; } - return true; - }); + }, + true); } return true; } @@ -419,45 +439,51 @@ void subghz_read_raw_set_status( switch(status) { case SubGhzReadRAWStatusStart: with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->status = SubGhzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; - string_reset(model->file_name); - string_set_str(model->sample_write, "0 spl."); - return true; - }); + furi_string_reset(model->file_name); + furi_string_set(model->sample_write, "0 spl."); + }, + true); break; case SubGhzReadRAWStatusIDLE: with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - model->status = SubGhzReadRAWStatusIDLE; - return true; - }); + instance->view, + SubGhzReadRAWModel * model, + { model->status = SubGhzReadRAWStatusIDLE; }, + true); break; case SubGhzReadRAWStatusLoadKeyTX: with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->status = SubGhzReadRAWStatusLoadKeyIDLE; model->rssi_history_end = false; model->ind_write = 0; - string_set_str(model->file_name, file_name); - string_set_str(model->sample_write, "RAW"); - return true; - }); + furi_string_set(model->file_name, file_name); + furi_string_set(model->sample_write, "RAW"); + }, + true); break; case SubGhzReadRAWStatusSaveKey: with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { model->status = SubGhzReadRAWStatusLoadKeyIDLE; if(!model->ind_write) { - string_set_str(model->file_name, file_name); - string_set_str(model->sample_write, "RAW"); + furi_string_set(model->file_name, file_name); + furi_string_set(model->sample_write, "RAW"); } else { - string_reset(model->file_name); + furi_string_reset(model->file_name); } - return true; - }); + }, + true); break; default: @@ -476,15 +502,17 @@ void subghz_read_raw_exit(void* context) { SubGhzReadRAW* instance = context; with_view_model( - instance->view, (SubGhzReadRAWModel * model) { + instance->view, + SubGhzReadRAWModel * model, + { if(model->status != SubGhzReadRAWStatusIDLE && model->status != SubGhzReadRAWStatusStart && model->status != SubGhzReadRAWStatusLoadKeyIDLE) { instance->callback(SubGhzCustomEventViewReadRAWIDLE, instance->context); model->status = SubGhzReadRAWStatusStart; } - return true; - }); + }, + true); } SubGhzReadRAW* subghz_read_raw_alloc() { @@ -500,14 +528,16 @@ SubGhzReadRAW* subghz_read_raw_alloc() { view_set_exit_callback(instance->view, subghz_read_raw_exit); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - string_init(model->frequency_str); - string_init(model->preset_str); - string_init(model->sample_write); - string_init(model->file_name); + instance->view, + SubGhzReadRAWModel * model, + { + model->frequency_str = furi_string_alloc(); + model->preset_str = furi_string_alloc(); + model->sample_write = furi_string_alloc(); + model->file_name = furi_string_alloc(); model->rssi_history = malloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); - return true; - }); + }, + true); return instance; } @@ -516,14 +546,16 @@ void subghz_read_raw_free(SubGhzReadRAW* instance) { furi_assert(instance); with_view_model( - instance->view, (SubGhzReadRAWModel * model) { - string_clear(model->frequency_str); - string_clear(model->preset_str); - string_clear(model->sample_write); - string_clear(model->file_name); + instance->view, + SubGhzReadRAWModel * model, + { + furi_string_free(model->frequency_str); + furi_string_free(model->preset_str); + furi_string_free(model->sample_write); + furi_string_free(model->file_name); free(model->rssi_history); - return true; - }); + }, + true); view_free(instance->view); free(instance); } diff --git a/applications/main/subghz/views/subghz_test_carrier.c b/applications/main/subghz/views/subghz_test_carrier.c index 6729eaad8..e533a6aac 100644 --- a/applications/main/subghz/views/subghz_test_carrier.c +++ b/applications/main/subghz/views/subghz_test_carrier.c @@ -89,7 +89,9 @@ bool subghz_test_carrier_input(InputEvent* event, void* context) { } with_view_model( - subghz_test_carrier->view, (SubGhzTestCarrierModel * model) { + subghz_test_carrier->view, + SubGhzTestCarrierModel * model, + { furi_hal_subghz_idle(); if(event->key == InputKeyLeft) { @@ -125,9 +127,8 @@ bool subghz_test_carrier_input(InputEvent* event, void* context) { SubGhzTestCarrierEventOnlyRx, subghz_test_carrier->context); } } - - return true; - }); + }, + true); return true; } @@ -142,15 +143,17 @@ void subghz_test_carrier_enter(void* context) { furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); with_view_model( - subghz_test_carrier->view, (SubGhzTestCarrierModel * model) { + subghz_test_carrier->view, + SubGhzTestCarrierModel * model, + { model->frequency = subghz_frequencies_433_92_testing; // 433 model->real_frequency = furi_hal_subghz_set_frequency(subghz_frequencies_testing[model->frequency]); model->path = FuriHalSubGhzPathIsolate; // isolate model->rssi = 0.0f; model->status = SubGhzTestCarrierModelStatusRx; - return true; - }); + }, + true); furi_hal_subghz_rx(); @@ -172,13 +175,14 @@ void subghz_test_carrier_rssi_timer_callback(void* context) { SubGhzTestCarrier* subghz_test_carrier = context; with_view_model( - subghz_test_carrier->view, (SubGhzTestCarrierModel * model) { + subghz_test_carrier->view, + SubGhzTestCarrierModel * model, + { if(model->status == SubGhzTestCarrierModelStatusRx) { model->rssi = furi_hal_subghz_get_rssi(); - return true; } - return false; - }); + }, + false); } SubGhzTestCarrier* subghz_test_carrier_alloc() { diff --git a/applications/main/subghz/views/subghz_test_packet.c b/applications/main/subghz/views/subghz_test_packet.c index c83aebec9..a42898f77 100644 --- a/applications/main/subghz/views/subghz_test_packet.c +++ b/applications/main/subghz/views/subghz_test_packet.c @@ -68,7 +68,9 @@ static void subghz_test_packet_rssi_timer_callback(void* context) { SubGhzTestPacket* instance = context; with_view_model( - instance->view, (SubGhzTestPacketModel * model) { + instance->view, + SubGhzTestPacketModel * model, + { if(model->status == SubGhzTestPacketModelStatusRx) { model->rssi = furi_hal_subghz_get_rssi(); model->packets = instance->packet_rx; @@ -77,8 +79,8 @@ static void subghz_test_packet_rssi_timer_callback(void* context) { SUBGHZ_TEST_PACKET_COUNT - subghz_encoder_princeton_for_testing_get_repeat_left(instance->encoder); } - return true; - }); + }, + true); } static void subghz_test_packet_draw(Canvas* canvas, SubGhzTestPacketModel* model) { @@ -137,7 +139,9 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { } with_view_model( - instance->view, (SubGhzTestPacketModel * model) { + instance->view, + SubGhzTestPacketModel * model, + { if(model->status == SubGhzTestPacketModelStatusRx) { furi_hal_subghz_stop_async_rx(); } else if(model->status == SubGhzTestPacketModelStatusTx) { @@ -179,9 +183,8 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { instance->callback(SubGhzTestPacketEventOnlyRx, instance->context); } } - - return true; - }); + }, + true); return true; } @@ -194,15 +197,17 @@ void subghz_test_packet_enter(void* context) { furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); with_view_model( - instance->view, (SubGhzTestPacketModel * model) { + instance->view, + SubGhzTestPacketModel * model, + { model->frequency = subghz_frequencies_433_92_testing; model->real_frequency = furi_hal_subghz_set_frequency(subghz_frequencies_testing[model->frequency]); model->path = FuriHalSubGhzPathIsolate; // isolate model->rssi = 0.0f; model->status = SubGhzTestPacketModelStatusRx; - return true; - }); + }, + true); furi_hal_subghz_start_async_rx(subghz_test_packet_rx_callback, instance); @@ -217,15 +222,17 @@ void subghz_test_packet_exit(void* context) { // Reinitialize IC to default state with_view_model( - instance->view, (SubGhzTestPacketModel * model) { + instance->view, + SubGhzTestPacketModel * model, + { if(model->status == SubGhzTestPacketModelStatusRx) { furi_hal_subghz_stop_async_rx(); } else if(model->status == SubGhzTestPacketModelStatusTx) { subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_get_tick()); furi_hal_subghz_stop_async_tx(); } - return true; - }); + }, + true); furi_hal_subghz_sleep(); } diff --git a/applications/main/subghz/views/subghz_test_static.c b/applications/main/subghz/views/subghz_test_static.c index 7af54c3c0..6abefda76 100644 --- a/applications/main/subghz/views/subghz_test_static.c +++ b/applications/main/subghz/views/subghz_test_static.c @@ -77,7 +77,9 @@ bool subghz_test_static_input(InputEvent* event, void* context) { } with_view_model( - instance->view, (SubGhzTestStaticModel * model) { + instance->view, + SubGhzTestStaticModel * model, + { if(event->type == InputTypeShort) { if(event->key == InputKeyLeft) { if(model->frequency > 0) model->frequency--; @@ -128,9 +130,8 @@ bool subghz_test_static_input(InputEvent* event, void* context) { } furi_record_close(RECORD_NOTIFICATION); } - - return true; - }); + }, + true); return true; } @@ -147,13 +148,14 @@ void subghz_test_static_enter(void* context) { instance->status_tx = SubGhzTestStaticStatusIDLE; with_view_model( - instance->view, (SubGhzTestStaticModel * model) { + instance->view, + SubGhzTestStaticModel * model, + { model->frequency = subghz_frequencies_433_92_testing; model->real_frequency = subghz_frequencies_testing[model->frequency]; model->button = 0; - - return true; - }); + }, + true); } void subghz_test_static_exit(void* context) { diff --git a/applications/main/subghz/views/transmitter.c b/applications/main/subghz/views/transmitter.c index dd2b6d321..833805ccb 100644 --- a/applications/main/subghz/views/transmitter.c +++ b/applications/main/subghz/views/transmitter.c @@ -11,9 +11,9 @@ struct SubGhzViewTransmitter { }; typedef struct { - string_t frequency_str; - string_t preset_str; - string_t key_str; + FuriString* frequency_str; + FuriString* preset_str; + FuriString* key_str; uint8_t show_button; } SubGhzViewTransmitterModel; @@ -35,13 +35,15 @@ void subghz_view_transmitter_add_data_to_show( uint8_t show_button) { furi_assert(subghz_transmitter); with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_set_str(model->key_str, key_str); - string_set_str(model->frequency_str, frequency_str); - string_set_str(model->preset_str, preset_str); + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { + furi_string_set(model->key_str, key_str); + furi_string_set(model->frequency_str, frequency_str); + furi_string_set(model->preset_str, preset_str); model->show_button = show_button; - return true; - }); + }, + true); } static void subghz_view_transmitter_button_right(Canvas* canvas, const char* str) { @@ -82,9 +84,9 @@ void subghz_view_transmitter_draw(Canvas* canvas, SubGhzViewTransmitterModel* mo canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - elements_multiline_text(canvas, 0, 8, string_get_cstr(model->key_str)); - canvas_draw_str(canvas, 78, 8, string_get_cstr(model->frequency_str)); - canvas_draw_str(canvas, 113, 8, string_get_cstr(model->preset_str)); + elements_multiline_text(canvas, 0, 8, furi_string_get_cstr(model->key_str)); + canvas_draw_str(canvas, 78, 8, furi_string_get_cstr(model->frequency_str)); + canvas_draw_str(canvas, 113, 8, furi_string_get_cstr(model->preset_str)); if(model->show_button) subghz_view_transmitter_button_right(canvas, "Send"); } @@ -95,23 +97,27 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { if(event->key == InputKeyBack && event->type == InputTypeShort) { with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_reset(model->frequency_str); - string_reset(model->preset_str); - string_reset(model->key_str); + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { + furi_string_reset(model->frequency_str); + furi_string_reset(model->preset_str); + furi_string_reset(model->key_str); model->show_button = 0; - return false; - }); + }, + false); return false; } with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { if(model->show_button) { can_be_sent = true; } - return true; - }); + }, + true); if(can_be_sent && event->key == InputKeyOk && event->type == InputTypePress) { subghz_transmitter->callback( @@ -149,12 +155,14 @@ SubGhzViewTransmitter* subghz_view_transmitter_alloc() { view_set_exit_callback(subghz_transmitter->view, subghz_view_transmitter_exit); with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_init(model->frequency_str); - string_init(model->preset_str); - string_init(model->key_str); - return true; - }); + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { + model->frequency_str = furi_string_alloc(); + model->preset_str = furi_string_alloc(); + model->key_str = furi_string_alloc(); + }, + true); return subghz_transmitter; } @@ -162,12 +170,14 @@ void subghz_view_transmitter_free(SubGhzViewTransmitter* subghz_transmitter) { furi_assert(subghz_transmitter); with_view_model( - subghz_transmitter->view, (SubGhzViewTransmitterModel * model) { - string_clear(model->frequency_str); - string_clear(model->preset_str); - string_clear(model->key_str); - return true; - }); + subghz_transmitter->view, + SubGhzViewTransmitterModel * model, + { + furi_string_free(model->frequency_str); + furi_string_free(model->preset_str); + furi_string_free(model->key_str); + }, + true); view_free(subghz_transmitter->view); free(subghz_transmitter); } diff --git a/applications/main/u2f/u2f_data.c b/applications/main/u2f/u2f_data.c index 117fbdbe3..900af462a 100644 --- a/applications/main/u2f/u2f_data.c +++ b/applications/main/u2f/u2f_data.c @@ -181,8 +181,8 @@ bool u2f_data_cert_key_load(uint8_t* cert_key) { // Check if unique key exists in secure eclave and generate it if missing if(!furi_hal_crypto_verify_key(U2F_DATA_FILE_ENCRYPTION_KEY_SLOT_UNIQUE)) return false; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); @@ -194,7 +194,7 @@ bool u2f_data_cert_key_load(uint8_t* cert_key) { break; } - if(strcmp(string_get_cstr(filetype), U2F_CERT_KEY_FILE_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(filetype), U2F_CERT_KEY_FILE_TYPE) != 0 || version != U2F_CERT_KEY_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -250,7 +250,7 @@ bool u2f_data_cert_key_load(uint8_t* cert_key) { flipper_format_free(flipper_format); furi_record_close(RECORD_STORAGE); - string_clear(filetype); + furi_string_free(filetype); if(cert_type == U2F_CERT_USER_UNENCRYPTED) { return u2f_data_cert_key_encrypt(cert_key); @@ -267,8 +267,8 @@ bool u2f_data_key_load(uint8_t* device_key) { uint8_t key[48]; uint32_t version = 0; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); @@ -279,7 +279,7 @@ bool u2f_data_key_load(uint8_t* device_key) { FURI_LOG_E(TAG, "Missing or incorrect header"); break; } - if(strcmp(string_get_cstr(filetype), U2F_DEVICE_KEY_FILE_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(filetype), U2F_DEVICE_KEY_FILE_TYPE) != 0 || version != U2F_DEVICE_KEY_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -308,7 +308,7 @@ bool u2f_data_key_load(uint8_t* device_key) { } flipper_format_free(flipper_format); furi_record_close(RECORD_STORAGE); - string_clear(filetype); + furi_string_free(filetype); return state; } @@ -366,8 +366,8 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) { uint8_t cnt_encr[48]; uint32_t version = 0; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* flipper_format = flipper_format_file_alloc(storage); @@ -378,7 +378,7 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) { FURI_LOG_E(TAG, "Missing or incorrect header"); break; } - if(strcmp(string_get_cstr(filetype), U2F_COUNTER_FILE_TYPE) != 0) { + if(strcmp(furi_string_get_cstr(filetype), U2F_COUNTER_FILE_TYPE) != 0) { FURI_LOG_E(TAG, "Type mismatch"); break; } @@ -417,7 +417,7 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) { } flipper_format_free(flipper_format); furi_record_close(RECORD_STORAGE); - string_clear(filetype); + furi_string_free(filetype); if(old_counter && state) { // Change counter endianness and rewrite counter file diff --git a/applications/main/u2f/views/u2f_view.c b/applications/main/u2f/views/u2f_view.c index 11e2c9b04..fa3d6cc24 100644 --- a/applications/main/u2f/views/u2f_view.c +++ b/applications/main/u2f/views/u2f_view.c @@ -85,18 +85,17 @@ void u2f_view_set_ok_callback(U2fView* u2f, U2fOkCallback callback, void* contex furi_assert(u2f); furi_assert(callback); with_view_model( - u2f->view, (U2fModel * model) { + u2f->view, + U2fModel * model, + { UNUSED(model); u2f->callback = callback; u2f->context = context; - return false; - }); + }, + false); } void u2f_view_set_state(U2fView* u2f, U2fViewMsg msg) { with_view_model( - u2f->view, (U2fModel * model) { - model->display_msg = msg; - return true; - }); + u2f->view, U2fModel * model, { model->display_msg = msg; }, true); } diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c index 3617dc0f1..2c65f6ab1 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keyboard.c @@ -209,6 +209,11 @@ static void bt_hid_keyboard_draw_callback(Canvas* canvas, void* context) { canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); canvas_set_font(canvas, FontPrimary); elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Keyboard"); + + canvas_draw_icon(canvas, 68, 3, &I_Pin_back_arrow_10x8); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned(canvas, 127, 4, AlignRight, AlignTop, "Hold to exit"); + elements_multiline_text_aligned( canvas, 4, 60, AlignLeft, AlignBottom, "Waiting for Connection..."); return; // Dont render the keyboard if we are not yet connected @@ -272,7 +277,9 @@ static void bt_hid_keyboard_get_select_key(BtHidKeyboardModel* model, BtHidKeybo static void bt_hid_keyboard_process(BtHidKeyboard* bt_hid_keyboard, InputEvent* event) { with_view_model( - bt_hid_keyboard->view, (BtHidKeyboardModel * model) { + bt_hid_keyboard->view, + BtHidKeyboardModel * model, + { if(event->key == InputKeyOk) { if(event->type == InputTypePress) { model->ok_pressed = true; @@ -333,8 +340,8 @@ static void bt_hid_keyboard_process(BtHidKeyboard* bt_hid_keyboard, InputEvent* bt_hid_keyboard_get_select_key(model, (BtHidKeyboardPoint){.x = 1, .y = 0}); } } - return true; - }); + }, + true); } static bool bt_hid_keyboard_input_callback(InputEvent* event, void* context) { @@ -377,8 +384,5 @@ View* bt_hid_keyboard_get_view(BtHidKeyboard* bt_hid_keyboard) { void bt_hid_keyboard_set_connected_status(BtHidKeyboard* bt_hid_keyboard, bool connected) { furi_assert(bt_hid_keyboard); with_view_model( - bt_hid_keyboard->view, (BtHidKeyboardModel * model) { - model->connected = connected; - return true; - }); + bt_hid_keyboard->view, BtHidKeyboardModel * model, { model->connected = connected; }, true); } diff --git a/applications/plugins/bt_hid_app/views/bt_hid_keynote.c b/applications/plugins/bt_hid_app/views/bt_hid_keynote.c index ea4ee16fa..db88b8000 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_keynote.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_keynote.c @@ -106,7 +106,9 @@ static void bt_hid_keynote_draw_callback(Canvas* canvas, void* context) { static void bt_hid_keynote_process(BtHidKeynote* bt_hid_keynote, InputEvent* event) { with_view_model( - bt_hid_keynote->view, (BtHidKeynoteModel * model) { + bt_hid_keynote->view, + BtHidKeynoteModel * model, + { if(event->type == InputTypePress) { if(event->key == InputKeyUp) { model->up_pressed = true; @@ -153,8 +155,8 @@ static void bt_hid_keynote_process(BtHidKeynote* bt_hid_keynote, InputEvent* eve furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_AC_BACK); } } - return true; - }); + }, + true); } static bool bt_hid_keynote_input_callback(InputEvent* event, void* context) { @@ -197,8 +199,5 @@ View* bt_hid_keynote_get_view(BtHidKeynote* bt_hid_keynote) { void bt_hid_keynote_set_connected_status(BtHidKeynote* bt_hid_keynote, bool connected) { furi_assert(bt_hid_keynote); with_view_model( - bt_hid_keynote->view, (BtHidKeynoteModel * model) { - model->connected = connected; - return true; - }); + bt_hid_keynote->view, BtHidKeynoteModel * model, { model->connected = connected; }, true); } diff --git a/applications/plugins/bt_hid_app/views/bt_hid_media.c b/applications/plugins/bt_hid_app/views/bt_hid_media.c index 258ea0a40..181cd347b 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_media.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_media.c @@ -107,7 +107,9 @@ static void bt_hid_media_draw_callback(Canvas* canvas, void* context) { static void bt_hid_media_process_press(BtHidMedia* bt_hid_media, InputEvent* event) { with_view_model( - bt_hid_media->view, (BtHidMediaModel * model) { + bt_hid_media->view, + BtHidMediaModel * model, + { if(event->key == InputKeyUp) { model->up_pressed = true; furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_INCREMENT); @@ -124,13 +126,15 @@ static void bt_hid_media_process_press(BtHidMedia* bt_hid_media, InputEvent* eve model->ok_pressed = true; furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_PLAY_PAUSE); } - return true; - }); + }, + true); } static void bt_hid_media_process_release(BtHidMedia* bt_hid_media, InputEvent* event) { with_view_model( - bt_hid_media->view, (BtHidMediaModel * model) { + bt_hid_media->view, + BtHidMediaModel * model, + { if(event->key == InputKeyUp) { model->up_pressed = false; furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_INCREMENT); @@ -147,8 +151,8 @@ static void bt_hid_media_process_release(BtHidMedia* bt_hid_media, InputEvent* e model->ok_pressed = false; furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_PLAY_PAUSE); } - return true; - }); + }, + true); } static bool bt_hid_media_input_callback(InputEvent* event, void* context) { @@ -196,8 +200,5 @@ View* bt_hid_media_get_view(BtHidMedia* bt_hid_media) { void bt_hid_media_set_connected_status(BtHidMedia* bt_hid_media, bool connected) { furi_assert(bt_hid_media); with_view_model( - bt_hid_media->view, (BtHidMediaModel * model) { - model->connected = connected; - return true; - }); + bt_hid_media->view, BtHidMediaModel * model, { model->connected = connected; }, true); } diff --git a/applications/plugins/bt_hid_app/views/bt_hid_mouse.c b/applications/plugins/bt_hid_app/views/bt_hid_mouse.c index 395cb52c9..098adb732 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_mouse.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_mouse.c @@ -103,7 +103,9 @@ static void bt_hid_mouse_draw_callback(Canvas* canvas, void* context) { static void bt_hid_mouse_process(BtHidMouse* bt_hid_mouse, InputEvent* event) { with_view_model( - bt_hid_mouse->view, (BtHidMouseModel * model) { + bt_hid_mouse->view, + BtHidMouseModel * model, + { if(event->key == InputKeyBack) { if(event->type == InputTypeShort) { furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_RIGHT); @@ -167,8 +169,8 @@ static void bt_hid_mouse_process(BtHidMouse* bt_hid_mouse, InputEvent* event) { model->up_pressed = false; } } - return true; - }); + }, + true); } static bool bt_hid_mouse_input_callback(InputEvent* event, void* context) { @@ -211,8 +213,5 @@ View* bt_hid_mouse_get_view(BtHidMouse* bt_hid_mouse) { void bt_hid_mouse_set_connected_status(BtHidMouse* bt_hid_mouse, bool connected) { furi_assert(bt_hid_mouse); with_view_model( - bt_hid_mouse->view, (BtHidMouseModel * model) { - model->connected = connected; - return true; - }); + bt_hid_mouse->view, BtHidMouseModel * model, { model->connected = connected; }, true); } diff --git a/applications/plugins/music_player/music_player.c b/applications/plugins/music_player/music_player.c index 40e9085fb..192500c2e 100644 --- a/applications/plugins/music_player/music_player.c +++ b/applications/plugins/music_player/music_player.c @@ -8,8 +8,6 @@ #include #include -#include - #define TAG "MusicPlayer" #define MUSIC_PLAYER_APP_PATH_FOLDER ANY_PATH("music_player") @@ -250,12 +248,16 @@ static void music_player_worker_callback( view_port_update(music_player->view_port); } +void music_player_clear(MusicPlayer* instance) { + memset(instance->model->duration_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); + memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); + music_player_worker_clear(instance->worker); +} + MusicPlayer* music_player_alloc() { MusicPlayer* instance = malloc(sizeof(MusicPlayer)); instance->model = malloc(sizeof(MusicPlayerModel)); - memset(instance->model->duration_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); - memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE); instance->model->volume = 3; instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); @@ -267,6 +269,8 @@ MusicPlayer* music_player_alloc() { instance->worker, MUSIC_PLAYER_VOLUMES[instance->model->volume]); music_player_worker_set_callback(instance->worker, music_player_worker_callback, instance); + music_player_clear(instance); + instance->view_port = view_port_alloc(); view_port_draw_callback_set(instance->view_port, render_callback, instance); view_port_input_callback_set(instance->view_port, input_callback, instance); @@ -296,14 +300,14 @@ void music_player_free(MusicPlayer* instance) { int32_t music_player_app(void* p) { MusicPlayer* music_player = music_player_alloc(); - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); do { if(p && strlen(p)) { - string_cat_str(file_path, p); + furi_string_set(file_path, (const char*)p); } else { - string_set_str(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); + furi_string_set(file_path, MUSIC_PLAYER_APP_PATH_FOLDER); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options( @@ -320,7 +324,7 @@ int32_t music_player_app(void* p) { } } - if(!music_player_worker_load(music_player->worker, string_get_cstr(file_path))) { + if(!music_player_worker_load(music_player->worker, furi_string_get_cstr(file_path))) { FURI_LOG_E(TAG, "Unable to load file"); break; } @@ -352,9 +356,11 @@ int32_t music_player_app(void* p) { } music_player_worker_stop(music_player->worker); - } while(0); + if(p && strlen(p)) break; // Exit instead of going to browser if launched with arg + music_player_clear(music_player); + } while(1); - string_clear(file_path); + furi_string_free(file_path); music_player_free(music_player); return 0; diff --git a/applications/plugins/music_player/music_player_cli.c b/applications/plugins/music_player/music_player_cli.c index 782004439..90060d7ee 100644 --- a/applications/plugins/music_player/music_player_cli.c +++ b/applications/plugins/music_player/music_player_cli.c @@ -3,20 +3,20 @@ #include #include "music_player_worker.h" -static void music_player_cli(Cli* cli, string_t args, void* context) { +static void music_player_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); MusicPlayerWorker* music_player_worker = music_player_worker_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); do { - if(storage_common_stat(storage, string_get_cstr(args), NULL) == FSE_OK) { - if(!music_player_worker_load(music_player_worker, string_get_cstr(args))) { - printf("Failed to open file %s\r\n", string_get_cstr(args)); + if(storage_common_stat(storage, furi_string_get_cstr(args), NULL) == FSE_OK) { + if(!music_player_worker_load(music_player_worker, furi_string_get_cstr(args))) { + printf("Failed to open file %s\r\n", furi_string_get_cstr(args)); break; } } else { if(!music_player_worker_load_rtttl_from_string( - music_player_worker, string_get_cstr(args))) { + music_player_worker, furi_string_get_cstr(args))) { printf("Argument is not a file or RTTTL\r\n"); break; } diff --git a/applications/plugins/music_player/music_player_worker.c b/applications/plugins/music_player/music_player_worker.c index ca4f1d8c9..3f1ac62f7 100644 --- a/applications/plugins/music_player/music_player_worker.c +++ b/applications/plugins/music_player/music_player_worker.c @@ -108,6 +108,10 @@ MusicPlayerWorker* music_player_worker_alloc() { return instance; } +void music_player_worker_clear(MusicPlayerWorker* instance) { + NoteBlockArray_reset(instance->notes); +} + void music_player_worker_free(MusicPlayerWorker* instance) { furi_assert(instance); furi_thread_free(instance->thread); @@ -129,6 +133,7 @@ static bool is_space(const char c) { static size_t extract_number(const char* string, uint32_t* number) { size_t ret = 0; + *number = 0; while(is_digit(*string)) { *number *= 10; *number += (*string - '0'); @@ -140,6 +145,7 @@ static size_t extract_number(const char* string, uint32_t* number) { static size_t extract_dots(const char* string, uint32_t* number) { size_t ret = 0; + *number = 0; while(*string == '.') { *number += 1; string++; @@ -258,7 +264,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c if(!is_valid) { FURI_LOG_E( TAG, - "Invalid note: %u%c%c%u.%u", + "Invalid note: %lu%c%c%lu.%lu", duration, note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, @@ -281,7 +287,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c if(music_player_worker_add_note(instance, semitone, duration, dots)) { FURI_LOG_D( TAG, - "Added note: %c%c%u.%u = %u %u", + "Added note: %c%c%lu.%lu = %u %lu", note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, octave, @@ -291,7 +297,7 @@ static bool music_player_worker_parse_notes(MusicPlayerWorker* instance, const c } else { FURI_LOG_E( TAG, - "Invalid note: %c%c%u.%u = %u %u", + "Invalid note: %c%c%lu.%lu = %u %lu", note_char == '\0' ? '_' : note_char, sharp_char == '\0' ? '_' : sharp_char, octave, @@ -326,8 +332,8 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c furi_assert(file_path); bool result = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); @@ -337,7 +343,8 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, MUSIC_PLAYER_FILETYPE) || (version != MUSIC_PLAYER_VERSION)) { + if(furi_string_cmp_str(temp_str, MUSIC_PLAYER_FILETYPE) || + (version != MUSIC_PLAYER_VERSION)) { FURI_LOG_E(TAG, "Incorrect file format or version"); break; } @@ -360,7 +367,7 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c break; } - if(!music_player_worker_parse_notes(instance, string_get_cstr(temp_str))) { + if(!music_player_worker_parse_notes(instance, furi_string_get_cstr(temp_str))) { break; } @@ -369,7 +376,7 @@ bool music_player_worker_load_fmf_from_file(MusicPlayerWorker* instance, const c furi_record_close(RECORD_STORAGE); flipper_format_free(file); - string_clear(temp_str); + furi_string_free(temp_str); return result; } @@ -379,8 +386,8 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const furi_assert(file_path); bool result = false; - string_t content; - string_init(content); + FuriString* content; + content = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(storage); @@ -395,17 +402,17 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const uint8_t buffer[65] = {0}; ret = storage_file_read(file, buffer, sizeof(buffer) - 1); for(size_t i = 0; i < ret; i++) { - string_push_back(content, buffer[i]); + furi_string_push_back(content, buffer[i]); } } while(ret > 0); - string_strim(content); - if(!string_size(content)) { + furi_string_trim(content); + if(!furi_string_size(content)) { FURI_LOG_E(TAG, "Empty file"); break; } - if(!music_player_worker_load_rtttl_from_string(instance, string_get_cstr(content))) { + if(!music_player_worker_load_rtttl_from_string(instance, furi_string_get_cstr(content))) { FURI_LOG_E(TAG, "Invalid file content"); break; } @@ -415,7 +422,7 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const storage_file_free(file); furi_record_close(RECORD_STORAGE); - string_clear(content); + furi_string_free(content); return result; } diff --git a/applications/plugins/music_player/music_player_worker.h b/applications/plugins/music_player/music_player_worker.h index 3aa99ea37..00320b11f 100644 --- a/applications/plugins/music_player/music_player_worker.h +++ b/applications/plugins/music_player/music_player_worker.h @@ -14,6 +14,8 @@ typedef struct MusicPlayerWorker MusicPlayerWorker; MusicPlayerWorker* music_player_worker_alloc(); +void music_player_worker_clear(MusicPlayerWorker* instance); + void music_player_worker_free(MusicPlayerWorker* instance); bool music_player_worker_load(MusicPlayerWorker* instance, const char* file_path); diff --git a/applications/plugins/picopass/application.fam b/applications/plugins/picopass/application.fam index 7a81e0804..bbe37e064 100644 --- a/applications/plugins/picopass/application.fam +++ b/applications/plugins/picopass/application.fam @@ -10,8 +10,11 @@ App( stack_size=4 * 1024, order=30, fap_icon="../../../assets/icons/Archive/125_10px.png", - fap_libs=[ - "mbedtls", - ], fap_category="Tools", + fap_libs=["mbedtls"], + fap_private_libs=[ + Lib( + name="loclass", + ), + ], ) diff --git a/applications/plugins/picopass/loclass/optimized_cipher.c b/applications/plugins/picopass/lib/loclass/optimized_cipher.c similarity index 100% rename from applications/plugins/picopass/loclass/optimized_cipher.c rename to applications/plugins/picopass/lib/loclass/optimized_cipher.c diff --git a/applications/plugins/picopass/loclass/optimized_cipher.h b/applications/plugins/picopass/lib/loclass/optimized_cipher.h similarity index 100% rename from applications/plugins/picopass/loclass/optimized_cipher.h rename to applications/plugins/picopass/lib/loclass/optimized_cipher.h diff --git a/applications/plugins/picopass/loclass/optimized_cipherutils.c b/applications/plugins/picopass/lib/loclass/optimized_cipherutils.c similarity index 100% rename from applications/plugins/picopass/loclass/optimized_cipherutils.c rename to applications/plugins/picopass/lib/loclass/optimized_cipherutils.c diff --git a/applications/plugins/picopass/loclass/optimized_cipherutils.h b/applications/plugins/picopass/lib/loclass/optimized_cipherutils.h similarity index 100% rename from applications/plugins/picopass/loclass/optimized_cipherutils.h rename to applications/plugins/picopass/lib/loclass/optimized_cipherutils.h diff --git a/applications/plugins/picopass/loclass/optimized_elite.c b/applications/plugins/picopass/lib/loclass/optimized_elite.c similarity index 100% rename from applications/plugins/picopass/loclass/optimized_elite.c rename to applications/plugins/picopass/lib/loclass/optimized_elite.c diff --git a/applications/plugins/picopass/loclass/optimized_elite.h b/applications/plugins/picopass/lib/loclass/optimized_elite.h similarity index 100% rename from applications/plugins/picopass/loclass/optimized_elite.h rename to applications/plugins/picopass/lib/loclass/optimized_elite.h diff --git a/applications/plugins/picopass/loclass/optimized_ikeys.c b/applications/plugins/picopass/lib/loclass/optimized_ikeys.c similarity index 100% rename from applications/plugins/picopass/loclass/optimized_ikeys.c rename to applications/plugins/picopass/lib/loclass/optimized_ikeys.c diff --git a/applications/plugins/picopass/loclass/optimized_ikeys.h b/applications/plugins/picopass/lib/loclass/optimized_ikeys.h similarity index 100% rename from applications/plugins/picopass/loclass/optimized_ikeys.h rename to applications/plugins/picopass/lib/loclass/optimized_ikeys.h diff --git a/applications/plugins/picopass/picopass_device.c b/applications/plugins/picopass/picopass_device.c index e7f3e0bed..b6e69cc21 100644 --- a/applications/plugins/picopass/picopass_device.c +++ b/applications/plugins/picopass/picopass_device.c @@ -18,7 +18,7 @@ PicopassDevice* picopass_device_alloc() { picopass_dev->dev_data.pacs.pin_length = 0; picopass_dev->storage = furi_record_open(RECORD_STORAGE); picopass_dev->dialogs = furi_record_open(RECORD_DIALOGS); - string_init(picopass_dev->load_path); + picopass_dev->load_path = furi_string_alloc(); return picopass_dev; } @@ -40,25 +40,25 @@ static bool picopass_device_save_file( FlipperFormat* file = flipper_format_file_alloc(dev->storage); PicopassPacs* pacs = &dev->dev_data.pacs; PicopassBlock* AA1 = dev->dev_data.AA1; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { - if(use_load_path && !string_empty_p(dev->load_path)) { + if(use_load_path && !furi_string_empty(dev->load_path)) { // Get directory name - path_extract_dirname(string_get_cstr(dev->load_path), temp_str); + path_extract_dirname(furi_string_get_cstr(dev->load_path), temp_str); // Create picopass directory if necessary - if(!storage_simply_mkdir(dev->storage, string_get_cstr(temp_str))) break; + if(!storage_simply_mkdir(dev->storage, furi_string_get_cstr(temp_str))) break; // Make path to file to save - string_cat_printf(temp_str, "/%s%s", dev_name, extension); + furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension); } else { // Create picopass directory if necessary if(!storage_simply_mkdir(dev->storage, PICOPASS_APP_FOLDER)) break; // First remove picopass device file if it was saved - string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); + furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); } // Open file - if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; if(dev->format == PicopassDeviceSaveFormatHF) { uint32_t fc = pacs->record.FacilityCode; @@ -87,9 +87,9 @@ static bool picopass_device_save_file( AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] : PICOPASS_MAX_APP_LIMIT; for(size_t i = 0; i < app_limit; i++) { - string_printf(temp_str, "Block %d", i); + furi_string_printf(temp_str, "Block %d", i); if(!flipper_format_write_hex( - file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { + file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { block_saved = false; break; } @@ -117,7 +117,7 @@ static bool picopass_device_save_file( if(!saved) { dialog_message_show_storage_error(dev->dialogs, "Can not save\nfile"); } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return saved; } @@ -132,13 +132,13 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) { return false; } -static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool show_dialog) { +static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, bool show_dialog) { bool parsed = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); PicopassBlock* AA1 = dev->dev_data.AA1; PicopassPacs* pacs = &dev->dev_data.pacs; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); bool deprecated_version = false; if(dev->loading_cb) { @@ -146,12 +146,13 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s } do { - if(!flipper_format_file_open_existing(file, string_get_cstr(path))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(path))) break; // Read and verify file header uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, picopass_file_header) || (version != picopass_file_version)) { + if(furi_string_cmp_str(temp_str, picopass_file_header) || + (version != picopass_file_version)) { deprecated_version = true; break; } @@ -159,9 +160,9 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s // Parse header blocks bool block_read = true; for(size_t i = 0; i < 6; i++) { - string_printf(temp_str, "Block %d", i); + furi_string_printf(temp_str, "Block %d", i); if(!flipper_format_read_hex( - file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { + file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { block_read = false; break; } @@ -169,9 +170,9 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s size_t app_limit = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0]; for(size_t i = 6; i < app_limit; i++) { - string_printf(temp_str, "Block %d", i); + furi_string_printf(temp_str, "Block %d", i); if(!flipper_format_read_hex( - file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { + file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) { block_read = false; break; } @@ -196,7 +197,7 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s } } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return parsed; @@ -208,7 +209,7 @@ void picopass_device_clear(PicopassDevice* dev) { picopass_device_data_clear(&dev->dev_data); memset(&dev->dev_data, 0, sizeof(dev->dev_data)); dev->format = PicopassDeviceSaveFormatHF; - string_reset(dev->load_path); + furi_string_reset(dev->load_path); } void picopass_device_free(PicopassDevice* picopass_dev) { @@ -216,7 +217,7 @@ void picopass_device_free(PicopassDevice* picopass_dev) { picopass_device_clear(picopass_dev); furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_DIALOGS); - string_clear(picopass_dev->load_path); + furi_string_free(picopass_dev->load_path); free(picopass_dev); } @@ -224,8 +225,8 @@ bool picopass_file_select(PicopassDevice* dev) { furi_assert(dev); // Input events and views are managed by file_browser - string_t picopass_app_folder; - string_init_set_str(picopass_app_folder, PICOPASS_APP_FOLDER); + FuriString* picopass_app_folder; + picopass_app_folder = furi_string_alloc_set(PICOPASS_APP_FOLDER); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options(&browser_options, PICOPASS_APP_EXTENSION, &I_Nfc_10px); @@ -233,17 +234,17 @@ bool picopass_file_select(PicopassDevice* dev) { bool res = dialog_file_browser_show( dev->dialogs, dev->load_path, picopass_app_folder, &browser_options); - string_clear(picopass_app_folder); + furi_string_free(picopass_app_folder); if(res) { - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_filename(dev->load_path, filename, true); - strncpy(dev->dev_name, string_get_cstr(filename), PICOPASS_DEV_NAME_MAX_LEN); + strncpy(dev->dev_name, furi_string_get_cstr(filename), PICOPASS_DEV_NAME_MAX_LEN); res = picopass_device_load_data(dev, dev->load_path, true); if(res) { picopass_device_set_name(dev, dev->dev_name); } - string_clear(filename); + furi_string_free(filename); } return res; @@ -262,18 +263,18 @@ bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) { furi_assert(dev); bool deleted = false; - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); do { // Delete original file - if(use_load_path && !string_empty_p(dev->load_path)) { - string_set(file_path, dev->load_path); + if(use_load_path && !furi_string_empty(dev->load_path)) { + furi_string_set(file_path, dev->load_path); } else { - string_printf( + furi_string_printf( file_path, "%s/%s%s", PICOPASS_APP_FOLDER, dev->dev_name, PICOPASS_APP_EXTENSION); } - if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; deleted = true; } while(0); @@ -281,7 +282,7 @@ bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) { dialog_message_show_storage_error(dev->dialogs, "Can not remove file"); } - string_clear(file_path); + furi_string_free(file_path); return deleted; } diff --git a/applications/plugins/picopass/picopass_device.h b/applications/plugins/picopass/picopass_device.h index 745b64bd5..ed6bb4781 100644 --- a/applications/plugins/picopass/picopass_device.h +++ b/applications/plugins/picopass/picopass_device.h @@ -7,8 +7,8 @@ #include #include "rfal_picopass.h" -#include "loclass/optimized_ikeys.h" -#include "loclass/optimized_cipher.h" +#include +#include #define PICOPASS_DEV_NAME_MAX_LEN 22 #define PICOPASS_READER_DATA_MAX_SIZE 64 @@ -71,7 +71,7 @@ typedef struct { DialogsApp* dialogs; PicopassDeviceData dev_data; char dev_name[PICOPASS_DEV_NAME_MAX_LEN + 1]; - string_t load_path; + FuriString* load_path; PicopassDeviceSaveFormat format; PicopassLoadingCallback loading_cb; void* loading_cb_ctx; diff --git a/applications/plugins/picopass/picopass_i.h b/applications/plugins/picopass/picopass_i.h index dec5a865f..8e011f222 100644 --- a/applications/plugins/picopass/picopass_i.h +++ b/applications/plugins/picopass/picopass_i.h @@ -51,7 +51,7 @@ struct Picopass { PicopassDevice* dev; char text_store[PICOPASS_TEXT_STORE_SIZE + 1]; - string_t text_box_store; + FuriString* text_box_store; // Common Views Submenu* submenu; diff --git a/applications/plugins/picopass/scenes/picopass_scene_device_info.c b/applications/plugins/picopass/scenes/picopass_scene_device_info.c index 38891b673..046e9c8e4 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_device_info.c +++ b/applications/plugins/picopass/scenes/picopass_scene_device_info.c @@ -14,10 +14,10 @@ void picopass_scene_device_info_widget_callback( void picopass_scene_device_info_on_enter(void* context) { Picopass* picopass = context; - string_t credential_str; - string_t wiegand_str; - string_init(credential_str); - string_init(wiegand_str); + FuriString* credential_str; + FuriString* wiegand_str; + credential_str = furi_string_alloc(); + wiegand_str = furi_string_alloc(); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); @@ -26,25 +26,31 @@ void picopass_scene_device_info_on_enter(void* context) { Widget* widget = picopass->widget; size_t bytesLength = 1 + pacs->record.bitLength / 8; - string_set_str(credential_str, ""); + furi_string_set(credential_str, ""); for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { - string_cat_printf(credential_str, " %02X", pacs->credential[i]); + furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]); } if(pacs->record.valid) { - string_cat_printf( + furi_string_cat_printf( wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber); } else { - string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); + furi_string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); } widget_add_string_element( - widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); + widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str)); widget_add_string_element( - widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(credential_str)); + widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + furi_string_get_cstr(credential_str)); - string_clear(credential_str); - string_clear(wiegand_str); + furi_string_free(credential_str); + furi_string_free(wiegand_str); widget_add_button_element( picopass->widget, diff --git a/applications/plugins/picopass/scenes/picopass_scene_read_card_success.c b/applications/plugins/picopass/scenes/picopass_scene_read_card_success.c index 785f3a7dd..37f1db4f2 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_read_card_success.c +++ b/applications/plugins/picopass/scenes/picopass_scene_read_card_success.c @@ -15,12 +15,12 @@ void picopass_scene_read_card_success_widget_callback( void picopass_scene_read_card_success_on_enter(void* context) { Picopass* picopass = context; - string_t credential_str; - string_t wiegand_str; - string_t sio_str; - string_init(credential_str); - string_init(wiegand_str); - string_init(sio_str); + FuriString* credential_str; + FuriString* wiegand_str; + FuriString* sio_str; + credential_str = furi_string_alloc(); + wiegand_str = furi_string_alloc(); + sio_str = furi_string_alloc(); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); @@ -32,10 +32,10 @@ void picopass_scene_read_card_success_on_enter(void* context) { Widget* widget = picopass->widget; if(pacs->record.bitLength == 0) { - string_cat_printf(wiegand_str, "Read Failed"); + furi_string_cat_printf(wiegand_str, "Read Failed"); if(pacs->se_enabled) { - string_cat_printf(credential_str, "SE enabled"); + furi_string_cat_printf(credential_str, "SE enabled"); } widget_add_button_element( @@ -47,20 +47,20 @@ void picopass_scene_read_card_success_on_enter(void* context) { } else { size_t bytesLength = 1 + pacs->record.bitLength / 8; - string_set_str(credential_str, ""); + furi_string_set(credential_str, ""); for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) { - string_cat_printf(credential_str, " %02X", pacs->credential[i]); + furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]); } if(pacs->record.valid) { - string_cat_printf( + furi_string_cat_printf( wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber); } else { - string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); + furi_string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength); } if(pacs->sio) { - string_cat_printf(sio_str, "+SIO"); + furi_string_cat_printf(sio_str, "+SIO"); } widget_add_button_element( @@ -79,15 +79,21 @@ void picopass_scene_read_card_success_on_enter(void* context) { } widget_add_string_element( - widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str)); + widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str)); widget_add_string_element( - widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(credential_str)); + widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + furi_string_get_cstr(credential_str)); widget_add_string_element( - widget, 64, 42, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(sio_str)); + widget, 64, 42, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str)); - string_clear(credential_str); - string_clear(wiegand_str); - string_clear(sio_str); + furi_string_free(credential_str); + furi_string_free(wiegand_str); + furi_string_free(sio_str); view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget); } diff --git a/applications/plugins/picopass/scenes/picopass_scene_save_name.c b/applications/plugins/picopass/scenes/picopass_scene_save_name.c index c5fa7dd1f..17ad5927a 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_save_name.c +++ b/applications/plugins/picopass/scenes/picopass_scene_save_name.c @@ -1,5 +1,4 @@ #include "../picopass_i.h" -#include "m-string.h" #include #include #include @@ -31,22 +30,22 @@ void picopass_scene_save_name_on_enter(void* context) { PICOPASS_DEV_NAME_MAX_LEN, dev_name_empty); - string_t folder_path; - string_init(folder_path); + FuriString* folder_path; + folder_path = furi_string_alloc(); - if(string_end_with_str_p(picopass->dev->load_path, PICOPASS_APP_EXTENSION)) { - path_extract_dirname(string_get_cstr(picopass->dev->load_path), folder_path); + if(furi_string_end_with(picopass->dev->load_path, PICOPASS_APP_EXTENSION)) { + path_extract_dirname(furi_string_get_cstr(picopass->dev->load_path), folder_path); } else { - string_set_str(folder_path, PICOPASS_APP_FOLDER); + furi_string_set(folder_path, PICOPASS_APP_FOLDER); } ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - string_get_cstr(folder_path), PICOPASS_APP_EXTENSION, picopass->dev->dev_name); + furi_string_get_cstr(folder_path), PICOPASS_APP_EXTENSION, picopass->dev->dev_name); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewTextInput); - string_clear(folder_path); + furi_string_free(folder_path); } bool picopass_scene_save_name_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/plugins/signal_generator/application.fam b/applications/plugins/signal_generator/application.fam new file mode 100644 index 000000000..7794ee492 --- /dev/null +++ b/applications/plugins/signal_generator/application.fam @@ -0,0 +1,12 @@ +App( + appid="signal_generator", + name="Signal Generator", + apptype=FlipperAppType.PLUGIN, + entry_point="signal_gen_app", + cdefines=["APP_SIGNAL_GEN"], + requires=["gui"], + stack_size=1 * 1024, + order=50, + fap_icon="signal_gen_10px.png", + fap_category="Tools", +) diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene.c b/applications/plugins/signal_generator/scenes/signal_gen_scene.c new file mode 100644 index 000000000..29b11ee3f --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene.c @@ -0,0 +1,30 @@ +#include "../signal_gen_app_i.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const signal_gen_scene_on_enter_handlers[])(void*) = { +#include "signal_gen_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const signal_gen_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "signal_gen_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const signal_gen_scene_on_exit_handlers[])(void* context) = { +#include "signal_gen_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers signal_gen_scene_handlers = { + .on_enter_handlers = signal_gen_scene_on_enter_handlers, + .on_event_handlers = signal_gen_scene_on_event_handlers, + .on_exit_handlers = signal_gen_scene_on_exit_handlers, + .scene_num = SignalGenSceneNum, +}; diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene.h b/applications/plugins/signal_generator/scenes/signal_gen_scene.h new file mode 100644 index 000000000..c139afa3b --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) SignalGenScene##id, +typedef enum { +#include "signal_gen_scene_config.h" + SignalGenSceneNum, +} SignalGenScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers signal_gen_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "signal_gen_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "signal_gen_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "signal_gen_scene_config.h" +#undef ADD_SCENE diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_config.h b/applications/plugins/signal_generator/scenes/signal_gen_scene_config.h new file mode 100644 index 000000000..b6c750256 --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_config.h @@ -0,0 +1,3 @@ +ADD_SCENE(signal_gen, start, Start) +ADD_SCENE(signal_gen, pwm, Pwm) +ADD_SCENE(signal_gen, mco, Mco) diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c new file mode 100644 index 000000000..0855cde0a --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_mco.c @@ -0,0 +1,145 @@ +#include "../signal_gen_app_i.h" + +typedef enum { + LineIndexPin, + LineIndexSource, + LineIndexDivision, +} LineIndex; + +static const char* const mco_pin_names[] = { + "13(Tx)", +}; + +static const char* const mco_source_names[] = { + "32768Hz", + "64MHz", + "~100K", + "~200K", + "~400K", + "~800K", + "~1MHz", + "~2MHz", + "~4MHz", + "~8MHz", + "~16MHz", + "~24MHz", + "~32MHz", + "~48MHz", +}; + +static const FuriHalClockMcoSourceId mco_sources[] = { + FuriHalClockMcoLse, + FuriHalClockMcoSysclk, + FuriHalClockMcoMsi100k, + FuriHalClockMcoMsi200k, + FuriHalClockMcoMsi400k, + FuriHalClockMcoMsi800k, + FuriHalClockMcoMsi1m, + FuriHalClockMcoMsi2m, + FuriHalClockMcoMsi4m, + FuriHalClockMcoMsi8m, + FuriHalClockMcoMsi16m, + FuriHalClockMcoMsi24m, + FuriHalClockMcoMsi32m, + FuriHalClockMcoMsi48m, +}; + +static const char* const mco_divisor_names[] = { + "1", + "2", + "4", + "8", + "16", +}; + +static const FuriHalClockMcoDivisorId mco_divisors[] = { + FuriHalClockMcoDiv1, + FuriHalClockMcoDiv2, + FuriHalClockMcoDiv4, + FuriHalClockMcoDiv8, + FuriHalClockMcoDiv16, +}; + +static void mco_source_list_change_callback(VariableItem* item) { + SignalGenApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, mco_source_names[index]); + + app->mco_src = mco_sources[index]; + + view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate); +} + +static void mco_divisor_list_change_callback(VariableItem* item) { + SignalGenApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, mco_divisor_names[index]); + + app->mco_div = mco_divisors[index]; + + view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenMcoEventUpdate); +} + +void signal_gen_scene_mco_on_enter(void* context) { + SignalGenApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + + VariableItem* item; + + item = variable_item_list_add(var_item_list, "GPIO Pin", COUNT_OF(mco_pin_names), NULL, NULL); + variable_item_set_current_value_index(item, 0); + variable_item_set_current_value_text(item, mco_pin_names[0]); + + item = variable_item_list_add( + var_item_list, + "Frequency", + COUNT_OF(mco_source_names), + mco_source_list_change_callback, + app); + variable_item_set_current_value_index(item, 0); + variable_item_set_current_value_text(item, mco_source_names[0]); + + item = variable_item_list_add( + var_item_list, + "Freq. divider", + COUNT_OF(mco_divisor_names), + mco_divisor_list_change_callback, + app); + variable_item_set_current_value_index(item, 0); + variable_item_set_current_value_text(item, mco_divisor_names[0]); + + variable_item_list_set_selected_item(var_item_list, LineIndexSource); + + view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewVarItemList); + + app->mco_src = FuriHalClockMcoLse; + app->mco_div = FuriHalClockMcoDiv1; + furi_hal_clock_mco_enable(app->mco_src, app->mco_div); + furi_hal_gpio_init_ex( + &gpio_usart_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn0MCO); +} + +bool signal_gen_scene_mco_on_event(void* context, SceneManagerEvent event) { + SignalGenApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SignalGenMcoEventUpdate) { + consumed = true; + furi_hal_clock_mco_enable(app->mco_src, app->mco_div); + } + } + return consumed; +} + +void signal_gen_scene_mco_on_exit(void* context) { + SignalGenApp* app = context; + variable_item_list_reset(app->var_item_list); + furi_hal_gpio_init_ex( + &gpio_usart_tx, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn7USART1); + furi_hal_clock_mco_disable(); +} diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_pwm.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_pwm.c new file mode 100644 index 000000000..f302c0232 --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_pwm.c @@ -0,0 +1,60 @@ +#include "../signal_gen_app_i.h" + +static const FuriHalPwmOutputId pwm_ch_id[] = { + FuriHalPwmOutputIdTim1PA7, + FuriHalPwmOutputIdLptim2PA4, +}; + +#define DEFAULT_FREQ 1000 +#define DEFAULT_DUTY 50 + +static void + signal_gen_pwm_callback(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context) { + SignalGenApp* app = context; + + app->pwm_freq = freq; + app->pwm_duty = duty; + + if(app->pwm_ch != pwm_ch_id[channel_id]) { + app->pwm_ch_prev = app->pwm_ch; + app->pwm_ch = pwm_ch_id[channel_id]; + view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventChannelChange); + } else { + app->pwm_ch = pwm_ch_id[channel_id]; + view_dispatcher_send_custom_event(app->view_dispatcher, SignalGenPwmEventUpdate); + } +} + +void signal_gen_scene_pwm_on_enter(void* context) { + SignalGenApp* app = context; + + view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewPwm); + + signal_gen_pwm_set_callback(app->pwm_view, signal_gen_pwm_callback, app); + + signal_gen_pwm_set_params(app->pwm_view, 0, DEFAULT_FREQ, DEFAULT_DUTY); + furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); +} + +bool signal_gen_scene_pwm_on_event(void* context, SceneManagerEvent event) { + SignalGenApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SignalGenPwmEventUpdate) { + consumed = true; + furi_hal_pwm_set_params(app->pwm_ch, app->pwm_freq, app->pwm_duty); + } else if(event.event == SignalGenPwmEventChannelChange) { + consumed = true; + furi_hal_pwm_stop(app->pwm_ch_prev); + furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); + } + } + return consumed; +} + +void signal_gen_scene_pwm_on_exit(void* context) { + SignalGenApp* app = context; + variable_item_list_reset(app->var_item_list); + furi_hal_pwm_stop(app->pwm_ch); +} diff --git a/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c b/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c new file mode 100644 index 000000000..3c7b9cc32 --- /dev/null +++ b/applications/plugins/signal_generator/scenes/signal_gen_scene_start.c @@ -0,0 +1,55 @@ +#include "../signal_gen_app_i.h" + +typedef enum { + SubmenuIndexPwm, + SubmenuIndexClockOutput, +} SubmenuIndex; + +void signal_gen_scene_start_submenu_callback(void* context, uint32_t index) { + SignalGenApp* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void signal_gen_scene_start_on_enter(void* context) { + SignalGenApp* app = context; + Submenu* submenu = app->submenu; + + submenu_add_item( + submenu, "PWM Generator", SubmenuIndexPwm, signal_gen_scene_start_submenu_callback, app); + submenu_add_item( + submenu, + "Clock Generator", + SubmenuIndexClockOutput, + signal_gen_scene_start_submenu_callback, + app); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(app->scene_manager, SignalGenSceneStart)); + + view_dispatcher_switch_to_view(app->view_dispatcher, SignalGenViewSubmenu); +} + +bool signal_gen_scene_start_on_event(void* context, SceneManagerEvent event) { + SignalGenApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexPwm) { + scene_manager_next_scene(app->scene_manager, SignalGenScenePwm); + consumed = true; + } else if(event.event == SubmenuIndexClockOutput) { + scene_manager_next_scene(app->scene_manager, SignalGenSceneMco); + consumed = true; + } + scene_manager_set_scene_state(app->scene_manager, SignalGenSceneStart, event.event); + } + + return consumed; +} + +void signal_gen_scene_start_on_exit(void* context) { + SignalGenApp* app = context; + + submenu_reset(app->submenu); +} diff --git a/applications/plugins/signal_generator/signal_gen_10px.png b/applications/plugins/signal_generator/signal_gen_10px.png new file mode 100644 index 000000000..9f6dcc5d0 Binary files /dev/null and b/applications/plugins/signal_generator/signal_gen_10px.png differ diff --git a/applications/plugins/signal_generator/signal_gen_app.c b/applications/plugins/signal_generator/signal_gen_app.c new file mode 100644 index 000000000..ca065d330 --- /dev/null +++ b/applications/plugins/signal_generator/signal_gen_app.c @@ -0,0 +1,93 @@ +#include "signal_gen_app_i.h" + +#include +#include + +static bool signal_gen_app_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + SignalGenApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool signal_gen_app_back_event_callback(void* context) { + furi_assert(context); + SignalGenApp* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static void signal_gen_app_tick_event_callback(void* context) { + furi_assert(context); + SignalGenApp* app = context; + scene_manager_handle_tick_event(app->scene_manager); +} + +SignalGenApp* signal_gen_app_alloc() { + SignalGenApp* app = malloc(sizeof(SignalGenApp)); + + app->gui = furi_record_open(RECORD_GUI); + + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&signal_gen_scene_handlers, app); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, signal_gen_app_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, signal_gen_app_back_event_callback); + view_dispatcher_set_tick_event_callback( + app->view_dispatcher, signal_gen_app_tick_event_callback, 100); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + app->var_item_list = variable_item_list_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + SignalGenViewVarItemList, + variable_item_list_get_view(app->var_item_list)); + + app->submenu = submenu_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SignalGenViewSubmenu, submenu_get_view(app->submenu)); + + app->pwm_view = signal_gen_pwm_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, SignalGenViewPwm, signal_gen_pwm_get_view(app->pwm_view)); + + scene_manager_next_scene(app->scene_manager, SignalGenSceneStart); + + return app; +} + +void signal_gen_app_free(SignalGenApp* app) { + furi_assert(app); + + // Views + view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewVarItemList); + view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewSubmenu); + view_dispatcher_remove_view(app->view_dispatcher, SignalGenViewPwm); + + submenu_free(app->submenu); + variable_item_list_free(app->var_item_list); + signal_gen_pwm_free(app->pwm_view); + + // View dispatcher + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + + // Close records + furi_record_close(RECORD_GUI); + + free(app); +} + +int32_t signal_gen_app(void* p) { + UNUSED(p); + SignalGenApp* signal_gen_app = signal_gen_app_alloc(); + + view_dispatcher_run(signal_gen_app->view_dispatcher); + + signal_gen_app_free(signal_gen_app); + + return 0; +} diff --git a/applications/plugins/signal_generator/signal_gen_app_i.h b/applications/plugins/signal_generator/signal_gen_app_i.h new file mode 100644 index 000000000..47c266475 --- /dev/null +++ b/applications/plugins/signal_generator/signal_gen_app_i.h @@ -0,0 +1,46 @@ +#pragma once + +#include "scenes/signal_gen_scene.h" + +#include "furi_hal_clock.h" +#include "furi_hal_pwm.h" + +#include +#include +#include +#include +#include +#include +#include "views/signal_gen_pwm.h" + +typedef struct SignalGenApp SignalGenApp; + +struct SignalGenApp { + Gui* gui; + ViewDispatcher* view_dispatcher; + SceneManager* scene_manager; + + VariableItemList* var_item_list; + Submenu* submenu; + SignalGenPwm* pwm_view; + + FuriHalClockMcoSourceId mco_src; + FuriHalClockMcoDivisorId mco_div; + + FuriHalPwmOutputId pwm_ch_prev; + FuriHalPwmOutputId pwm_ch; + uint32_t pwm_freq; + uint8_t pwm_duty; +}; + +typedef enum { + SignalGenViewVarItemList, + SignalGenViewSubmenu, + SignalGenViewPwm, +} SignalGenAppView; + +typedef enum { + SignalGenMcoEventUpdate, + SignalGenPwmEventUpdate, + SignalGenPwmEventChannelChange, +} SignalGenCustomEvent; diff --git a/applications/plugins/signal_generator/views/signal_gen_pwm.c b/applications/plugins/signal_generator/views/signal_gen_pwm.c new file mode 100644 index 000000000..6d1a3c1ba --- /dev/null +++ b/applications/plugins/signal_generator/views/signal_gen_pwm.c @@ -0,0 +1,309 @@ +#include "../signal_gen_app_i.h" +#include "furi_hal.h" +#include + +typedef enum { + LineIndexChannel, + LineIndexFrequency, + LineIndexDuty, + LineIndexTotalCount +} LineIndex; + +static const char* const pwm_ch_names[] = {"2(A7)", "4(A4)"}; + +struct SignalGenPwm { + View* view; + SignalGenPwmViewCallback callback; + void* context; +}; + +typedef struct { + LineIndex line_sel; + bool edit_mode; + uint8_t edit_digit; + + uint8_t channel_id; + uint32_t freq; + uint8_t duty; + +} SignalGenPwmViewModel; + +#define ITEM_H 64 / 3 +#define ITEM_W 128 + +#define VALUE_X 100 +#define VALUE_W 45 + +#define FREQ_VALUE_X 62 +#define FREQ_MAX 1000000UL +#define FREQ_DIGITS_NB 7 + +static void pwm_set_config(SignalGenPwm* pwm) { + FuriHalPwmOutputId channel; + uint32_t freq; + uint8_t duty; + + with_view_model( + pwm->view, + SignalGenPwmViewModel * model, + { + channel = model->channel_id; + freq = model->freq; + duty = model->duty; + }, + false); + + furi_assert(pwm->callback); + pwm->callback(channel, freq, duty, pwm->context); +} + +static void pwm_channel_change(SignalGenPwmViewModel* model, InputEvent* event) { + if(event->key == InputKeyLeft) { + if(model->channel_id > 0) { + model->channel_id--; + } + } else if(event->key == InputKeyRight) { + if(model->channel_id < (COUNT_OF(pwm_ch_names) - 1)) { + model->channel_id++; + } + } +} + +static void pwm_duty_change(SignalGenPwmViewModel* model, InputEvent* event) { + if(event->key == InputKeyLeft) { + if(model->duty > 0) { + model->duty--; + } + } else if(event->key == InputKeyRight) { + if(model->duty < 100) { + model->duty++; + } + } +} + +static bool pwm_freq_edit(SignalGenPwmViewModel* model, InputEvent* event) { + bool consumed = false; + if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { + if(event->key == InputKeyRight) { + if(model->edit_digit > 0) { + model->edit_digit--; + } + consumed = true; + } else if(event->key == InputKeyLeft) { + if(model->edit_digit < (FREQ_DIGITS_NB - 1)) { + model->edit_digit++; + } + consumed = true; + } else if(event->key == InputKeyUp) { + uint32_t step = 1; + for(uint8_t i = 0; i < model->edit_digit; i++) { + step *= 10; + } + if((model->freq + step) < FREQ_MAX) { + model->freq += step; + } else { + model->freq = FREQ_MAX; + } + consumed = true; + } else if(event->key == InputKeyDown) { + uint32_t step = 1; + for(uint8_t i = 0; i < model->edit_digit; i++) { + step *= 10; + } + if(model->freq > (step + 1)) { + model->freq -= step; + } else { + model->freq = 1; + } + consumed = true; + } + } + return consumed; +} + +static void signal_gen_pwm_draw_callback(Canvas* canvas, void* _model) { + SignalGenPwmViewModel* model = _model; + char* line_label = NULL; + char val_text[16]; + + for(uint8_t line = 0; line < LineIndexTotalCount; line++) { + if(line == LineIndexChannel) { + line_label = "GPIO Pin"; + } else if(line == LineIndexFrequency) { + line_label = "Frequency"; + } else if(line == LineIndexDuty) { + line_label = "Pulse width"; + } + + canvas_set_color(canvas, ColorBlack); + if(line == model->line_sel) { + elements_slightly_rounded_box(canvas, 0, ITEM_H * line + 1, ITEM_W, ITEM_H - 1); + canvas_set_color(canvas, ColorWhite); + } + + uint8_t text_y = ITEM_H * line + ITEM_H / 2 + 2; + + canvas_draw_str_aligned(canvas, 6, text_y, AlignLeft, AlignCenter, line_label); + + if(line == LineIndexChannel) { + snprintf(val_text, sizeof(val_text), "%s", pwm_ch_names[model->channel_id]); + canvas_draw_str_aligned(canvas, VALUE_X, text_y, AlignCenter, AlignCenter, val_text); + if(model->channel_id != 0) { + canvas_draw_str_aligned( + canvas, VALUE_X - VALUE_W / 2, text_y, AlignCenter, AlignCenter, "<"); + } + if(model->channel_id != (COUNT_OF(pwm_ch_names) - 1)) { + canvas_draw_str_aligned( + canvas, VALUE_X + VALUE_W / 2, text_y, AlignCenter, AlignCenter, ">"); + } + } else if(line == LineIndexFrequency) { + snprintf(val_text, sizeof(val_text), "%7lu Hz", model->freq); + canvas_set_font(canvas, FontKeyboard); + canvas_draw_str_aligned( + canvas, FREQ_VALUE_X, text_y, AlignLeft, AlignCenter, val_text); + canvas_set_font(canvas, FontSecondary); + + if(model->edit_mode) { + uint8_t icon_x = (FREQ_VALUE_X) + (FREQ_DIGITS_NB - model->edit_digit - 1) * 6; + canvas_draw_icon(canvas, icon_x, text_y - 9, &I_SmallArrowUp_3x5); + canvas_draw_icon(canvas, icon_x, text_y + 5, &I_SmallArrowDown_3x5); + } + } else if(line == LineIndexDuty) { + snprintf(val_text, sizeof(val_text), "%d%%", model->duty); + canvas_draw_str_aligned(canvas, VALUE_X, text_y, AlignCenter, AlignCenter, val_text); + if(model->duty != 0) { + canvas_draw_str_aligned( + canvas, VALUE_X - VALUE_W / 2, text_y, AlignCenter, AlignCenter, "<"); + } + if(model->duty != 100) { + canvas_draw_str_aligned( + canvas, VALUE_X + VALUE_W / 2, text_y, AlignCenter, AlignCenter, ">"); + } + } + } +} + +static bool signal_gen_pwm_input_callback(InputEvent* event, void* context) { + furi_assert(context); + SignalGenPwm* pwm = context; + bool consumed = false; + bool need_update = false; + + with_view_model( + pwm->view, + SignalGenPwmViewModel * model, + { + if(model->edit_mode == false) { + if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { + if(event->key == InputKeyUp) { + if(model->line_sel == 0) { + model->line_sel = LineIndexTotalCount - 1; + } else { + model->line_sel = + CLAMP(model->line_sel - 1, LineIndexTotalCount - 1, 0); + } + consumed = true; + } else if(event->key == InputKeyDown) { + if(model->line_sel == LineIndexTotalCount - 1) { + model->line_sel = 0; + } else { + model->line_sel = + CLAMP(model->line_sel + 1, LineIndexTotalCount - 1, 0); + } + consumed = true; + } else if((event->key == InputKeyLeft) || (event->key == InputKeyRight)) { + if(model->line_sel == LineIndexChannel) { + pwm_channel_change(model, event); + need_update = true; + } else if(model->line_sel == LineIndexDuty) { + pwm_duty_change(model, event); + need_update = true; + } else if(model->line_sel == LineIndexFrequency) { + model->edit_mode = true; + } + consumed = true; + } else if(event->key == InputKeyOk) { + if(model->line_sel == LineIndexFrequency) { + model->edit_mode = true; + } + consumed = true; + } + } + } else { + if((event->key == InputKeyOk) || (event->key == InputKeyBack)) { + if(event->type == InputTypeShort) { + model->edit_mode = false; + consumed = true; + } + } else { + if(model->line_sel == LineIndexFrequency) { + consumed = pwm_freq_edit(model, event); + need_update = consumed; + } + } + } + }, + true); + + if(need_update) { + pwm_set_config(pwm); + } + + return consumed; +} + +SignalGenPwm* signal_gen_pwm_alloc() { + SignalGenPwm* pwm = malloc(sizeof(SignalGenPwm)); + + pwm->view = view_alloc(); + view_allocate_model(pwm->view, ViewModelTypeLocking, sizeof(SignalGenPwmViewModel)); + view_set_context(pwm->view, pwm); + view_set_draw_callback(pwm->view, signal_gen_pwm_draw_callback); + view_set_input_callback(pwm->view, signal_gen_pwm_input_callback); + + return pwm; +} + +void signal_gen_pwm_free(SignalGenPwm* pwm) { + furi_assert(pwm); + view_free(pwm->view); + free(pwm); +} + +View* signal_gen_pwm_get_view(SignalGenPwm* pwm) { + furi_assert(pwm); + return pwm->view; +} + +void signal_gen_pwm_set_callback( + SignalGenPwm* pwm, + SignalGenPwmViewCallback callback, + void* context) { + furi_assert(pwm); + furi_assert(callback); + + with_view_model( + pwm->view, + SignalGenPwmViewModel * model, + { + UNUSED(model); + pwm->callback = callback; + pwm->context = context; + }, + false); +} + +void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty) { + with_view_model( + pwm->view, + SignalGenPwmViewModel * model, + { + model->channel_id = channel_id; + model->freq = freq; + model->duty = duty; + }, + true); + + furi_assert(pwm->callback); + pwm->callback(channel_id, freq, duty, pwm->context); +} diff --git a/applications/plugins/signal_generator/views/signal_gen_pwm.h b/applications/plugins/signal_generator/views/signal_gen_pwm.h new file mode 100644 index 000000000..986794e7a --- /dev/null +++ b/applications/plugins/signal_generator/views/signal_gen_pwm.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include "../signal_gen_app_i.h" + +typedef struct SignalGenPwm SignalGenPwm; +typedef void ( + *SignalGenPwmViewCallback)(uint8_t channel_id, uint32_t freq, uint8_t duty, void* context); + +SignalGenPwm* signal_gen_pwm_alloc(); + +void signal_gen_pwm_free(SignalGenPwm* pwm); + +View* signal_gen_pwm_get_view(SignalGenPwm* pwm); + +void signal_gen_pwm_set_callback( + SignalGenPwm* pwm, + SignalGenPwmViewCallback callback, + void* context); + +void signal_gen_pwm_set_params(SignalGenPwm* pwm, uint8_t channel_id, uint32_t freq, uint8_t duty); diff --git a/applications/plugins/snake_game/snake_game.c b/applications/plugins/snake_game/snake_game.c index b7aabb17c..0b665a943 100644 --- a/applications/plugins/snake_game/snake_game.c +++ b/applications/plugins/snake_game/snake_game.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include typedef struct { // +-----x @@ -59,6 +61,35 @@ typedef struct { InputEvent input; } SnakeEvent; +const NotificationSequence sequence_fail = { + &message_vibro_on, + + &message_note_ds4, + &message_delay_10, + &message_sound_off, + &message_delay_10, + + &message_note_ds4, + &message_delay_10, + &message_sound_off, + &message_delay_10, + + &message_note_ds4, + &message_delay_10, + &message_sound_off, + &message_delay_10, + + &message_vibro_off, + NULL, +}; + +const NotificationSequence sequence_eat = { + &message_note_c7, + &message_delay_50, + &message_sound_off, + NULL, +}; + static void snake_game_render_callback(Canvas* const canvas, void* ctx) { const SnakeState* snake_state = acquire_mutex((ValueMutex*)ctx, 25); if(snake_state == NULL) { @@ -230,7 +261,8 @@ static void snake_game_move_snake(SnakeState* const snake_state, Point const nex snake_state->points[0] = next_step; } -static void snake_game_process_game_step(SnakeState* const snake_state) { +static void + snake_game_process_game_step(SnakeState* const snake_state, NotificationApp* notification) { if(snake_state->state == GameStateGameOver) { return; } @@ -249,6 +281,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { return; } else if(snake_state->state == GameStateLastChance) { snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } } else { @@ -260,6 +293,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { crush = snake_game_collision_with_tail(snake_state, next_step); if(crush) { snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } @@ -268,6 +302,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { snake_state->len++; if(snake_state->len >= MAX_SNAKE_LEN) { snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } } @@ -276,6 +311,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state) { if(eatFruit) { snake_state->fruit = snake_game_get_new_fruit(snake_state); + notification_message(notification, &sequence_eat); } } @@ -306,6 +342,9 @@ int32_t snake_game_app(void* p) { // Open GUI and register view_port Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + + notification_message_block(notification, &sequence_display_backlight_enforce_on); SnakeEvent event; for(bool processing = true; processing;) { @@ -341,7 +380,7 @@ int32_t snake_game_app(void* p) { } } } else if(event.type == EventTypeTick) { - snake_game_process_game_step(snake_state); + snake_game_process_game_step(snake_state, notification); } } else { // event timeout @@ -351,10 +390,14 @@ int32_t snake_game_app(void* p) { release_mutex(&state_mutex, snake_state); } + // Wait for all notifications to be played and return backlight to normal state + notification_message_block(notification, &sequence_display_backlight_enforce_auto); + furi_timer_free(timer); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); view_port_free(view_port); furi_message_queue_free(event_queue); delete_mutex(&state_mutex); diff --git a/applications/services/bt/bt_cli.c b/applications/services/bt/bt_cli.c index ff5ebb448..02bf6cee4 100644 --- a/applications/services/bt/bt_cli.c +++ b/applications/services/bt/bt_cli.c @@ -7,18 +7,18 @@ #include "bt_settings.h" #include "bt_service/bt.h" -static void bt_cli_command_hci_info(Cli* cli, string_t args, void* context) { +static void bt_cli_command_hci_info(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); furi_hal_bt_dump_state(buffer); - printf("%s", string_get_cstr(buffer)); - string_clear(buffer); + printf("%s", furi_string_get_cstr(buffer)); + furi_string_free(buffer); } -static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { +static void bt_cli_command_carrier_tx(Cli* cli, FuriString* args, void* context) { UNUSED(context); int channel = 0; int power = 0; @@ -50,7 +50,7 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { } while(false); } -static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { +static void bt_cli_command_carrier_rx(Cli* cli, FuriString* args, void* context) { UNUSED(context); int channel = 0; @@ -81,7 +81,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { } while(false); } -static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { +static void bt_cli_command_packet_tx(Cli* cli, FuriString* args, void* context) { UNUSED(context); int channel = 0; int pattern = 0; @@ -129,7 +129,7 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { } while(false); } -static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { +static void bt_cli_command_packet_rx(Cli* cli, FuriString* args, void* context) { UNUSED(context); int channel = 0; int datarate = 1; @@ -178,12 +178,12 @@ static void bt_cli_print_usage() { } } -static void bt_cli(Cli* cli, string_t args, void* context) { +static void bt_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); furi_record_open(RECORD_BT); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); BtSettings bt_settings; bt_settings_load(&bt_settings); @@ -192,24 +192,24 @@ static void bt_cli(Cli* cli, string_t args, void* context) { bt_cli_print_usage(); break; } - if(string_cmp_str(cmd, "hci_info") == 0) { + if(furi_string_cmp_str(cmd, "hci_info") == 0) { bt_cli_command_hci_info(cli, args, NULL); break; } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && furi_hal_bt_is_testing_supported()) { - if(string_cmp_str(cmd, "tx_carrier") == 0) { + if(furi_string_cmp_str(cmd, "tx_carrier") == 0) { bt_cli_command_carrier_tx(cli, args, NULL); break; } - if(string_cmp_str(cmd, "rx_carrier") == 0) { + if(furi_string_cmp_str(cmd, "rx_carrier") == 0) { bt_cli_command_carrier_rx(cli, args, NULL); break; } - if(string_cmp_str(cmd, "tx_packet") == 0) { + if(furi_string_cmp_str(cmd, "tx_packet") == 0) { bt_cli_command_packet_tx(cli, args, NULL); break; } - if(string_cmp_str(cmd, "rx_packet") == 0) { + if(furi_string_cmp_str(cmd, "rx_packet") == 0) { bt_cli_command_packet_rx(cli, args, NULL); break; } @@ -222,7 +222,7 @@ static void bt_cli(Cli* cli, string_t args, void* context) { furi_hal_bt_start_advertising(); } - string_clear(cmd); + furi_string_free(cmd); furi_record_close(RECORD_BT); } diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index bc80acc15..aeb2beec9 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -75,14 +75,14 @@ static void bt_pin_code_hide(Bt* bt) { static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) { furi_assert(bt); notification_message(bt->notification, &sequence_display_backlight_on); - string_t pin_str; + FuriString* pin_str; dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64, 0, 0); - string_init_printf(pin_str, "Verify code\n%06d", pin); + pin_str = furi_string_alloc_printf("Verify code\n%06ld", pin); dialog_message_set_text( - bt->dialog_message, string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); + bt->dialog_message, furi_string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); dialog_message_set_buttons(bt->dialog_message, "Cancel", "OK", NULL); DialogMessageButton button = dialog_message_show(bt->dialogs, bt->dialog_message); - string_clear(pin_str); + furi_string_free(pin_str); return button == DialogMessageButtonCenter; } @@ -277,7 +277,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { static void bt_on_key_storage_change_callback(uint8_t* addr, uint16_t size, void* context) { furi_assert(context); Bt* bt = context; - FURI_LOG_I(TAG, "Changed addr start: %08lX, size changed: %d", addr, size); + FURI_LOG_I(TAG, "Changed addr start: %p, size changed: %d", addr, size); BtMessage message = {.type = BtMessageTypeKeysStorageUpdated}; furi_check( furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); diff --git a/applications/services/cli/cli.c b/applications/services/cli/cli.c index e554ac898..f29dca9ce 100644 --- a/applications/services/cli/cli.c +++ b/applications/services/cli/cli.c @@ -11,8 +11,8 @@ Cli* cli_alloc() { CliCommandTree_init(cli->commands); - string_init(cli->last_line); - string_init(cli->line); + cli->last_line = furi_string_alloc(); + cli->line = furi_string_alloc(); cli->session = NULL; @@ -138,34 +138,26 @@ void cli_nl(Cli* cli) { void cli_prompt(Cli* cli) { UNUSED(cli); - printf("\r\n>: %s", string_get_cstr(cli->line)); + printf("\r\n>: %s", furi_string_get_cstr(cli->line)); fflush(stdout); } void cli_reset(Cli* cli) { // cli->last_line is cleared and cli->line's buffer moved to cli->last_line - string_move(cli->last_line, cli->line); + furi_string_move(cli->last_line, cli->line); // Reiniting cli->line - string_init(cli->line); + cli->line = furi_string_alloc(); cli->cursor_position = 0; } static void cli_handle_backspace(Cli* cli) { if(cli->cursor_position > 0) { - furi_assert(string_size(cli->line) > 0); + furi_assert(furi_string_size(cli->line) > 0); // Other side printf("\e[D\e[1P"); fflush(stdout); // Our side - string_t temp; - string_init(temp); - string_reserve(temp, string_size(cli->line) - 1); - string_set_strn(temp, string_get_cstr(cli->line), cli->cursor_position - 1); - string_cat_str(temp, string_get_cstr(cli->line) + cli->cursor_position); - - // cli->line is cleared and temp's buffer moved to cli->line - string_move(cli->line, temp); - // NO MEMORY LEAK, STOP REPORTING IT + furi_string_replace_at(cli->line, cli->cursor_position - 1, 1, ""); cli->cursor_position--; } else { @@ -174,11 +166,11 @@ static void cli_handle_backspace(Cli* cli) { } static void cli_normalize_line(Cli* cli) { - string_strim(cli->line); - cli->cursor_position = string_size(cli->line); + furi_string_trim(cli->line); + cli->cursor_position = furi_string_size(cli->line); } -static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { +static void cli_execute_command(Cli* cli, CliCommand* command, FuriString* args) { if(!(command->flags & CliCommandFlagInsomniaSafe)) { furi_hal_power_insomnia_enter(); } @@ -208,25 +200,25 @@ static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { static void cli_handle_enter(Cli* cli) { cli_normalize_line(cli); - if(string_size(cli->line) == 0) { + if(furi_string_size(cli->line) == 0) { cli_prompt(cli); return; } // Command and args container - string_t command; - string_init(command); - string_t args; - string_init(args); + FuriString* command; + command = furi_string_alloc(); + FuriString* args; + args = furi_string_alloc(); // Split command and args - size_t ws = string_search_char(cli->line, ' '); - if(ws == STRING_FAILURE) { - string_set(command, cli->line); + size_t ws = furi_string_search_char(cli->line, ' '); + if(ws == FURI_STRING_FAILURE) { + furi_string_set(command, cli->line); } else { - string_set_n(command, cli->line, 0, ws); - string_set_n(args, cli->line, ws, string_size(cli->line)); - string_strim(args); + furi_string_set_n(command, cli->line, 0, ws); + furi_string_set_n(args, cli->line, ws, furi_string_size(cli->line)); + furi_string_trim(args); } // Search for command @@ -244,7 +236,7 @@ static void cli_handle_enter(Cli* cli) { cli_nl(cli); printf( "`%s` command not found, use `help` or `?` to list all available commands", - string_get_cstr(command)); + furi_string_get_cstr(command)); cli_putc(cli, CliSymbolAsciiBell); } @@ -252,59 +244,59 @@ static void cli_handle_enter(Cli* cli) { cli_prompt(cli); // Cleanup command and args - string_clear(command); - string_clear(args); + furi_string_free(command); + furi_string_free(args); } static void cli_handle_autocomplete(Cli* cli) { cli_normalize_line(cli); - if(string_size(cli->line) == 0) { + if(furi_string_size(cli->line) == 0) { return; } cli_nl(cli); // Prepare common base for autocomplete - string_t common; - string_init(common); + FuriString* common; + common = furi_string_alloc(); // Iterate throw commands for M_EACH(cli_command, cli->commands, CliCommandTree_t) { // Process only if starts with line buffer - if(string_start_with_string_p(*cli_command->key_ptr, cli->line)) { + if(furi_string_start_with(*cli_command->key_ptr, cli->line)) { // Show autocomplete option - printf("%s\r\n", string_get_cstr(*cli_command->key_ptr)); + printf("%s\r\n", furi_string_get_cstr(*cli_command->key_ptr)); // Process common base for autocomplete - if(string_size(common) > 0) { + if(furi_string_size(common) > 0) { // Choose shortest string - const size_t key_size = string_size(*cli_command->key_ptr); - const size_t common_size = string_size(common); + const size_t key_size = furi_string_size(*cli_command->key_ptr); + const size_t common_size = furi_string_size(common); const size_t min_size = key_size > common_size ? common_size : key_size; size_t i = 0; while(i < min_size) { // Stop when do not match - if(string_get_char(*cli_command->key_ptr, i) != - string_get_char(common, i)) { + if(furi_string_get_char(*cli_command->key_ptr, i) != + furi_string_get_char(common, i)) { break; } i++; } // Cut right part if any - string_left(common, i); + furi_string_left(common, i); } else { // Start with something - string_set(common, *cli_command->key_ptr); + furi_string_set(common, *cli_command->key_ptr); } } } // Replace line buffer if autocomplete better - if(string_size(common) > string_size(cli->line)) { - string_set(cli->line, common); - cli->cursor_position = string_size(cli->line); + if(furi_string_size(common) > furi_string_size(cli->line)) { + furi_string_set(cli->line, common); + cli->cursor_position = furi_string_size(cli->line); } // Cleanup - string_clear(common); + furi_string_free(common); // Show prompt cli_prompt(cli); } @@ -312,16 +304,16 @@ static void cli_handle_autocomplete(Cli* cli) { static void cli_handle_escape(Cli* cli, char c) { if(c == 'A') { // Use previous command if line buffer is empty - if(string_size(cli->line) == 0 && string_cmp(cli->line, cli->last_line) != 0) { + if(furi_string_size(cli->line) == 0 && furi_string_cmp(cli->line, cli->last_line) != 0) { // Set line buffer and cursor position - string_set(cli->line, cli->last_line); - cli->cursor_position = string_size(cli->line); + furi_string_set(cli->line, cli->last_line); + cli->cursor_position = furi_string_size(cli->line); // Show new line to user - printf("%s", string_get_cstr(cli->line)); + printf("%s", furi_string_get_cstr(cli->line)); } } else if(c == 'B') { } else if(c == 'C') { - if(cli->cursor_position < string_size(cli->line)) { + if(cli->cursor_position < furi_string_size(cli->line)) { cli->cursor_position++; printf("\e[C"); } @@ -362,21 +354,13 @@ void cli_process_input(Cli* cli) { } else if(in_chr == CliSymbolAsciiCR) { cli_handle_enter(cli); } else if(in_chr >= 0x20 && in_chr < 0x7F) { - if(cli->cursor_position == string_size(cli->line)) { - string_push_back(cli->line, in_chr); + if(cli->cursor_position == furi_string_size(cli->line)) { + furi_string_push_back(cli->line, in_chr); cli_putc(cli, in_chr); } else { - // ToDo: better way? - string_t temp; - string_init(temp); - string_reserve(temp, string_size(cli->line) + 1); - string_set_strn(temp, string_get_cstr(cli->line), cli->cursor_position); - string_push_back(temp, in_chr); - string_cat_str(temp, string_get_cstr(cli->line) + cli->cursor_position); - - // cli->line is cleared and temp's buffer moved to cli->line - string_move(cli->line, temp); - // NO MEMORY LEAK, STOP REPORTING IT + // Insert character to line buffer + const char in_str[2] = {in_chr, 0}; + furi_string_replace_at(cli->line, cli->cursor_position, 0, in_str); // Print character in replace mode printf("\e[4h%c\e[4l", in_chr); @@ -394,14 +378,14 @@ void cli_add_command( CliCommandFlag flags, CliCallback callback, void* context) { - string_t name_str; - string_init_set_str(name_str, name); - string_strim(name_str); + FuriString* name_str; + name_str = furi_string_alloc_set(name); + furi_string_trim(name_str); size_t name_replace; do { - name_replace = string_replace_str(name_str, " ", "_"); - } while(name_replace != STRING_FAILURE); + name_replace = furi_string_replace(name_str, " ", "_"); + } while(name_replace != FURI_STRING_FAILURE); CliCommand c; c.callback = callback; @@ -412,24 +396,24 @@ void cli_add_command( CliCommandTree_set_at(cli->commands, name_str, c); furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); - string_clear(name_str); + furi_string_free(name_str); } void cli_delete_command(Cli* cli, const char* name) { - string_t name_str; - string_init_set_str(name_str, name); - string_strim(name_str); + FuriString* name_str; + name_str = furi_string_alloc_set(name); + furi_string_trim(name_str); size_t name_replace; do { - name_replace = string_replace_str(name_str, " ", "_"); - } while(name_replace != STRING_FAILURE); + name_replace = furi_string_replace(name_str, " ", "_"); + } while(name_replace != FURI_STRING_FAILURE); furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); CliCommandTree_erase(cli->commands, name_str); furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); - string_clear(name_str); + furi_string_free(name_str); } void cli_session_open(Cli* cli, void* session) { diff --git a/applications/services/cli/cli.h b/applications/services/cli/cli.h index 549e72cc5..09f54f056 100644 --- a/applications/services/cli/cli.h +++ b/applications/services/cli/cli.h @@ -4,8 +4,7 @@ */ #pragma once - -#include +#include #ifdef __cplusplus extern "C" { @@ -43,7 +42,7 @@ typedef struct Cli Cli; * @param args string with what was passed after command * @param context pointer to whatever you gave us on cli_add_command */ -typedef void (*CliCallback)(Cli* cli, string_t args, void* context); +typedef void (*CliCallback)(Cli* cli, FuriString* args, void* context); /** Add cli command Registers you command callback * diff --git a/applications/services/cli/cli_command_gpio.c b/applications/services/cli/cli_command_gpio.c index d5ec8d654..54671eda4 100644 --- a/applications/services/cli/cli_command_gpio.c +++ b/applications/services/cli/cli_command_gpio.c @@ -35,11 +35,11 @@ void cli_command_gpio_print_usage() { printf("\tread \t - Read gpio value\r\n"); } -static bool pin_name_to_int(string_t pin_name, size_t* result) { +static bool pin_name_to_int(FuriString* pin_name, size_t* result) { bool found = false; bool debug = furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug); for(size_t i = 0; i < COUNT_OF(cli_command_gpio_pins); i++) { - if(!string_cmp(pin_name, cli_command_gpio_pins[i].name)) { + if(!furi_string_cmp(pin_name, cli_command_gpio_pins[i].name)) { if(!cli_command_gpio_pins[i].debug || (cli_command_gpio_pins[i].debug && debug)) { *result = i; found = true; @@ -63,29 +63,29 @@ static void gpio_print_pins(void) { typedef enum { OK, ERR_CMD_SYNTAX, ERR_PIN, ERR_VALUE } GpioParseError; -static GpioParseError gpio_command_parse(string_t args, size_t* pin_num, uint8_t* value) { - string_t pin_name; - string_init(pin_name); +static GpioParseError gpio_command_parse(FuriString* args, size_t* pin_num, uint8_t* value) { + FuriString* pin_name; + pin_name = furi_string_alloc(); - size_t ws = string_search_char(args, ' '); - if(ws == STRING_FAILURE) { + size_t ws = furi_string_search_char(args, ' '); + if(ws == FURI_STRING_FAILURE) { return ERR_CMD_SYNTAX; } - string_set_n(pin_name, args, 0, ws); - string_right(args, ws); - string_strim(args); + furi_string_set_n(pin_name, args, 0, ws); + furi_string_right(args, ws); + furi_string_trim(args); if(!pin_name_to_int(pin_name, pin_num)) { - string_clear(pin_name); + furi_string_free(pin_name); return ERR_PIN; } - string_clear(pin_name); + furi_string_free(pin_name); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { *value = 0; - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { *value = 1; } else { return ERR_VALUE; @@ -94,7 +94,7 @@ static GpioParseError gpio_command_parse(string_t args, size_t* pin_num, uint8_t return OK; } -void cli_command_gpio_mode(Cli* cli, string_t args, void* context) { +void cli_command_gpio_mode(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); @@ -104,7 +104,7 @@ void cli_command_gpio_mode(Cli* cli, string_t args, void* context) { GpioParseError err = gpio_command_parse(args, &num, &value); if(ERR_CMD_SYNTAX == err) { - cli_print_usage("gpio mode", " <0|1>", string_get_cstr(args)); + cli_print_usage("gpio mode", " <0|1>", furi_string_get_cstr(args)); return; } else if(ERR_PIN == err) { gpio_print_pins(); @@ -134,7 +134,7 @@ void cli_command_gpio_mode(Cli* cli, string_t args, void* context) { } } -void cli_command_gpio_read(Cli* cli, string_t args, void* context) { +void cli_command_gpio_read(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); @@ -156,7 +156,7 @@ void cli_command_gpio_read(Cli* cli, string_t args, void* context) { printf("Pin %s <= %u", cli_command_gpio_pins[num].name, val); } -void cli_command_gpio_set(Cli* cli, string_t args, void* context) { +void cli_command_gpio_set(Cli* cli, FuriString* args, void* context) { UNUSED(context); size_t num = 0; @@ -164,7 +164,7 @@ void cli_command_gpio_set(Cli* cli, string_t args, void* context) { GpioParseError err = gpio_command_parse(args, &num, &value); if(ERR_CMD_SYNTAX == err) { - cli_print_usage("gpio set", " <0|1>", string_get_cstr(args)); + cli_print_usage("gpio set", " <0|1>", furi_string_get_cstr(args)); return; } else if(ERR_PIN == err) { gpio_print_pins(); @@ -196,9 +196,9 @@ void cli_command_gpio_set(Cli* cli, string_t args, void* context) { printf("Pin %s => %u", cli_command_gpio_pins[num].name, !!value); } -void cli_command_gpio(Cli* cli, string_t args, void* context) { - string_t cmd; - string_init(cmd); +void cli_command_gpio(Cli* cli, FuriString* args, void* context) { + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -206,17 +206,17 @@ void cli_command_gpio(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "mode") == 0) { + if(furi_string_cmp_str(cmd, "mode") == 0) { cli_command_gpio_mode(cli, args, context); break; } - if(string_cmp_str(cmd, "set") == 0) { + if(furi_string_cmp_str(cmd, "set") == 0) { cli_command_gpio_set(cli, args, context); break; } - if(string_cmp_str(cmd, "read") == 0) { + if(furi_string_cmp_str(cmd, "read") == 0) { cli_command_gpio_read(cli, args, context); break; } @@ -224,5 +224,5 @@ void cli_command_gpio(Cli* cli, string_t args, void* context) { cli_command_gpio_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } diff --git a/applications/services/cli/cli_command_gpio.h b/applications/services/cli/cli_command_gpio.h index c9b908a08..7ae5aa625 100644 --- a/applications/services/cli/cli_command_gpio.h +++ b/applications/services/cli/cli_command_gpio.h @@ -2,4 +2,4 @@ #include "cli_i.h" -void cli_command_gpio(Cli* cli, string_t args, void* context); +void cli_command_gpio(Cli* cli, FuriString* args, void* context); diff --git a/applications/services/cli/cli_commands.c b/applications/services/cli/cli_commands.c index a6dd672fc..239434b7a 100644 --- a/applications/services/cli/cli_commands.c +++ b/applications/services/cli/cli_commands.c @@ -7,7 +7,6 @@ #include #include #include -#include // Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'` #define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d" @@ -22,13 +21,13 @@ void cli_command_device_info_callback(const char* key, const char* value, bool l * Device Info Command * This command is intended to be used by humans */ -void cli_command_device_info(Cli* cli, string_t args, void* context) { +void cli_command_device_info(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); furi_hal_info_get(cli_command_device_info_callback, context); } -void cli_command_help(Cli* cli, string_t args, void* context) { +void cli_command_help(Cli* cli, FuriString* args, void* context) { UNUSED(args); UNUSED(context); printf("Commands we have:"); @@ -49,34 +48,34 @@ void cli_command_help(Cli* cli, string_t args, void* context) { printf("\r\n"); // Left Column if(!CliCommandTree_end_p(it_left)) { - printf("%-30s", string_get_cstr(*CliCommandTree_ref(it_left)->key_ptr)); + printf("%-30s", furi_string_get_cstr(*CliCommandTree_ref(it_left)->key_ptr)); CliCommandTree_next(it_left); } // Right Column if(!CliCommandTree_end_p(it_right)) { - printf("%s", string_get_cstr(*CliCommandTree_ref(it_right)->key_ptr)); + printf("%s", furi_string_get_cstr(*CliCommandTree_ref(it_right)->key_ptr)); CliCommandTree_next(it_right); } }; - if(string_size(args) > 0) { + if(furi_string_size(args) > 0) { cli_nl(); printf("Also I have no clue what '"); - printf("%s", string_get_cstr(args)); + printf("%s", furi_string_get_cstr(args)); printf("' is."); } } -void cli_command_date(Cli* cli, string_t args, void* context) { +void cli_command_date(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); FuriHalRtcDateTime datetime = {0}; - if(string_size(args) > 0) { + if(furi_string_size(args) > 0) { uint16_t hours, minutes, seconds, month, day, year, weekday; int ret = sscanf( - string_get_cstr(args), + furi_string_get_cstr(args), "%hu-%hu-%hu %hu:%hu:%hu %hu", &year, &month, @@ -101,7 +100,7 @@ void cli_command_date(Cli* cli, string_t args, void* context) { "Invalid datetime format, use `%s`. sscanf %d %s", "%Y-%m-%d %H:%M:%S %u", ret, - string_get_cstr(args)); + furi_string_get_cstr(args)); return; } @@ -140,97 +139,128 @@ void cli_command_date(Cli* cli, string_t args, void* context) { #define CLI_COMMAND_LOG_BUFFER_SIZE 64 void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* context) { - xStreamBufferSend(context, buffer, size, 0); + furi_stream_buffer_send(context, buffer, size, 0); } -void cli_command_log(Cli* cli, string_t args, void* context) { - UNUSED(args); +void cli_command_log_level_set_from_string(FuriString* level) { + if(furi_string_cmpi_str(level, "default") == 0) { + furi_log_set_level(FuriLogLevelDefault); + } else if(furi_string_cmpi_str(level, "none") == 0) { + furi_log_set_level(FuriLogLevelNone); + } else if(furi_string_cmpi_str(level, "error") == 0) { + furi_log_set_level(FuriLogLevelError); + } else if(furi_string_cmpi_str(level, "warn") == 0) { + furi_log_set_level(FuriLogLevelWarn); + } else if(furi_string_cmpi_str(level, "info") == 0) { + furi_log_set_level(FuriLogLevelInfo); + } else if(furi_string_cmpi_str(level, "debug") == 0) { + furi_log_set_level(FuriLogLevelDebug); + } else if(furi_string_cmpi_str(level, "trace") == 0) { + furi_log_set_level(FuriLogLevelTrace); + } else { + printf("Unknown log level\r\n"); + } +} + +void cli_command_log(Cli* cli, FuriString* args, void* context) { UNUSED(context); - StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1); + FuriStreamBuffer* ring = furi_stream_buffer_alloc(CLI_COMMAND_LOG_RING_SIZE, 1); uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE]; + FuriLogLevel previous_level = furi_log_get_level(); + bool restore_log_level = false; + + if(furi_string_size(args) > 0) { + cli_command_log_level_set_from_string(args); + restore_log_level = true; + } furi_hal_console_set_tx_callback(cli_command_log_tx_callback, ring); printf("Press CTRL+C to stop...\r\n"); while(!cli_cmd_interrupt_received(cli)) { - size_t ret = xStreamBufferReceive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50); + size_t ret = furi_stream_buffer_receive(ring, buffer, CLI_COMMAND_LOG_BUFFER_SIZE, 50); cli_write(cli, buffer, ret); } furi_hal_console_set_tx_callback(NULL, NULL); - vStreamBufferDelete(ring); + if(restore_log_level) { + // There will be strange behaviour if log level is set from settings while log command is running + furi_log_set_level(previous_level); + } + + furi_stream_buffer_free(ring); } -void cli_command_vibro(Cli* cli, string_t args, void* context) { +void cli_command_vibro(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message_block(notification, &sequence_reset_vibro); furi_record_close(RECORD_NOTIFICATION); - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); notification_message_block(notification, &sequence_set_vibro_on); furi_record_close(RECORD_NOTIFICATION); } else { - cli_print_usage("vibro", "<1|0>", string_get_cstr(args)); + cli_print_usage("vibro", "<1|0>", furi_string_get_cstr(args)); } } -void cli_command_debug(Cli* cli, string_t args, void* context) { +void cli_command_debug(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); loader_update_menu(); printf("Debug disabled."); - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { furi_hal_rtc_set_flag(FuriHalRtcFlagDebug); loader_update_menu(); printf("Debug enabled."); } else { - cli_print_usage("debug", "<1|0>", string_get_cstr(args)); + cli_print_usage("debug", "<1|0>", furi_string_get_cstr(args)); } } -void cli_command_led(Cli* cli, string_t args, void* context) { +void cli_command_led(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); // Get first word as light name NotificationMessage notification_led_message; - string_t light_name; - string_init(light_name); - size_t ws = string_search_char(args, ' '); - if(ws == STRING_FAILURE) { - cli_print_usage("led", " <0-255>", string_get_cstr(args)); - string_clear(light_name); + FuriString* light_name; + light_name = furi_string_alloc(); + size_t ws = furi_string_search_char(args, ' '); + if(ws == FURI_STRING_FAILURE) { + cli_print_usage("led", " <0-255>", furi_string_get_cstr(args)); + furi_string_free(light_name); return; } else { - string_set_n(light_name, args, 0, ws); - string_right(args, ws); - string_strim(args); + furi_string_set_n(light_name, args, 0, ws); + furi_string_right(args, ws); + furi_string_trim(args); } // Check light name - if(!string_cmp(light_name, "r")) { + if(!furi_string_cmp(light_name, "r")) { notification_led_message.type = NotificationMessageTypeLedRed; - } else if(!string_cmp(light_name, "g")) { + } else if(!furi_string_cmp(light_name, "g")) { notification_led_message.type = NotificationMessageTypeLedGreen; - } else if(!string_cmp(light_name, "b")) { + } else if(!furi_string_cmp(light_name, "b")) { notification_led_message.type = NotificationMessageTypeLedBlue; - } else if(!string_cmp(light_name, "bl")) { + } else if(!furi_string_cmp(light_name, "bl")) { notification_led_message.type = NotificationMessageTypeLedDisplayBacklight; } else { - cli_print_usage("led", " <0-255>", string_get_cstr(args)); - string_clear(light_name); + cli_print_usage("led", " <0-255>", furi_string_get_cstr(args)); + furi_string_free(light_name); return; } - string_clear(light_name); + furi_string_free(light_name); // Read light value from the rest of the string char* end_ptr; - uint32_t value = strtoul(string_get_cstr(args), &end_ptr, 0); + uint32_t value = strtoul(furi_string_get_cstr(args), &end_ptr, 0); if(!(value < 256 && *end_ptr == '\0')) { - cli_print_usage("led", " <0-255>", string_get_cstr(args)); + cli_print_usage("led", " <0-255>", furi_string_get_cstr(args)); return; } @@ -249,7 +279,7 @@ void cli_command_led(Cli* cli, string_t args, void* context) { furi_record_close(RECORD_NOTIFICATION); } -void cli_command_ps(Cli* cli, string_t args, void* context) { +void cli_command_ps(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); @@ -272,7 +302,7 @@ void cli_command_ps(Cli* cli, string_t args, void* context) { printf("\r\nTotal: %d", thread_num); } -void cli_command_free(Cli* cli, string_t args, void* context) { +void cli_command_free(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); @@ -286,7 +316,7 @@ void cli_command_free(Cli* cli, string_t args, void* context) { printf("Maximum pool block: %d\r\n", memmgr_pool_get_max_block()); } -void cli_command_free_blocks(Cli* cli, string_t args, void* context) { +void cli_command_free_blocks(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); @@ -294,7 +324,7 @@ void cli_command_free_blocks(Cli* cli, string_t args, void* context) { memmgr_heap_printf_free_blocks(); } -void cli_command_i2c(Cli* cli, string_t args, void* context) { +void cli_command_i2c(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(args); UNUSED(context); diff --git a/applications/services/cli/cli_i.h b/applications/services/cli/cli_i.h index ba4582d0d..858cd0c8f 100644 --- a/applications/services/cli/cli_i.h +++ b/applications/services/cli/cli_i.h @@ -36,8 +36,8 @@ struct CliSession { BPTREE_DEF2( CliCommandTree, CLI_COMMANDS_TREE_RANK, - string_t, - STRING_OPLIST, + FuriString*, + FURI_STRING_OPLIST, CliCommand, M_POD_OPLIST) @@ -47,8 +47,8 @@ struct Cli { CliCommandTree_t commands; FuriMutex* mutex; FuriSemaphore* idle_sem; - string_t last_line; - string_t line; + FuriString* last_line; + FuriString* line; CliSession* session; size_t cursor_position; diff --git a/applications/services/cli/cli_vcp.c b/applications/services/cli/cli_vcp.c index f2893a48b..1e27e185b 100644 --- a/applications/services/cli/cli_vcp.c +++ b/applications/services/cli/cli_vcp.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "cli_i.h" #define TAG "CliVcp" @@ -29,8 +28,8 @@ typedef enum { typedef struct { FuriThread* thread; - StreamBufferHandle_t tx_stream; - StreamBufferHandle_t rx_stream; + FuriStreamBuffer* tx_stream; + FuriStreamBuffer* rx_stream; volatile bool connected; volatile bool running; @@ -62,8 +61,8 @@ static const uint8_t ascii_eot = 0x04; static void cli_vcp_init() { if(vcp == NULL) { vcp = malloc(sizeof(CliVcp)); - vcp->tx_stream = xStreamBufferCreate(VCP_TX_BUF_SIZE, 1); - vcp->rx_stream = xStreamBufferCreate(VCP_RX_BUF_SIZE, 1); + vcp->tx_stream = furi_stream_buffer_alloc(VCP_TX_BUF_SIZE, 1); + vcp->rx_stream = furi_stream_buffer_alloc(VCP_RX_BUF_SIZE, 1); } furi_assert(vcp->thread == NULL); @@ -113,7 +112,7 @@ static int32_t vcp_worker(void* context) { #endif if(vcp->connected == false) { vcp->connected = true; - xStreamBufferSend(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); + furi_stream_buffer_send(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); } } @@ -124,8 +123,8 @@ static int32_t vcp_worker(void* context) { #endif if(vcp->connected == true) { vcp->connected = false; - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); - xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); } } @@ -134,7 +133,7 @@ static int32_t vcp_worker(void* context) { #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "StreamRx"); #endif - if(xStreamBufferSpacesAvailable(vcp->rx_stream) >= USB_CDC_PKT_LEN) { + if(furi_stream_buffer_spaces_available(vcp->rx_stream) >= USB_CDC_PKT_LEN) { flags |= VcpEvtRx; missed_rx--; } @@ -142,14 +141,15 @@ static int32_t vcp_worker(void* context) { // New data received if(flags & VcpEvtRx) { - if(xStreamBufferSpacesAvailable(vcp->rx_stream) >= USB_CDC_PKT_LEN) { + if(furi_stream_buffer_spaces_available(vcp->rx_stream) >= USB_CDC_PKT_LEN) { int32_t len = furi_hal_cdc_receive(VCP_IF_NUM, vcp->data_buffer, USB_CDC_PKT_LEN); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "Rx %d", len); #endif if(len > 0) { furi_check( - xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) == + furi_stream_buffer_send( + vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) == (size_t)len); } } else { @@ -173,7 +173,7 @@ static int32_t vcp_worker(void* context) { // CDC write transfer done if(flags & VcpEvtTx) { size_t len = - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "Tx %d", len); #endif @@ -202,8 +202,8 @@ static int32_t vcp_worker(void* context) { furi_hal_usb_unlock(); furi_hal_usb_set_config(vcp->usb_if_prev, NULL); } - xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); - xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); + furi_stream_buffer_receive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); + furi_stream_buffer_send(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); break; } } @@ -229,7 +229,7 @@ static size_t cli_vcp_rx(uint8_t* buffer, size_t size, uint32_t timeout) { size_t batch_size = size; if(batch_size > VCP_RX_BUF_SIZE) batch_size = VCP_RX_BUF_SIZE; - size_t len = xStreamBufferReceive(vcp->rx_stream, buffer, batch_size, timeout); + size_t len = furi_stream_buffer_receive(vcp->rx_stream, buffer, batch_size, timeout); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "rx %u ", batch_size); #endif @@ -262,7 +262,7 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) { size_t batch_size = size; if(batch_size > USB_CDC_PKT_LEN) batch_size = USB_CDC_PKT_LEN; - xStreamBufferSend(vcp->tx_stream, buffer, batch_size, FuriWaitForever); + furi_stream_buffer_send(vcp->tx_stream, buffer, batch_size, FuriWaitForever); furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamTx); #ifdef CLI_VCP_DEBUG FURI_LOG_D(TAG, "tx %u", batch_size); diff --git a/applications/services/crypto/crypto_cli.c b/applications/services/crypto/crypto_cli.c index 26e1fb9c0..a64a3ad0b 100644 --- a/applications/services/crypto/crypto_cli.c +++ b/applications/services/crypto/crypto_cli.c @@ -17,7 +17,7 @@ void crypto_cli_print_usage() { "\tstore_key \t - Store key in secure enclave. !!! NON-REVERSABLE OPERATION - READ MANUAL FIRST !!!\r\n"); }; -void crypto_cli_encrypt(Cli* cli, string_t args) { +void crypto_cli_encrypt(Cli* cli, FuriString* args) { int key_slot = 0; bool key_loaded = false; uint8_t iv[16]; @@ -41,8 +41,8 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { printf("Enter plain text and press Ctrl+C to complete encryption:\r\n"); - string_t input; - string_init(input); + FuriString* input; + input = furi_string_alloc(); char c; while(cli_read(cli, (uint8_t*)&c, 1) == 1) { if(c == CliSymbolAsciiETX) { @@ -51,14 +51,14 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { } else if(c >= 0x20 && c < 0x7F) { putc(c, stdout); fflush(stdout); - string_push_back(input, c); + furi_string_push_back(input, c); } else if(c == CliSymbolAsciiCR) { printf("\r\n"); - string_cat_str(input, "\r\n"); + furi_string_cat(input, "\r\n"); } } - size_t size = string_size(input); + size_t size = furi_string_size(input); if(size > 0) { // C-string null termination and block alignments size++; @@ -66,9 +66,10 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { if(remain) { size = size - remain + 16; } - string_reserve(input, size); + furi_string_reserve(input, size); uint8_t* output = malloc(size); - if(!furi_hal_crypto_encrypt((const uint8_t*)string_get_cstr(input), output, size)) { + if(!furi_hal_crypto_encrypt( + (const uint8_t*)furi_string_get_cstr(input), output, size)) { printf("Failed to encrypt input"); } else { printf("Hex-encoded encrypted data:\r\n"); @@ -83,7 +84,7 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { printf("No input"); } - string_clear(input); + furi_string_free(input); } while(0); if(key_loaded) { @@ -91,7 +92,7 @@ void crypto_cli_encrypt(Cli* cli, string_t args) { } } -void crypto_cli_decrypt(Cli* cli, string_t args) { +void crypto_cli_decrypt(Cli* cli, FuriString* args) { int key_slot = 0; bool key_loaded = false; uint8_t iv[16]; @@ -115,8 +116,8 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { printf("Enter Hex-encoded data and press Ctrl+C to complete decryption:\r\n"); - string_t hex_input; - string_init(hex_input); + FuriString* hex_input; + hex_input = furi_string_alloc(); char c; while(cli_read(cli, (uint8_t*)&c, 1) == 1) { if(c == CliSymbolAsciiETX) { @@ -125,14 +126,14 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { } else if(c >= 0x20 && c < 0x7F) { putc(c, stdout); fflush(stdout); - string_push_back(hex_input, c); + furi_string_push_back(hex_input, c); } else if(c == CliSymbolAsciiCR) { printf("\r\n"); } } - string_strim(hex_input); - size_t hex_size = string_size(hex_input); + furi_string_trim(hex_input); + size_t hex_size = furi_string_size(hex_input); if(hex_size > 0 && hex_size % 2 == 0) { size_t size = hex_size / 2; uint8_t* input = malloc(size); @@ -155,7 +156,7 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { printf("Invalid or empty input"); } - string_clear(hex_input); + furi_string_free(hex_input); } while(0); if(key_loaded) { @@ -163,7 +164,7 @@ void crypto_cli_decrypt(Cli* cli, string_t args) { } } -void crypto_cli_has_key(Cli* cli, string_t args) { +void crypto_cli_has_key(Cli* cli, FuriString* args) { UNUSED(cli); int key_slot = 0; uint8_t iv[16]; @@ -185,12 +186,12 @@ void crypto_cli_has_key(Cli* cli, string_t args) { } while(0); } -void crypto_cli_store_key(Cli* cli, string_t args) { +void crypto_cli_store_key(Cli* cli, FuriString* args) { UNUSED(cli); int key_slot = 0; int key_size = 0; - string_t key_type; - string_init(key_type); + FuriString* key_type; + key_type = furi_string_alloc(); uint8_t data[32 + 12] = {}; FuriHalCryptoKey key; @@ -207,19 +208,19 @@ void crypto_cli_store_key(Cli* cli, string_t args) { break; } - if(string_cmp_str(key_type, "master") == 0) { + if(furi_string_cmp_str(key_type, "master") == 0) { if(key_slot != 0) { printf("Master keyslot must be is 0"); break; } key.type = FuriHalCryptoKeyTypeMaster; - } else if(string_cmp_str(key_type, "simple") == 0) { + } else if(furi_string_cmp_str(key_type, "simple") == 0) { if(key_slot < 1 || key_slot > 99) { printf("Simple keyslot must be in range"); break; } key.type = FuriHalCryptoKeyTypeSimple; - } else if(string_cmp_str(key_type, "encrypted") == 0) { + } else if(furi_string_cmp_str(key_type, "encrypted") == 0) { key.type = FuriHalCryptoKeyTypeEncrypted; data_size += 12; } else { @@ -275,13 +276,13 @@ void crypto_cli_store_key(Cli* cli, string_t args) { } } while(0); - string_clear(key_type); + furi_string_free(key_type); } -static void crypto_cli(Cli* cli, string_t args, void* context) { +static void crypto_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -289,22 +290,22 @@ static void crypto_cli(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "encrypt") == 0) { + if(furi_string_cmp_str(cmd, "encrypt") == 0) { crypto_cli_encrypt(cli, args); break; } - if(string_cmp_str(cmd, "decrypt") == 0) { + if(furi_string_cmp_str(cmd, "decrypt") == 0) { crypto_cli_decrypt(cli, args); break; } - if(string_cmp_str(cmd, "has_key") == 0) { + if(furi_string_cmp_str(cmd, "has_key") == 0) { crypto_cli_has_key(cli, args); break; } - if(string_cmp_str(cmd, "store_key") == 0) { + if(furi_string_cmp_str(cmd, "store_key") == 0) { crypto_cli_store_key(cli, args); break; } @@ -312,7 +313,7 @@ static void crypto_cli(Cli* cli, string_t args, void* context) { crypto_cli_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } void crypto_on_system_start() { diff --git a/applications/services/desktop/animations/animation_manager.c b/applications/services/desktop/animations/animation_manager.c index 1e2a521e1..36c5b3975 100644 --- a/applications/services/desktop/animations/animation_manager.c +++ b/applications/services/desktop/animations/animation_manager.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -50,7 +49,7 @@ struct AnimationManager { AnimationManagerSetNewIdleAnimationCallback new_idle_callback; AnimationManagerSetNewIdleAnimationCallback check_blocking_callback; void* context; - string_t freezed_animation_name; + FuriString* freezed_animation_name; int32_t freezed_animation_time_left; ViewStack* view_stack; }; @@ -279,7 +278,7 @@ AnimationManager* animation_manager_alloc(void) { animation_manager->view_stack = view_stack_alloc(); View* animation_view = bubble_animation_get_view(animation_manager->animation_view); view_stack_add_view(animation_manager->view_stack, animation_view); - string_init(animation_manager->freezed_animation_name); + animation_manager->freezed_animation_name = furi_string_alloc(); animation_manager->idle_animation_timer = furi_timer_alloc(animation_manager_timer_callback, FuriTimerTypeOnce, animation_manager); @@ -317,7 +316,7 @@ void animation_manager_free(AnimationManager* animation_manager) { storage_get_pubsub(storage), animation_manager->pubsub_subscription_storage); furi_record_close(RECORD_STORAGE); - string_clear(animation_manager->freezed_animation_name); + furi_string_free(animation_manager->freezed_animation_name); View* animation_view = bubble_animation_get_view(animation_manager->animation_view); view_stack_remove_view(animation_manager->view_stack, animation_view); bubble_animation_view_free(animation_manager->animation_view); @@ -433,7 +432,7 @@ bool animation_manager_is_animation_loaded(AnimationManager* animation_manager) void animation_manager_unload_and_stall_animation(AnimationManager* animation_manager) { furi_assert(animation_manager); furi_assert(animation_manager->current_animation); - furi_assert(!string_size(animation_manager->freezed_animation_name)); + furi_assert(!furi_string_size(animation_manager->freezed_animation_name)); furi_assert( (animation_manager->state == AnimationManagerStateIdle) || (animation_manager->state == AnimationManagerStateBlocked)); @@ -461,7 +460,7 @@ void animation_manager_unload_and_stall_animation(AnimationManager* animation_ma StorageAnimationManifestInfo* meta = animation_storage_get_meta(animation_manager->current_animation); /* copy str, not move, because it can be internal animation */ - string_set_str(animation_manager->freezed_animation_name, meta->name); + furi_string_set(animation_manager->freezed_animation_name, meta->name); bubble_animation_freeze(animation_manager->animation_view); animation_storage_free_storage_animation(&animation_manager->current_animation); @@ -470,14 +469,14 @@ void animation_manager_unload_and_stall_animation(AnimationManager* animation_ma void animation_manager_load_and_continue_animation(AnimationManager* animation_manager) { furi_assert(animation_manager); furi_assert(!animation_manager->current_animation); - furi_assert(string_size(animation_manager->freezed_animation_name)); + furi_assert(furi_string_size(animation_manager->freezed_animation_name)); furi_assert( (animation_manager->state == AnimationManagerStateFreezedIdle) || (animation_manager->state == AnimationManagerStateFreezedBlocked)); if(animation_manager->state == AnimationManagerStateFreezedBlocked) { StorageAnimation* restore_animation = animation_storage_find_animation( - string_get_cstr(animation_manager->freezed_animation_name)); + furi_string_get_cstr(animation_manager->freezed_animation_name)); /* all blocked animations must be in flipper -> we can * always find blocking animation */ furi_assert(restore_animation); @@ -489,7 +488,7 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m if(!blocked) { /* if no blocking - try restore last one idle */ StorageAnimation* restore_animation = animation_storage_find_animation( - string_get_cstr(animation_manager->freezed_animation_name)); + furi_string_get_cstr(animation_manager->freezed_animation_name)); if(restore_animation) { Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); @@ -517,7 +516,7 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m FURI_LOG_E( TAG, "Failed to restore \'%s\'", - string_get_cstr(animation_manager->freezed_animation_name)); + furi_string_get_cstr(animation_manager->freezed_animation_name)); } } } else { @@ -535,7 +534,7 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m animation_storage_get_meta(animation_manager->current_animation)->name); bubble_animation_unfreeze(animation_manager->animation_view); - string_reset(animation_manager->freezed_animation_name); + furi_string_reset(animation_manager->freezed_animation_name); furi_assert(animation_manager->current_animation); } diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index e0c6bf411..0727fd6ae 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -5,7 +5,6 @@ #include #include #include -#include #include "animation_manager.h" #include "animation_storage.h" @@ -32,8 +31,8 @@ static bool animation_storage_load_single_manifest_info( Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); flipper_format_set_strict_mode(file, true); - string_t read_string; - string_init(read_string); + FuriString* read_string; + read_string = furi_string_alloc(); do { uint32_t u32value; @@ -41,20 +40,20 @@ static bool animation_storage_load_single_manifest_info( if(!flipper_format_file_open_existing(file, ANIMATION_MANIFEST_FILE)) break; if(!flipper_format_read_header(file, read_string, &u32value)) break; - if(string_cmp_str(read_string, "Flipper Animation Manifest")) break; + if(furi_string_cmp_str(read_string, "Flipper Animation Manifest")) break; manifest_info->name = NULL; /* skip other animation names */ flipper_format_set_strict_mode(file, false); while(flipper_format_read_string(file, "Name", read_string) && - string_cmp_str(read_string, name)) + furi_string_cmp_str(read_string, name)) ; - if(string_cmp_str(read_string, name)) break; + if(furi_string_cmp_str(read_string, name)) break; flipper_format_set_strict_mode(file, true); - manifest_info->name = malloc(string_size(read_string) + 1); - strcpy((char*)manifest_info->name, string_get_cstr(read_string)); + manifest_info->name = malloc(furi_string_size(read_string) + 1); + strcpy((char*)manifest_info->name, furi_string_get_cstr(read_string)); if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break; manifest_info->min_butthurt = u32value; @@ -72,7 +71,7 @@ static bool animation_storage_load_single_manifest_info( if(!result && manifest_info->name) { free((void*)manifest_info->name); } - string_clear(read_string); + furi_string_free(read_string); flipper_format_free(file); furi_record_close(RECORD_STORAGE); @@ -88,8 +87,8 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis FlipperFormat* file = flipper_format_file_alloc(storage); /* Forbid skipping fields */ flipper_format_set_strict_mode(file, true); - string_t read_string; - string_init(read_string); + FuriString* read_string; + read_string = furi_string_alloc(); do { uint32_t u32value; @@ -98,7 +97,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis if(FSE_OK != storage_sd_status(storage)) break; if(!flipper_format_file_open_existing(file, ANIMATION_MANIFEST_FILE)) break; if(!flipper_format_read_header(file, read_string, &u32value)) break; - if(string_cmp_str(read_string, "Flipper Animation Manifest")) break; + if(furi_string_cmp_str(read_string, "Flipper Animation Manifest")) break; do { storage_animation = malloc(sizeof(StorageAnimation)); storage_animation->external = true; @@ -106,8 +105,9 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis storage_animation->manifest_info.name = NULL; if(!flipper_format_read_string(file, "Name", read_string)) break; - storage_animation->manifest_info.name = malloc(string_size(read_string) + 1); - strcpy((char*)storage_animation->manifest_info.name, string_get_cstr(read_string)); + storage_animation->manifest_info.name = malloc(furi_string_size(read_string) + 1); + strcpy( + (char*)storage_animation->manifest_info.name, furi_string_get_cstr(read_string)); if(!flipper_format_read_uint32(file, "Min butthurt", &u32value, 1)) break; storage_animation->manifest_info.min_butthurt = u32value; @@ -126,7 +126,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis animation_storage_free_storage_animation(&storage_animation); } while(0); - string_clear(read_string); + furi_string_free(read_string); flipper_format_free(file); // add hard-coded animations @@ -231,16 +231,16 @@ void animation_storage_free_storage_animation(StorageAnimation** storage_animati *storage_animation = NULL; } -static bool animation_storage_cast_align(string_t align_str, Align* align) { - if(!string_cmp_str(align_str, "Bottom")) { +static bool animation_storage_cast_align(FuriString* align_str, Align* align) { + if(!furi_string_cmp(align_str, "Bottom")) { *align = AlignBottom; - } else if(!string_cmp_str(align_str, "Top")) { + } else if(!furi_string_cmp(align_str, "Top")) { *align = AlignTop; - } else if(!string_cmp_str(align_str, "Left")) { + } else if(!furi_string_cmp(align_str, "Left")) { *align = AlignLeft; - } else if(!string_cmp_str(align_str, "Right")) { + } else if(!furi_string_cmp(align_str, "Right")) { *align = AlignRight; - } else if(!string_cmp_str(align_str, "Center")) { + } else if(!furi_string_cmp(align_str, "Center")) { *align = AlignCenter; } else { return false; @@ -291,33 +291,35 @@ static bool animation_storage_load_frames( bool frames_ok = false; File* file = storage_file_alloc(storage); FileInfo file_info; - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); size_t max_filesize = ROUND_UP_TO(width, 8) * height + 1; for(int i = 0; i < icon->frame_count; ++i) { frames_ok = false; - string_printf(filename, ANIMATION_DIR "/%s/frame_%d.bm", name, i); + furi_string_printf(filename, ANIMATION_DIR "/%s/frame_%d.bm", name, i); - if(storage_common_stat(storage, string_get_cstr(filename), &file_info) != FSE_OK) break; + if(storage_common_stat(storage, furi_string_get_cstr(filename), &file_info) != FSE_OK) + break; if(file_info.size > max_filesize) { FURI_LOG_E( TAG, - "Filesize %d, max: %d (width %d, height %d)", + "Filesize %lld, max: %d (width %d, height %d)", file_info.size, max_filesize, width, height); break; } - if(!storage_file_open(file, string_get_cstr(filename), FSAM_READ, FSOM_OPEN_EXISTING)) { - FURI_LOG_E(TAG, "Can't open file \'%s\'", string_get_cstr(filename)); + if(!storage_file_open( + file, furi_string_get_cstr(filename), FSAM_READ, FSOM_OPEN_EXISTING)) { + FURI_LOG_E(TAG, "Can't open file \'%s\'", furi_string_get_cstr(filename)); break; } FURI_CONST_ASSIGN_PTR(icon->frames[i], malloc(file_info.size)); if(storage_file_read(file, (void*)icon->frames[i], file_info.size) != file_info.size) { - FURI_LOG_E(TAG, "Read failed: \'%s\'", string_get_cstr(filename)); + FURI_LOG_E(TAG, "Read failed: \'%s\'", furi_string_get_cstr(filename)); break; } storage_file_close(file); @@ -327,8 +329,8 @@ static bool animation_storage_load_frames( if(!frames_ok) { FURI_LOG_E( TAG, - "Load \'%s\' failed, %dx%d, size: %d", - string_get_cstr(filename), + "Load \'%s\' failed, %dx%d, size: %lld", + furi_string_get_cstr(filename), width, height, file_info.size); @@ -341,15 +343,15 @@ static bool animation_storage_load_frames( } storage_file_free(file); - string_clear(filename); + furi_string_free(filename); return frames_ok; } static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFormat* ff) { uint32_t u32value; - string_t str; - string_init(str); + FuriString* str; + str = furi_string_alloc(); bool success = false; furi_assert(!animation->frame_bubble_sequences); @@ -396,12 +398,12 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo FURI_CONST_ASSIGN(bubble->bubble.y, u32value); if(!flipper_format_read_string(ff, "Text", str)) break; - if(string_size(str) > 100) break; + if(furi_string_size(str) > 100) break; - string_replace_all_str(str, "\\n", "\n"); + furi_string_replace_all(str, "\\n", "\n"); - FURI_CONST_ASSIGN_PTR(bubble->bubble.text, malloc(string_size(str) + 1)); - strcpy((char*)bubble->bubble.text, string_get_cstr(str)); + FURI_CONST_ASSIGN_PTR(bubble->bubble.text, malloc(furi_string_size(str) + 1)); + strcpy((char*)bubble->bubble.text, furi_string_get_cstr(str)); if(!flipper_format_read_string(ff, "AlignH", str)) break; if(!animation_storage_cast_align(str, (Align*)&bubble->bubble.align_h)) break; @@ -423,7 +425,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo } } - string_clear(str); + furi_string_free(str); return success; } @@ -438,8 +440,8 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { FlipperFormat* ff = flipper_format_file_alloc(storage); /* Forbid skipping fields */ flipper_format_set_strict_mode(ff, true); - string_t str; - string_init(str); + FuriString* str; + str = furi_string_alloc(); animation->frame_bubble_sequences = NULL; bool success = false; @@ -448,10 +450,10 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { if(FSE_OK != storage_sd_status(storage)) break; - string_printf(str, ANIMATION_DIR "/%s/" ANIMATION_META_FILE, name); - if(!flipper_format_file_open_existing(ff, string_get_cstr(str))) break; + furi_string_printf(str, ANIMATION_DIR "/%s/" ANIMATION_META_FILE, name); + if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(str))) break; if(!flipper_format_read_header(ff, str, &u32value)) break; - if(string_cmp_str(str, "Flipper Animation")) break; + if(furi_string_cmp_str(str, "Flipper Animation")) break; if(!flipper_format_read_uint32(ff, "Width", &width, 1)) break; if(!flipper_format_read_uint32(ff, "Height", &height, 1)) break; @@ -492,7 +494,7 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { success = true; } while(0); - string_clear(str); + furi_string_free(str); flipper_format_free(ff); if(u32array) { free(u32array); diff --git a/applications/services/desktop/animations/animation_storage.h b/applications/services/desktop/animations/animation_storage.h index e53c1133f..16c0feab4 100644 --- a/applications/services/desktop/animations/animation_storage.h +++ b/applications/services/desktop/animations/animation_storage.h @@ -2,7 +2,6 @@ #include #include #include "views/bubble_animation_view.h" -#include /** Main structure to handle animation data. * Contains all, including animation playing data (BubbleAnimation), diff --git a/applications/services/desktop/views/desktop_view_debug.c b/applications/services/desktop/views/desktop_view_debug.c index c965432f1..f9c8aedc2 100644 --- a/applications/services/desktop/views/desktop_view_debug.c +++ b/applications/services/desktop/views/desktop_view_debug.c @@ -124,16 +124,17 @@ bool desktop_debug_input(InputEvent* event, void* context) { DesktopViewStatsScreens current = 0; with_view_model( - debug_view->view, (DesktopDebugViewModel * model) { - + debug_view->view, + DesktopDebugViewModel * model, + { #ifdef SRV_DOLPHIN_STATE_DEBUG if((event->key == InputKeyDown) || (event->key == InputKeyUp)) { model->screen = !model->screen; } #endif current = model->screen; - return true; - }); + }, + true); size_t count = (event->type == InputTypeRepeat) ? 10 : 1; if(current == DesktopViewStatsMeta) { @@ -181,20 +182,19 @@ void desktop_debug_get_dolphin_data(DesktopDebugView* debug_view) { Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); with_view_model( - debug_view->view, (DesktopDebugViewModel * model) { + debug_view->view, + DesktopDebugViewModel * model, + { model->icounter = stats.icounter; model->butthurt = stats.butthurt; model->timestamp = stats.timestamp; - return true; - }); + }, + true); furi_record_close(RECORD_DOLPHIN); } void desktop_debug_reset_screen_idx(DesktopDebugView* debug_view) { with_view_model( - debug_view->view, (DesktopDebugViewModel * model) { - model->screen = 0; - return true; - }); + debug_view->view, DesktopDebugViewModel * model, { model->screen = 0; }, true); } diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c index 294191bf2..8cb8a7a12 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.c +++ b/applications/services/desktop/views/desktop_view_lock_menu.c @@ -24,27 +24,24 @@ void desktop_lock_menu_set_callback( void desktop_lock_menu_set_pin_state(DesktopLockMenuView* lock_menu, bool pin_is_set) { with_view_model( - lock_menu->view, (DesktopLockMenuViewModel * model) { - model->pin_is_set = pin_is_set; - return true; - }); + lock_menu->view, + DesktopLockMenuViewModel * model, + { model->pin_is_set = pin_is_set; }, + true); } void desktop_lock_menu_set_dummy_mode_state(DesktopLockMenuView* lock_menu, bool dummy_mode) { with_view_model( - lock_menu->view, (DesktopLockMenuViewModel * model) { - model->dummy_mode = dummy_mode; - return true; - }); + lock_menu->view, + DesktopLockMenuViewModel * model, + { model->dummy_mode = dummy_mode; }, + true); } void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx) { furi_assert(idx < DesktopLockMenuIndexTotalCount); with_view_model( - lock_menu->view, (DesktopLockMenuViewModel * model) { - model->idx = idx; - return true; - }); + lock_menu->view, DesktopLockMenuViewModel * model, { model->idx = idx; }, true); } void desktop_lock_menu_draw_callback(Canvas* canvas, void* model) { @@ -95,10 +92,12 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { uint8_t idx = 0; bool consumed = false; bool dummy_mode = false; + bool update = false; with_view_model( - lock_menu->view, (DesktopLockMenuViewModel * model) { - bool ret = false; + lock_menu->view, + DesktopLockMenuViewModel * model, + { if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) { if(event->key == InputKeyUp) { if(model->idx == 0) { @@ -106,7 +105,7 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { } else { model->idx = CLAMP(model->idx - 1, DesktopLockMenuIndexTotalCount - 1, 0); } - ret = true; + update = true; consumed = true; } else if(event->key == InputKeyDown) { if(model->idx == DesktopLockMenuIndexTotalCount - 1) { @@ -114,14 +113,14 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { } else { model->idx = CLAMP(model->idx + 1, DesktopLockMenuIndexTotalCount - 1, 0); } - ret = true; + update = true; consumed = true; } } idx = model->idx; dummy_mode = model->dummy_mode; - return ret; - }); + }, + update); if(event->key == InputKeyOk) { if((idx == DesktopLockMenuIndexLock) && (event->type == InputTypeShort)) { diff --git a/applications/services/dialogs/dialogs.h b/applications/services/dialogs/dialogs.h index 2522c8b54..4e836e365 100644 --- a/applications/services/dialogs/dialogs.h +++ b/applications/services/dialogs/dialogs.h @@ -1,7 +1,6 @@ #pragma once #include #include -#include "m-string.h" #include #ifdef __cplusplus @@ -56,8 +55,8 @@ void dialog_file_browser_set_basic_options( */ bool dialog_file_browser_show( DialogsApp* context, - string_ptr result_path, - string_ptr path, + FuriString* result_path, + FuriString* path, const DialogsFileBrowserOptions* options); /****************** MESSAGE ******************/ diff --git a/applications/services/dialogs/dialogs_api.c b/applications/services/dialogs/dialogs_api.c index fd3b2e961..6fd51782d 100644 --- a/applications/services/dialogs/dialogs_api.c +++ b/applications/services/dialogs/dialogs_api.c @@ -1,14 +1,13 @@ #include "dialogs/dialogs_message.h" #include "dialogs_i.h" #include "dialogs_api_lock.h" -#include "m-string.h" /****************** File browser ******************/ bool dialog_file_browser_show( DialogsApp* context, - string_ptr result_path, - string_ptr path, + FuriString* result_path, + FuriString* path, const DialogsFileBrowserOptions* options) { FuriApiLock lock = API_LOCK_INIT_LOCKED(); furi_check(lock != NULL); diff --git a/applications/services/dialogs/dialogs_message.h b/applications/services/dialogs/dialogs_message.h index 2dc66f133..91e040ce4 100644 --- a/applications/services/dialogs/dialogs_message.h +++ b/applications/services/dialogs/dialogs_message.h @@ -2,7 +2,6 @@ #include #include "dialogs_i.h" #include "dialogs_api_lock.h" -#include "m-string.h" #ifdef __cplusplus extern "C" { @@ -13,8 +12,8 @@ typedef struct { bool skip_assets; bool hide_ext; const Icon* file_icon; - string_ptr result_path; - string_ptr preselected_filename; + FuriString* result_path; + FuriString* preselected_filename; FileBrowserLoadItemCallback item_callback; void* item_callback_context; } DialogsAppMessageDataFileBrowser; diff --git a/applications/services/dolphin/helpers/dolphin_state.c b/applications/services/dolphin/helpers/dolphin_state.c index 95e2f42f4..10cb85c28 100644 --- a/applications/services/dolphin/helpers/dolphin_state.c +++ b/applications/services/dolphin/helpers/dolphin_state.c @@ -171,7 +171,7 @@ void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { FURI_LOG_D( TAG, - "icounter %d, butthurt %d", + "icounter %ld, butthurt %ld", dolphin_state->data.icounter, dolphin_state->data.butthurt); } diff --git a/applications/services/gui/canvas.h b/applications/services/gui/canvas.h index 4923e2e66..49bbd7d68 100644 --- a/applications/services/gui/canvas.h +++ b/applications/services/gui/canvas.h @@ -61,7 +61,7 @@ typedef struct { uint8_t descender; } CanvasFontParameters; -/** Canvas anonymouse structure */ +/** Canvas anonymous structure */ typedef struct Canvas Canvas; /** Get Canvas width @@ -297,7 +297,7 @@ void canvas_draw_disc(Canvas* canvas, uint8_t x, uint8_t y, uint8_t r); * @param y y coordinate of base and height intersection * @param base length of triangle side * @param height length of triangle height - * @param dir CanvasDirection triangle orientaion + * @param dir CanvasDirection triangle orientation */ void canvas_draw_triangle( Canvas* canvas, @@ -323,7 +323,7 @@ void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch); */ void canvas_set_bitmap_mode(Canvas* canvas, bool alpha); -/** Draw rounded-corner frame of width, height at x,y, with round value raduis +/** Draw rounded-corner frame of width, height at x,y, with round value radius * * @param canvas Canvas instance * @param x x coordinate diff --git a/applications/services/gui/elements.c b/applications/services/gui/elements.c index 58b446038..0f7cf73f4 100644 --- a/applications/services/gui/elements.c +++ b/applications/services/gui/elements.c @@ -8,7 +8,6 @@ #include #include -#include #include #include "canvas_i.h" @@ -189,12 +188,12 @@ static size_t end = text + strlen(text); } size_t text_size = end - text; - string_t str; - string_init_set_str(str, text); - string_left(str, text_size); + FuriString* str; + str = furi_string_alloc_set(text); + furi_string_left(str, text_size); size_t result = 0; - uint16_t len_px = canvas_string_width(canvas, string_get_cstr(str)); + uint16_t len_px = canvas_string_width(canvas, furi_string_get_cstr(str)); uint8_t px_left = 0; if(horizontal == AlignCenter) { if(x > (canvas_width(canvas) / 2)) { @@ -224,7 +223,7 @@ static size_t result = text_size; } - string_clear(str); + furi_string_free(str); return result; } @@ -240,7 +239,7 @@ void elements_multiline_text_aligned( uint8_t lines_count = 0; uint8_t font_height = canvas_current_font_height(canvas); - string_t line; + FuriString* line; /* go through text line by line and count lines */ for(const char* start = text; start[0];) { @@ -261,14 +260,14 @@ void elements_multiline_text_aligned( size_t chars_fit = elements_get_max_chars_to_fit(canvas, horizontal, start, x); if((start[chars_fit] == '\n') || (start[chars_fit] == 0)) { - string_init_printf(line, "%.*s", chars_fit, start); + line = furi_string_alloc_printf("%.*s", chars_fit, start); } else if((y + font_height) > canvas_height(canvas)) { - string_init_printf(line, "%.*s...\n", chars_fit, start); + line = furi_string_alloc_printf("%.*s...\n", chars_fit, start); } else { - string_init_printf(line, "%.*s-\n", chars_fit, start); + line = furi_string_alloc_printf("%.*s-\n", chars_fit, start); } - canvas_draw_str_aligned(canvas, x, y, horizontal, vertical, string_get_cstr(line)); - string_clear(line); + canvas_draw_str_aligned(canvas, x, y, horizontal, vertical, furi_string_get_cstr(line)); + furi_string_free(line); y += font_height; if(y > canvas_height(canvas)) { break; @@ -284,22 +283,22 @@ void elements_multiline_text(Canvas* canvas, uint8_t x, uint8_t y, const char* t furi_assert(text); uint8_t font_height = canvas_current_font_height(canvas); - string_t str; - string_init(str); + FuriString* str; + str = furi_string_alloc(); const char* start = text; char* end; do { end = strchr(start, '\n'); if(end) { - string_set_strn(str, start, end - start); + furi_string_set_strn(str, start, end - start); } else { - string_set_str(str, start); + furi_string_set(str, start); } - canvas_draw_str(canvas, x, y, string_get_cstr(str)); + canvas_draw_str(canvas, x, y, furi_string_get_cstr(str)); start = end + 1; y += font_height; } while(end && y < 64); - string_clear(str); + furi_string_free(str); } void elements_multiline_text_framed(Canvas* canvas, uint8_t x, uint8_t y, const char* text) { @@ -533,18 +532,18 @@ void elements_bubble_str( canvas_draw_line(canvas, x2, y2, x3, y3); } -void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width) { +void elements_string_fit_width(Canvas* canvas, FuriString* string, uint8_t width) { furi_assert(canvas); furi_assert(string); - uint16_t len_px = canvas_string_width(canvas, string_get_cstr(string)); + uint16_t len_px = canvas_string_width(canvas, furi_string_get_cstr(string)); if(len_px > width) { width -= canvas_string_width(canvas, "..."); do { - string_left(string, string_size(string) - 1); - len_px = canvas_string_width(canvas, string_get_cstr(string)); + furi_string_left(string, furi_string_size(string) - 1); + len_px = canvas_string_width(canvas, furi_string_get_cstr(string)); } while(len_px > width); - string_cat(string, "..."); + furi_string_cat(string, "..."); } } diff --git a/applications/services/gui/elements.h b/applications/services/gui/elements.h index 2329ca27b..b2d204de7 100644 --- a/applications/services/gui/elements.h +++ b/applications/services/gui/elements.h @@ -9,7 +9,7 @@ #pragma once #include -#include +#include #include "canvas.h" #ifdef __cplusplus @@ -190,7 +190,7 @@ void elements_bubble_str( * @param string string to trim * @param width max width */ -void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width); +void elements_string_fit_width(Canvas* canvas, FuriString* string, uint8_t width); /** Draw text box element * diff --git a/applications/services/gui/gui.c b/applications/services/gui/gui.c index 6b4b9a0a7..0535b32b8 100644 --- a/applications/services/gui/gui.c +++ b/applications/services/gui/gui.c @@ -260,7 +260,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { "non-complementary input, discarding key: %s type: %s, sequence: %p", input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); return; } @@ -290,7 +290,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { view_port, input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); view_port_input(gui->ongoing_input_view_port, input_event); } else { FURI_LOG_D( @@ -300,7 +300,7 @@ void gui_input(Gui* gui, InputEvent* input_event) { view_port, input_get_key_name(input_event->key), input_get_type_name(input_event->type), - input_event->sequence); + (void*)input_event->sequence); } gui_unlock(gui); diff --git a/applications/services/gui/modules/button_menu.c b/applications/services/gui/modules/button_menu.c index 84fea7888..37a04326a 100644 --- a/applications/services/gui/modules/button_menu.c +++ b/applications/services/gui/modules/button_menu.c @@ -79,8 +79,8 @@ static void button_menu_draw_common_button( canvas_draw_rframe(canvas, item_x, item_y, ITEM_WIDTH, ITEM_HEIGHT, 5); } - string_t disp_str; - string_init_set_str(disp_str, text); + FuriString* disp_str; + disp_str = furi_string_alloc_set(text); elements_string_fit_width(canvas, disp_str, ITEM_WIDTH - 6); canvas_draw_str_aligned( @@ -89,9 +89,9 @@ static void button_menu_draw_common_button( item_y + (ITEM_HEIGHT / 2), AlignCenter, AlignCenter, - string_get_cstr(disp_str)); + furi_string_get_cstr(disp_str)); - string_clear(disp_str); + furi_string_free(disp_str); } static void button_menu_view_draw_callback(Canvas* canvas, void* _model) { @@ -116,12 +116,12 @@ static void button_menu_view_draw_callback(Canvas* canvas, void* _model) { } if(model->header) { - string_t disp_str; - string_init_set_str(disp_str, model->header); + FuriString* disp_str; + disp_str = furi_string_alloc_set(model->header); elements_string_fit_width(canvas, disp_str, ITEM_WIDTH - 6); canvas_draw_str_aligned( - canvas, 32, 10, AlignCenter, AlignCenter, string_get_cstr(disp_str)); - string_clear(disp_str); + canvas, 32, 10, AlignCenter, AlignCenter, furi_string_get_cstr(disp_str)); + furi_string_free(disp_str); } for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it); @@ -148,28 +148,32 @@ static void button_menu_process_up(ButtonMenu* button_menu) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { if(model->position > 0) { model->position--; } else { model->position = ButtonMenuItemArray_size(model->items) - 1; } - return true; - }); + }, + true); } static void button_menu_process_down(ButtonMenu* button_menu) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { if(model->position < (ButtonMenuItemArray_size(model->items) - 1)) { model->position++; } else { model->position = 0; } - return true; - }); + }, + true); } static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) { @@ -178,12 +182,14 @@ static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) { ButtonMenuItem* item = NULL; with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { if(model->position < (ButtonMenuItemArray_size(model->items))) { item = ButtonMenuItemArray_get(model->items, model->position); } - return false; - }); + }, + false); if(item) { if(item->type == ButtonMenuItemTypeControl) { @@ -248,22 +254,21 @@ void button_menu_reset(ButtonMenu* button_menu) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { ButtonMenuItemArray_reset(model->items); model->position = 0; model->header = NULL; - return true; - }); + }, + true); } void button_menu_set_header(ButtonMenu* button_menu, const char* header) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { - model->header = header; - return true; - }); + button_menu->view, ButtonMenuModel * model, { model->header = header; }, true); } ButtonMenuItem* button_menu_add_item( @@ -278,15 +283,17 @@ ButtonMenuItem* button_menu_add_item( furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { item = ButtonMenuItemArray_push_new(model->items); item->label = label; item->index = index; item->type = type; item->callback = callback; item->callback_context = callback_context; - return true; - }); + }, + true); return item; } @@ -301,12 +308,14 @@ ButtonMenu* button_menu_alloc(void) { view_set_input_callback(button_menu->view, button_menu_view_input_callback); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { ButtonMenuItemArray_init(model->items); model->position = 0; model->header = NULL; - return true; - }); + }, + true); button_menu->freeze_input = false; return button_menu; @@ -316,10 +325,10 @@ void button_menu_free(ButtonMenu* button_menu) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { - ButtonMenuItemArray_clear(model->items); - return true; - }); + button_menu->view, + ButtonMenuModel * model, + { ButtonMenuItemArray_clear(model->items); }, + true); view_free(button_menu->view); free(button_menu); } @@ -328,7 +337,9 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) { furi_assert(button_menu); with_view_model( - button_menu->view, (ButtonMenuModel * model) { + button_menu->view, + ButtonMenuModel * model, + { uint8_t item_position = 0; ButtonMenuItemArray_it_t it; for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it); @@ -338,6 +349,6 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) { break; } } - return true; - }); + }, + true); } diff --git a/applications/services/gui/modules/button_panel.c b/applications/services/gui/modules/button_panel.c index c823e4b18..47b6ed488 100644 --- a/applications/services/gui/modules/button_panel.c +++ b/applications/services/gui/modules/button_panel.c @@ -70,15 +70,17 @@ ButtonPanel* button_panel_alloc() { view_set_input_callback(button_panel->view, button_panel_view_input_callback); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { model->reserve_x = 0; model->reserve_y = 0; model->selected_item_x = 0; model->selected_item_y = 0; ButtonMatrix_init(model->button_matrix); LabelList_init(model->labels); - return true; - }); + }, + true); return button_panel; } @@ -88,7 +90,9 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re furi_check(reserve_y > 0); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { model->reserve_x = reserve_x; model->reserve_y = reserve_y; ButtonMatrix_reserve(model->button_matrix, model->reserve_y); @@ -99,8 +103,8 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re // TODO: do we need to clear allocated memory of ptr-s to ButtonItem ?? } LabelList_init(model->labels); - return true; - }); + }, + true); } void button_panel_free(ButtonPanel* button_panel) { @@ -109,11 +113,13 @@ void button_panel_free(ButtonPanel* button_panel) { button_panel_reset(button_panel); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { LabelList_clear(model->labels); ButtonMatrix_clear(model->button_matrix); - return true; - }); + }, + true); view_free(button_panel->view); free(button_panel); @@ -123,7 +129,9 @@ void button_panel_reset(ButtonPanel* button_panel) { furi_assert(button_panel); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { for(size_t x = 0; x < model->reserve_x; ++x) { for(size_t y = 0; y < model->reserve_y; ++y) { ButtonItem** button_item = button_panel_get_item(model, x, y); @@ -137,8 +145,8 @@ void button_panel_reset(ButtonPanel* button_panel) { model->selected_item_y = 0; LabelList_reset(model->labels); ButtonMatrix_reset(model->button_matrix); - return true; - }); + }, + true); } static ButtonItem** button_panel_get_item(ButtonPanelModel* model, size_t x, size_t y) { @@ -165,7 +173,9 @@ void button_panel_add_item( furi_assert(button_panel); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { ButtonItem** button_item_ptr = button_panel_get_item(model, matrix_place_x, matrix_place_y); furi_check(*button_item_ptr == NULL); @@ -178,8 +188,8 @@ void button_panel_add_item( button_item->icon.name = icon_name; button_item->icon.name_selected = icon_name_selected; button_item->index = index; - return true; - }); + }, + true); } View* button_panel_get_view(ButtonPanel* button_panel) { @@ -216,114 +226,123 @@ static void button_panel_view_draw_callback(Canvas* canvas, void* _model) { static void button_panel_process_down(ButtonPanel* button_panel) { with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { uint16_t new_selected_item_x = model->selected_item_x; uint16_t new_selected_item_y = model->selected_item_y; size_t i; - if(new_selected_item_y >= (model->reserve_y - 1)) return false; + if(new_selected_item_y < (model->reserve_y - 1)) { + ++new_selected_item_y; - ++new_selected_item_y; - - for(i = 0; i < model->reserve_x; ++i) { - new_selected_item_x = (model->selected_item_x + i) % model->reserve_x; - if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { - break; + for(i = 0; i < model->reserve_x; ++i) { + new_selected_item_x = (model->selected_item_x + i) % model->reserve_x; + if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { + break; + } + } + if(i != model->reserve_x) { + model->selected_item_x = new_selected_item_x; + model->selected_item_y = new_selected_item_y; } } - if(i == model->reserve_x) return false; - - model->selected_item_x = new_selected_item_x; - model->selected_item_y = new_selected_item_y; - - return true; - }); + }, + true); } static void button_panel_process_up(ButtonPanel* button_panel) { with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { size_t new_selected_item_x = model->selected_item_x; size_t new_selected_item_y = model->selected_item_y; size_t i; - if(new_selected_item_y <= 0) return false; + if(new_selected_item_y > 0) { + --new_selected_item_y; - --new_selected_item_y; - - for(i = 0; i < model->reserve_x; ++i) { - new_selected_item_x = (model->selected_item_x + i) % model->reserve_x; - if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { - break; + for(i = 0; i < model->reserve_x; ++i) { + new_selected_item_x = (model->selected_item_x + i) % model->reserve_x; + if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { + break; + } + } + if(i != model->reserve_x) { + model->selected_item_x = new_selected_item_x; + model->selected_item_y = new_selected_item_y; } } - if(i == model->reserve_x) return false; - - model->selected_item_x = new_selected_item_x; - model->selected_item_y = new_selected_item_y; - return true; - }); + }, + true); } static void button_panel_process_left(ButtonPanel* button_panel) { with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { size_t new_selected_item_x = model->selected_item_x; size_t new_selected_item_y = model->selected_item_y; size_t i; - if(new_selected_item_x <= 0) return false; + if(new_selected_item_x > 0) { + --new_selected_item_x; - --new_selected_item_x; - - for(i = 0; i < model->reserve_y; ++i) { - new_selected_item_y = (model->selected_item_y + i) % model->reserve_y; - if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { - break; + for(i = 0; i < model->reserve_y; ++i) { + new_selected_item_y = (model->selected_item_y + i) % model->reserve_y; + if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { + break; + } + } + if(i != model->reserve_y) { + model->selected_item_x = new_selected_item_x; + model->selected_item_y = new_selected_item_y; } } - if(i == model->reserve_y) return false; - - model->selected_item_x = new_selected_item_x; - model->selected_item_y = new_selected_item_y; - return true; - }); + }, + true); } static void button_panel_process_right(ButtonPanel* button_panel) { with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { uint16_t new_selected_item_x = model->selected_item_x; uint16_t new_selected_item_y = model->selected_item_y; size_t i; - if(new_selected_item_x >= (model->reserve_x - 1)) return false; + if(new_selected_item_x < (model->reserve_x - 1)) { + ++new_selected_item_x; - ++new_selected_item_x; - - for(i = 0; i < model->reserve_y; ++i) { - new_selected_item_y = (model->selected_item_y + i) % model->reserve_y; - if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { - break; + for(i = 0; i < model->reserve_y; ++i) { + new_selected_item_y = (model->selected_item_y + i) % model->reserve_y; + if(*button_panel_get_item(model, new_selected_item_x, new_selected_item_y)) { + break; + } + } + if(i != model->reserve_y) { + model->selected_item_x = new_selected_item_x; + model->selected_item_y = new_selected_item_y; } } - if(i == model->reserve_y) return false; - - model->selected_item_x = new_selected_item_x; - model->selected_item_y = new_selected_item_y; - return true; - }); + }, + true); } void button_panel_process_ok(ButtonPanel* button_panel) { ButtonItem* button_item = NULL; with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { button_item = *button_panel_get_item(model, model->selected_item_x, model->selected_item_y); - return true; - }); + }, + true); if(button_item && button_item->callback) { button_item->callback(button_item->callback_context, button_item->index); @@ -374,12 +393,14 @@ void button_panel_add_label( furi_assert(button_panel); with_view_model( - button_panel->view, (ButtonPanelModel * model) { + button_panel->view, + ButtonPanelModel * model, + { LabelElement* label = LabelList_push_raw(model->labels); label->x = x; label->y = y; label->font = font; label->str = label_str; - return true; - }); + }, + true); } diff --git a/applications/services/gui/modules/button_panel.h b/applications/services/gui/modules/button_panel.h index 0c17e3a7c..f3b0bae70 100644 --- a/applications/services/gui/modules/button_panel.h +++ b/applications/services/gui/modules/button_panel.h @@ -53,7 +53,7 @@ void button_panel_reserve(ButtonPanel* button_panel, size_t reserve_x, size_t re * @param button_panel ButtonPanel instance * @param index value to pass to callback * @param matrix_place_x coordinates by x-axis on virtual grid, it - * is only used for naviagation + * is only used for navigation * @param matrix_place_y coordinates by y-axis on virtual grid, it * is only used for naviagation * @param x x-coordinate to draw icon on diff --git a/applications/services/gui/modules/byte_input.c b/applications/services/gui/modules/byte_input.c index bb18a107a..8d7e7fd4f 100644 --- a/applications/services/gui/modules/byte_input.c +++ b/applications/services/gui/modules/byte_input.c @@ -618,42 +618,30 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) { switch(event->key) { case InputKeyLeft: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_left(model); - return true; - }); + byte_input->view, ByteInputModel * model, { byte_input_handle_left(model); }, true); consumed = true; break; case InputKeyRight: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_right(model); - return true; - }); + byte_input->view, + ByteInputModel * model, + { byte_input_handle_right(model); }, + true); consumed = true; break; case InputKeyUp: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_up(model); - return true; - }); + byte_input->view, ByteInputModel * model, { byte_input_handle_up(model); }, true); consumed = true; break; case InputKeyDown: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_down(model); - return true; - }); + byte_input->view, ByteInputModel * model, { byte_input_handle_down(model); }, true); consumed = true; break; case InputKeyOk: with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_handle_ok(model); - return true; - }); + byte_input->view, ByteInputModel * model, { byte_input_handle_ok(model); }, true); consumed = true; break; default: @@ -664,10 +652,10 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) { if((event->type == InputTypeLong || event->type == InputTypeRepeat) && event->key == InputKeyBack) { with_view_model( - byte_input->view, (ByteInputModel * model) { - byte_input_clear_selected_byte(model); - return true; - }); + byte_input->view, + ByteInputModel * model, + { byte_input_clear_selected_byte(model); }, + true); consumed = true; } @@ -703,14 +691,16 @@ ByteInput* byte_input_alloc() { view_set_input_callback(byte_input->view, byte_input_view_input_callback); with_view_model( - byte_input->view, (ByteInputModel * model) { + byte_input->view, + ByteInputModel * model, + { model->header = ""; model->input_callback = NULL; model->changed_callback = NULL; model->callback_context = NULL; byte_input_reset_model_input_data(model); - return true; - }); + }, + true); return byte_input; } @@ -755,15 +745,17 @@ void byte_input_set_result_callback( uint8_t* bytes, uint8_t bytes_count) { with_view_model( - byte_input->view, (ByteInputModel * model) { + byte_input->view, + ByteInputModel * model, + { byte_input_reset_model_input_data(model); model->input_callback = input_callback; model->changed_callback = changed_callback; model->callback_context = callback_context; model->bytes = bytes; model->bytes_count = bytes_count; - return true; - }); + }, + true); } /** @@ -774,8 +766,5 @@ void byte_input_set_result_callback( */ void byte_input_set_header_text(ByteInput* byte_input, const char* text) { with_view_model( - byte_input->view, (ByteInputModel * model) { - model->header = text; - return true; - }); + byte_input->view, ByteInputModel * model, { model->header = text; }, true); } diff --git a/applications/services/gui/modules/dialog_ex.c b/applications/services/gui/modules/dialog_ex.c index dee2a0971..1cb467232 100644 --- a/applications/services/gui/modules/dialog_ex.c +++ b/applications/services/gui/modules/dialog_ex.c @@ -90,12 +90,14 @@ static bool dialog_ex_view_input_callback(InputEvent* event, void* context) { const char* right_text = NULL; with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { left_text = model->left_text; center_text = model->center_text; right_text = model->right_text; - return true; - }); + }, + true); if(dialog_ex->callback) { if(event->type == InputTypeShort) { @@ -149,7 +151,9 @@ DialogEx* dialog_ex_alloc() { view_set_draw_callback(dialog_ex->view, dialog_ex_view_draw_callback); view_set_input_callback(dialog_ex->view, dialog_ex_view_input_callback); with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->header.text = NULL; model->header.x = 0; model->header.y = 0; @@ -169,9 +173,8 @@ DialogEx* dialog_ex_alloc() { model->left_text = NULL; model->center_text = NULL; model->right_text = NULL; - - return true; - }); + }, + true); dialog_ex->enable_extended_events = false; return dialog_ex; } @@ -206,14 +209,16 @@ void dialog_ex_set_header( Align vertical) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->header.text = text; model->header.x = x; model->header.y = y; model->header.horizontal = horizontal; model->header.vertical = vertical; - return true; - }); + }, + true); } void dialog_ex_set_text( @@ -225,52 +230,47 @@ void dialog_ex_set_text( Align vertical) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->text.text = text; model->text.x = x; model->text.y = y; model->text.horizontal = horizontal; model->text.vertical = vertical; - return true; - }); + }, + true); } void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* icon) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->icon.x = x; model->icon.y = y; model->icon.icon = icon; - return true; - }); + }, + true); } void dialog_ex_set_left_button_text(DialogEx* dialog_ex, const char* text) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { - model->left_text = text; - return true; - }); + dialog_ex->view, DialogExModel * model, { model->left_text = text; }, true); } void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { - model->center_text = text; - return true; - }); + dialog_ex->view, DialogExModel * model, { model->center_text = text; }, true); } void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text) { furi_assert(dialog_ex); with_view_model( - dialog_ex->view, (DialogExModel * model) { - model->right_text = text; - return true; - }); + dialog_ex->view, DialogExModel * model, { model->right_text = text; }, true); } void dialog_ex_reset(DialogEx* dialog_ex) { @@ -279,15 +279,17 @@ void dialog_ex_reset(DialogEx* dialog_ex) { .text = NULL, .x = 0, .y = 0, .horizontal = AlignLeft, .vertical = AlignLeft}; IconElement clean_icon_el = {.icon = NULL, .x = 0, .y = 0}; with_view_model( - dialog_ex->view, (DialogExModel * model) { + dialog_ex->view, + DialogExModel * model, + { model->header = clean_text_el; model->text = clean_text_el; model->icon = clean_icon_el; model->left_text = NULL; model->center_text = NULL; model->right_text = NULL; - return true; - }); + }, + true); dialog_ex->context = NULL; dialog_ex->callback = NULL; } diff --git a/applications/services/gui/modules/file_browser.c b/applications/services/gui/modules/file_browser.c index 1c0c8c74c..60e78b01c 100644 --- a/applications/services/gui/modules/file_browser.c +++ b/applications/services/gui/modules/file_browser.c @@ -5,7 +5,6 @@ #include #include #include "furi_hal_resources.h" -#include "m-string.h" #include #include #include @@ -28,23 +27,23 @@ typedef enum { } BrowserItemType; typedef struct { - string_t path; + FuriString* path; BrowserItemType type; uint8_t* custom_icon_data; - string_t display_name; + FuriString* display_name; } BrowserItem_t; static void BrowserItem_t_init(BrowserItem_t* obj) { obj->type = BrowserItemTypeLoading; - string_init(obj->path); - string_init(obj->display_name); + obj->path = furi_string_alloc(); + obj->display_name = furi_string_alloc(); obj->custom_icon_data = NULL; } static void BrowserItem_t_init_set(BrowserItem_t* obj, const BrowserItem_t* src) { obj->type = src->type; - string_init_set(obj->path, src->path); - string_init_set(obj->display_name, src->display_name); + obj->path = furi_string_alloc_set(src->path); + obj->display_name = furi_string_alloc_set(src->display_name); if(src->custom_icon_data) { obj->custom_icon_data = malloc(CUSTOM_ICON_MAX_SIZE); memcpy(obj->custom_icon_data, src->custom_icon_data, CUSTOM_ICON_MAX_SIZE); @@ -55,10 +54,9 @@ static void BrowserItem_t_init_set(BrowserItem_t* obj, const BrowserItem_t* src) static void BrowserItem_t_set(BrowserItem_t* obj, const BrowserItem_t* src) { obj->type = src->type; - string_set(obj->path, src->path); - string_set(obj->display_name, src->display_name); + furi_string_set(obj->path, src->path); + furi_string_set(obj->display_name, src->display_name); if(src->custom_icon_data) { - obj->custom_icon_data = malloc(CUSTOM_ICON_MAX_SIZE); memcpy(obj->custom_icon_data, src->custom_icon_data, CUSTOM_ICON_MAX_SIZE); } else { obj->custom_icon_data = NULL; @@ -66,8 +64,8 @@ static void BrowserItem_t_set(BrowserItem_t* obj, const BrowserItem_t* src) { } static void BrowserItem_t_clear(BrowserItem_t* obj) { - string_clear(obj->path); - string_clear(obj->display_name); + furi_string_free(obj->path); + furi_string_free(obj->display_name); if(obj->custom_icon_data) { free(obj->custom_icon_data); } @@ -94,7 +92,7 @@ struct FileBrowser { FileBrowserLoadItemCallback item_callback; void* item_context; - string_ptr result_path; + FuriString* result_path; }; typedef struct { @@ -125,10 +123,11 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context); static void browser_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root); static void browser_list_load_cb(void* context, uint32_t list_load_offset); -static void browser_list_item_cb(void* context, string_t item_path, bool is_folder, bool is_last); +static void + browser_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last); static void browser_long_load_cb(void* context); -FileBrowser* file_browser_alloc(string_ptr result_path) { +FileBrowser* file_browser_alloc(FuriString* result_path) { furi_assert(result_path); FileBrowser* browser = malloc(sizeof(FileBrowser)); browser->view = view_alloc(); @@ -140,10 +139,7 @@ FileBrowser* file_browser_alloc(string_ptr result_path) { browser->result_path = result_path; with_view_model( - browser->view, (FileBrowserModel * model) { - items_array_init(model->items); - return false; - }); + browser->view, FileBrowserModel * model, { items_array_init(model->items); }, false); return browser; } @@ -152,10 +148,7 @@ void file_browser_free(FileBrowser* browser) { furi_assert(browser); with_view_model( - browser->view, (FileBrowserModel * model) { - items_array_clear(model->items); - return false; - }); + browser->view, FileBrowserModel * model, { items_array_clear(model->items); }, false); view_free(browser->view); free(browser); @@ -179,14 +172,16 @@ void file_browser_configure( browser->hide_ext = hide_ext; with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { model->file_icon = file_icon; model->hide_ext = hide_ext; - return false; - }); + }, + false); } -void file_browser_start(FileBrowser* browser, string_t path) { +void file_browser_start(FileBrowser* browser, FuriString* path) { furi_assert(browser); browser->worker = file_browser_worker_alloc(path, browser->ext_filter, browser->skip_assets); file_browser_worker_set_callback_context(browser->worker, browser); @@ -200,14 +195,16 @@ void file_browser_stop(FileBrowser* browser) { furi_assert(browser); file_browser_worker_free(browser->worker); with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { items_array_reset(model->items); model->item_cnt = 0; model->item_idx = 0; model->array_offset = 0; model->list_offset = 0; - return false; - }); + }, + false); } void file_browser_set_callback(FileBrowser* browser, FileBrowserCallback callback, void* context) { @@ -258,7 +255,9 @@ static void browser_update_offset(FileBrowser* browser) { furi_assert(browser); with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { uint16_t bounds = model->item_cnt > (LIST_ITEMS - 1) ? 2 : model->item_cnt; if((model->item_cnt > (LIST_ITEMS - 1)) && @@ -273,9 +272,8 @@ static void browser_update_offset(FileBrowser* browser) { model->list_offset = CLAMP(model->item_idx - 1, (int32_t)model->item_cnt - bounds, 0); } - - return false; - }); + }, + false); } static void @@ -286,7 +284,9 @@ static void int32_t load_offset = 0; with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { items_array_reset(model->items); if(is_root) { model->item_cnt = item_cnt; @@ -304,8 +304,8 @@ static void model->is_root = is_root; model->list_loading = true; model->folder_loading = false; - return true; - }); + }, + true); browser_update_offset(browser); file_browser_worker_load(browser->worker, load_offset, ITEM_LIST_LEN_MAX); @@ -320,7 +320,9 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) { back_item.type = BrowserItemTypeBack; with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { items_array_reset(model->items); model->array_offset = list_load_offset; if(!model->is_root) { @@ -330,13 +332,14 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) { model->array_offset += 1; } } - return false; - }); + }, + true); BrowserItem_t_clear(&back_item); } -static void browser_list_item_cb(void* context, string_t item_path, bool is_folder, bool is_last) { +static void + browser_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last) { furi_assert(context); FileBrowser* browser = (FileBrowser*)context; @@ -344,8 +347,8 @@ static void browser_list_item_cb(void* context, string_t item_path, bool is_fold item.custom_icon_data = NULL; if(!is_last) { - string_init_set(item.path, item_path); - string_init(item.display_name); + item.path = furi_string_alloc_set(item_path); + item.display_name = furi_string_alloc(); if(is_folder) { item.type = BrowserItemTypeFolder; } else { @@ -363,7 +366,7 @@ static void browser_list_item_cb(void* context, string_t item_path, bool is_fold } } - if(string_empty_p(item.display_name)) { + if(furi_string_empty(item.display_name)) { path_extract_filename( item_path, item.display_name, @@ -371,19 +374,21 @@ static void browser_list_item_cb(void* context, string_t item_path, bool is_fold } with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { items_array_push_back(model->items, item); // TODO: calculate if element is visible - return true; - }); - string_clear(item.display_name); - string_clear(item.path); + }, + true); + furi_string_free(item.display_name); + furi_string_free(item.path); + if(item.custom_icon_data) { + free(item.custom_icon_data); + } } else { with_view_model( - browser->view, (FileBrowserModel * model) { - model->list_loading = false; - return true; - }); + browser->view, FileBrowserModel * model, { model->list_loading = false; }, true); } } @@ -392,10 +397,7 @@ static void browser_long_load_cb(void* context) { FileBrowser* browser = (FileBrowser*)context; with_view_model( - browser->view, (FileBrowserModel * model) { - model->folder_loading = true; - return true; - }); + browser->view, FileBrowserModel * model, { model->folder_loading = true; }, true); } static void browser_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) { @@ -427,8 +429,8 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { uint32_t array_size = items_array_size(model->items); bool show_scrollbar = model->item_cnt > LIST_ITEMS; - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); for(uint32_t i = 0; i < MIN(model->item_cnt, LIST_ITEMS); i++) { int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u); @@ -440,16 +442,16 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { BrowserItem_t* item = items_array_get( model->items, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0)); item_type = item->type; - string_set(filename, item->display_name); + furi_string_set(filename, item->display_name); if(item_type == BrowserItemTypeFile) { custom_icon_data = item->custom_icon_data; } } else { - string_set_str(filename, "---"); + furi_string_set(filename, "---"); } if(item_type == BrowserItemTypeBack) { - string_set_str(filename, ". ."); + furi_string_set(filename, ". ."); } elements_string_fit_width( @@ -471,7 +473,8 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { canvas_draw_icon( canvas, 2, Y_OFFSET + 1 + i * FRAME_HEIGHT, BrowserItemIcons[item_type]); } - canvas_draw_str(canvas, 15, Y_OFFSET + 9 + i * FRAME_HEIGHT, string_get_cstr(filename)); + canvas_draw_str( + canvas, 15, Y_OFFSET + 9 + i * FRAME_HEIGHT, furi_string_get_cstr(filename)); } if(show_scrollbar) { @@ -484,7 +487,7 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) { model->item_cnt); } - string_clear(filename); + furi_string_free(filename); } static void file_browser_view_draw_callback(Canvas* canvas, void* _model) { @@ -504,17 +507,16 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { bool is_loading = false; with_view_model( - browser->view, (FileBrowserModel * model) { - is_loading = model->folder_loading; - return false; - }); + browser->view, FileBrowserModel * model, { is_loading = model->folder_loading; }, false); if(is_loading) { return false; } else if(event->key == InputKeyUp || event->key == InputKeyDown) { if(event->type == InputTypeShort || event->type == InputTypeRepeat) { with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { if(event->key == InputKeyUp) { model->item_idx = ((model->item_idx - 1) + model->item_cnt) % model->item_cnt; @@ -539,8 +541,8 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { browser->worker, load_offset, ITEM_LIST_LEN_MAX); } } - return true; - }); + }, + true); browser_update_offset(browser); consumed = true; } @@ -549,7 +551,9 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { BrowserItem_t* selected_item = NULL; int32_t select_index = 0; with_view_model( - browser->view, (FileBrowserModel * model) { + browser->view, + FileBrowserModel * model, + { if(browser_is_item_in_array(model, model->item_idx)) { selected_item = items_array_get(model->items, model->item_idx - model->array_offset); @@ -558,8 +562,8 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { select_index -= 1; } } - return false; - }); + }, + false); if(selected_item) { if(selected_item->type == BrowserItemTypeBack) { @@ -568,7 +572,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { file_browser_worker_folder_enter( browser->worker, selected_item->path, select_index); } else if(selected_item->type == BrowserItemTypeFile) { - string_set(browser->result_path, selected_item->path); + furi_string_set(browser->result_path, selected_item->path); if(browser->callback) { browser->callback(browser->context); } @@ -580,10 +584,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) { if(event->type == InputTypeShort) { bool is_root = false; with_view_model( - browser->view, (FileBrowserModel * model) { - is_root = model->is_root; - return false; - }); + browser->view, FileBrowserModel * model, { is_root = model->is_root; }, false); if(!is_root) { file_browser_worker_folder_exit(browser->worker); } diff --git a/applications/services/gui/modules/file_browser.h b/applications/services/gui/modules/file_browser.h index 57a9f096a..c9fdddb55 100644 --- a/applications/services/gui/modules/file_browser.h +++ b/applications/services/gui/modules/file_browser.h @@ -5,7 +5,6 @@ #pragma once -#include "m-string.h" #include #ifdef __cplusplus @@ -15,10 +14,13 @@ extern "C" { typedef struct FileBrowser FileBrowser; typedef void (*FileBrowserCallback)(void* context); -typedef bool ( - *FileBrowserLoadItemCallback)(string_t path, void* context, uint8_t** icon, string_t item_name); +typedef bool (*FileBrowserLoadItemCallback)( + FuriString* path, + void* context, + uint8_t** icon, + FuriString* item_name); -FileBrowser* file_browser_alloc(string_ptr result_path); +FileBrowser* file_browser_alloc(FuriString* result_path); void file_browser_free(FileBrowser* browser); @@ -31,7 +33,7 @@ void file_browser_configure( const Icon* file_icon, bool hide_ext); -void file_browser_start(FileBrowser* browser, string_t path); +void file_browser_start(FileBrowser* browser, FuriString* path); void file_browser_stop(FileBrowser* browser); diff --git a/applications/services/gui/modules/file_browser_worker.c b/applications/services/gui/modules/file_browser_worker.c index 36df6cc83..fdaf8273f 100644 --- a/applications/services/gui/modules/file_browser_worker.c +++ b/applications/services/gui/modules/file_browser_worker.c @@ -1,7 +1,6 @@ #include "file_browser_worker.h" #include #include -#include "m-string.h" #include "storage/filesystem_api_defines.h" #include #include @@ -35,8 +34,8 @@ ARRAY_DEF(idx_last_array, int32_t) struct BrowserWorker { FuriThread* thread; - string_t filter_extension; - string_t path_next; + FuriString* filter_extension; + FuriString* path_next; int32_t item_sel_idx; uint32_t load_offset; uint32_t load_count; @@ -50,11 +49,11 @@ struct BrowserWorker { BrowserWorkerLongLoadCallback long_load_cb; }; -static bool browser_path_is_file(string_t path) { +static bool browser_path_is_file(FuriString* path) { bool state = false; FileInfo file_info; Storage* storage = furi_record_open(RECORD_STORAGE); - if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { + if(storage_common_stat(storage, furi_string_get_cstr(path), &file_info) == FSE_OK) { if((file_info.flags & FSF_DIRECTORY) == 0) { state = true; } @@ -63,50 +62,50 @@ static bool browser_path_is_file(string_t path) { return state; } -static bool browser_path_trim(string_t path) { +static bool browser_path_trim(FuriString* path) { bool is_root = false; - size_t filename_start = string_search_rchar(path, '/'); - string_left(path, filename_start); - if((string_empty_p(path)) || (filename_start == STRING_FAILURE)) { - string_set_str(path, BROWSER_ROOT); + size_t filename_start = furi_string_search_rchar(path, '/'); + furi_string_left(path, filename_start); + if((furi_string_empty(path)) || (filename_start == FURI_STRING_FAILURE)) { + furi_string_set(path, BROWSER_ROOT); is_root = true; } return is_root; } -static bool browser_filter_by_name(BrowserWorker* browser, string_t name, bool is_folder) { +static bool browser_filter_by_name(BrowserWorker* browser, FuriString* name, bool is_folder) { if(is_folder) { // Skip assets folders (if enabled) if(browser->skip_assets) { - return ((string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)); + return ((furi_string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)); } else { return true; } } else { // Filter files by extension - if((string_empty_p(browser->filter_extension)) || - (string_cmp_str(browser->filter_extension, "*") == 0)) { + if((furi_string_empty(browser->filter_extension)) || + (furi_string_cmp_str(browser->filter_extension, "*") == 0)) { return true; } - if(string_end_with_string_p(name, browser->filter_extension)) { + if(furi_string_end_with(name, browser->filter_extension)) { return true; } } return false; } -static bool browser_folder_check_and_switch(string_t path) { +static bool browser_folder_check_and_switch(FuriString* path) { FileInfo file_info; Storage* storage = furi_record_open(RECORD_STORAGE); bool is_root = false; - if(string_search_rchar(path, '/') == 0) { + if(furi_string_search_rchar(path, '/') == 0) { is_root = true; } while(1) { // Check if folder is existing and navigate back if not - if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { + if(storage_common_stat(storage, furi_string_get_cstr(path), &file_info) == FSE_OK) { if(file_info.flags & FSF_DIRECTORY) { break; } @@ -122,8 +121,8 @@ static bool browser_folder_check_and_switch(string_t path) { static bool browser_folder_init( BrowserWorker* browser, - string_t path, - string_t filename, + FuriString* path, + FuriString* filename, uint32_t* item_cnt, int32_t* file_idx) { bool state = false; @@ -134,13 +133,13 @@ static bool browser_folder_init( File* directory = storage_file_alloc(storage); char name_temp[FILE_NAME_LEN_MAX]; - string_t name_str; - string_init(name_str); + FuriString* name_str; + name_str = furi_string_alloc(); *item_cnt = 0; *file_idx = -1; - if(storage_dir_open(directory, string_get_cstr(path))) { + if(storage_dir_open(directory, furi_string_get_cstr(path))) { state = true; while(1) { if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) { @@ -148,10 +147,10 @@ static bool browser_folder_init( } if((storage_file_get_error(directory) == FSE_OK) && (name_temp[0] != '\0')) { total_files_cnt++; - string_set_str(name_str, name_temp); + furi_string_set(name_str, name_temp); if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { - if(!string_empty_p(filename)) { - if(string_cmp(name_str, filename) == 0) { + if(!furi_string_empty(filename)) { + if(furi_string_cmp(name_str, filename) == 0) { *file_idx = *item_cnt; } } @@ -167,7 +166,7 @@ static bool browser_folder_init( } } - string_clear(name_str); + furi_string_free(name_str); storage_dir_close(directory); storage_file_free(directory); @@ -178,20 +177,20 @@ static bool browser_folder_init( } static bool - browser_folder_load(BrowserWorker* browser, string_t path, uint32_t offset, uint32_t count) { + browser_folder_load(BrowserWorker* browser, FuriString* path, uint32_t offset, uint32_t count) { FileInfo file_info; Storage* storage = furi_record_open(RECORD_STORAGE); File* directory = storage_file_alloc(storage); char name_temp[FILE_NAME_LEN_MAX]; - string_t name_str; - string_init(name_str); + FuriString* name_str; + name_str = furi_string_alloc(); uint32_t items_cnt = 0; do { - if(!storage_dir_open(directory, string_get_cstr(path))) { + if(!storage_dir_open(directory, furi_string_get_cstr(path))) { break; } @@ -201,7 +200,7 @@ static bool break; } if(storage_file_get_error(directory) == FSE_OK) { - string_set_str(name_str, name_temp); + furi_string_set(name_str, name_temp); if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { items_cnt++; } @@ -223,9 +222,9 @@ static bool break; } if(storage_file_get_error(directory) == FSE_OK) { - string_set_str(name_str, name_temp); + furi_string_set(name_str, name_temp); if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) { - string_printf(name_str, "%s/%s", string_get_cstr(path), name_temp); + furi_string_printf(name_str, "%s/%s", furi_string_get_cstr(path), name_temp); if(browser->list_item_cb) { browser->list_item_cb( browser->cb_ctx, name_str, (file_info.flags & FSF_DIRECTORY), false); @@ -241,7 +240,7 @@ static bool } } while(0); - string_clear(name_str); + furi_string_free(name_str); storage_dir_close(directory); storage_file_free(directory); @@ -257,12 +256,12 @@ static int32_t browser_worker(void* context) { FURI_LOG_D(TAG, "Start"); uint32_t items_cnt = 0; - string_t path; - string_init_set_str(path, BROWSER_ROOT); + FuriString* path; + path = furi_string_alloc_set(BROWSER_ROOT); browser->item_sel_idx = -1; - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange); @@ -282,7 +281,7 @@ static int32_t browser_worker(void* context) { } if(flags & WorkerEvtFolderEnter) { - string_set(path, browser->path_next); + furi_string_set(path, browser->path_next); bool is_root = browser_folder_check_and_switch(path); // Push previous selected item index to history array @@ -292,14 +291,14 @@ static int32_t browser_worker(void* context) { browser_folder_init(browser, path, filename, &items_cnt, &file_idx); FURI_LOG_D( TAG, - "Enter folder: %s items: %u idx: %d", - string_get_cstr(path), + "Enter folder: %s items: %lu idx: %ld", + furi_string_get_cstr(path), items_cnt, file_idx); if(browser->folder_cb) { browser->folder_cb(browser->cb_ctx, items_cnt, file_idx, is_root); } - string_reset(filename); + furi_string_reset(filename); } if(flags & WorkerEvtFolderExit) { @@ -313,7 +312,11 @@ static int32_t browser_worker(void* context) { idx_last_array_pop_back(&file_idx, browser->idx_last); } FURI_LOG_D( - TAG, "Exit to: %s items: %u idx: %d", string_get_cstr(path), items_cnt, file_idx); + TAG, + "Exit to: %s items: %lu idx: %ld", + furi_string_get_cstr(path), + items_cnt, + file_idx); if(browser->folder_cb) { browser->folder_cb(browser->cb_ctx, items_cnt, file_idx, is_root); } @@ -323,12 +326,12 @@ static int32_t browser_worker(void* context) { bool is_root = browser_folder_check_and_switch(path); int32_t file_idx = 0; - string_reset(filename); + furi_string_reset(filename); browser_folder_init(browser, path, filename, &items_cnt, &file_idx); FURI_LOG_D( TAG, - "Refresh folder: %s items: %u idx: %d", - string_get_cstr(path), + "Refresh folder: %s items: %lu idx: %ld", + furi_string_get_cstr(path), items_cnt, browser->item_sel_idx); if(browser->folder_cb) { @@ -337,7 +340,8 @@ static int32_t browser_worker(void* context) { } if(flags & WorkerEvtLoad) { - FURI_LOG_D(TAG, "Load offset: %u cnt: %u", browser->load_offset, browser->load_count); + FURI_LOG_D( + TAG, "Load offset: %lu cnt: %lu", browser->load_offset, browser->load_count); browser_folder_load(browser, path, browser->load_offset, browser->load_count); } @@ -346,21 +350,22 @@ static int32_t browser_worker(void* context) { } } - string_clear(filename); - string_clear(path); + furi_string_free(filename); + furi_string_free(path); FURI_LOG_D(TAG, "End"); return 0; } -BrowserWorker* file_browser_worker_alloc(string_t path, const char* filter_ext, bool skip_assets) { +BrowserWorker* + file_browser_worker_alloc(FuriString* path, const char* filter_ext, bool skip_assets) { BrowserWorker* browser = malloc(sizeof(BrowserWorker)); idx_last_array_init(browser->idx_last); - string_init_set_str(browser->filter_extension, filter_ext); + browser->filter_extension = furi_string_alloc_set(filter_ext); browser->skip_assets = skip_assets; - string_init_set(browser->path_next, path); + browser->path_next = furi_string_alloc_set(path); browser->thread = furi_thread_alloc(); furi_thread_set_name(browser->thread, "BrowserWorker"); @@ -379,8 +384,8 @@ void file_browser_worker_free(BrowserWorker* browser) { furi_thread_join(browser->thread); furi_thread_free(browser->thread); - string_clear(browser->filter_extension); - string_clear(browser->path_next); + furi_string_free(browser->filter_extension); + furi_string_free(browser->path_next); idx_last_array_clear(browser->idx_last); @@ -422,19 +427,19 @@ void file_browser_worker_set_long_load_callback( void file_browser_worker_set_config( BrowserWorker* browser, - string_t path, + FuriString* path, const char* filter_ext, bool skip_assets) { furi_assert(browser); - string_set(browser->path_next, path); - string_set_str(browser->filter_extension, filter_ext); + furi_string_set(browser->path_next, path); + furi_string_set(browser->filter_extension, filter_ext); browser->skip_assets = skip_assets; furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtConfigChange); } -void file_browser_worker_folder_enter(BrowserWorker* browser, string_t path, int32_t item_idx) { +void file_browser_worker_folder_enter(BrowserWorker* browser, FuriString* path, int32_t item_idx) { furi_assert(browser); - string_set(browser->path_next, path); + furi_string_set(browser->path_next, path); browser->item_sel_idx = item_idx; furi_thread_flags_set(furi_thread_get_id(browser->thread), WorkerEvtFolderEnter); } diff --git a/applications/services/gui/modules/file_browser_worker.h b/applications/services/gui/modules/file_browser_worker.h index 18c0b4817..230bb5b45 100644 --- a/applications/services/gui/modules/file_browser_worker.h +++ b/applications/services/gui/modules/file_browser_worker.h @@ -1,6 +1,5 @@ #pragma once -#include "m-string.h" #include #include @@ -17,12 +16,13 @@ typedef void (*BrowserWorkerFolderOpenCallback)( typedef void (*BrowserWorkerListLoadCallback)(void* context, uint32_t list_load_offset); typedef void (*BrowserWorkerListItemCallback)( void* context, - string_t item_path, + FuriString* item_path, bool is_folder, bool is_last); typedef void (*BrowserWorkerLongLoadCallback)(void* context); -BrowserWorker* file_browser_worker_alloc(string_t path, const char* filter_ext, bool skip_assets); +BrowserWorker* + file_browser_worker_alloc(FuriString* path, const char* filter_ext, bool skip_assets); void file_browser_worker_free(BrowserWorker* browser); @@ -46,11 +46,11 @@ void file_browser_worker_set_long_load_callback( void file_browser_worker_set_config( BrowserWorker* browser, - string_t path, + FuriString* path, const char* filter_ext, bool skip_assets); -void file_browser_worker_folder_enter(BrowserWorker* browser, string_t path, int32_t item_idx); +void file_browser_worker_folder_enter(BrowserWorker* browser, FuriString* path, int32_t item_idx); void file_browser_worker_folder_exit(BrowserWorker* browser); diff --git a/applications/services/gui/modules/menu.c b/applications/services/gui/modules/menu.c index 67d46d5f3..db0717f77 100644 --- a/applications/services/gui/modules/menu.c +++ b/applications/services/gui/modules/menu.c @@ -103,25 +103,29 @@ static bool menu_input_callback(InputEvent* event, void* context) { static void menu_enter(void* context) { Menu* menu = context; with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItem* item = MenuItemArray_get(model->items, model->position); if(item && item->icon) { icon_animation_start(item->icon); } - return false; - }); + }, + false); } static void menu_exit(void* context) { Menu* menu = context; with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItem* item = MenuItemArray_get(model->items, model->position); if(item && item->icon) { icon_animation_stop(item->icon); } - return false; - }); + }, + false); } Menu* menu_alloc() { @@ -135,11 +139,13 @@ Menu* menu_alloc() { view_set_exit_callback(menu->view, menu_exit); with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItemArray_init(model->items); model->position = 0; - return true; - }); + }, + true); return menu; } @@ -168,7 +174,9 @@ void menu_add_item( MenuItem* item = NULL; with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { item = MenuItemArray_push_new(model->items); item->label = label; item->icon = icon ? icon_animation_alloc(icon) : icon_animation_alloc(&A_Plugins_14); @@ -176,14 +184,16 @@ void menu_add_item( item->index = index; item->callback = callback; item->callback_context = context; - return true; - }); + }, + true); } void menu_reset(Menu* menu) { furi_assert(menu); with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { for M_EACH(item, model->items, MenuItemArray_t) { icon_animation_stop(item->icon); @@ -192,25 +202,27 @@ void menu_reset(Menu* menu) { MenuItemArray_reset(model->items); model->position = 0; - return true; - }); + }, + true); } void menu_set_selected_item(Menu* menu, uint32_t index) { with_view_model( - menu->view, (MenuModel * model) { - if(index >= MenuItemArray_size(model->items)) { - return false; + menu->view, + MenuModel * model, + { + if(index < MenuItemArray_size(model->items)) { + model->position = index; } - - model->position = index; - return true; - }); + }, + true); } static void menu_process_up(Menu* menu) { with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItem* item = MenuItemArray_get(model->items, model->position); if(item && item->icon) { icon_animation_stop(item->icon); @@ -226,13 +238,15 @@ static void menu_process_up(Menu* menu) { if(item && item->icon) { icon_animation_start(item->icon); } - return true; - }); + }, + true); } static void menu_process_down(Menu* menu) { with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { MenuItem* item = MenuItemArray_get(model->items, model->position); if(item && item->icon) { icon_animation_stop(item->icon); @@ -248,19 +262,21 @@ static void menu_process_down(Menu* menu) { if(item && item->icon) { icon_animation_start(item->icon); } - return true; - }); + }, + true); } static void menu_process_ok(Menu* menu) { MenuItem* item = NULL; with_view_model( - menu->view, (MenuModel * model) { + menu->view, + MenuModel * model, + { if(model->position < MenuItemArray_size(model->items)) { item = MenuItemArray_get(model->items, model->position); } - return true; - }); + }, + true); if(item && item->callback) { item->callback(item->callback_context, item->index); } diff --git a/applications/services/gui/modules/popup.c b/applications/services/gui/modules/popup.c index b3cb5e536..08e8d8c2b 100644 --- a/applications/services/gui/modules/popup.c +++ b/applications/services/gui/modules/popup.c @@ -124,7 +124,9 @@ Popup* popup_alloc() { view_set_exit_callback(popup->view, popup_stop_timer); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { model->header.text = NULL; model->header.x = 0; model->header.y = 0; @@ -140,8 +142,8 @@ Popup* popup_alloc() { model->icon.x = 0; model->icon.y = 0; model->icon.icon = NULL; - return true; - }); + }, + true); return popup; } @@ -176,14 +178,16 @@ void popup_set_header( Align vertical) { furi_assert(popup); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { model->header.text = text; model->header.x = x; model->header.y = y; model->header.horizontal = horizontal; model->header.vertical = vertical; - return true; - }); + }, + true); } void popup_set_text( @@ -195,25 +199,29 @@ void popup_set_text( Align vertical) { furi_assert(popup); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { model->text.text = text; model->text.x = x; model->text.y = y; model->text.horizontal = horizontal; model->text.vertical = vertical; - return true; - }); + }, + true); } void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, const Icon* icon) { furi_assert(popup); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { model->icon.x = x; model->icon.y = y; model->icon.icon = icon; - return true; - }); + }, + true); } void popup_set_timeout(Popup* popup, uint32_t timeout_in_ms) { @@ -233,12 +241,14 @@ void popup_reset(Popup* popup) { furi_assert(popup); with_view_model( - popup->view, (PopupModel * model) { + popup->view, + PopupModel * model, + { memset(&model->header, 0, sizeof(model->header)); memset(&model->text, 0, sizeof(model->text)); memset(&model->icon, 0, sizeof(model->icon)); - return false; - }); + }, + false); popup->callback = NULL; popup->context = NULL; popup->timer_enabled = false; diff --git a/applications/services/gui/modules/submenu.c b/applications/services/gui/modules/submenu.c index 9fefeca08..949598772 100644 --- a/applications/services/gui/modules/submenu.c +++ b/applications/services/gui/modules/submenu.c @@ -65,17 +65,17 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) { canvas_set_color(canvas, ColorBlack); } - string_t disp_str; - string_init_set_str(disp_str, SubmenuItemArray_cref(it)->label); + FuriString* disp_str; + disp_str = furi_string_alloc_set(SubmenuItemArray_cref(it)->label); elements_string_fit_width(canvas, disp_str, item_width - 20); canvas_draw_str( canvas, 6, y_offset + (item_position * item_height) + item_height - 4, - string_get_cstr(disp_str)); + furi_string_get_cstr(disp_str)); - string_clear(disp_str); + furi_string_free(disp_str); } position++; @@ -128,13 +128,15 @@ Submenu* submenu_alloc() { view_set_input_callback(submenu->view, submenu_view_input_callback); with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { SubmenuItemArray_init(model->items); model->position = 0; model->window_position = 0; model->header = NULL; - return true; - }); + }, + true); return submenu; } @@ -143,10 +145,7 @@ void submenu_free(Submenu* submenu) { furi_assert(submenu); with_view_model( - submenu->view, (SubmenuModel * model) { - SubmenuItemArray_clear(model->items); - return true; - }); + submenu->view, SubmenuModel * model, { SubmenuItemArray_clear(model->items); }, true); view_free(submenu->view); free(submenu); } @@ -167,32 +166,38 @@ void submenu_add_item( furi_assert(submenu); with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { item = SubmenuItemArray_push_new(model->items); item->label = label; item->index = index; item->callback = callback; item->callback_context = callback_context; - return true; - }); + }, + true); } void submenu_reset(Submenu* submenu) { furi_assert(submenu); with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { SubmenuItemArray_reset(model->items); model->position = 0; model->window_position = 0; model->header = NULL; - return true; - }); + }, + true); } void submenu_set_selected_item(Submenu* submenu, uint32_t index) { with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { uint32_t position = 0; SubmenuItemArray_it_t it; for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it); @@ -225,14 +230,15 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) { (SubmenuItemArray_size(model->items) - items_on_screen); } } - - return true; - }); + }, + true); } void submenu_process_up(Submenu* submenu) { with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { uint8_t items_on_screen = model->header ? 3 : 4; if(model->position > 0) { model->position--; @@ -246,13 +252,15 @@ void submenu_process_up(Submenu* submenu) { model->window_position = model->position - (items_on_screen - 1); } } - return true; - }); + }, + true); } void submenu_process_down(Submenu* submenu) { with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { uint8_t items_on_screen = model->header ? 3 : 4; if(model->position < (SubmenuItemArray_size(model->items) - 1)) { model->position++; @@ -265,20 +273,22 @@ void submenu_process_down(Submenu* submenu) { model->position = 0; model->window_position = 0; } - return true; - }); + }, + true); } void submenu_process_ok(Submenu* submenu) { SubmenuItem* item = NULL; with_view_model( - submenu->view, (SubmenuModel * model) { + submenu->view, + SubmenuModel * model, + { if(model->position < (SubmenuItemArray_size(model->items))) { item = SubmenuItemArray_get(model->items, model->position); } - return true; - }); + }, + true); if(item && item->callback) { item->callback(item->callback_context, item->index); @@ -289,8 +299,5 @@ void submenu_set_header(Submenu* submenu, const char* header) { furi_assert(submenu); with_view_model( - submenu->view, (SubmenuModel * model) { - model->header = header; - return true; - }); + submenu->view, SubmenuModel * model, { model->header = header; }, true); } diff --git a/applications/services/gui/modules/text_box.c b/applications/services/gui/modules/text_box.c index 52307ec25..99d7d04f1 100644 --- a/applications/services/gui/modules/text_box.c +++ b/applications/services/gui/modules/text_box.c @@ -1,6 +1,5 @@ #include "text_box.h" #include "gui/canvas.h" -#include #include #include #include @@ -12,7 +11,7 @@ struct TextBox { typedef struct { const char* text; char* text_pos; - string_t text_formatted; + FuriString* text_formatted; int32_t scroll_pos; int32_t scroll_num; TextBoxFont font; @@ -22,20 +21,24 @@ typedef struct { static void text_box_process_down(TextBox* text_box) { with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { if(model->scroll_pos < model->scroll_num - 1) { model->scroll_pos++; // Search next line start while(*model->text_pos++ != '\n') ; } - return true; - }); + }, + true); } static void text_box_process_up(TextBox* text_box) { with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { if(model->scroll_pos > 0) { model->scroll_pos--; // Reach last symbol of previous line @@ -47,8 +50,8 @@ static void text_box_process_up(TextBox* text_box) { model->text_pos++; } } - return true; - }); + }, + true); } static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) { @@ -66,17 +69,17 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) { if(line_width + glyph_width > text_width) { line_num++; line_width = 0; - string_push_back(model->text_formatted, '\n'); + furi_string_push_back(model->text_formatted, '\n'); } line_width += glyph_width; } else { line_num++; line_width = 0; } - string_push_back(model->text_formatted, symb); + furi_string_push_back(model->text_formatted, symb); } line_num++; - model->text = string_get_cstr(model->text_formatted); + model->text = furi_string_get_cstr(model->text_formatted); model->text_pos = (char*)model->text; if(model->focus == TextBoxFocusEnd && line_num > 5) { // Set text position to 5th line from the end @@ -138,13 +141,15 @@ TextBox* text_box_alloc() { view_set_input_callback(text_box->view, text_box_view_input_callback); with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { model->text = NULL; - string_init_set_str(model->text_formatted, ""); + model->text_formatted = furi_string_alloc_set(""); model->formatted = false; model->font = TextBoxFontText; - return true; - }); + }, + true); return text_box; } @@ -153,10 +158,7 @@ void text_box_free(TextBox* text_box) { furi_assert(text_box); with_view_model( - text_box->view, (TextBoxModel * model) { - string_clear(model->text_formatted); - return true; - }); + text_box->view, TextBoxModel * model, { furi_string_free(model->text_formatted); }, true); view_free(text_box->view); free(text_box); } @@ -170,13 +172,15 @@ void text_box_reset(TextBox* text_box) { furi_assert(text_box); with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { model->text = NULL; - string_set_str(model->text_formatted, ""); + furi_string_set(model->text_formatted, ""); model->font = TextBoxFontText; model->focus = TextBoxFocusStart; - return true; - }); + }, + true); } void text_box_set_text(TextBox* text_box, const char* text) { @@ -184,31 +188,27 @@ void text_box_set_text(TextBox* text_box, const char* text) { furi_assert(text); with_view_model( - text_box->view, (TextBoxModel * model) { + text_box->view, + TextBoxModel * model, + { model->text = text; - string_reset(model->text_formatted); - string_reserve(model->text_formatted, strlen(text)); + furi_string_reset(model->text_formatted); + furi_string_reserve(model->text_formatted, strlen(text)); model->formatted = false; - return true; - }); + }, + true); } void text_box_set_font(TextBox* text_box, TextBoxFont font) { furi_assert(text_box); with_view_model( - text_box->view, (TextBoxModel * model) { - model->font = font; - return true; - }); + text_box->view, TextBoxModel * model, { model->font = font; }, true); } void text_box_set_focus(TextBox* text_box, TextBoxFocus focus) { furi_assert(text_box); with_view_model( - text_box->view, (TextBoxModel * model) { - model->focus = focus; - return true; - }); + text_box->view, TextBoxModel * model, { model->focus = focus; }, true); } diff --git a/applications/services/gui/modules/text_input.c b/applications/services/gui/modules/text_input.c index 58d7ecab0..79fa87728 100644 --- a/applications/services/gui/modules/text_input.c +++ b/applications/services/gui/modules/text_input.c @@ -27,7 +27,7 @@ typedef struct { TextInputValidatorCallback validator_callback; void* validator_callback_context; - string_t validator_text; + FuriString* validator_text; bool valadator_message_visible; } TextInputModel; @@ -232,7 +232,8 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) { canvas_set_color(canvas, ColorBlack); } - if(text_length == 0 && char_is_lowercase(keys[column].text)) { + if(model->clear_default_text || + (text_length == 0 && char_is_lowercase(keys[column].text))) { canvas_draw_glyph( canvas, keyboard_origin_x + keys[column].x, @@ -256,7 +257,7 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) { canvas_draw_icon(canvas, 10, 14, &I_WarningDolphin_45x42); canvas_draw_rframe(canvas, 8, 8, 112, 50, 3); canvas_draw_rframe(canvas, 9, 9, 110, 48, 2); - elements_multiline_text(canvas, 62, 20, string_get_cstr(model->validator_text)); + elements_multiline_text(canvas, 62, 20, furi_string_get_cstr(model->validator_text)); canvas_set_font(canvas, FontKeyboard); } } @@ -428,10 +429,10 @@ void text_input_timer_callback(void* context) { TextInput* text_input = context; with_view_model( - text_input->view, (TextInputModel * model) { - model->valadator_message_visible = false; - return true; - }); + text_input->view, + TextInputModel * model, + { model->valadator_message_visible = false; }, + true); } TextInput* text_input_alloc() { @@ -445,10 +446,10 @@ TextInput* text_input_alloc() { text_input->timer = furi_timer_alloc(text_input_timer_callback, FuriTimerTypeOnce, text_input); with_view_model( - text_input->view, (TextInputModel * model) { - string_init(model->validator_text); - return false; - }); + text_input->view, + TextInputModel * model, + { model->validator_text = furi_string_alloc(); }, + false); text_input_reset(text_input); @@ -458,10 +459,10 @@ TextInput* text_input_alloc() { void text_input_free(TextInput* text_input) { furi_assert(text_input); with_view_model( - text_input->view, (TextInputModel * model) { - string_clear(model->validator_text); - return false; - }); + text_input->view, + TextInputModel * model, + { furi_string_free(model->validator_text); }, + false); // Send stop command furi_timer_stop(text_input->timer); @@ -476,7 +477,9 @@ void text_input_free(TextInput* text_input) { void text_input_reset(TextInput* text_input) { furi_assert(text_input); with_view_model( - text_input->view, (TextInputModel * model) { + text_input->view, + TextInputModel * model, + { model->text_buffer_size = 0; model->header = ""; model->selected_row = 0; @@ -488,10 +491,10 @@ void text_input_reset(TextInput* text_input) { model->callback_context = NULL; model->validator_callback = NULL; model->validator_callback_context = NULL; - string_reset(model->validator_text); + furi_string_reset(model->validator_text); model->valadator_message_visible = false; - return true; - }); + }, + true); } View* text_input_get_view(TextInput* text_input) { @@ -507,7 +510,9 @@ void text_input_set_result_callback( size_t text_buffer_size, bool clear_default_text) { with_view_model( - text_input->view, (TextInputModel * model) { + text_input->view, + TextInputModel * model, + { model->callback = callback; model->callback_context = callback_context; model->text_buffer = text_buffer; @@ -518,8 +523,8 @@ void text_input_set_result_callback( model->selected_row = 2; model->selected_column = 8; } - return true; - }); + }, + true); } void text_input_set_validator( @@ -527,37 +532,36 @@ void text_input_set_validator( TextInputValidatorCallback callback, void* callback_context) { with_view_model( - text_input->view, (TextInputModel * model) { + text_input->view, + TextInputModel * model, + { model->validator_callback = callback; model->validator_callback_context = callback_context; - return true; - }); + }, + true); } TextInputValidatorCallback text_input_get_validator_callback(TextInput* text_input) { TextInputValidatorCallback validator_callback = NULL; with_view_model( - text_input->view, (TextInputModel * model) { - validator_callback = model->validator_callback; - return false; - }); + text_input->view, + TextInputModel * model, + { validator_callback = model->validator_callback; }, + false); return validator_callback; } void* text_input_get_validator_callback_context(TextInput* text_input) { void* validator_callback_context = NULL; with_view_model( - text_input->view, (TextInputModel * model) { - validator_callback_context = model->validator_callback_context; - return false; - }); + text_input->view, + TextInputModel * model, + { validator_callback_context = model->validator_callback_context; }, + false); return validator_callback_context; } void text_input_set_header_text(TextInput* text_input, const char* text) { with_view_model( - text_input->view, (TextInputModel * model) { - model->header = text; - return true; - }); + text_input->view, TextInputModel * model, { model->header = text; }, true); } diff --git a/applications/services/gui/modules/text_input.h b/applications/services/gui/modules/text_input.h index d30fcd4ca..893fbd533 100644 --- a/applications/services/gui/modules/text_input.h +++ b/applications/services/gui/modules/text_input.h @@ -7,7 +7,6 @@ #include #include "validators.h" -#include #ifdef __cplusplus extern "C" { @@ -16,7 +15,7 @@ extern "C" { /** Text input anonymous structure */ typedef struct TextInput TextInput; typedef void (*TextInputCallback)(void* context); -typedef bool (*TextInputValidatorCallback)(const char* text, string_t error, void* context); +typedef bool (*TextInputValidatorCallback)(const char* text, FuriString* error, void* context); /** Allocate and initialize text input * diff --git a/applications/services/gui/modules/validators.c b/applications/services/gui/modules/validators.c index d5fb0fa22..0463b1c26 100644 --- a/applications/services/gui/modules/validators.c +++ b/applications/services/gui/modules/validators.c @@ -8,7 +8,7 @@ struct ValidatorIsFile { char* current_name; }; -bool validator_is_file_callback(const char* text, string_t error, void* context) { +bool validator_is_file_callback(const char* text, FuriString* error, void* context) { furi_assert(context); ValidatorIsFile* instance = context; @@ -19,16 +19,16 @@ bool validator_is_file_callback(const char* text, string_t error, void* context) } bool ret = true; - string_t path; - string_init_printf(path, "%s/%s%s", instance->app_path_folder, text, instance->app_extension); + FuriString* path = furi_string_alloc_printf( + "%s/%s%s", instance->app_path_folder, text, instance->app_extension); Storage* storage = furi_record_open(RECORD_STORAGE); - if(storage_common_stat(storage, string_get_cstr(path), NULL) == FSE_OK) { + if(storage_common_stat(storage, furi_string_get_cstr(path), NULL) == FSE_OK) { ret = false; - string_printf(error, "This name\nexists!\nChoose\nanother one."); + furi_string_printf(error, "This name\nexists!\nChoose\nanother one."); } else { ret = true; } - string_clear(path); + furi_string_free(path); furi_record_close(RECORD_STORAGE); return ret; diff --git a/applications/services/gui/modules/validators.h b/applications/services/gui/modules/validators.h index c4c4ef54c..d9200b6db 100644 --- a/applications/services/gui/modules/validators.h +++ b/applications/services/gui/modules/validators.h @@ -1,6 +1,5 @@ #pragma once -#include #include #ifdef __cplusplus @@ -15,7 +14,7 @@ ValidatorIsFile* validator_is_file_alloc_init( void validator_is_file_free(ValidatorIsFile* instance); -bool validator_is_file_callback(const char* text, string_t error, void* context); +bool validator_is_file_callback(const char* text, FuriString* error, void* context); #ifdef __cplusplus } diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 4e5e4664f..acd46ee4b 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -8,7 +8,7 @@ struct VariableItem { const char* label; uint8_t current_value_index; - string_t current_value_text; + FuriString* current_value_text; uint8_t values_count; VariableItemChangeCallback change_callback; void* context; @@ -77,7 +77,7 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { item_text_y, AlignCenter, AlignBottom, - string_get_cstr(item->current_value_text)); + furi_string_get_cstr(item->current_value_text)); if(item->current_value_index < (item->values_count - 1)) { canvas_draw_str(canvas, 115, item_text_y, ">"); @@ -92,7 +92,9 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { void variable_item_list_set_selected_item(VariableItemList* variable_item_list, uint8_t index) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { uint8_t position = index; if(position >= VariableItemArray_size(model->items)) { position = 0; @@ -112,9 +114,8 @@ void variable_item_list_set_selected_item(VariableItemList* variable_item_list, model->window_position = (VariableItemArray_size(model->items) - 4); } } - - return true; - }); + }, + true); } uint8_t variable_item_list_get_selected_item_index(VariableItemList* variable_item_list) { @@ -181,7 +182,9 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) void variable_item_list_process_up(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { uint8_t items_on_screen = 4; if(model->position > 0) { model->position--; @@ -195,13 +198,15 @@ void variable_item_list_process_up(VariableItemList* variable_item_list) { model->window_position = model->position - (items_on_screen - 1); } } - return true; - }); + }, + true); } void variable_item_list_process_down(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { uint8_t items_on_screen = 4; if(model->position < (VariableItemArray_size(model->items) - 1)) { model->position++; @@ -214,8 +219,8 @@ void variable_item_list_process_down(VariableItemList* variable_item_list) { model->position = 0; model->window_position = 0; } - return true; - }); + }, + true); } VariableItem* variable_item_list_get_selected_item(VariableItemListModel* model) { @@ -239,7 +244,9 @@ VariableItem* variable_item_list_get_selected_item(VariableItemListModel* model) void variable_item_list_process_left(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItem* item = variable_item_list_get_selected_item(model); if(item->current_value_index > 0) { item->current_value_index--; @@ -247,13 +254,15 @@ void variable_item_list_process_left(VariableItemList* variable_item_list) { item->change_callback(item); } } - return true; - }); + }, + true); } void variable_item_list_process_right(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItem* item = variable_item_list_get_selected_item(model); if(item->current_value_index < (item->values_count - 1)) { item->current_value_index++; @@ -261,18 +270,20 @@ void variable_item_list_process_right(VariableItemList* variable_item_list) { item->change_callback(item); } } - return true; - }); + }, + true); } void variable_item_list_process_ok(VariableItemList* variable_item_list) { with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { if(variable_item_list->callback) { variable_item_list->callback(variable_item_list->context, model->position); } - return false; - }); + }, + false); } VariableItemList* variable_item_list_alloc() { @@ -285,12 +296,14 @@ VariableItemList* variable_item_list_alloc() { view_set_input_callback(variable_item_list->view, variable_item_list_input_callback); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItemArray_init(model->items); model->position = 0; model->window_position = 0; - return true; - }); + }, + true); return variable_item_list; } @@ -299,15 +312,17 @@ void variable_item_list_free(VariableItemList* variable_item_list) { furi_assert(variable_item_list); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItemArray_it_t it; for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it); VariableItemArray_next(it)) { - string_clear(VariableItemArray_ref(it)->current_value_text); + furi_string_free(VariableItemArray_ref(it)->current_value_text); } VariableItemArray_clear(model->items); - return false; - }); + }, + false); view_free(variable_item_list->view); free(variable_item_list); } @@ -316,15 +331,17 @@ void variable_item_list_reset(VariableItemList* variable_item_list) { furi_assert(variable_item_list); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { VariableItemArray_it_t it; for(VariableItemArray_it(it, model->items); !VariableItemArray_end_p(it); VariableItemArray_next(it)) { - string_clear(VariableItemArray_ref(it)->current_value_text); + furi_string_free(VariableItemArray_ref(it)->current_value_text); } VariableItemArray_reset(model->items); - return false; - }); + }, + false); } View* variable_item_list_get_view(VariableItemList* variable_item_list) { @@ -343,16 +360,18 @@ VariableItem* variable_item_list_add( furi_assert(variable_item_list); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { item = VariableItemArray_push_new(model->items); item->label = label; item->values_count = values_count; item->change_callback = change_callback; item->context = context; item->current_value_index = 0; - string_init(item->current_value_text); - return true; - }); + item->current_value_text = furi_string_alloc(); + }, + true); return item; } @@ -363,12 +382,14 @@ void variable_item_list_set_enter_callback( void* context) { furi_assert(callback); with_view_model( - variable_item_list->view, (VariableItemListModel * model) { + variable_item_list->view, + VariableItemListModel * model, + { UNUSED(model); variable_item_list->callback = callback; variable_item_list->context = context; - return false; - }); + }, + false); } void variable_item_set_current_value_index(VariableItem* item, uint8_t current_value_index) { @@ -376,7 +397,7 @@ void variable_item_set_current_value_index(VariableItem* item, uint8_t current_v } void variable_item_set_current_value_text(VariableItem* item, const char* current_value_text) { - string_set_str(item->current_value_text, current_value_text); + furi_string_set(item->current_value_text, current_value_text); } uint8_t variable_item_get_current_value_index(VariableItem* item) { diff --git a/applications/services/gui/modules/widget.c b/applications/services/gui/modules/widget.c index 802f76e24..6153b425b 100644 --- a/applications/services/gui/modules/widget.c +++ b/applications/services/gui/modules/widget.c @@ -36,7 +36,9 @@ static bool gui_widget_view_input_callback(InputEvent* event, void* context) { // Call all Widget Elements input handlers with_view_model( - widget->view, (GuiWidgetModel * model) { + widget->view, + GuiWidgetModel * model, + { ElementArray_it_t it; ElementArray_it(it, model->element); while(!ElementArray_end_p(it)) { @@ -46,8 +48,8 @@ static bool gui_widget_view_input_callback(InputEvent* event, void* context) { } ElementArray_next(it); } - return true; - }); + }, + true); return consumed; } @@ -61,10 +63,7 @@ Widget* widget_alloc() { view_set_input_callback(widget->view, gui_widget_view_input_callback); with_view_model( - widget->view, (GuiWidgetModel * model) { - ElementArray_init(model->element); - return true; - }); + widget->view, GuiWidgetModel * model, { ElementArray_init(model->element); }, true); return widget; } @@ -73,7 +72,9 @@ void widget_reset(Widget* widget) { furi_assert(widget); with_view_model( - widget->view, (GuiWidgetModel * model) { + widget->view, + GuiWidgetModel * model, + { ElementArray_it_t it; ElementArray_it(it, model->element); while(!ElementArray_end_p(it)) { @@ -83,8 +84,8 @@ void widget_reset(Widget* widget) { ElementArray_next(it); } ElementArray_reset(model->element); - return true; - }); + }, + true); } void widget_free(Widget* widget) { @@ -93,10 +94,7 @@ void widget_free(Widget* widget) { widget_reset(widget); // Free elements container with_view_model( - widget->view, (GuiWidgetModel * model) { - ElementArray_clear(model->element); - return true; - }); + widget->view, GuiWidgetModel * model, { ElementArray_clear(model->element); }, true); view_free(widget->view); free(widget); @@ -112,11 +110,13 @@ static void widget_add_element(Widget* widget, WidgetElement* element) { furi_assert(element); with_view_model( - widget->view, (GuiWidgetModel * model) { + widget->view, + GuiWidgetModel * model, + { element->parent = widget; ElementArray_push_back(model->element, element); - return true; - }); + }, + true); } void widget_add_string_multiline_element( diff --git a/applications/services/gui/modules/widget_elements/widget_element_button.c b/applications/services/gui/modules/widget_elements/widget_element_button.c index 92be25907..be33b1897 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_button.c +++ b/applications/services/gui/modules/widget_elements/widget_element_button.c @@ -1,10 +1,9 @@ #include "widget_element_i.h" #include -#include typedef struct { GuiButtonType button_type; - string_t text; + FuriString* text; ButtonCallback callback; void* context; } GuiButtonModel; @@ -18,11 +17,11 @@ static void gui_button_draw(Canvas* canvas, WidgetElement* element) { canvas_set_font(canvas, FontSecondary); if(model->button_type == GuiButtonTypeLeft) { - elements_button_left(canvas, string_get_cstr(model->text)); + elements_button_left(canvas, furi_string_get_cstr(model->text)); } else if(model->button_type == GuiButtonTypeRight) { - elements_button_right(canvas, string_get_cstr(model->text)); + elements_button_right(canvas, furi_string_get_cstr(model->text)); } else if(model->button_type == GuiButtonTypeCenter) { - elements_button_center(canvas, string_get_cstr(model->text)); + elements_button_center(canvas, furi_string_get_cstr(model->text)); } } @@ -50,7 +49,7 @@ static void gui_button_free(WidgetElement* gui_button) { furi_assert(gui_button); GuiButtonModel* model = gui_button->model; - string_clear(model->text); + furi_string_free(model->text); free(gui_button->model); free(gui_button); } @@ -65,7 +64,7 @@ WidgetElement* widget_element_button_create( model->button_type = button_type; model->callback = callback; model->context = context; - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); // Allocate and init Element WidgetElement* gui_button = malloc(sizeof(WidgetElement)); diff --git a/applications/services/gui/modules/widget_elements/widget_element_string.c b/applications/services/gui/modules/widget_elements/widget_element_string.c index a03c2b6d8..feb22ad1c 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_string.c +++ b/applications/services/gui/modules/widget_elements/widget_element_string.c @@ -1,5 +1,4 @@ #include "widget_element_i.h" -#include typedef struct { uint8_t x; @@ -7,7 +6,7 @@ typedef struct { Align horizontal; Align vertical; Font font; - string_t text; + FuriString* text; } GuiStringModel; static void gui_string_draw(Canvas* canvas, WidgetElement* element) { @@ -15,7 +14,7 @@ static void gui_string_draw(Canvas* canvas, WidgetElement* element) { furi_assert(element); GuiStringModel* model = element->model; - if(string_size(model->text)) { + if(furi_string_size(model->text)) { canvas_set_font(canvas, model->font); canvas_draw_str_aligned( canvas, @@ -23,7 +22,7 @@ static void gui_string_draw(Canvas* canvas, WidgetElement* element) { model->y, model->horizontal, model->vertical, - string_get_cstr(model->text)); + furi_string_get_cstr(model->text)); } } @@ -31,7 +30,7 @@ static void gui_string_free(WidgetElement* gui_string) { furi_assert(gui_string); GuiStringModel* model = gui_string->model; - string_clear(model->text); + furi_string_free(model->text); free(gui_string->model); free(gui_string); } @@ -52,7 +51,7 @@ WidgetElement* widget_element_string_create( model->horizontal = horizontal; model->vertical = vertical; model->font = font; - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); // Allocate and init Element WidgetElement* gui_string = malloc(sizeof(WidgetElement)); diff --git a/applications/services/gui/modules/widget_elements/widget_element_string_multiline.c b/applications/services/gui/modules/widget_elements/widget_element_string_multiline.c index 01a70a0d0..9ad2a1a83 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_string_multiline.c +++ b/applications/services/gui/modules/widget_elements/widget_element_string_multiline.c @@ -1,5 +1,4 @@ #include "widget_element_i.h" -#include #include typedef struct { @@ -8,7 +7,7 @@ typedef struct { Align horizontal; Align vertical; Font font; - string_t text; + FuriString* text; } GuiStringMultiLineModel; static void gui_string_multiline_draw(Canvas* canvas, WidgetElement* element) { @@ -16,7 +15,7 @@ static void gui_string_multiline_draw(Canvas* canvas, WidgetElement* element) { furi_assert(element); GuiStringMultiLineModel* model = element->model; - if(string_size(model->text)) { + if(furi_string_size(model->text)) { canvas_set_font(canvas, model->font); elements_multiline_text_aligned( canvas, @@ -24,7 +23,7 @@ static void gui_string_multiline_draw(Canvas* canvas, WidgetElement* element) { model->y, model->horizontal, model->vertical, - string_get_cstr(model->text)); + furi_string_get_cstr(model->text)); } } @@ -32,7 +31,7 @@ static void gui_string_multiline_free(WidgetElement* gui_string) { furi_assert(gui_string); GuiStringMultiLineModel* model = gui_string->model; - string_clear(model->text); + furi_string_free(model->text); free(gui_string->model); free(gui_string); } @@ -53,7 +52,7 @@ WidgetElement* widget_element_string_multiline_create( model->horizontal = horizontal; model->vertical = vertical; model->font = font; - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); // Allocate and init Element WidgetElement* gui_string = malloc(sizeof(WidgetElement)); diff --git a/applications/services/gui/modules/widget_elements/widget_element_text_box.c b/applications/services/gui/modules/widget_elements/widget_element_text_box.c index 4750f8f8f..2c6948202 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_text_box.c +++ b/applications/services/gui/modules/widget_elements/widget_element_text_box.c @@ -1,5 +1,4 @@ #include "widget_element_i.h" -#include #include typedef struct { @@ -9,7 +8,7 @@ typedef struct { uint8_t height; Align horizontal; Align vertical; - string_t text; + FuriString* text; bool strip_to_dots; } GuiTextBoxModel; @@ -18,7 +17,7 @@ static void gui_text_box_draw(Canvas* canvas, WidgetElement* element) { furi_assert(element); GuiTextBoxModel* model = element->model; - if(string_size(model->text)) { + if(furi_string_size(model->text)) { elements_text_box( canvas, model->x, @@ -27,7 +26,7 @@ static void gui_text_box_draw(Canvas* canvas, WidgetElement* element) { model->height, model->horizontal, model->vertical, - string_get_cstr(model->text), + furi_string_get_cstr(model->text), model->strip_to_dots); } } @@ -36,7 +35,7 @@ static void gui_text_box_free(WidgetElement* gui_string) { furi_assert(gui_string); GuiTextBoxModel* model = gui_string->model; - string_clear(model->text); + furi_string_free(model->text); free(gui_string->model); free(gui_string); } @@ -60,7 +59,7 @@ WidgetElement* widget_element_text_box_create( model->height = height; model->horizontal = horizontal; model->vertical = vertical; - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); model->strip_to_dots = strip_to_dots; // Allocate and init Element diff --git a/applications/services/gui/modules/widget_elements/widget_element_text_scroll.c b/applications/services/gui/modules/widget_elements/widget_element_text_scroll.c index 6682b106a..a4d766389 100644 --- a/applications/services/gui/modules/widget_elements/widget_element_text_scroll.c +++ b/applications/services/gui/modules/widget_elements/widget_element_text_scroll.c @@ -1,5 +1,4 @@ #include "widget_element_i.h" -#include #include #include @@ -8,7 +7,7 @@ typedef struct { Font font; Align horizontal; - string_t text; + FuriString* text; } TextScrollLineArray; ARRAY_DEF(TextScrollLineArray, TextScrollLineArray, M_POD_OPLIST) @@ -19,19 +18,19 @@ typedef struct { uint8_t y; uint8_t width; uint8_t height; - string_t text; + FuriString* text; uint8_t scroll_pos_total; uint8_t scroll_pos_current; bool text_formatted; } WidgetElementTextScrollModel; static bool - widget_element_text_scroll_process_ctrl_symbols(TextScrollLineArray* line, string_t text) { + widget_element_text_scroll_process_ctrl_symbols(TextScrollLineArray* line, FuriString* text) { bool processed = false; do { - if(string_get_char(text, 0) != '\e') break; - char ctrl_symbol = string_get_char(text, 1); + if(furi_string_get_char(text, 0) != '\e') break; + char ctrl_symbol = furi_string_get_char(text, 1); if(ctrl_symbol == 'c') { line->horizontal = AlignCenter; } else if(ctrl_symbol == 'r') { @@ -39,7 +38,7 @@ static bool } else if(ctrl_symbol == '#') { line->font = FontPrimary; } - string_right(text, 2); + furi_string_right(text, 2); processed = true; } while(false); @@ -51,7 +50,7 @@ void widget_element_text_scroll_add_line(WidgetElement* element, TextScrollLineA TextScrollLineArray new_line; new_line.font = line->font; new_line.horizontal = line->horizontal; - string_init_set(new_line.text, line->text); + new_line.text = furi_string_alloc_set(line->text); TextScrollLineArray_push_back(model->line_array, new_line); } @@ -59,7 +58,7 @@ static void widget_element_text_scroll_fill_lines(Canvas* canvas, WidgetElement* WidgetElementTextScrollModel* model = element->model; TextScrollLineArray line_tmp; bool all_text_processed = false; - string_init(line_tmp.text); + line_tmp.text = furi_string_alloc(); bool reached_new_line = true; uint16_t total_height = 0; @@ -68,7 +67,7 @@ static void widget_element_text_scroll_fill_lines(Canvas* canvas, WidgetElement* // Set default line properties line_tmp.font = FontSecondary; line_tmp.horizontal = AlignLeft; - string_reset(line_tmp.text); + furi_string_reset(line_tmp.text); // Process control symbols while(widget_element_text_scroll_process_ctrl_symbols(&line_tmp, model->text)) ; @@ -84,38 +83,38 @@ static void widget_element_text_scroll_fill_lines(Canvas* canvas, WidgetElement* uint8_t line_width = 0; uint16_t char_i = 0; while(true) { - char next_char = string_get_char(model->text, char_i++); + char next_char = furi_string_get_char(model->text, char_i++); if(next_char == '\0') { - string_push_back(line_tmp.text, '\0'); + furi_string_push_back(line_tmp.text, '\0'); widget_element_text_scroll_add_line(element, &line_tmp); total_height += params->leading_default - params->height; all_text_processed = true; break; } else if(next_char == '\n') { - string_push_back(line_tmp.text, '\0'); + furi_string_push_back(line_tmp.text, '\0'); widget_element_text_scroll_add_line(element, &line_tmp); - string_right(model->text, char_i); + furi_string_right(model->text, char_i); total_height += params->leading_default - params->height; reached_new_line = true; break; } else { line_width += canvas_glyph_width(canvas, next_char); if(line_width > model->width) { - string_push_back(line_tmp.text, '\0'); + furi_string_push_back(line_tmp.text, '\0'); widget_element_text_scroll_add_line(element, &line_tmp); - string_right(model->text, char_i - 1); - string_reset(line_tmp.text); + furi_string_right(model->text, char_i - 1); + furi_string_reset(line_tmp.text); total_height += params->leading_default - params->height; reached_new_line = false; break; } else { - string_push_back(line_tmp.text, next_char); + furi_string_push_back(line_tmp.text, next_char); } } } } - string_clear(line_tmp.text); + furi_string_free(line_tmp.text); } static void widget_element_text_scroll_draw(Canvas* canvas, WidgetElement* element) { @@ -150,7 +149,7 @@ static void widget_element_text_scroll_draw(Canvas* canvas, WidgetElement* eleme x = model->x + model->width; } canvas_draw_str_aligned( - canvas, x, y, line->horizontal, AlignTop, string_get_cstr(line->text)); + canvas, x, y, line->horizontal, AlignTop, furi_string_get_cstr(line->text)); y += params->leading_default; } // Draw scroll bar @@ -205,10 +204,10 @@ static void widget_element_text_scroll_free(WidgetElement* text_scroll) { for(TextScrollLineArray_it(it, model->line_array); !TextScrollLineArray_end_p(it); TextScrollLineArray_next(it)) { TextScrollLineArray* line = TextScrollLineArray_ref(it); - string_clear(line->text); + furi_string_free(line->text); } TextScrollLineArray_clear(model->line_array); - string_clear(model->text); + furi_string_free(model->text); free(text_scroll->model); furi_mutex_free(text_scroll->model_mutex); free(text_scroll); @@ -231,7 +230,7 @@ WidgetElement* widget_element_text_scroll_create( model->scroll_pos_current = 0; model->scroll_pos_total = 1; TextScrollLineArray_init(model->line_array); - string_init_set_str(model->text, text); + model->text = furi_string_alloc_set(text); WidgetElement* text_scroll = malloc(sizeof(WidgetElement)); text_scroll->parent = NULL; diff --git a/applications/services/gui/view.h b/applications/services/gui/view.h index 5b4bf3609..b40f8ded5 100644 --- a/applications/services/gui/view.h +++ b/applications/services/gui/view.h @@ -211,25 +211,25 @@ void view_commit_model(View* view, bool update); #endif #ifdef __cplusplus -#define with_view_model_cpp(view, type, var, function_body) \ +#define with_view_model_cpp(view, type, var, code, update) \ { \ - type* p = static_cast(view_get_model(view)); \ - bool update = [&](type * var) function_body(p); \ + type var = static_cast(view_get_model(view)); \ + {code}; \ view_commit_model(view, update); \ } #else /** With clause for view model * * @param view View instance pointer - * @param function_body a (){} lambda declaration, executed within you - * parent function context + * @param type View model type + * @param code Code block that will be executed between model lock and unlock + * @param update Bool flag, if true, view will be updated after code block. Can be variable, so code block can decide if update is needed. * - * @return true if you want to emit view update, false otherwise */ -#define with_view_model(view, function_body) \ - { \ - void* p = view_get_model(view); \ - bool update = ({ bool __fn__ function_body __fn__; })(p); \ - view_commit_model(view, update); \ +#define with_view_model(view, type, code, update) \ + { \ + type = view_get_model(view); \ + {code}; \ + view_commit_model(view, update); \ } #endif diff --git a/applications/services/gui/view_dispatcher.c b/applications/services/gui/view_dispatcher.c index 307206c14..6e4ce8360 100644 --- a/applications/services/gui/view_dispatcher.c +++ b/applications/services/gui/view_dispatcher.c @@ -246,7 +246,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e "non-complementary input, discarding key: %s, type: %s, sequence: %p", input_get_key_name(event->key), input_get_type_name(event->type), - event->sequence); + (void*)event->sequence); return; } @@ -286,7 +286,7 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e view_dispatcher->current_view, input_get_key_name(event->key), input_get_type_name(event->type), - event->sequence); + (void*)event->sequence); view_input(view_dispatcher->ongoing_input_view, event); } } diff --git a/applications/services/input/input_cli.c b/applications/services/input/input_cli.c index 037ac53e5..d9a8eaeba 100644 --- a/applications/services/input/input_cli.c +++ b/applications/services/input/input_cli.c @@ -19,7 +19,7 @@ static void input_cli_dump_events_callback(const void* value, void* ctx) { furi_message_queue_put(input_queue, value, FuriWaitForever); } -static void input_cli_dump(Cli* cli, string_t args, Input* input) { +static void input_cli_dump(Cli* cli, FuriString* args, Input* input) { UNUSED(args); FuriMessageQueue* input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); FuriPubSubSubscription* input_subscription = @@ -47,11 +47,11 @@ static void input_cli_send_print_usage() { printf("\t\t \t - one of 'press', 'release', 'short', 'long'\r\n"); } -static void input_cli_send(Cli* cli, string_t args, Input* input) { +static void input_cli_send(Cli* cli, FuriString* args, Input* input) { UNUSED(cli); InputEvent event; - string_t key_str; - string_init(key_str); + FuriString* key_str; + key_str = furi_string_alloc(); bool parsed = false; do { @@ -59,29 +59,29 @@ static void input_cli_send(Cli* cli, string_t args, Input* input) { if(!args_read_string_and_trim(args, key_str)) { break; } - if(!string_cmp(key_str, "up")) { + if(!furi_string_cmp(key_str, "up")) { event.key = InputKeyUp; - } else if(!string_cmp(key_str, "down")) { + } else if(!furi_string_cmp(key_str, "down")) { event.key = InputKeyDown; - } else if(!string_cmp(key_str, "left")) { + } else if(!furi_string_cmp(key_str, "left")) { event.key = InputKeyLeft; - } else if(!string_cmp(key_str, "right")) { + } else if(!furi_string_cmp(key_str, "right")) { event.key = InputKeyRight; - } else if(!string_cmp(key_str, "ok")) { + } else if(!furi_string_cmp(key_str, "ok")) { event.key = InputKeyOk; - } else if(!string_cmp(key_str, "back")) { + } else if(!furi_string_cmp(key_str, "back")) { event.key = InputKeyBack; } else { break; } // Parse Type - if(!string_cmp(args, "press")) { + if(!furi_string_cmp(args, "press")) { event.type = InputTypePress; - } else if(!string_cmp(args, "release")) { + } else if(!furi_string_cmp(args, "release")) { event.type = InputTypeRelease; - } else if(!string_cmp(args, "short")) { + } else if(!furi_string_cmp(args, "short")) { event.type = InputTypeShort; - } else if(!string_cmp(args, "long")) { + } else if(!furi_string_cmp(args, "long")) { event.type = InputTypeLong; } else { break; @@ -94,26 +94,26 @@ static void input_cli_send(Cli* cli, string_t args, Input* input) { } else { input_cli_send_print_usage(); } - string_clear(key_str); + furi_string_free(key_str); } -void input_cli(Cli* cli, string_t args, void* context) { +void input_cli(Cli* cli, FuriString* args, void* context) { furi_assert(cli); furi_assert(context); Input* input = context; - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { input_cli_usage(); break; } - if(string_cmp_str(cmd, "dump") == 0) { + if(furi_string_cmp_str(cmd, "dump") == 0) { input_cli_dump(cli, args, input); break; } - if(string_cmp_str(cmd, "send") == 0) { + if(furi_string_cmp_str(cmd, "send") == 0) { input_cli_send(cli, args, input); break; } @@ -121,5 +121,5 @@ void input_cli(Cli* cli, string_t args, void* context) { input_cli_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } diff --git a/applications/services/input/input_i.h b/applications/services/input/input_i.h index f709e0487..14d8b0735 100644 --- a/applications/services/input/input_i.h +++ b/applications/services/input/input_i.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #define INPUT_DEBOUNCE_TICKS_HALF (INPUT_DEBOUNCE_TICKS / 2) @@ -46,4 +45,4 @@ void input_press_timer_callback(void* arg); void input_isr(void* _ctx); /** Input CLI command handler */ -void input_cli(Cli* cli, string_t args, void* context); +void input_cli(Cli* cli, FuriString* args, void* context); diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index cf7e5a108..bc456536c 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -61,6 +61,7 @@ static void loader_cli_print_usage() { printf("Cmd list:\r\n"); printf("\tlist\t - List available applications\r\n"); printf("\topen \t - Open application by name\r\n"); + printf("\tinfo\t - Show loader state\r\n"); } static FlipperApplication const* loader_find_application_by_name_in_list( @@ -98,15 +99,20 @@ const FlipperApplication* loader_find_application_by_name(const char* name) { return application; } -void loader_cli_open(Cli* cli, string_t args, Loader* instance) { +static void loader_cli_open(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); if(loader_is_locked(instance)) { - printf("Can't start, furi application is running"); + if(instance->application) { + furi_assert(instance->application->name); + printf("Can't start, %s application is running", instance->application->name); + } else { + printf("Can't start, furi application is running"); + } return; } - string_t application_name; - string_init(application_name); + FuriString* application_name; + application_name = furi_string_alloc(); do { if(!args_read_probably_quoted_string_and_trim(args, application_name)) { @@ -115,14 +121,14 @@ void loader_cli_open(Cli* cli, string_t args, Loader* instance) { } const FlipperApplication* application = - loader_find_application_by_name(string_get_cstr(application_name)); + loader_find_application_by_name(furi_string_get_cstr(application_name)); if(!application) { - printf("%s doesn't exists\r\n", string_get_cstr(application_name)); + printf("%s doesn't exists\r\n", furi_string_get_cstr(application_name)); break; } - string_strim(args); - if(!loader_start_application(application, string_get_cstr(args))) { + furi_string_trim(args); + if(!loader_start_application(application, furi_string_get_cstr(args))) { printf("Can't start, furi application is running"); return; } else { @@ -134,10 +140,10 @@ void loader_cli_open(Cli* cli, string_t args, Loader* instance) { } } while(false); - string_clear(application_name); + furi_string_free(application_name); } -void loader_cli_list(Cli* cli, string_t args, Loader* instance) { +static void loader_cli_list(Cli* cli, FuriString* args, Loader* instance) { UNUSED(cli); UNUSED(args); UNUSED(instance); @@ -159,12 +165,28 @@ void loader_cli_list(Cli* cli, string_t args, Loader* instance) { } } -static void loader_cli(Cli* cli, string_t args, void* _ctx) { +static void loader_cli_info(Cli* cli, FuriString* args, Loader* instance) { + UNUSED(cli); + UNUSED(args); + if(!loader_is_locked(instance)) { + printf("No application is running\r\n"); + } else { + printf("Running application: "); + if(instance->application) { + furi_assert(instance->application->name); + printf("%s\r\n", instance->application->name); + } else { + printf("unknown\r\n"); + } + } +} + +static void loader_cli(Cli* cli, FuriString* args, void* _ctx) { furi_assert(_ctx); Loader* instance = _ctx; - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -172,20 +194,25 @@ static void loader_cli(Cli* cli, string_t args, void* _ctx) { break; } - if(string_cmp_str(cmd, "list") == 0) { + if(furi_string_cmp_str(cmd, "list") == 0) { loader_cli_list(cli, args, instance); break; } - if(string_cmp_str(cmd, "open") == 0) { + if(furi_string_cmp_str(cmd, "open") == 0) { loader_cli_open(cli, args, instance); break; } + if(furi_string_cmp_str(cmd, "info") == 0) { + loader_cli_info(cli, args, instance); + break; + } + loader_cli_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } LoaderStatus loader_start(Loader* instance, const char* name, const char* args) { diff --git a/applications/services/power/power_cli.c b/applications/services/power/power_cli.c index 6af396318..5c28137e9 100644 --- a/applications/services/power/power_cli.c +++ b/applications/services/power/power_cli.c @@ -5,7 +5,7 @@ #include #include -void power_cli_off(Cli* cli, string_t args) { +void power_cli_off(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); Power* power = furi_record_open(RECORD_POWER); @@ -14,13 +14,13 @@ void power_cli_off(Cli* cli, string_t args) { power_off(power); } -void power_cli_reboot(Cli* cli, string_t args) { +void power_cli_reboot(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); power_reboot(PowerBootModeNormal); } -void power_cli_reboot2dfu(Cli* cli, string_t args) { +void power_cli_reboot2dfu(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); power_reboot(PowerBootModeDfu); @@ -32,37 +32,37 @@ static void power_cli_info_callback(const char* key, const char* value, bool las printf("%-24s: %s\r\n", key, value); } -void power_cli_info(Cli* cli, string_t args) { +void power_cli_info(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); furi_hal_power_info_get(power_cli_info_callback, NULL); } -void power_cli_debug(Cli* cli, string_t args) { +void power_cli_debug(Cli* cli, FuriString* args) { UNUSED(cli); UNUSED(args); furi_hal_power_dump_state(); } -void power_cli_5v(Cli* cli, string_t args) { +void power_cli_5v(Cli* cli, FuriString* args) { UNUSED(cli); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { furi_hal_power_disable_otg(); - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { furi_hal_power_enable_otg(); } else { - cli_print_usage("power_otg", "<1|0>", string_get_cstr(args)); + cli_print_usage("power_otg", "<1|0>", furi_string_get_cstr(args)); } } -void power_cli_3v3(Cli* cli, string_t args) { +void power_cli_3v3(Cli* cli, FuriString* args) { UNUSED(cli); - if(!string_cmp(args, "0")) { + if(!furi_string_cmp(args, "0")) { furi_hal_power_disable_external_3_3v(); - } else if(!string_cmp(args, "1")) { + } else if(!furi_string_cmp(args, "1")) { furi_hal_power_enable_external_3_3v(); } else { - cli_print_usage("power_ext", "<1|0>", string_get_cstr(args)); + cli_print_usage("power_ext", "<1|0>", furi_string_get_cstr(args)); } } @@ -82,10 +82,10 @@ static void power_cli_command_print_usage() { } } -void power_cli(Cli* cli, string_t args, void* context) { +void power_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_init(cmd); + FuriString* cmd; + cmd = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -93,38 +93,38 @@ void power_cli(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "off") == 0) { + if(furi_string_cmp_str(cmd, "off") == 0) { power_cli_off(cli, args); break; } - if(string_cmp_str(cmd, "reboot") == 0) { + if(furi_string_cmp_str(cmd, "reboot") == 0) { power_cli_reboot(cli, args); break; } - if(string_cmp_str(cmd, "reboot2dfu") == 0) { + if(furi_string_cmp_str(cmd, "reboot2dfu") == 0) { power_cli_reboot2dfu(cli, args); break; } - if(string_cmp_str(cmd, "info") == 0) { + if(furi_string_cmp_str(cmd, "info") == 0) { power_cli_info(cli, args); break; } - if(string_cmp_str(cmd, "debug") == 0) { + if(furi_string_cmp_str(cmd, "debug") == 0) { power_cli_debug(cli, args); break; } - if(string_cmp_str(cmd, "5v") == 0) { + if(furi_string_cmp_str(cmd, "5v") == 0) { power_cli_5v(cli, args); break; } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - if(string_cmp_str(cmd, "3v3") == 0) { + if(furi_string_cmp_str(cmd, "3v3") == 0) { power_cli_3v3(cli, args); break; } @@ -133,7 +133,7 @@ void power_cli(Cli* cli, string_t args, void* context) { power_cli_command_print_usage(); } while(false); - string_clear(cmd); + furi_string_free(cmd); } void power_on_system_start() { diff --git a/applications/services/power/power_service/views/power_off.c b/applications/services/power/power_service/views/power_off.c index 398ebe4ab..b0046325c 100644 --- a/applications/services/power/power_service/views/power_off.c +++ b/applications/services/power/power_service/views/power_off.c @@ -87,19 +87,13 @@ View* power_off_get_view(PowerOff* power_off) { void power_off_set_time_left(PowerOff* power_off, uint8_t time_left) { furi_assert(power_off); with_view_model( - power_off->view, (PowerOffModel * model) { - model->time_left_sec = time_left; - return true; - }); + power_off->view, PowerOffModel * model, { model->time_left_sec = time_left; }, true); } PowerOffResponse power_off_get_response(PowerOff* power_off) { furi_assert(power_off); PowerOffResponse response; with_view_model( - power_off->view, (PowerOffModel * model) { - response = model->response; - return false; - }); + power_off->view, PowerOffModel * model, { response = model->response; }, false); return response; } diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index abba6ea42..06c05173c 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #define TAG "RpcSrv" @@ -62,7 +60,7 @@ struct RpcSession { FuriThread* thread; RpcHandlerDict_t handlers; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; PB_Main* decoded_message; bool terminate; void** system_contexts; @@ -152,7 +150,7 @@ size_t furi_assert(encoded_bytes); furi_assert(size > 0); - size_t bytes_sent = xStreamBufferSend(session->stream, encoded_bytes, size, timeout); + size_t bytes_sent = furi_stream_buffer_send(session->stream, encoded_bytes, size, timeout); furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtNewData); @@ -161,7 +159,7 @@ size_t size_t rpc_session_get_available_size(RpcSession* session) { furi_assert(session); - return xStreamBufferSpacesAvailable(session->stream); + return furi_stream_buffer_spaces_available(session->stream); } bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { @@ -175,9 +173,9 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { size_t bytes_received = 0; while(1) { - bytes_received += - xStreamBufferReceive(session->stream, buf + bytes_received, count - bytes_received, 0); - if(xStreamBufferIsEmpty(session->stream)) { + bytes_received += furi_stream_buffer_receive( + session->stream, buf + bytes_received, count - bytes_received, 0); + if(furi_stream_buffer_is_empty(session->stream)) { if(session->buffer_is_empty_callback) { session->buffer_is_empty_callback(session->context); } @@ -191,7 +189,7 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) { } else { flags = furi_thread_flags_wait(RPC_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever); if(flags & RpcEvtDisconnect) { - if(xStreamBufferIsEmpty(session->stream)) { + if(furi_stream_buffer_is_empty(session->stream)) { session->terminate = true; istream->bytes_left = 0; bytes_received = 0; @@ -280,7 +278,7 @@ static int32_t rpc_session_worker(void* context) { } if(message_decode_failed) { - xStreamBufferReset(session->stream); + furi_stream_buffer_reset(session->stream); if(!session->terminate) { /* Protobuf can't determine start and end of message. * Handle this by adding varint at beginning @@ -330,7 +328,7 @@ static void rpc_session_free_callback(FuriThreadState thread_state, void* contex free(session->system_contexts); free(session->decoded_message); RpcHandlerDict_clear(session->handlers); - vStreamBufferDelete(session->stream); + furi_stream_buffer_free(session->stream); furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever); if(session->terminated_callback) { @@ -349,7 +347,7 @@ RpcSession* rpc_session_open(Rpc* rpc) { RpcSession* session = malloc(sizeof(RpcSession)); session->callbacks_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - session->stream = xStreamBufferCreate(RPC_BUFFER_SIZE, 1); + session->stream = furi_stream_buffer_alloc(RPC_BUFFER_SIZE, 1); session->rpc = rpc; session->terminate = false; session->decode_error = false; diff --git a/applications/services/rpc/rpc_app.c b/applications/services/rpc/rpc_app.c index b8b34170e..301055570 100644 --- a/applications/services/rpc/rpc_app.c +++ b/applications/services/rpc/rpc_app.c @@ -32,7 +32,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); - FURI_LOG_D(TAG, "StartProcess: id %d", request->command_id); + FURI_LOG_D(TAG, "StartProcess: id %ld", request->command_id); PB_CommandStatus result = PB_CommandStatus_ERROR_APP_CANT_START; @@ -63,7 +63,7 @@ static void rpc_system_app_start_process(const PB_Main* request, void* context) furi_record_close(RECORD_LOADER); - FURI_LOG_D(TAG, "StartProcess: response id %d, result %d", request->command_id, result); + FURI_LOG_D(TAG, "StartProcess: response id %ld, result %d", request->command_id, result); rpc_send_and_release_empty(session, request->command_id, result); } @@ -108,7 +108,7 @@ static void rpc_system_app_exit_request(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - FURI_LOG_D(TAG, "ExitRequest: id %d", request->command_id); + FURI_LOG_D(TAG, "ExitRequest: id %ld", request->command_id); furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); rpc_app->last_id = request->command_id; @@ -116,7 +116,7 @@ static void rpc_system_app_exit_request(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ExitRequest: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ExitRequest: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -132,7 +132,7 @@ static void rpc_system_app_load_file(const PB_Main* request, void* context) { PB_CommandStatus status; if(rpc_app->app_callback) { - FURI_LOG_D(TAG, "LoadFile: id %d", request->command_id); + FURI_LOG_D(TAG, "LoadFile: id %ld", request->command_id); furi_assert(!rpc_app->last_id); furi_assert(!rpc_app->last_data); rpc_app->last_id = request->command_id; @@ -141,7 +141,7 @@ static void rpc_system_app_load_file(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "LoadFile: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "LoadFile: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -166,7 +166,7 @@ static void rpc_system_app_button_press(const PB_Main* request, void* context) { } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ButtonPress: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ButtonPress: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -190,7 +190,7 @@ static void rpc_system_app_button_release(const PB_Main* request, void* context) } else { status = PB_CommandStatus_ERROR_APP_NOT_RUNNING; FURI_LOG_E( - TAG, "ButtonRelease: APP_NOT_RUNNING, id %d, status: %d", request->command_id, status); + TAG, "ButtonRelease: APP_NOT_RUNNING, id %ld, status: %d", request->command_id, status); rpc_send_and_release_empty(session, request->command_id, status); } } @@ -243,7 +243,7 @@ void rpc_system_app_confirm(RpcAppSystem* rpc_app, RpcAppSystemEvent event, bool free(rpc_app->last_data); rpc_app->last_data = NULL; } - FURI_LOG_D(TAG, "AppConfirm: event %d last_id %d status %d", event, last_id, status); + FURI_LOG_D(TAG, "AppConfirm: event %d last_id %ld status %d", event, last_id, status); rpc_send_and_release_empty(session, last_id, status); break; default: diff --git a/applications/services/rpc/rpc_cli.c b/applications/services/rpc/rpc_cli.c index 8cb0f76ac..82023e316 100644 --- a/applications/services/rpc/rpc_cli.c +++ b/applications/services/rpc/rpc_cli.c @@ -37,14 +37,14 @@ static void rpc_cli_session_terminated_callback(void* context) { furi_semaphore_release(cli_rpc->terminate_semaphore); } -void rpc_cli_command_start_session(Cli* cli, string_t args, void* context) { +void rpc_cli_command_start_session(Cli* cli, FuriString* args, void* context) { UNUSED(args); furi_assert(cli); furi_assert(context); Rpc* rpc = context; uint32_t mem_before = memmgr_get_free_heap(); - FURI_LOG_D(TAG, "Free memory %d", mem_before); + FURI_LOG_D(TAG, "Free memory %ld", mem_before); furi_hal_usb_lock(); RpcSession* rpc_session = rpc_session_open(rpc); diff --git a/applications/services/rpc/rpc_debug.c b/applications/services/rpc/rpc_debug.c index 9c04bd89a..8eb81dece 100644 --- a/applications/services/rpc/rpc_debug.c +++ b/applications/services/rpc/rpc_debug.c @@ -1,15 +1,14 @@ #include "rpc_i.h" -#include static size_t rpc_debug_print_file_msg( - string_t str, + FuriString* str, const char* prefix, const PB_Storage_File* msg_file, size_t msg_files_size) { size_t cnt = 0; for(size_t i = 0; i < msg_files_size; ++i, ++msg_file) { - string_cat_printf( + furi_string_cat_printf( str, "%s[%c] size: %5ld", prefix, @@ -17,11 +16,11 @@ static size_t rpc_debug_print_file_msg( msg_file->size); if(msg_file->name) { - string_cat_printf(str, " \'%s\'", msg_file->name); + furi_string_cat_printf(str, " \'%s\'", msg_file->name); } if(msg_file->data && msg_file->data->size) { - string_cat_printf( + furi_string_cat_printf( str, " (%d):\'%.*s%s\'", msg_file->data->size, @@ -30,42 +29,42 @@ static size_t rpc_debug_print_file_msg( msg_file->data->size > 30 ? "..." : ""); } - string_cat_printf(str, "\r\n"); + furi_string_cat_printf(str, "\r\n"); } return cnt; } void rpc_debug_print_data(const char* prefix, uint8_t* buffer, size_t size) { - string_t str; - string_init(str); - string_reserve(str, 100 + size * 5); + FuriString* str; + str = furi_string_alloc(); + furi_string_reserve(str, 100 + size * 5); - string_cat_printf(str, "\r\n%s DEC(%d): {", prefix, size); + furi_string_cat_printf(str, "\r\n%s DEC(%d): {", prefix, size); for(size_t i = 0; i < size; ++i) { - string_cat_printf(str, "%d, ", buffer[i]); + furi_string_cat_printf(str, "%d, ", buffer[i]); } - string_cat_printf(str, "}\r\n"); + furi_string_cat_printf(str, "}\r\n"); - printf("%s", string_get_cstr(str)); - string_reset(str); - string_reserve(str, 100 + size * 3); + printf("%s", furi_string_get_cstr(str)); + furi_string_reset(str); + furi_string_reserve(str, 100 + size * 3); - string_cat_printf(str, "%s HEX(%d): {", prefix, size); + furi_string_cat_printf(str, "%s HEX(%d): {", prefix, size); for(size_t i = 0; i < size; ++i) { - string_cat_printf(str, "%02X", buffer[i]); + furi_string_cat_printf(str, "%02X", buffer[i]); } - string_cat_printf(str, "}\r\n\r\n"); + furi_string_cat_printf(str, "}\r\n\r\n"); - printf("%s", string_get_cstr(str)); - string_clear(str); + printf("%s", furi_string_get_cstr(str)); + furi_string_free(str); } void rpc_debug_print_message(const PB_Main* message) { - string_t str; - string_init(str); + FuriString* str; + str = furi_string_alloc(); - string_cat_printf( + furi_string_cat_printf( str, "PB_Main: {\r\n\tresult: %d cmd_id: %ld (%s)\r\n", message->command_status, @@ -74,106 +73,106 @@ void rpc_debug_print_message(const PB_Main* message) { switch(message->which_content) { default: /* not implemented yet */ - string_cat_printf(str, "\tNOT_IMPLEMENTED (%d) {\r\n", message->which_content); + furi_string_cat_printf(str, "\tNOT_IMPLEMENTED (%d) {\r\n", message->which_content); break; case PB_Main_stop_session_tag: - string_cat_printf(str, "\tstop_session {\r\n"); + furi_string_cat_printf(str, "\tstop_session {\r\n"); break; case PB_Main_app_start_request_tag: { - string_cat_printf(str, "\tapp_start {\r\n"); + furi_string_cat_printf(str, "\tapp_start {\r\n"); const char* name = message->content.app_start_request.name; const char* args = message->content.app_start_request.args; if(name) { - string_cat_printf(str, "\t\tname: %s\r\n", name); + furi_string_cat_printf(str, "\t\tname: %s\r\n", name); } if(args) { - string_cat_printf(str, "\t\targs: %s\r\n", args); + furi_string_cat_printf(str, "\t\targs: %s\r\n", args); } break; } case PB_Main_app_lock_status_request_tag: { - string_cat_printf(str, "\tapp_lock_status_request {\r\n"); + furi_string_cat_printf(str, "\tapp_lock_status_request {\r\n"); break; } case PB_Main_app_lock_status_response_tag: { - string_cat_printf(str, "\tapp_lock_status_response {\r\n"); + furi_string_cat_printf(str, "\tapp_lock_status_response {\r\n"); bool lock_status = message->content.app_lock_status_response.locked; - string_cat_printf(str, "\t\tlocked: %s\r\n", lock_status ? "true" : "false"); + furi_string_cat_printf(str, "\t\tlocked: %s\r\n", lock_status ? "true" : "false"); break; } case PB_Main_storage_md5sum_request_tag: { - string_cat_printf(str, "\tmd5sum_request {\r\n"); + furi_string_cat_printf(str, "\tmd5sum_request {\r\n"); const char* path = message->content.storage_md5sum_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_md5sum_response_tag: { - string_cat_printf(str, "\tmd5sum_response {\r\n"); + furi_string_cat_printf(str, "\tmd5sum_response {\r\n"); const char* path = message->content.storage_md5sum_response.md5sum; if(path) { - string_cat_printf(str, "\t\tmd5sum: %s\r\n", path); + furi_string_cat_printf(str, "\t\tmd5sum: %s\r\n", path); } break; } case PB_Main_system_ping_request_tag: - string_cat_printf(str, "\tping_request {\r\n"); + furi_string_cat_printf(str, "\tping_request {\r\n"); break; case PB_Main_system_ping_response_tag: - string_cat_printf(str, "\tping_response {\r\n"); + furi_string_cat_printf(str, "\tping_response {\r\n"); break; case PB_Main_system_device_info_request_tag: - string_cat_printf(str, "\tdevice_info_request {\r\n"); + furi_string_cat_printf(str, "\tdevice_info_request {\r\n"); break; case PB_Main_system_device_info_response_tag: - string_cat_printf(str, "\tdevice_info_response {\r\n"); - string_cat_printf( + furi_string_cat_printf(str, "\tdevice_info_response {\r\n"); + furi_string_cat_printf( str, "\t\t%s: %s\r\n", message->content.system_device_info_response.key, message->content.system_device_info_response.value); break; case PB_Main_storage_mkdir_request_tag: - string_cat_printf(str, "\tmkdir {\r\n"); + furi_string_cat_printf(str, "\tmkdir {\r\n"); break; case PB_Main_storage_delete_request_tag: { - string_cat_printf(str, "\tdelete {\r\n"); + furi_string_cat_printf(str, "\tdelete {\r\n"); const char* path = message->content.storage_delete_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_empty_tag: - string_cat_printf(str, "\tempty {\r\n"); + furi_string_cat_printf(str, "\tempty {\r\n"); break; case PB_Main_storage_info_request_tag: { - string_cat_printf(str, "\tinfo_request {\r\n"); + furi_string_cat_printf(str, "\tinfo_request {\r\n"); const char* path = message->content.storage_info_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_info_response_tag: { - string_cat_printf(str, "\tinfo_response {\r\n"); - string_cat_printf( - str, "\t\ttotal_space: %lu\r\n", message->content.storage_info_response.total_space); - string_cat_printf( - str, "\t\tfree_space: %lu\r\n", message->content.storage_info_response.free_space); + furi_string_cat_printf(str, "\tinfo_response {\r\n"); + furi_string_cat_printf( + str, "\t\ttotal_space: %llu\r\n", message->content.storage_info_response.total_space); + furi_string_cat_printf( + str, "\t\tfree_space: %llu\r\n", message->content.storage_info_response.free_space); break; } case PB_Main_storage_stat_request_tag: { - string_cat_printf(str, "\tstat_request {\r\n"); + furi_string_cat_printf(str, "\tstat_request {\r\n"); const char* path = message->content.storage_stat_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_stat_response_tag: { - string_cat_printf(str, "\tstat_response {\r\n"); + furi_string_cat_printf(str, "\tstat_response {\r\n"); if(message->content.storage_stat_response.has_file) { const PB_Storage_File* msg_file = &message->content.storage_stat_response.file; rpc_debug_print_file_msg(str, "\t\t\t", msg_file, 1); @@ -181,26 +180,26 @@ void rpc_debug_print_message(const PB_Main* message) { break; } case PB_Main_storage_list_request_tag: { - string_cat_printf(str, "\tlist_request {\r\n"); + furi_string_cat_printf(str, "\tlist_request {\r\n"); const char* path = message->content.storage_list_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_read_request_tag: { - string_cat_printf(str, "\tread_request {\r\n"); + furi_string_cat_printf(str, "\tread_request {\r\n"); const char* path = message->content.storage_read_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } break; } case PB_Main_storage_write_request_tag: { - string_cat_printf(str, "\twrite_request {\r\n"); + furi_string_cat_printf(str, "\twrite_request {\r\n"); const char* path = message->content.storage_write_request.path; if(path) { - string_cat_printf(str, "\t\tpath: %s\r\n", path); + furi_string_cat_printf(str, "\t\tpath: %s\r\n", path); } if(message->content.storage_write_request.has_file) { const PB_Storage_File* msg_file = &message->content.storage_write_request.file; @@ -209,7 +208,7 @@ void rpc_debug_print_message(const PB_Main* message) { break; } case PB_Main_storage_read_response_tag: - string_cat_printf(str, "\tread_response {\r\n"); + furi_string_cat_printf(str, "\tread_response {\r\n"); if(message->content.storage_read_response.has_file) { const PB_Storage_File* msg_file = &message->content.storage_read_response.file; rpc_debug_print_file_msg(str, "\t\t\t", msg_file, 1); @@ -218,43 +217,43 @@ void rpc_debug_print_message(const PB_Main* message) { case PB_Main_storage_list_response_tag: { const PB_Storage_File* msg_file = message->content.storage_list_response.file; size_t msg_file_count = message->content.storage_list_response.file_count; - string_cat_printf(str, "\tlist_response {\r\n"); + furi_string_cat_printf(str, "\tlist_response {\r\n"); rpc_debug_print_file_msg(str, "\t\t", msg_file, msg_file_count); break; } case PB_Main_storage_rename_request_tag: { - string_cat_printf(str, "\trename_request {\r\n"); - string_cat_printf( + furi_string_cat_printf(str, "\trename_request {\r\n"); + furi_string_cat_printf( str, "\t\told_path: %s\r\n", message->content.storage_rename_request.old_path); - string_cat_printf( + furi_string_cat_printf( str, "\t\tnew_path: %s\r\n", message->content.storage_rename_request.new_path); break; } case PB_Main_gui_start_screen_stream_request_tag: - string_cat_printf(str, "\tstart_screen_stream {\r\n"); + furi_string_cat_printf(str, "\tstart_screen_stream {\r\n"); break; case PB_Main_gui_stop_screen_stream_request_tag: - string_cat_printf(str, "\tstop_screen_stream {\r\n"); + furi_string_cat_printf(str, "\tstop_screen_stream {\r\n"); break; case PB_Main_gui_screen_frame_tag: - string_cat_printf(str, "\tscreen_frame {\r\n"); + furi_string_cat_printf(str, "\tscreen_frame {\r\n"); break; case PB_Main_gui_send_input_event_request_tag: - string_cat_printf(str, "\tsend_input_event {\r\n"); - string_cat_printf( + furi_string_cat_printf(str, "\tsend_input_event {\r\n"); + furi_string_cat_printf( str, "\t\tkey: %d\r\n", message->content.gui_send_input_event_request.key); - string_cat_printf( + furi_string_cat_printf( str, "\t\type: %d\r\n", message->content.gui_send_input_event_request.type); break; case PB_Main_gui_start_virtual_display_request_tag: - string_cat_printf(str, "\tstart_virtual_display {\r\n"); + furi_string_cat_printf(str, "\tstart_virtual_display {\r\n"); break; case PB_Main_gui_stop_virtual_display_request_tag: - string_cat_printf(str, "\tstop_virtual_display {\r\n"); + furi_string_cat_printf(str, "\tstop_virtual_display {\r\n"); break; } - string_cat_printf(str, "\t}\r\n}\r\n"); - printf("%s", string_get_cstr(str)); + furi_string_cat_printf(str, "\t}\r\n}\r\n"); + printf("%s", furi_string_get_cstr(str)); - string_clear(str); + furi_string_free(str); } diff --git a/applications/services/rpc/rpc_i.h b/applications/services/rpc/rpc_i.h index 9ffd054a0..af9033f0a 100644 --- a/applications/services/rpc/rpc_i.h +++ b/applications/services/rpc/rpc_i.h @@ -38,6 +38,6 @@ void rpc_system_gpio_free(void* ctx); void rpc_debug_print_message(const PB_Main* message); void rpc_debug_print_data(const char* prefix, uint8_t* buffer, size_t size); -void rpc_cli_command_start_session(Cli* cli, string_t args, void* context); +void rpc_cli_command_start_session(Cli* cli, FuriString* args, void* context); PB_CommandStatus rpc_system_storage_get_error(FS_Error fs_error); diff --git a/applications/services/storage/storage.h b/applications/services/storage/storage.h index 1a7c93495..968b69048 100644 --- a/applications/services/storage/storage.h +++ b/applications/services/storage/storage.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include "filesystem_api_defines.h" #include "storage_sd_api.h" @@ -292,7 +291,7 @@ FS_Error storage_sd_status(Storage* api); /******************* Internal LFS Functions *******************/ -typedef void (*Storage_name_converter)(string_t); +typedef void (*Storage_name_converter)(FuriString*); /** Backs up internal storage to a tar archive * @param api pointer to the api @@ -350,7 +349,7 @@ void storage_get_next_filename( const char* dirname, const char* filename, const char* fileextension, - string_t nextfilename, + FuriString* nextfilename, uint8_t max_len); #ifdef __cplusplus diff --git a/applications/services/storage/storage_cli.c b/applications/services/storage/storage_cli.c index 802ebd548..880fb9700 100644 --- a/applications/services/storage/storage_cli.c +++ b/applications/services/storage/storage_cli.c @@ -38,11 +38,11 @@ static void storage_cli_print_error(FS_Error error) { printf("Storage error: %s\r\n", storage_error_get_desc(error)); } -static void storage_cli_info(Cli* cli, string_t path) { +static void storage_cli_info(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - if(string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { + if(furi_string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { uint64_t total_space; uint64_t free_space; FS_Error error = @@ -52,12 +52,12 @@ static void storage_cli_info(Cli* cli, string_t path) { storage_cli_print_error(error); } else { printf( - "Label: %s\r\nType: LittleFS\r\n%luKB total\r\n%luKB free\r\n", + "Label: %s\r\nType: LittleFS\r\n%luKiB total\r\n%luKiB free\r\n", furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); } - } else if(string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { + } else if(furi_string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { SDInfo sd_info; FS_Error error = storage_sd_info(api, &sd_info); @@ -65,7 +65,7 @@ static void storage_cli_info(Cli* cli, string_t path) { storage_cli_print_error(error); } else { printf( - "Label: %s\r\nType: %s\r\n%luKB total\r\n%luKB free\r\n", + "Label: %s\r\nType: %s\r\n%luKiB total\r\n%luKiB free\r\n", sd_info.label, sd_api_get_fs_type_text(sd_info.fs_type), sd_info.kb_total, @@ -78,10 +78,10 @@ static void storage_cli_info(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); }; -static void storage_cli_format(Cli* cli, string_t path) { - if(string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { +static void storage_cli_format(Cli* cli, FuriString* path) { + if(furi_string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0) { storage_cli_print_error(FSE_NOT_IMPLEMENTED); - } else if(string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { + } else if(furi_string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0) { printf("Formatting SD card, All data will be lost! Are you sure (y/n)?\r\n"); char answer = cli_getc(cli); if(answer == 'y' || answer == 'Y') { @@ -104,9 +104,9 @@ static void storage_cli_format(Cli* cli, string_t path) { } }; -static void storage_cli_list(Cli* cli, string_t path) { +static void storage_cli_list(Cli* cli, FuriString* path) { UNUSED(cli); - if(string_cmp_str(path, "/") == 0) { + if(furi_string_cmp_str(path, "/") == 0) { printf("\t[D] int\r\n"); printf("\t[D] ext\r\n"); printf("\t[D] any\r\n"); @@ -114,7 +114,7 @@ static void storage_cli_list(Cli* cli, string_t path) { Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); - if(storage_dir_open(file, string_get_cstr(path))) { + if(storage_dir_open(file, furi_string_get_cstr(path))) { FileInfo fileinfo; char name[MAX_NAME_LENGTH]; bool read_done = false; @@ -141,28 +141,31 @@ static void storage_cli_list(Cli* cli, string_t path) { } } -static void storage_cli_tree(Cli* cli, string_t path) { - if(string_cmp_str(path, "/") == 0) { - string_set(path, STORAGE_INT_PATH_PREFIX); +static void storage_cli_tree(Cli* cli, FuriString* path) { + if(furi_string_cmp_str(path, "/") == 0) { + furi_string_set(path, STORAGE_INT_PATH_PREFIX); storage_cli_tree(cli, path); - string_set(path, STORAGE_EXT_PATH_PREFIX); + furi_string_set(path, STORAGE_EXT_PATH_PREFIX); storage_cli_tree(cli, path); } else { Storage* api = furi_record_open(RECORD_STORAGE); DirWalk* dir_walk = dir_walk_alloc(api); - string_t name; - string_init(name); + FuriString* name; + name = furi_string_alloc(); - if(dir_walk_open(dir_walk, string_get_cstr(path))) { + if(dir_walk_open(dir_walk, furi_string_get_cstr(path))) { FileInfo fileinfo; bool read_done = false; while(dir_walk_read(dir_walk, name, &fileinfo) == DirWalkOK) { read_done = true; if(fileinfo.flags & FSF_DIRECTORY) { - printf("\t[D] %s\r\n", string_get_cstr(name)); + printf("\t[D] %s\r\n", furi_string_get_cstr(name)); } else { - printf("\t[F] %s %lub\r\n", string_get_cstr(name), (uint32_t)(fileinfo.size)); + printf( + "\t[F] %s %lub\r\n", + furi_string_get_cstr(name), + (uint32_t)(fileinfo.size)); } } @@ -173,18 +176,18 @@ static void storage_cli_tree(Cli* cli, string_t path) { storage_cli_print_error(dir_walk_get_error(dir_walk)); } - string_clear(name); + furi_string_free(name); dir_walk_free(dir_walk); furi_record_close(RECORD_STORAGE); } } -static void storage_cli_read(Cli* cli, string_t path) { +static void storage_cli_read(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); - if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { const uint16_t buffer_size = 128; uint16_t read_size = 0; uint8_t* data = malloc(buffer_size); @@ -210,14 +213,14 @@ static void storage_cli_read(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_write(Cli* cli, string_t path) { +static void storage_cli_write(Cli* cli, FuriString* path) { Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); const uint16_t buffer_size = 512; uint8_t* buffer = malloc(buffer_size); - if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { printf("Just write your text data. New line by Ctrl+Enter, exit by Ctrl+C.\r\n"); uint32_t read_index = 0; @@ -264,16 +267,16 @@ static void storage_cli_write(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) { +static void storage_cli_read_chunks(Cli* cli, FuriString* path, FuriString* args) { Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); uint32_t buffer_size; - int parsed_count = sscanf(string_get_cstr(args), "%lu", &buffer_size); + int parsed_count = sscanf(furi_string_get_cstr(args), "%lu", &buffer_size); if(parsed_count == EOF || parsed_count != 1) { storage_cli_print_usage(); - } else if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + } else if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { uint64_t file_size = storage_file_size(file); printf("Size: %lu\r\n", (uint32_t)file_size); @@ -304,17 +307,17 @@ static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) { +static void storage_cli_write_chunk(Cli* cli, FuriString* path, FuriString* args) { Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); uint32_t buffer_size; - int parsed_count = sscanf(string_get_cstr(args), "%lu", &buffer_size); + int parsed_count = sscanf(furi_string_get_cstr(args), "%lu", &buffer_size); if(parsed_count == EOF || parsed_count != 1) { storage_cli_print_usage(); } else { - if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) { printf("Ready\r\n"); if(buffer_size) { @@ -342,32 +345,32 @@ static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_stat(Cli* cli, string_t path) { +static void storage_cli_stat(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - if(string_cmp_str(path, "/") == 0) { + if(furi_string_cmp_str(path, "/") == 0) { printf("Storage\r\n"); } else if( - string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0 || - string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0 || - string_cmp_str(path, STORAGE_ANY_PATH_PREFIX) == 0) { + furi_string_cmp_str(path, STORAGE_EXT_PATH_PREFIX) == 0 || + furi_string_cmp_str(path, STORAGE_INT_PATH_PREFIX) == 0 || + furi_string_cmp_str(path, STORAGE_ANY_PATH_PREFIX) == 0) { uint64_t total_space; uint64_t free_space; FS_Error error = - storage_common_fs_info(api, string_get_cstr(path), &total_space, &free_space); + storage_common_fs_info(api, furi_string_get_cstr(path), &total_space, &free_space); if(error != FSE_OK) { storage_cli_print_error(error); } else { printf( - "Storage, %luKB total, %luKB free\r\n", + "Storage, %luKiB total, %luKiB free\r\n", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); } } else { FileInfo fileinfo; - FS_Error error = storage_common_stat(api, string_get_cstr(path), &fileinfo); + FS_Error error = storage_common_stat(api, furi_string_get_cstr(path), &fileinfo); if(error == FSE_OK) { if(fileinfo.flags & FSF_DIRECTORY) { @@ -383,31 +386,31 @@ static void storage_cli_stat(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_copy(Cli* cli, string_t old_path, string_t args) { +static void storage_cli_copy(Cli* cli, FuriString* old_path, FuriString* args) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - string_t new_path; - string_init(new_path); + FuriString* new_path; + new_path = furi_string_alloc(); if(!args_read_probably_quoted_string_and_trim(args, new_path)) { storage_cli_print_usage(); } else { - FS_Error error = - storage_common_copy(api, string_get_cstr(old_path), string_get_cstr(new_path)); + FS_Error error = storage_common_copy( + api, furi_string_get_cstr(old_path), furi_string_get_cstr(new_path)); if(error != FSE_OK) { storage_cli_print_error(error); } } - string_clear(new_path); + furi_string_free(new_path); furi_record_close(RECORD_STORAGE); } -static void storage_cli_remove(Cli* cli, string_t path) { +static void storage_cli_remove(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - FS_Error error = storage_common_remove(api, string_get_cstr(path)); + FS_Error error = storage_common_remove(api, furi_string_get_cstr(path)); if(error != FSE_OK) { storage_cli_print_error(error); @@ -416,31 +419,31 @@ static void storage_cli_remove(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_rename(Cli* cli, string_t old_path, string_t args) { +static void storage_cli_rename(Cli* cli, FuriString* old_path, FuriString* args) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - string_t new_path; - string_init(new_path); + FuriString* new_path; + new_path = furi_string_alloc(); if(!args_read_probably_quoted_string_and_trim(args, new_path)) { storage_cli_print_usage(); } else { - FS_Error error = - storage_common_rename(api, string_get_cstr(old_path), string_get_cstr(new_path)); + FS_Error error = storage_common_rename( + api, furi_string_get_cstr(old_path), furi_string_get_cstr(new_path)); if(error != FSE_OK) { storage_cli_print_error(error); } } - string_clear(new_path); + furi_string_free(new_path); furi_record_close(RECORD_STORAGE); } -static void storage_cli_mkdir(Cli* cli, string_t path) { +static void storage_cli_mkdir(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); - FS_Error error = storage_common_mkdir(api, string_get_cstr(path)); + FS_Error error = storage_common_mkdir(api, furi_string_get_cstr(path)); if(error != FSE_OK) { storage_cli_print_error(error); @@ -449,12 +452,12 @@ static void storage_cli_mkdir(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -static void storage_cli_md5(Cli* cli, string_t path) { +static void storage_cli_md5(Cli* cli, FuriString* path) { UNUSED(cli); Storage* api = furi_record_open(RECORD_STORAGE); File* file = storage_file_alloc(api); - if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { const uint16_t buffer_size = 512; const uint8_t hash_size = 16; uint8_t* data = malloc(buffer_size); @@ -487,12 +490,12 @@ static void storage_cli_md5(Cli* cli, string_t path) { furi_record_close(RECORD_STORAGE); } -void storage_cli(Cli* cli, string_t args, void* context) { +void storage_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); - string_t cmd; - string_t path; - string_init(cmd); - string_init(path); + FuriString* cmd; + FuriString* path; + cmd = furi_string_alloc(); + path = furi_string_alloc(); do { if(!args_read_string_and_trim(args, cmd)) { @@ -505,72 +508,72 @@ void storage_cli(Cli* cli, string_t args, void* context) { break; } - if(string_cmp_str(cmd, "info") == 0) { + if(furi_string_cmp_str(cmd, "info") == 0) { storage_cli_info(cli, path); break; } - if(string_cmp_str(cmd, "format") == 0) { + if(furi_string_cmp_str(cmd, "format") == 0) { storage_cli_format(cli, path); break; } - if(string_cmp_str(cmd, "list") == 0) { + if(furi_string_cmp_str(cmd, "list") == 0) { storage_cli_list(cli, path); break; } - if(string_cmp_str(cmd, "tree") == 0) { + if(furi_string_cmp_str(cmd, "tree") == 0) { storage_cli_tree(cli, path); break; } - if(string_cmp_str(cmd, "read") == 0) { + if(furi_string_cmp_str(cmd, "read") == 0) { storage_cli_read(cli, path); break; } - if(string_cmp_str(cmd, "read_chunks") == 0) { + if(furi_string_cmp_str(cmd, "read_chunks") == 0) { storage_cli_read_chunks(cli, path, args); break; } - if(string_cmp_str(cmd, "write") == 0) { + if(furi_string_cmp_str(cmd, "write") == 0) { storage_cli_write(cli, path); break; } - if(string_cmp_str(cmd, "write_chunk") == 0) { + if(furi_string_cmp_str(cmd, "write_chunk") == 0) { storage_cli_write_chunk(cli, path, args); break; } - if(string_cmp_str(cmd, "copy") == 0) { + if(furi_string_cmp_str(cmd, "copy") == 0) { storage_cli_copy(cli, path, args); break; } - if(string_cmp_str(cmd, "remove") == 0) { + if(furi_string_cmp_str(cmd, "remove") == 0) { storage_cli_remove(cli, path); break; } - if(string_cmp_str(cmd, "rename") == 0) { + if(furi_string_cmp_str(cmd, "rename") == 0) { storage_cli_rename(cli, path, args); break; } - if(string_cmp_str(cmd, "mkdir") == 0) { + if(furi_string_cmp_str(cmd, "mkdir") == 0) { storage_cli_mkdir(cli, path); break; } - if(string_cmp_str(cmd, "md5") == 0) { + if(furi_string_cmp_str(cmd, "md5") == 0) { storage_cli_md5(cli, path); break; } - if(string_cmp_str(cmd, "stat") == 0) { + if(furi_string_cmp_str(cmd, "stat") == 0) { storage_cli_stat(cli, path); break; } @@ -578,11 +581,11 @@ void storage_cli(Cli* cli, string_t args, void* context) { storage_cli_print_usage(); } while(false); - string_clear(path); - string_clear(cmd); + furi_string_free(path); + furi_string_free(cmd); } -static void storage_cli_factory_reset(Cli* cli, string_t args, void* context) { +static void storage_cli_factory_reset(Cli* cli, FuriString* args, void* context) { UNUSED(args); UNUSED(context); printf("All data will be lost! Are you sure (y/n)?\r\n"); diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index 80cafb282..c0c730fb7 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -1,6 +1,5 @@ #include #include -#include #include "storage.h" #include "storage_i.h" #include "storage_message.h" @@ -120,7 +119,11 @@ bool storage_file_open( furi_event_flag_free(event); FURI_LOG_T( - TAG, "File %p - %p open (%s)", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE, path); + TAG, + "File %p - %p open (%s)", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE), + path); return result; } @@ -133,7 +136,11 @@ bool storage_file_close(File* file) { S_API_MESSAGE(StorageCommandFileClose); S_API_EPILOGUE; - FURI_LOG_T(TAG, "File %p - %p closed", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE); + FURI_LOG_T( + TAG, + "File %p - %p closed", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE)); file->type = FileTypeClosed; return S_RETURN_BOOL; @@ -292,7 +299,11 @@ bool storage_dir_open(File* file, const char* path) { furi_event_flag_free(event); FURI_LOG_T( - TAG, "Dir %p - %p open (%s)", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE, path); + TAG, + "Dir %p - %p open (%s)", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE), + path); return result; } @@ -304,7 +315,11 @@ bool storage_dir_close(File* file) { S_API_MESSAGE(StorageCommandDirClose); S_API_EPILOGUE; - FURI_LOG_T(TAG, "Dir %p - %p closed", (uint32_t)file - SRAM_BASE, file->file_id - SRAM_BASE); + FURI_LOG_T( + TAG, + "Dir %p - %p closed", + (void*)((uint32_t)file - SRAM_BASE), + (void*)(file->file_id - SRAM_BASE)); file->type = FileTypeClosed; @@ -374,13 +389,13 @@ static FS_Error storage_copy_recursive(Storage* storage, const char* old_path, const char* new_path) { FS_Error error = storage_common_mkdir(storage, new_path); DirWalk* dir_walk = dir_walk_alloc(storage); - string_t path; - string_t tmp_new_path; - string_t tmp_old_path; + FuriString* path; + FuriString* tmp_new_path; + FuriString* tmp_old_path; FileInfo fileinfo; - string_init(path); - string_init(tmp_new_path); - string_init(tmp_old_path); + path = furi_string_alloc(); + tmp_new_path = furi_string_alloc(); + tmp_old_path = furi_string_alloc(); do { if(error != FSE_OK) break; @@ -399,15 +414,17 @@ static FS_Error } else if(res == DirWalkLast) { break; } else { - string_set(tmp_old_path, path); - string_right(path, strlen(old_path)); - string_printf(tmp_new_path, "%s%s", new_path, string_get_cstr(path)); + furi_string_set(tmp_old_path, path); + furi_string_right(path, strlen(old_path)); + furi_string_printf(tmp_new_path, "%s%s", new_path, furi_string_get_cstr(path)); if(fileinfo.flags & FSF_DIRECTORY) { - error = storage_common_mkdir(storage, string_get_cstr(tmp_new_path)); + error = storage_common_mkdir(storage, furi_string_get_cstr(tmp_new_path)); } else { error = storage_common_copy( - storage, string_get_cstr(tmp_old_path), string_get_cstr(tmp_new_path)); + storage, + furi_string_get_cstr(tmp_old_path), + furi_string_get_cstr(tmp_new_path)); } if(error != FSE_OK) break; @@ -416,9 +433,9 @@ static FS_Error } while(false); - string_clear(tmp_new_path); - string_clear(tmp_old_path); - string_clear(path); + furi_string_free(tmp_new_path); + furi_string_free(tmp_old_path); + furi_string_free(path); dir_walk_free(dir_walk); return error; } @@ -459,11 +476,11 @@ static FS_Error storage_merge_recursive(Storage* storage, const char* old_path, const char* new_path) { FS_Error error = storage_common_mkdir(storage, new_path); DirWalk* dir_walk = dir_walk_alloc(storage); - string_t path, file_basename, tmp_new_path; + FuriString *path, *file_basename, *tmp_new_path; FileInfo fileinfo; - string_init(path); - string_init(file_basename); - string_init(tmp_new_path); + path = furi_string_alloc(); + file_basename = furi_string_alloc(); + tmp_new_path = furi_string_alloc(); do { if((error != FSE_OK) && (error != FSE_EXIST)) break; @@ -483,14 +500,15 @@ static FS_Error } else if(res == DirWalkLast) { break; } else { - path_extract_basename(string_get_cstr(path), file_basename); - path_concat(new_path, string_get_cstr(file_basename), tmp_new_path); + path_extract_basename(furi_string_get_cstr(path), file_basename); + path_concat(new_path, furi_string_get_cstr(file_basename), tmp_new_path); if(fileinfo.flags & FSF_DIRECTORY) { - if(storage_common_stat(storage, string_get_cstr(tmp_new_path), &fileinfo) == - FSE_OK) { + if(storage_common_stat( + storage, furi_string_get_cstr(tmp_new_path), &fileinfo) == FSE_OK) { if(fileinfo.flags & FSF_DIRECTORY) { - error = storage_common_mkdir(storage, string_get_cstr(tmp_new_path)); + error = + storage_common_mkdir(storage, furi_string_get_cstr(tmp_new_path)); if(error != FSE_OK) { break; } @@ -498,7 +516,7 @@ static FS_Error } } error = storage_common_merge( - storage, string_get_cstr(path), string_get_cstr(tmp_new_path)); + storage, furi_string_get_cstr(path), furi_string_get_cstr(tmp_new_path)); if(error != FSE_OK) { break; @@ -508,9 +526,9 @@ static FS_Error } while(false); - string_clear(tmp_new_path); - string_clear(file_basename); - string_clear(path); + furi_string_free(tmp_new_path); + furi_string_free(file_basename); + furi_string_free(path); dir_walk_free(dir_walk); return error; } @@ -518,8 +536,8 @@ static FS_Error FS_Error storage_common_merge(Storage* storage, const char* old_path, const char* new_path) { FS_Error error; const char* new_path_tmp; - string_t new_path_next; - string_init(new_path_next); + FuriString* new_path_next; + new_path_next = furi_string_alloc(); FileInfo fileinfo; error = storage_common_stat(storage, old_path, &fileinfo); @@ -530,13 +548,13 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char } else { error = storage_common_stat(storage, new_path, &fileinfo); if(error == FSE_OK) { - string_set_str(new_path_next, new_path); - string_t dir_path; - string_t filename; + furi_string_set(new_path_next, new_path); + FuriString* dir_path; + FuriString* filename; char extension[MAX_EXT_LEN]; - string_init(dir_path); - string_init(filename); + dir_path = furi_string_alloc(); + filename = furi_string_alloc(); path_extract_filename(new_path_next, filename, true); path_extract_dirname(new_path, dir_path); @@ -544,17 +562,18 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char storage_get_next_filename( storage, - string_get_cstr(dir_path), - string_get_cstr(filename), + furi_string_get_cstr(dir_path), + furi_string_get_cstr(filename), extension, new_path_next, 255); - string_cat_printf(dir_path, "/%s%s", string_get_cstr(new_path_next), extension); - string_set(new_path_next, dir_path); + furi_string_cat_printf( + dir_path, "/%s%s", furi_string_get_cstr(new_path_next), extension); + furi_string_set(new_path_next, dir_path); - string_clear(dir_path); - string_clear(filename); - new_path_tmp = string_get_cstr(new_path_next); + furi_string_free(dir_path); + furi_string_free(filename); + new_path_tmp = furi_string_get_cstr(new_path_next); } else { new_path_tmp = new_path; } @@ -577,7 +596,7 @@ FS_Error storage_common_merge(Storage* storage, const char* old_path, const char } } - string_clear(new_path_next); + furi_string_free(new_path_next); return error; } @@ -672,7 +691,7 @@ File* storage_file_alloc(Storage* storage) { file->type = FileTypeClosed; file->storage = storage; - FURI_LOG_T(TAG, "File/Dir %p alloc", (uint32_t)file - SRAM_BASE); + FURI_LOG_T(TAG, "File/Dir %p alloc", (void*)((uint32_t)file - SRAM_BASE)); return file; } @@ -694,7 +713,7 @@ void storage_file_free(File* file) { } } - FURI_LOG_T(TAG, "File/Dir %p free", (uint32_t)file - SRAM_BASE); + FURI_LOG_T(TAG, "File/Dir %p free", (void*)((uint32_t)file - SRAM_BASE)); free(file); } @@ -707,8 +726,8 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { furi_assert(path); FileInfo fileinfo; bool result = false; - string_t fullname; - string_t cur_dir; + FuriString* fullname; + FuriString* cur_dir; if(storage_simply_remove(storage, path)) { return true; @@ -716,26 +735,26 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { char* name = malloc(MAX_NAME_LENGTH + 1); File* dir = storage_file_alloc(storage); - string_init_set_str(cur_dir, path); + cur_dir = furi_string_alloc_set(path); bool go_deeper = false; while(1) { - if(!storage_dir_open(dir, string_get_cstr(cur_dir))) { + if(!storage_dir_open(dir, furi_string_get_cstr(cur_dir))) { storage_dir_close(dir); break; } while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) { if(fileinfo.flags & FSF_DIRECTORY) { - string_cat_printf(cur_dir, "/%s", name); + furi_string_cat_printf(cur_dir, "/%s", name); go_deeper = true; break; } - string_init_printf(fullname, "%s/%s", string_get_cstr(cur_dir), name); - FS_Error error = storage_common_remove(storage, string_get_cstr(fullname)); + fullname = furi_string_alloc_printf("%s/%s", furi_string_get_cstr(cur_dir), name); + FS_Error error = storage_common_remove(storage, furi_string_get_cstr(fullname)); furi_check(error == FSE_OK); - string_clear(fullname); + furi_string_free(fullname); } storage_dir_close(dir); @@ -744,13 +763,13 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { continue; } - FS_Error error = storage_common_remove(storage, string_get_cstr(cur_dir)); + FS_Error error = storage_common_remove(storage, furi_string_get_cstr(cur_dir)); furi_check(error == FSE_OK); - if(string_cmp(cur_dir, path)) { - size_t last_char = string_search_rchar(cur_dir, '/'); - furi_assert(last_char != STRING_FAILURE); - string_left(cur_dir, last_char); + if(furi_string_cmp(cur_dir, path)) { + size_t last_char = furi_string_search_rchar(cur_dir, '/'); + furi_assert(last_char != FURI_STRING_FAILURE); + furi_string_left(cur_dir, last_char); } else { result = true; break; @@ -758,7 +777,7 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { } storage_file_free(dir); - string_clear(cur_dir); + furi_string_free(cur_dir); free(name); return result; } @@ -780,22 +799,22 @@ void storage_get_next_filename( const char* dirname, const char* filename, const char* fileextension, - string_t nextfilename, + FuriString* nextfilename, uint8_t max_len) { - string_t temp_str; + FuriString* temp_str; uint16_t num = 0; - string_init_printf(temp_str, "%s/%s%s", dirname, filename, fileextension); + temp_str = furi_string_alloc_printf("%s/%s%s", dirname, filename, fileextension); - while(storage_common_stat(storage, string_get_cstr(temp_str), NULL) == FSE_OK) { + while(storage_common_stat(storage, furi_string_get_cstr(temp_str), NULL) == FSE_OK) { num++; - string_printf(temp_str, "%s/%s%d%s", dirname, filename, num, fileextension); + furi_string_printf(temp_str, "%s/%s%d%s", dirname, filename, num, fileextension); } if(num && (max_len > strlen(filename))) { - string_printf(nextfilename, "%s%d", filename, num); + furi_string_printf(nextfilename, "%s%d", filename, num); } else { - string_printf(nextfilename, "%s", filename); + furi_string_printf(nextfilename, "%s", filename); } - string_clear(temp_str); + furi_string_free(temp_str); } diff --git a/applications/services/storage/storage_glue.c b/applications/services/storage/storage_glue.c index d9d599c5c..c5682f67b 100644 --- a/applications/services/storage/storage_glue.c +++ b/applications/services/storage/storage_glue.c @@ -7,25 +7,25 @@ void storage_file_init(StorageFile* obj) { obj->file = NULL; obj->type = ST_ERROR; obj->file_data = NULL; - string_init(obj->path); + obj->path = furi_string_alloc(); } void storage_file_init_set(StorageFile* obj, const StorageFile* src) { obj->file = src->file; obj->type = src->type; obj->file_data = src->file_data; - string_init_set(obj->path, src->path); + obj->path = furi_string_alloc_set(src->path); } void storage_file_set(StorageFile* obj, const StorageFile* src) { obj->file = src->file; obj->type = src->type; obj->file_data = src->file_data; - string_set(obj->path, src->path); + furi_string_set(obj->path, src->path); } void storage_file_clear(StorageFile* obj) { - string_clear(obj->path); + furi_string_free(obj->path); } /****************** storage data ******************/ @@ -101,7 +101,7 @@ bool storage_has_file(const File* file, StorageData* storage_data) { return result; } -bool storage_path_already_open(string_t path, StorageFileList_t array) { +bool storage_path_already_open(FuriString* path, StorageFileList_t array) { bool open = false; StorageFileList_it_t it; @@ -109,7 +109,7 @@ bool storage_path_already_open(string_t path, StorageFileList_t array) { for(StorageFileList_it(it, array); !StorageFileList_end_p(it); StorageFileList_next(it)) { const StorageFile* storage_file = StorageFileList_cref(it); - if(string_cmp(storage_file->path, path) == 0) { + if(furi_string_cmp(storage_file->path, path) == 0) { open = true; break; } @@ -158,14 +158,18 @@ void* storage_get_storage_file_data(const File* file, StorageData* storage) { return founded_file->file_data; } -void storage_push_storage_file(File* file, string_t path, StorageType type, StorageData* storage) { +void storage_push_storage_file( + File* file, + FuriString* path, + StorageType type, + StorageData* storage) { StorageFile* storage_file = StorageFileList_push_new(storage->files); furi_check(storage_file != NULL); file->file_id = (uint32_t)storage_file; storage_file->file = file; storage_file->type = type; - string_set(storage_file->path, path); + furi_string_set(storage_file->path, path); } bool storage_pop_storage_file(File* file, StorageData* storage) { diff --git a/applications/services/storage/storage_glue.h b/applications/services/storage/storage_glue.h index 7cf2e072a..53fa0de19 100644 --- a/applications/services/storage/storage_glue.h +++ b/applications/services/storage/storage_glue.h @@ -2,7 +2,6 @@ #include #include "filesystem_api_internal.h" -#include #include #ifdef __cplusplus @@ -21,7 +20,7 @@ typedef struct { File* file; StorageType type; void* file_data; - string_t path; + FuriString* path; } StorageFile; typedef enum { @@ -62,12 +61,16 @@ struct StorageData { }; bool storage_has_file(const File* file, StorageData* storage_data); -bool storage_path_already_open(string_t path, StorageFileList_t files); +bool storage_path_already_open(FuriString* path, StorageFileList_t files); void storage_set_storage_file_data(const File* file, void* file_data, StorageData* storage); void* storage_get_storage_file_data(const File* file, StorageData* storage); -void storage_push_storage_file(File* file, string_t path, StorageType type, StorageData* storage); +void storage_push_storage_file( + File* file, + FuriString* path, + StorageType type, + StorageData* storage); bool storage_pop_storage_file(File* file, StorageData* storage); #ifdef __cplusplus diff --git a/applications/services/storage/storage_internal_api.c b/applications/services/storage/storage_internal_api.c index 620eae367..6d620b9c0 100644 --- a/applications/services/storage/storage_internal_api.c +++ b/applications/services/storage/storage_internal_api.c @@ -1,5 +1,4 @@ #include -#include #include "storage.h" #include diff --git a/applications/services/storage/storage_processing.c b/applications/services/storage/storage_processing.c index 46ca4e165..8643e974e 100644 --- a/applications/services/storage/storage_processing.c +++ b/applications/services/storage/storage_processing.c @@ -1,7 +1,6 @@ #include "storage_processing.h" #include #include -#include #define FS_CALL(_storage, _fn) \ storage_data_lock(_storage); \ @@ -68,21 +67,22 @@ static StorageType storage_get_type_by_path(Storage* app, const char* path) { return type; } -static void storage_path_change_to_real_storage(string_t path, StorageType real_storage) { - if(memcmp(string_get_cstr(path), STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) == +static void storage_path_change_to_real_storage(FuriString* path, StorageType real_storage) { + if(memcmp( + furi_string_get_cstr(path), STORAGE_ANY_PATH_PREFIX, strlen(STORAGE_ANY_PATH_PREFIX)) == 0) { switch(real_storage) { case ST_EXT: - string_set_char(path, 0, STORAGE_EXT_PATH_PREFIX[0]); - string_set_char(path, 1, STORAGE_EXT_PATH_PREFIX[1]); - string_set_char(path, 2, STORAGE_EXT_PATH_PREFIX[2]); - string_set_char(path, 3, STORAGE_EXT_PATH_PREFIX[3]); + furi_string_set_char(path, 0, STORAGE_EXT_PATH_PREFIX[0]); + furi_string_set_char(path, 1, STORAGE_EXT_PATH_PREFIX[1]); + furi_string_set_char(path, 2, STORAGE_EXT_PATH_PREFIX[2]); + furi_string_set_char(path, 3, STORAGE_EXT_PATH_PREFIX[3]); break; case ST_INT: - string_set_char(path, 0, STORAGE_INT_PATH_PREFIX[0]); - string_set_char(path, 1, STORAGE_INT_PATH_PREFIX[1]); - string_set_char(path, 2, STORAGE_INT_PATH_PREFIX[2]); - string_set_char(path, 3, STORAGE_INT_PATH_PREFIX[3]); + furi_string_set_char(path, 0, STORAGE_INT_PATH_PREFIX[0]); + furi_string_set_char(path, 1, STORAGE_INT_PATH_PREFIX[1]); + furi_string_set_char(path, 2, STORAGE_INT_PATH_PREFIX[2]); + furi_string_set_char(path, 3, STORAGE_INT_PATH_PREFIX[3]); break; default: break; @@ -107,8 +107,8 @@ bool storage_process_file_open( file->error_id = FSE_INVALID_NAME; } else { storage = storage_get_storage_by_type(app, type); - string_t real_path; - string_init_set(real_path, path); + FuriString* real_path; + real_path = furi_string_alloc_set(path); storage_path_change_to_real_storage(real_path, type); if(storage_path_already_open(real_path, storage->files)) { @@ -118,7 +118,7 @@ bool storage_process_file_open( FS_CALL(storage, file.open(storage, file, remove_vfs(path), access_mode, open_mode)); } - string_clear(real_path); + furi_string_free(real_path); } return ret; @@ -266,8 +266,8 @@ bool storage_process_dir_open(Storage* app, File* file, const char* path) { file->error_id = FSE_INVALID_NAME; } else { storage = storage_get_storage_by_type(app, type); - string_t real_path; - string_init_set(real_path, path); + FuriString* real_path; + real_path = furi_string_alloc_set(path); storage_path_change_to_real_storage(real_path, type); if(storage_path_already_open(real_path, storage->files)) { @@ -276,7 +276,7 @@ bool storage_process_dir_open(Storage* app, File* file, const char* path) { storage_push_storage_file(file, real_path, type, storage); FS_CALL(storage, dir.open(storage, file, remove_vfs(path))); } - string_clear(real_path); + furi_string_free(real_path); } return ret; @@ -350,8 +350,8 @@ static FS_Error storage_process_common_remove(Storage* app, const char* path) { FS_Error ret = FSE_OK; StorageType type = storage_get_type_by_path(app, path); - string_t real_path; - string_init_set(real_path, path); + FuriString* real_path; + real_path = furi_string_alloc_set(path); storage_path_change_to_real_storage(real_path, type); do { @@ -369,7 +369,7 @@ static FS_Error storage_process_common_remove(Storage* app, const char* path) { FS_CALL(storage, common.remove(storage, remove_vfs(path))); } while(false); - string_clear(real_path); + furi_string_free(real_path); return ret; } diff --git a/applications/services/storage/storage_test_app.c b/applications/services/storage/storage_test_app.c index 8bfa9826c..852953e99 100644 --- a/applications/services/storage/storage_test_app.c +++ b/applications/services/storage/storage_test_app.c @@ -224,13 +224,12 @@ static void do_dir_test(Storage* api, const char* path) { } static void do_test_start(Storage* api, const char* path) { - string_t str_path; - string_init_printf(str_path, "%s/test-folder", path); + FuriString* str_path = furi_string_alloc_printf("%s/test-folder", path); FURI_LOG_I(TAG, "--------- START \"%s\" ---------", path); // mkdir - FS_Error result = storage_common_mkdir(api, string_get_cstr(str_path)); + FS_Error result = storage_common_mkdir(api, furi_string_get_cstr(str_path)); if(result == FSE_OK) { FURI_LOG_I(TAG, "mkdir ok"); @@ -240,7 +239,7 @@ static void do_test_start(Storage* api, const char* path) { // stat FileInfo fileinfo; - result = storage_common_stat(api, string_get_cstr(str_path), &fileinfo); + result = storage_common_stat(api, furi_string_get_cstr(str_path), &fileinfo); if(result == FSE_OK) { if(fileinfo.flags & FSF_DIRECTORY) { @@ -252,16 +251,14 @@ static void do_test_start(Storage* api, const char* path) { FURI_LOG_E(TAG, "stat #1, %s", storage_error_get_desc(result)); } - string_clear(str_path); + furi_string_free(str_path); } static void do_test_end(Storage* api, const char* path) { uint64_t total_space; uint64_t free_space; - string_t str_path_1; - string_t str_path_2; - string_init_printf(str_path_1, "%s/test-folder", path); - string_init_printf(str_path_2, "%s/test-folder2", path); + FuriString* str_path_1 = furi_string_alloc_printf("%s/test-folder", path); + FuriString* str_path_2 = furi_string_alloc_printf("%s/test-folder2", path); FURI_LOG_I(TAG, "--------- END \"%s\" ---------", path); @@ -277,7 +274,8 @@ static void do_test_end(Storage* api, const char* path) { } // rename #1 - result = storage_common_rename(api, string_get_cstr(str_path_1), string_get_cstr(str_path_2)); + result = storage_common_rename( + api, furi_string_get_cstr(str_path_1), furi_string_get_cstr(str_path_2)); if(result == FSE_OK) { FURI_LOG_I(TAG, "rename #1 ok"); } else { @@ -285,7 +283,7 @@ static void do_test_end(Storage* api, const char* path) { } // remove #1 - result = storage_common_remove(api, string_get_cstr(str_path_2)); + result = storage_common_remove(api, furi_string_get_cstr(str_path_2)); if(result == FSE_OK) { FURI_LOG_I(TAG, "remove #1 ok"); } else { @@ -293,10 +291,11 @@ static void do_test_end(Storage* api, const char* path) { } // rename #2 - string_printf(str_path_1, "%s/test.txt", path); - string_printf(str_path_2, "%s/test2.txt", path); + furi_string_printf(str_path_1, "%s/test.txt", path); + furi_string_printf(str_path_2, "%s/test2.txt", path); - result = storage_common_rename(api, string_get_cstr(str_path_1), string_get_cstr(str_path_2)); + result = storage_common_rename( + api, furi_string_get_cstr(str_path_1), furi_string_get_cstr(str_path_2)); if(result == FSE_OK) { FURI_LOG_I(TAG, "rename #2 ok"); } else { @@ -304,15 +303,15 @@ static void do_test_end(Storage* api, const char* path) { } // remove #2 - result = storage_common_remove(api, string_get_cstr(str_path_2)); + result = storage_common_remove(api, furi_string_get_cstr(str_path_2)); if(result == FSE_OK) { FURI_LOG_I(TAG, "remove #2 ok"); } else { FURI_LOG_E(TAG, "remove #2, %s", storage_error_get_desc(result)); } - string_clear(str_path_1); - string_clear(str_path_2); + furi_string_free(str_path_1); + furi_string_free(str_path_2); } int32_t storage_test_app(void* p) { diff --git a/applications/services/storage/storages/storage_int.c b/applications/services/storage/storages/storage_int.c index 758397354..4fa5d130c 100644 --- a/applications/services/storage/storages/storage_int.c +++ b/applications/services/storage/storages/storage_int.c @@ -77,12 +77,12 @@ static int storage_int_device_read( FURI_LOG_T( TAG, - "Device read: block %d, off %d, buffer: %p, size %d, translated address: %p", + "Device read: block %ld, off %ld, buffer: %p, size %ld, translated address: %p", block, off, buffer, size, - address); + (void*)address); memcpy(buffer, (void*)address, size); @@ -100,12 +100,12 @@ static int storage_int_device_prog( FURI_LOG_T( TAG, - "Device prog: block %d, off %d, buffer: %p, size %d, translated address: %p", + "Device prog: block %ld, off %ld, buffer: %p, size %ld, translated address: %p", block, off, buffer, size, - address); + (void*)address); int ret = 0; while(size > 0) { @@ -122,7 +122,7 @@ static int storage_int_device_erase(const struct lfs_config* c, lfs_block_t bloc LFSData* lfs_data = c->context; size_t page = lfs_data->start_page + block; - FURI_LOG_D(TAG, "Device erase: page %d, translated page: %x", block, page); + FURI_LOG_D(TAG, "Device erase: page %ld, translated page: %x", block, page); furi_hal_flash_erase(page); return 0; @@ -338,11 +338,12 @@ static bool storage_int_file_open( storage_set_storage_file_data(file, handle, storage); if(!enough_free_space) { - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_basename(path, filename); - bool is_dot_file = (!string_empty_p(filename) && (string_get_char(filename, 0) == '.')); - string_clear(filename); + bool is_dot_file = + (!furi_string_empty(filename) && (furi_string_get_char(filename, 0) == '.')); + furi_string_free(filename); /* Restrict write & creation access to all non-dot files */ if(!is_dot_file && (flags & (LFS_O_CREAT | LFS_O_WRONLY))) { @@ -739,8 +740,8 @@ void storage_int_init(StorageData* storage) { LFSData* lfs_data = storage_int_lfs_data_alloc(); FURI_LOG_I( TAG, - "Config: start %p, read %d, write %d, page size: %d, page count: %d, cycles: %d", - lfs_data->start_address, + "Config: start %p, read %ld, write %ld, page size: %ld, page count: %ld, cycles: %ld", + (void*)lfs_data->start_address, lfs_data->config.read_size, lfs_data->config.prog_size, lfs_data->config.block_size, diff --git a/applications/settings/about/about.c b/applications/settings/about/about.c index 6b4489f0a..a42969b2b 100644 --- a/applications/settings/about/about.c +++ b/applications/settings/about/about.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -78,11 +77,11 @@ static DialogMessageButton icon2_screen(DialogsApp* dialogs, DialogMessage* mess static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); const char* my_name = furi_hal_version_get_name_ptr(); - string_cat_printf( + furi_string_cat_printf( buffer, "%d.F%dB%dC%d %s:%s %s\n", furi_hal_version_get_hw_version(), @@ -93,26 +92,26 @@ static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage* furi_hal_region_get_name(), my_name ? my_name : "Unknown"); - string_cat_printf(buffer, "Serial Number:\n"); + furi_string_cat_printf(buffer, "Serial Number:\n"); const uint8_t* uid = furi_hal_version_uid(); for(size_t i = 0; i < furi_hal_version_uid_size(); i++) { - string_cat_printf(buffer, "%02X", uid[i]); + furi_string_cat_printf(buffer, "%02X", uid[i]); } dialog_message_set_header(message, "HW Version Info:", 0, 0, AlignLeft, AlignTop); - dialog_message_set_text(message, string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); + dialog_message_set_text(message, furi_string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); - string_clear(buffer); + furi_string_free(buffer); return result; } static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; - string_t buffer; - string_init(buffer); + FuriString* buffer; + buffer = furi_string_alloc(); const Version* ver = furi_hal_version_get_firmware_version(); const BleGlueC2Info* c2_ver = NULL; #ifdef SRV_BT @@ -120,9 +119,9 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* #endif if(!ver) { - string_cat_printf(buffer, "No info\n"); + furi_string_cat_printf(buffer, "No info\n"); } else { - string_cat_printf( + furi_string_cat_printf( buffer, "%s [%s]\n%s%s [%s] %s\n[%d] %s", version_get_version(ver), @@ -136,11 +135,11 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* } dialog_message_set_header(message, "FW Version Info:", 0, 0, AlignLeft, AlignTop); - dialog_message_set_text(message, string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); + dialog_message_set_text(message, furi_string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); - string_clear(buffer); + furi_string_free(buffer); return result; } diff --git a/applications/settings/power_settings_app/views/battery_info.c b/applications/settings/power_settings_app/views/battery_info.c index aa3a1e962..1a8bc71ec 100644 --- a/applications/settings/power_settings_app/views/battery_info.c +++ b/applications/settings/power_settings_app/views/battery_info.c @@ -119,8 +119,8 @@ void battery_info_set_data(BatteryInfo* battery_info, BatteryInfoModel* data) { furi_assert(battery_info); furi_assert(data); with_view_model( - battery_info->view, (BatteryInfoModel * model) { - memcpy(model, data, sizeof(BatteryInfoModel)); - return true; - }); + battery_info->view, + BatteryInfoModel * model, + { memcpy(model, data, sizeof(BatteryInfoModel)); }, + true); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_benchmark.c b/applications/settings/storage_settings/scenes/storage_settings_scene_benchmark.c index ddeea4eba..71a3df78b 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_benchmark.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_benchmark.c @@ -92,19 +92,19 @@ static void storage_settings_scene_benchmark(StorageSettings* app) { app->fs_api, bench_size[i], bench_data, &bench_w_speed[i])) break; - if(i > 0) string_cat_printf(app->text_string, "\n"); - string_cat_printf(app->text_string, "%ub : W %luK ", bench_size[i], bench_w_speed[i]); + if(i > 0) furi_string_cat_printf(app->text_string, "\n"); + furi_string_cat_printf(app->text_string, "%ub : W %luK ", bench_size[i], bench_w_speed[i]); dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); dialog_ex_set_text( - dialog_ex, string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); + dialog_ex, furi_string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); if(!storage_settings_scene_bench_read( app->fs_api, bench_size[i], bench_data, &bench_r_speed[i])) break; - string_cat_printf(app->text_string, "R %luK", bench_r_speed[i]); + furi_string_cat_printf(app->text_string, "R %luK", bench_r_speed[i]); dialog_ex_set_text( - dialog_ex, string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); + dialog_ex, furi_string_get_cstr(app->text_string), 0, 32, AlignLeft, AlignCenter); } free(bench_data); @@ -159,5 +159,5 @@ void storage_settings_scene_benchmark_on_exit(void* context) { dialog_ex_reset(dialog_ex); - string_reset(app->text_string); + furi_string_reset(app->text_string); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_factory_reset.c b/applications/settings/storage_settings/scenes/storage_settings_scene_factory_reset.c index a69479681..64d2b96b1 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_factory_reset.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_factory_reset.c @@ -49,13 +49,13 @@ bool storage_settings_scene_factory_reset_on_event(void* context, SceneManagerEv case DialogExResultRight: counter++; if(counter < STORAGE_SETTINGS_SCENE_FACTORY_RESET_CONFIRM_COUNT) { - string_printf( + furi_string_printf( app->text_string, "%ld presses left", STORAGE_SETTINGS_SCENE_FACTORY_RESET_CONFIRM_COUNT - counter); dialog_ex_set_text( app->dialog_ex, - string_get_cstr(app->text_string), + furi_string_get_cstr(app->text_string), 64, 32, AlignCenter, @@ -83,5 +83,5 @@ void storage_settings_scene_factory_reset_on_exit(void* context) { dialog_ex_reset(dialog_ex); - string_reset(app->text_string); + furi_string_reset(app->text_string); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c b/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c index 76c7fd0ec..f205efc0a 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_internal_info.c @@ -25,14 +25,14 @@ void storage_settings_scene_internal_info_on_enter(void* context) { dialog_ex_set_text( dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter); } else { - string_printf( + furi_string_printf( app->text_string, - "Label: %s\nType: LittleFS\n%lu KB total\n%lu KB free", + "Label: %s\nType: LittleFS\n%lu KiB total\n%lu KiB free", furi_hal_version_get_name_ptr() ? furi_hal_version_get_name_ptr() : "Unknown", (uint32_t)(total_space / 1024), (uint32_t)(free_space / 1024)); dialog_ex_set_text( - dialog_ex, string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); + dialog_ex, furi_string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); } view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); @@ -58,5 +58,5 @@ void storage_settings_scene_internal_info_on_exit(void* context) { dialog_ex_reset(dialog_ex); - string_reset(app->text_string); + furi_string_reset(app->text_string); } diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c b/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c index cfb4f310d..ede610d0e 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_sd_info.c @@ -24,15 +24,15 @@ void storage_settings_scene_sd_info_on_enter(void* context) { dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop); dialog_ex_set_center_button_text(dialog_ex, "Ok"); } else { - string_printf( + furi_string_printf( app->text_string, - "Label: %s\nType: %s\n%lu KB total\n%lu KB free", + "Label: %s\nType: %s\n%lu KiB total\n%lu KiB free", sd_info.label, sd_api_get_fs_type_text(sd_info.fs_type), sd_info.kb_total, sd_info.kb_free); dialog_ex_set_text( - dialog_ex, string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); + dialog_ex, furi_string_get_cstr(app->text_string), 4, 4, AlignLeft, AlignTop); } view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); @@ -70,5 +70,5 @@ void storage_settings_scene_sd_info_on_exit(void* context) { dialog_ex_reset(dialog_ex); - string_reset(app->text_string); + furi_string_reset(app->text_string); } diff --git a/applications/settings/storage_settings/storage_settings.c b/applications/settings/storage_settings/storage_settings.c index f580e6369..77a8f0f22 100644 --- a/applications/settings/storage_settings/storage_settings.c +++ b/applications/settings/storage_settings/storage_settings.c @@ -21,7 +21,7 @@ static StorageSettings* storage_settings_alloc() { app->view_dispatcher = view_dispatcher_alloc(); app->scene_manager = scene_manager_alloc(&storage_settings_scene_handlers, app); - string_init(app->text_string); + app->text_string = furi_string_alloc(); view_dispatcher_enable_queue(app->view_dispatcher); view_dispatcher_set_event_callback_context(app->view_dispatcher, app); @@ -60,7 +60,7 @@ static void storage_settings_free(StorageSettings* app) { furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_NOTIFICATION); - string_clear(app->text_string); + furi_string_free(app->text_string); free(app); } diff --git a/applications/settings/storage_settings/storage_settings.h b/applications/settings/storage_settings/storage_settings.h index f2d071c47..4cf185e0c 100644 --- a/applications/settings/storage_settings/storage_settings.h +++ b/applications/settings/storage_settings/storage_settings.h @@ -34,7 +34,7 @@ typedef struct { DialogEx* dialog_ex; // text - string_t text_string; + FuriString* text_string; } StorageSettings; typedef enum { diff --git a/applications/system/storage_move_to_sd/storage_move_to_sd.c b/applications/system/storage_move_to_sd/storage_move_to_sd.c index e5b195d55..2027bd237 100644 --- a/applications/system/storage_move_to_sd/storage_move_to_sd.c +++ b/applications/system/storage_move_to_sd/storage_move_to_sd.c @@ -2,7 +2,6 @@ #include #include #include "loader/loader.h" -#include "m-string.h" #include #include #include @@ -28,25 +27,26 @@ bool storage_move_to_sd_perform(void) { dir_walk_set_recursive(dir_walk, false); dir_walk_set_filter_cb(dir_walk, storage_move_to_sd_check_entry, NULL); - string_t path_src, path_dst; + FuriString *path_src, *path_dst; - string_init(path_dst); - string_init(path_src); + path_dst = furi_string_alloc(); + path_src = furi_string_alloc(); if(dir_walk_open(dir_walk, STORAGE_INT_PATH_PREFIX)) { while(dir_walk_read(dir_walk, path_src, NULL) == DirWalkOK) { - string_set(path_dst, path_src); - string_replace_at( + furi_string_set(path_dst, path_src); + furi_string_replace_at( path_dst, 0, strlen(STORAGE_INT_PATH_PREFIX), STORAGE_EXT_PATH_PREFIX); - storage_common_merge(storage, string_get_cstr(path_src), string_get_cstr(path_dst)); - storage_simply_remove_recursive(storage, string_get_cstr(path_src)); + storage_common_merge( + storage, furi_string_get_cstr(path_src), furi_string_get_cstr(path_dst)); + storage_simply_remove_recursive(storage, furi_string_get_cstr(path_src)); } } dir_walk_free(dir_walk); - string_clear(path_dst); - string_clear(path_src); + furi_string_free(path_dst); + furi_string_free(path_src); furi_record_close(RECORD_STORAGE); @@ -62,8 +62,8 @@ static bool storage_move_to_sd_check(void) { dir_walk_set_recursive(dir_walk, false); dir_walk_set_filter_cb(dir_walk, storage_move_to_sd_check_entry, NULL); - string_t name; - string_init(name); + FuriString* name; + name = furi_string_alloc(); if(dir_walk_open(dir_walk, STORAGE_INT_PATH_PREFIX)) { // if at least 1 entry is present, we should migrate @@ -71,7 +71,7 @@ static bool storage_move_to_sd_check(void) { } dir_walk_free(dir_walk); - string_clear(name); + furi_string_free(name); furi_record_close(RECORD_STORAGE); diff --git a/applications/system/updater/cli/updater_cli.c b/applications/system/updater/cli/updater_cli.c index ec209bd1d..c3cdbb5f7 100644 --- a/applications/system/updater/cli/updater_cli.c +++ b/applications/system/updater/cli/updater_cli.c @@ -1,7 +1,6 @@ #include #include -#include #include #include #include @@ -12,16 +11,16 @@ #include #include -typedef void (*cmd_handler)(string_t args); +typedef void (*cmd_handler)(FuriString* args); typedef struct { const char* command; const cmd_handler handler; } CliSubcommand; -static void updater_cli_install(string_t manifest_path) { - printf("Verifying update package at '%s'\r\n", string_get_cstr(manifest_path)); +static void updater_cli_install(FuriString* manifest_path) { + printf("Verifying update package at '%s'\r\n", furi_string_get_cstr(manifest_path)); - UpdatePrepareResult result = update_operation_prepare(string_get_cstr(manifest_path)); + UpdatePrepareResult result = update_operation_prepare(furi_string_get_cstr(manifest_path)); if(result != UpdatePrepareResultOK) { printf( "Error: %s. Stopping update.\r\n", @@ -33,23 +32,23 @@ static void updater_cli_install(string_t manifest_path) { furi_hal_power_reset(); } -static void updater_cli_backup(string_t args) { - printf("Backup /int to '%s'\r\n", string_get_cstr(args)); +static void updater_cli_backup(FuriString* args) { + printf("Backup /int to '%s'\r\n", furi_string_get_cstr(args)); Storage* storage = furi_record_open(RECORD_STORAGE); - bool success = lfs_backup_create(storage, string_get_cstr(args)); + bool success = lfs_backup_create(storage, furi_string_get_cstr(args)); furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } -static void updater_cli_restore(string_t args) { - printf("Restore /int from '%s'\r\n", string_get_cstr(args)); +static void updater_cli_restore(FuriString* args) { + printf("Restore /int from '%s'\r\n", furi_string_get_cstr(args)); Storage* storage = furi_record_open(RECORD_STORAGE); - bool success = lfs_backup_unpack(storage, string_get_cstr(args)); + bool success = lfs_backup_unpack(storage, furi_string_get_cstr(args)); furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } -static void updater_cli_help(string_t args) { +static void updater_cli_help(FuriString* args) { UNUSED(args); printf("Commands:\r\n" "\tinstall /ext/path/to/update.fuf - verify & apply update package\r\n" @@ -64,25 +63,25 @@ static const CliSubcommand update_cli_subcommands[] = { {.command = "help", .handler = updater_cli_help}, }; -static void updater_cli_ep(Cli* cli, string_t args, void* context) { +static void updater_cli_ep(Cli* cli, FuriString* args, void* context) { UNUSED(cli); UNUSED(context); - string_t subcommand; - string_init(subcommand); - if(!args_read_string_and_trim(args, subcommand) || string_empty_p(args)) { + FuriString* subcommand; + subcommand = furi_string_alloc(); + if(!args_read_string_and_trim(args, subcommand) || furi_string_empty(args)) { updater_cli_help(args); - string_clear(subcommand); + furi_string_free(subcommand); return; } for(size_t idx = 0; idx < COUNT_OF(update_cli_subcommands); ++idx) { const CliSubcommand* subcmd_def = &update_cli_subcommands[idx]; - if(string_cmp_str(subcommand, subcmd_def->command) == 0) { - string_clear(subcommand); + if(furi_string_cmp_str(subcommand, subcmd_def->command) == 0) { + furi_string_free(subcommand); subcmd_def->handler(args); return; } } - string_clear(subcommand); + furi_string_free(subcommand); updater_cli_help(args); } diff --git a/applications/system/updater/scenes/updater_scene_loadcfg.c b/applications/system/updater/scenes/updater_scene_loadcfg.c index c7f48c78b..14f7b203a 100644 --- a/applications/system/updater/scenes/updater_scene_loadcfg.c +++ b/applications/system/updater/scenes/updater_scene_loadcfg.c @@ -25,7 +25,7 @@ void updater_scene_loadcfg_on_enter(void* context) { malloc(sizeof(UpdaterManifestProcessingState)); pending_upd->manifest = update_manifest_alloc(); - if(update_manifest_init(pending_upd->manifest, string_get_cstr(updater->startup_arg))) { + if(update_manifest_init(pending_upd->manifest, furi_string_get_cstr(updater->startup_arg))) { widget_add_string_element( updater->widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, "Update"); @@ -37,7 +37,7 @@ void updater_scene_loadcfg_on_enter(void* context) { 32, AlignCenter, AlignCenter, - string_get_cstr(pending_upd->manifest->version), + furi_string_get_cstr(pending_upd->manifest->version), true); widget_add_button_element( @@ -72,7 +72,7 @@ bool updater_scene_loadcfg_on_event(void* context, SceneManagerEvent event) { switch(event.event) { case UpdaterCustomEventStartUpdate: updater->preparation_result = - update_operation_prepare(string_get_cstr(updater->startup_arg)); + update_operation_prepare(furi_string_get_cstr(updater->startup_arg)); if(updater->preparation_result == UpdatePrepareResultOK) { furi_hal_power_reset(); } else { @@ -99,7 +99,7 @@ void updater_scene_loadcfg_on_exit(void* context) { if(updater->pending_update) { update_manifest_free(updater->pending_update->manifest); - string_clear(updater->pending_update->message); + furi_string_free(updater->pending_update->message); } widget_reset(updater->widget); diff --git a/applications/system/updater/updater.c b/applications/system/updater/updater.c index e9bedc72e..e749f3ce6 100644 --- a/applications/system/updater/updater.c +++ b/applications/system/updater/updater.c @@ -35,10 +35,10 @@ static void Updater* updater_alloc(const char* arg) { Updater* updater = malloc(sizeof(Updater)); if(arg && strlen(arg)) { - string_init_set_str(updater->startup_arg, arg); - string_replace_str(updater->startup_arg, ANY_PATH(""), EXT_PATH("")); + updater->startup_arg = furi_string_alloc_set(arg); + furi_string_replace(updater->startup_arg, ANY_PATH(""), EXT_PATH("")); } else { - string_init(updater->startup_arg); + updater->startup_arg = furi_string_alloc(); } updater->storage = furi_record_open(RECORD_STORAGE); @@ -94,7 +94,7 @@ Updater* updater_alloc(const char* arg) { void updater_free(Updater* updater) { furi_assert(updater); - string_clear(updater->startup_arg); + furi_string_free(updater->startup_arg); if(updater->update_task) { update_task_set_progress_cb(updater->update_task, NULL, NULL); update_task_free(updater->update_task); diff --git a/applications/system/updater/updater_i.h b/applications/system/updater/updater_i.h index 8a021a08d..ae249f38f 100644 --- a/applications/system/updater/updater_i.h +++ b/applications/system/updater/updater_i.h @@ -35,7 +35,7 @@ typedef enum { typedef struct UpdaterManifestProcessingState { UpdateManifest* manifest; - string_t message; + FuriString* message; bool ready_to_be_applied; } UpdaterManifestProcessingState; @@ -54,7 +54,7 @@ typedef struct { UpdateTask* update_task; Widget* widget; - string_t startup_arg; + FuriString* startup_arg; int32_t idle_ticks; } Updater; diff --git a/applications/system/updater/util/update_task.c b/applications/system/updater/util/update_task.c index b04773197..de172dd49 100644 --- a/applications/system/updater/util/update_task.c +++ b/applications/system/updater/util/update_task.c @@ -69,19 +69,19 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = { static UpdateTaskStageGroup update_task_get_task_groups(UpdateTask* update_task) { UpdateTaskStageGroup ret = UpdateTaskStageGroupPreUpdate | UpdateTaskStageGroupPostUpdate; UpdateManifest* manifest = update_task->manifest; - if(!string_empty_p(manifest->radio_image)) { + if(!furi_string_empty(manifest->radio_image)) { ret |= UpdateTaskStageGroupRadio; } if(update_manifest_has_obdata(manifest)) { ret |= UpdateTaskStageGroupOptionBytes; } - if(!string_empty_p(manifest->firmware_dfu_image)) { + if(!furi_string_empty(manifest->firmware_dfu_image)) { ret |= UpdateTaskStageGroupFirmware; } - if(!string_empty_p(manifest->resource_bundle)) { + if(!furi_string_empty(manifest->resource_bundle)) { ret |= UpdateTaskStageGroupResources; } - if(!string_empty_p(manifest->splash_file)) { + if(!furi_string_empty(manifest->splash_file)) { ret |= UpdateTaskStageGroupSplashscreen; } return ret; @@ -109,14 +109,14 @@ void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, ui } /* Build error message with code "[stage_idx-stage_percent]" */ if(stage >= UpdateTaskStageError) { - string_printf( + furi_string_printf( update_task->state.status, "%s #[%d-%d]", update_task_stage_descr[stage], update_task->state.stage, update_task->state.stage_progress); } else { - string_set_str(update_task->state.status, update_task_stage_descr[stage]); + furi_string_set(update_task->state.status, update_task_stage_descr[stage]); } /* Store stage update */ update_task->state.stage = stage; @@ -149,7 +149,7 @@ void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, ui if(update_task->status_change_cb) { (update_task->status_change_cb)( - string_get_cstr(update_task->state.status), + furi_string_get_cstr(update_task->state.status), adapted_progress, update_stage_is_error(update_task->state.stage), update_task->status_change_cb_state); @@ -165,26 +165,26 @@ static void update_task_close_file(UpdateTask* update_task) { storage_file_close(update_task->file); } -static bool update_task_check_file_exists(UpdateTask* update_task, string_t filename) { +static bool update_task_check_file_exists(UpdateTask* update_task, FuriString* filename) { furi_assert(update_task); - string_t tmp_path; - string_init_set(tmp_path, update_task->update_path); - path_append(tmp_path, string_get_cstr(filename)); - bool exists = storage_file_exists(update_task->storage, string_get_cstr(tmp_path)); - string_clear(tmp_path); + FuriString* tmp_path; + tmp_path = furi_string_alloc_set(update_task->update_path); + path_append(tmp_path, furi_string_get_cstr(filename)); + bool exists = storage_file_exists(update_task->storage, furi_string_get_cstr(tmp_path)); + furi_string_free(tmp_path); return exists; } -bool update_task_open_file(UpdateTask* update_task, string_t filename) { +bool update_task_open_file(UpdateTask* update_task, FuriString* filename) { furi_assert(update_task); update_task_close_file(update_task); - string_t tmp_path; - string_init_set(tmp_path, update_task->update_path); - path_append(tmp_path, string_get_cstr(filename)); + FuriString* tmp_path; + tmp_path = furi_string_alloc_set(update_task->update_path); + path_append(tmp_path, furi_string_get_cstr(filename)); bool open_success = storage_file_open( - update_task->file, string_get_cstr(tmp_path), FSAM_READ, FSOM_OPEN_EXISTING); - string_clear(tmp_path); + update_task->file, furi_string_get_cstr(tmp_path), FSAM_READ, FSOM_OPEN_EXISTING); + furi_string_free(tmp_path); return open_success; } @@ -207,14 +207,14 @@ UpdateTask* update_task_alloc() { update_task->state.stage = UpdateTaskStageProgress; update_task->state.stage_progress = 0; update_task->state.overall_progress = 0; - string_init(update_task->state.status); + update_task->state.status = furi_string_alloc(); update_task->manifest = update_manifest_alloc(); update_task->storage = furi_record_open(RECORD_STORAGE); update_task->file = storage_file_alloc(update_task->storage); update_task->status_change_cb = NULL; update_task->boot_mode = furi_hal_rtc_get_boot_mode(); - string_init(update_task->update_path); + update_task->update_path = furi_string_alloc(); FuriThread* thread = update_task->thread = furi_thread_alloc(); @@ -246,7 +246,7 @@ void update_task_free(UpdateTask* update_task) { update_manifest_free(update_task->manifest); furi_record_close(RECORD_STORAGE); - string_clear(update_task->update_path); + furi_string_free(update_task->update_path); free(update_task); } @@ -261,8 +261,8 @@ bool update_task_parse_manifest(UpdateTask* update_task) { update_task_set_progress(update_task, UpdateTaskStageReadManifest, 0); bool result = false; - string_t manifest_path; - string_init(manifest_path); + FuriString* manifest_path; + manifest_path = furi_string_alloc(); do { update_task_set_progress(update_task, UpdateTaskStageProgress, 13); @@ -276,11 +276,11 @@ bool update_task_parse_manifest(UpdateTask* update_task) { break; } - path_extract_dirname(string_get_cstr(manifest_path), update_task->update_path); + path_extract_dirname(furi_string_get_cstr(manifest_path), update_task->update_path); update_task_set_progress(update_task, UpdateTaskStageProgress, 30); UpdateManifest* manifest = update_task->manifest; - if(!update_manifest_init(manifest, string_get_cstr(manifest_path))) { + if(!update_manifest_init(manifest, furi_string_get_cstr(manifest_path))) { break; } @@ -320,7 +320,7 @@ bool update_task_parse_manifest(UpdateTask* update_task) { result = true; } while(false); - string_clear(manifest_path); + furi_string_free(manifest_path); return result; } diff --git a/applications/system/updater/util/update_task.h b/applications/system/updater/util/update_task.h index 1f2915568..b3ac3f2f8 100644 --- a/applications/system/updater/util/update_task.h +++ b/applications/system/updater/util/update_task.h @@ -8,9 +8,8 @@ extern "C" { #include #include -#include -#define UPDATE_DELAY_OPERATION_OK 300 +#define UPDATE_DELAY_OPERATION_OK 10 #define UPDATE_DELAY_OPERATION_ERROR INT_MAX typedef enum { @@ -59,7 +58,7 @@ typedef enum { typedef struct { UpdateTaskStage stage; uint8_t overall_progress, stage_progress; - string_t status; + FuriString* status; UpdateTaskStageGroup groups; uint32_t total_progress_points; uint32_t completed_stages_points; diff --git a/applications/system/updater/util/update_task_i.h b/applications/system/updater/util/update_task_i.h index 95c63f644..0dbeca5f4 100644 --- a/applications/system/updater/util/update_task_i.h +++ b/applications/system/updater/util/update_task_i.h @@ -8,7 +8,7 @@ typedef struct UpdateTask { UpdateTaskState state; - string_t update_path; + FuriString* update_path; UpdateManifest* manifest; FuriThread* thread; Storage* storage; @@ -20,7 +20,7 @@ typedef struct UpdateTask { void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, uint8_t progress); bool update_task_parse_manifest(UpdateTask* update_task); -bool update_task_open_file(UpdateTask* update_task, string_t filename); +bool update_task_open_file(UpdateTask* update_task, FuriString* filename); int32_t update_task_worker_flash_writer(void* context); int32_t update_task_worker_backup_restore(void* context); diff --git a/applications/system/updater/util/update_task_worker_backup.c b/applications/system/updater/util/update_task_worker_backup.c index 09e459533..ce62da2a1 100644 --- a/applications/system/updater/util/update_task_worker_backup.c +++ b/applications/system/updater/util/update_task_worker_backup.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -21,19 +22,22 @@ static bool update_task_pre_update(UpdateTask* update_task) { bool success = false; - string_t backup_file_path; - string_init(backup_file_path); + FuriString* backup_file_path; + backup_file_path = furi_string_alloc(); path_concat( - string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, backup_file_path); + furi_string_get_cstr(update_task->update_path), + LFS_BACKUP_DEFAULT_FILENAME, + backup_file_path); update_task_set_progress(update_task, UpdateTaskStageLfsBackup, 0); /* to avoid bootloops */ furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); - if((success = lfs_backup_create(update_task->storage, string_get_cstr(backup_file_path)))) { + if((success = + lfs_backup_create(update_task->storage, furi_string_get_cstr(backup_file_path)))) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeUpdate); } - string_clear(backup_file_path); + furi_string_free(backup_file_path); return success; } @@ -50,24 +54,62 @@ static bool update_task_resource_unpack_cb(const char* name, bool is_directory, update_task_set_progress( unpack_progress->update_task, UpdateTaskStageProgress, - unpack_progress->processed_files * 100 / (unpack_progress->total_files + 1)); + /* For this stage, last 70% of progress = extraction */ + 30 + (unpack_progress->processed_files * 70) / (unpack_progress->total_files + 1)); return true; } +static void + update_task_cleanup_resources(UpdateTask* update_task, uint32_t n_approx_file_entries) { + ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(update_task->storage); + do { + FURI_LOG_I(TAG, "Cleaning up old manifest"); + if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("Manifest"))) { + FURI_LOG_W(TAG, "No existing manifest"); + break; + } + + /* We got # of entries in TAR file. Approx 1/4th is dir entries, we skip them */ + n_approx_file_entries = n_approx_file_entries * 3 / 4 + 1; + uint32_t n_processed_files = 0; + + ResourceManifestEntry* entry_ptr = NULL; + while((entry_ptr = resource_manifest_reader_next(manifest_reader))) { + if(entry_ptr->type == ResourceManifestEntryTypeFile) { + update_task_set_progress( + update_task, + UpdateTaskStageProgress, + /* For this stage, first 30% of progress = cleanup */ + (n_processed_files++ * 30) / (n_approx_file_entries + 1)); + + FuriString* file_path = furi_string_alloc(); + path_concat( + STORAGE_EXT_PATH_PREFIX, furi_string_get_cstr(entry_ptr->name), file_path); + FURI_LOG_D(TAG, "Removing %s", furi_string_get_cstr(file_path)); + storage_simply_remove(update_task->storage, furi_string_get_cstr(file_path)); + furi_string_free(file_path); + } + } + } while(false); + resource_manifest_reader_free(manifest_reader); +} + static bool update_task_post_update(UpdateTask* update_task) { bool success = false; - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); TarArchive* archive = tar_archive_alloc(update_task->storage); do { path_concat( - string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, file_path); + furi_string_get_cstr(update_task->update_path), + LFS_BACKUP_DEFAULT_FILENAME, + file_path); update_task_set_progress(update_task, UpdateTaskStageLfsRestore, 0); - CHECK_RESULT(lfs_backup_unpack(update_task->storage, string_get_cstr(file_path))); + CHECK_RESULT(lfs_backup_unpack(update_task->storage, furi_string_get_cstr(file_path))); if(update_task->state.groups & UpdateTaskStageGroupResources) { TarUnpackProgress progress = { @@ -78,39 +120,41 @@ static bool update_task_post_update(UpdateTask* update_task) { update_task_set_progress(update_task, UpdateTaskStageResourcesUpdate, 0); path_concat( - string_get_cstr(update_task->update_path), - string_get_cstr(update_task->manifest->resource_bundle), + furi_string_get_cstr(update_task->update_path), + furi_string_get_cstr(update_task->manifest->resource_bundle), file_path); tar_archive_set_file_callback(archive, update_task_resource_unpack_cb, &progress); CHECK_RESULT( - tar_archive_open(archive, string_get_cstr(file_path), TAR_OPEN_MODE_READ)); + tar_archive_open(archive, furi_string_get_cstr(file_path), TAR_OPEN_MODE_READ)); progress.total_files = tar_archive_get_entries_count(archive); if(progress.total_files > 0) { + update_task_cleanup_resources(update_task, progress.total_files); + CHECK_RESULT(tar_archive_unpack_to(archive, STORAGE_EXT_PATH_PREFIX, NULL)); } } if(update_task->state.groups & UpdateTaskStageGroupSplashscreen) { update_task_set_progress(update_task, UpdateTaskStageSplashscreenInstall, 0); - string_t tmp_path; - string_init_set(tmp_path, update_task->update_path); - path_append(tmp_path, string_get_cstr(update_task->manifest->splash_file)); + FuriString* tmp_path; + tmp_path = furi_string_alloc_set(update_task->update_path); + path_append(tmp_path, furi_string_get_cstr(update_task->manifest->splash_file)); if(storage_common_copy( update_task->storage, - string_get_cstr(tmp_path), + furi_string_get_cstr(tmp_path), INT_PATH(SLIDESHOW_FILE_NAME)) != FSE_OK) { // actually, not critical } - string_clear(tmp_path); + furi_string_free(tmp_path); update_task_set_progress(update_task, UpdateTaskStageSplashscreenInstall, 100); } success = true; } while(false); tar_archive_free(archive); - string_clear(file_path); + furi_string_free(file_path); return success; } diff --git a/applications/system/updater/util/update_task_worker_flasher.c b/applications/system/updater/util/update_task_worker_flasher.c index 7b598c50b..7358a6334 100644 --- a/applications/system/updater/util/update_task_worker_flasher.c +++ b/applications/system/updater/util/update_task_worker_flasher.c @@ -271,7 +271,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { match = false; FURI_LOG_E( TAG, - "OB MISMATCH: #%d: real %08X != %08X (exp.), full %08X", + "OB MISMATCH: #%d: real %08lX != %08lX (exp.), full %08lX", idx, device_ob_value_masked, ref_value, @@ -289,7 +289,7 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { (manifest->ob_reference.obs[idx].values.base & manifest->ob_write_mask.obs[idx].values.base); - FURI_LOG_W(TAG, "Fixing up OB byte #%d to %08X", idx, patched_value); + FURI_LOG_W(TAG, "Fixing up OB byte #%d to %08lX", idx, patched_value); ob_dirty = true; bool is_fixed = furi_hal_flash_ob_set_word(idx, patched_value) && @@ -301,16 +301,16 @@ bool update_task_validate_optionbytes(UpdateTask* update_task) { * reference value */ FURI_LOG_W( TAG, - "OB #%d is FUBAR (fixed&masked %08X, not %08X)", + "OB #%d is FUBAR (fixed&masked %08lX, not %08lX)", idx, patched_value, ref_value); } } } else { - FURI_LOG_I( + FURI_LOG_D( TAG, - "OB MATCH: #%d: real %08X == %08X (exp.)", + "OB MATCH: #%d: real %08lX == %08lX (exp.)", idx, device_ob_value_masked, ref_value); diff --git a/applications/system/updater/views/updater_main.c b/applications/system/updater/views/updater_main.c index 72541b9ab..5ed3c70aa 100644 --- a/applications/system/updater/views/updater_main.c +++ b/applications/system/updater/views/updater_main.c @@ -18,7 +18,7 @@ struct UpdaterMainView { static const uint8_t PROGRESS_RENDER_STEP = 1; /* percent, to limit rendering rate */ typedef struct { - string_t status; + FuriString* status; uint8_t progress, rendered_progress; bool failed; } UpdaterProgressModel; @@ -28,22 +28,25 @@ void updater_main_model_set_state( const char* message, uint8_t progress, bool failed) { + bool update = false; with_view_model( - main_view->view, (UpdaterProgressModel * model) { + main_view->view, + UpdaterProgressModel * model, + { model->failed = failed; model->progress = progress; - if(string_cmp_str(model->status, message)) { - string_set(model->status, message); + if(furi_string_cmp_str(model->status, message)) { + furi_string_set(model->status, message); model->rendered_progress = progress; - return true; - } - if((model->rendered_progress > progress) || - ((progress - model->rendered_progress) > PROGRESS_RENDER_STEP)) { + update = true; + } else if( + (model->rendered_progress > progress) || + ((progress - model->rendered_progress) > PROGRESS_RENDER_STEP)) { model->rendered_progress = progress; - return true; + update = true; } - return false; - }); + }, + update); } View* updater_main_get_view(UpdaterMainView* main_view) { @@ -80,7 +83,7 @@ static void updater_main_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 42, 16, AlignLeft, AlignTop, "Update Failed!"); canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned( - canvas, 42, 32, AlignLeft, AlignTop, string_get_cstr(model->status)); + canvas, 42, 32, AlignLeft, AlignTop, furi_string_get_cstr(model->status)); canvas_draw_icon(canvas, 7, 16, &I_Warning_30x23); canvas_draw_str_aligned( @@ -91,7 +94,7 @@ static void updater_main_draw_callback(Canvas* canvas, void* _model) { canvas_draw_str_aligned(canvas, 55, 14, AlignLeft, AlignTop, "UPDATING"); canvas_set_font(canvas, FontSecondary); canvas_draw_str_aligned( - canvas, 64, 51, AlignCenter, AlignTop, string_get_cstr(model->status)); + canvas, 64, 51, AlignCenter, AlignTop, furi_string_get_cstr(model->status)); canvas_draw_icon(canvas, 4, 5, &I_Updating_32x40); elements_progress_bar(canvas, 42, 29, 80, (float)model->progress / 100); } @@ -104,10 +107,10 @@ UpdaterMainView* updater_main_alloc() { view_allocate_model(main_view->view, ViewModelTypeLocking, sizeof(UpdaterProgressModel)); with_view_model( - main_view->view, (UpdaterProgressModel * model) { - string_init_set(model->status, "Waiting for SD card"); - return true; - }); + main_view->view, + UpdaterProgressModel * model, + { model->status = furi_string_alloc_set("Waiting for SD card"); }, + true); view_set_context(main_view->view, main_view); view_set_input_callback(main_view->view, updater_main_input); @@ -119,10 +122,7 @@ UpdaterMainView* updater_main_alloc() { void updater_main_free(UpdaterMainView* main_view) { furi_assert(main_view); with_view_model( - main_view->view, (UpdaterProgressModel * model) { - string_clear(model->status); - return false; - }); + main_view->view, UpdaterProgressModel * model, { furi_string_free(model->status); }, false); view_free(main_view->view); free(main_view); } diff --git a/assets/SConscript b/assets/SConscript index 47713d1a6..e1bf546cc 100644 --- a/assets/SConscript +++ b/assets/SConscript @@ -1,33 +1,21 @@ Import("env") +from fbt.version import get_git_commit_unix_timestamp + assetsenv = env.Clone( tools=["fbt_assets"], FW_LIB_NAME="assets", + GIT_UNIX_TIMESTAMP=get_git_commit_unix_timestamp(), ) assetsenv.ApplyLibFlags() -if not assetsenv["VERBOSE"]: - assetsenv.SetDefault( - ICONSCOMSTR="\tICONS\t${TARGET}", - PROTOCOMSTR="\tPROTO\t${SOURCE}", - DOLPHINCOMSTR="\tDOLPHIN\t${DOLPHIN_RES_TYPE}", - RESMANIFESTCOMSTR="\tMANIFEST\t${TARGET}", - PBVERCOMSTR="\tPBVER\t${TARGET}", - ) - -# Gathering icons sources -icons_src = assetsenv.GlobRecursive("*.png", "icons") -icons_src += assetsenv.GlobRecursive("frame_rate", "icons") - -icons = assetsenv.IconBuilder( - assetsenv.Dir("compiled"), ICON_SRC_DIR=assetsenv.Dir("#/assets/icons") +icons = assetsenv.CompileIcons( + assetsenv.Dir("compiled"), assetsenv.Dir("#/assets/icons") ) -assetsenv.Depends(icons, icons_src) assetsenv.Alias("icons", icons) # Protobuf .proto -> .c + .h - proto_src = assetsenv.Glob("protobuf/*.proto", source=True) proto_options = assetsenv.Glob("protobuf/*.options", source=True) proto = assetsenv.ProtoBuilder(assetsenv.Dir("compiled"), proto_src) @@ -90,10 +78,11 @@ if assetsenv["IS_BASE_FIRMWARE"]: "#/assets/resources/Manifest", assetsenv.GlobRecursive("*", "resources", exclude="Manifest"), action=Action( - '${PYTHON3} "${ASSETS_COMPILER}" manifest "${TARGET.dir.posix}"', + '${PYTHON3} "${ASSETS_COMPILER}" manifest "${TARGET.dir.posix}" --timestamp=${GIT_UNIX_TIMESTAMP}', "${RESMANIFESTCOMSTR}", ), ) + assetsenv.Precious(resources) assetsenv.AlwaysBuild(resources) assetsenv.Clean( resources, diff --git a/assets/icons/Interface/SmallArrowDown_3x5.png b/assets/icons/Interface/SmallArrowDown_3x5.png new file mode 100644 index 000000000..1912e5d24 Binary files /dev/null and b/assets/icons/Interface/SmallArrowDown_3x5.png differ diff --git a/assets/icons/Interface/SmallArrowDown_4x7.png b/assets/icons/Interface/SmallArrowDown_4x7.png new file mode 100644 index 000000000..5c5252b16 Binary files /dev/null and b/assets/icons/Interface/SmallArrowDown_4x7.png differ diff --git a/assets/icons/Interface/SmallArrowUp_3x5.png b/assets/icons/Interface/SmallArrowUp_3x5.png new file mode 100644 index 000000000..9c6242078 Binary files /dev/null and b/assets/icons/Interface/SmallArrowUp_3x5.png differ diff --git a/assets/icons/Interface/SmallArrowUp_4x7.png b/assets/icons/Interface/SmallArrowUp_4x7.png new file mode 100644 index 000000000..886369abc Binary files /dev/null and b/assets/icons/Interface/SmallArrowUp_4x7.png differ diff --git a/assets/icons/NFC/Modern_reader_18x34.png b/assets/icons/NFC/Modern_reader_18x34.png new file mode 100644 index 000000000..b19c0f30c Binary files /dev/null and b/assets/icons/NFC/Modern_reader_18x34.png differ diff --git a/assets/icons/NFC/Move_flipper_26x39.png b/assets/icons/NFC/Move_flipper_26x39.png new file mode 100644 index 000000000..ff4af9ff0 Binary files /dev/null and b/assets/icons/NFC/Move_flipper_26x39.png differ diff --git a/assets/icons/NFC/Release_arrow_18x15.png b/assets/icons/NFC/Release_arrow_18x15.png new file mode 100644 index 000000000..187a90345 Binary files /dev/null and b/assets/icons/NFC/Release_arrow_18x15.png differ diff --git a/assets/resources/badusb/demo_windows.txt b/assets/resources/badusb/demo_windows.txt index df4353510..f304f5e8d 100644 --- a/assets/resources/badusb/demo_windows.txt +++ b/assets/resources/badusb/demo_windows.txt @@ -78,7 +78,7 @@ ENTER STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script format ENTER -STRING More information about script synax can be found here: +STRING More information about script syntax can be found here: ENTER STRING https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript ENTER diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir index 7866febc6..97c384591 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -74,3 +74,41 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 8972 4491 592 1651 592 1655 598 532 599 535 597 542 600 541 601 544 598 1656 597 526 595 1652 591 1658 595 539 593 545 597 545 597 546 596 537 594 529 592 535 596 1653 600 534 597 541 601 539 592 552 600 533 598 525 596 530 591 538 593 539 592 1665 598 1662 591 1673 601 533 598 526 595 533 598 532 600 534 597 540 591 548 594 550 592 542 600 523 598 528 593 536 595 537 594 543 599 542 600 543 599 517 594 7937 593 531 601 526 595 535 597 537 594 542 600 541 601 543 599 1654 599 523 598 528 593 536 596 538 594 542 600 541 590 552 600 532 599 524 597 528 593 536 595 537 595 541 601 539 593 551 591 542 600 522 599 527 594 536 595 537 594 543 599 540 591 552 600 532 600 523 598 527 594 535 596 537 595 542 600 540 591 552 600 532 600 523 598 528 593 536 595 538 593 543 599 541 601 543 599 535 596 527 594 532 600 531 601 534 597 540 592 549 593 552 600 534 597 525 596 529 592 1655 598 534 597 1656 597 1661 592 1671 592 1644 599 7934 596 529 592 535 597 535 597 538 593 544 598 543 599 545 597 538 593 1650 593 535 596 534 597 536 595 540 591 547 595 547 595 536 595 526 595 529 592 536 595 535 596 539 593 546 596 547 595 538 593 528 593 531 601 529 592 541 601 536 596 545 597 548 594 540 592 532 600 526 595 535 596 1656 597 541 601 540 592 553 599 534 597 526 595 532 599 531 600 533 598 539 593 548 594 552 600 535 596 1647 596 531 590 538 593 1656 597 538 594 545 597 545 597 518 593 +# +# Model: Daichi DA25AVQS1-W +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9131 4318 815 389 817 1523 784 391 815 1523 784 1494 813 422 784 391 816 421 785 1524 784 392 814 422 783 1525 782 424 782 422 784 422 784 422 784 396 809 423 783 422 782 423 783 423 783 1496 812 1525 782 424 783 423 783 422 783 423 783 394 811 1526 782 424 782 1524 782 423 783 423 782 1525 782 423 675 19938 810 425 781 424 674 502 811 423 675 531 675 531 675 531 676 530 675 531 675 531 675 502 704 530 675 530 676 530 676 502 704 530 676 530 676 530 675 530 675 530 676 530 675 530 676 530 676 529 677 529 677 529 677 530 677 529 677 1631 676 529 677 1630 678 1631 677 +# +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9076 4455 677 1629 678 528 677 528 677 1630 677 529 677 530 676 530 676 531 675 531 675 531 675 531 675 531 674 531 675 532 674 531 674 532 674 531 675 532 674 531 674 531 674 532 674 1633 674 1633 674 532 674 532 674 532 674 532 674 532 674 1634 673 533 673 1634 673 533 674 532 674 1633 674 533 673 19965 674 531 674 532 675 531 675 531 675 531 675 531 675 531 675 531 675 532 674 531 675 531 676 531 674 531 675 531 675 531 674 531 675 531 675 532 674 532 674 531 675 532 674 532 674 531 675 531 675 532 674 532 674 532 674 532 674 1633 674 1633 674 532 674 532 674 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9076 4453 679 1628 703 503 703 503 702 1607 700 506 699 507 699 507 699 507 699 1609 698 1610 698 1609 699 507 699 508 698 508 698 508 698 508 698 508 698 507 699 508 698 508 698 508 697 1609 698 1610 698 508 698 508 698 508 698 508 698 509 697 1610 697 508 698 1610 698 508 698 508 698 1610 697 509 697 19941 699 507 699 507 699 507 699 508 698 508 698 508 698 508 698 508 697 508 698 508 698 507 699 508 698 508 698 508 698 508 698 508 698 508 698 508 697 509 697 509 697 508 698 508 698 508 698 508 698 509 697 508 697 509 697 509 696 509 697 1635 673 533 673 1611 696 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 148 110377 9082 4422 707 499 706 500 704 1603 703 1606 701 505 700 507 699 506 700 507 699 506 700 1607 700 1608 700 1609 699 506 699 507 699 506 699 507 699 507 699 506 700 507 699 507 699 507 699 1608 699 1607 699 507 699 507 699 507 699 507 699 507 699 1609 699 507 699 1608 699 507 699 507 699 1609 699 507 699 19940 700 506 700 506 699 507 699 507 699 506 700 506 700 507 699 507 699 507 700 507 699 506 699 507 699 507 699 507 699 507 699 507 699 507 699 507 699 507 698 507 700 507 699 507 699 507 699 507 699 507 699 508 698 508 698 507 699 507 699 508 698 1610 699 508 698 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9081 4423 707 499 706 500 704 1604 702 1606 701 505 701 506 700 506 700 506 700 1608 700 1607 700 1609 699 506 700 506 700 506 700 506 700 506 700 507 699 506 700 506 700 507 699 507 699 1608 700 1608 699 507 699 507 699 507 699 507 699 507 699 1608 699 507 698 1609 698 507 699 507 699 1609 699 507 699 19938 699 506 700 506 700 507 699 506 699 506 700 506 699 506 700 507 699 507 699 507 700 506 699 507 699 507 699 507 699 507 699 507 698 507 699 507 699 507 699 507 699 507 699 507 699 507 699 507 700 507 699 507 698 507 699 507 699 1609 699 507 698 1609 699 1609 699 +# +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 9106 4398 731 499 706 500 705 502 702 504 701 505 701 505 701 1606 701 505 701 1607 701 505 701 506 700 1607 700 506 700 506 700 505 700 505 701 506 700 506 700 506 699 506 700 506 700 1607 700 506 700 506 700 506 700 505 701 506 700 506 700 1608 699 506 700 1608 699 506 700 506 700 1608 700 506 700 19941 701 1606 700 505 701 505 701 506 700 505 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 701 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 700 506 699 506 700 506 700 1608 700 1607 700 506 700 506 700 + diff --git a/documentation/AppManifests.md b/documentation/AppManifests.md index 7bc8d0a47..4fec9d22c 100644 --- a/documentation/AppManifests.md +++ b/documentation/AppManifests.md @@ -41,16 +41,71 @@ Only 2 parameters are mandatory: ***appid*** and ***apptype***, others are optio * **order**: Order of an application within its group when sorting entries in it. The lower the order is, the closer to the start of the list the item is placed. *Used for ordering startup hooks and menu entries.* * **sdk_headers**: List of C header files from this app's code to include in API definitions for external applications. + +#### Parameters for external applications + The following parameters are used only for [FAPs](./AppsOnSDCard.md): -* **sources**: list of file name masks, used for gathering sources within app folder. Default value of ["\*.c\*"] includes C and CPP source files. -* **fap_version**: string, 2 numbers in form of "x.y": application version to be embedded within .fap file. +* **sources**: list of strings, file name masks, used for gathering sources within app folder. Default value of `["*.c*"]` includes C and C++ source files. Application cannot use `"lib"` folder for their own source code, as it is reserved for **fap_private_libs**. +* **fap_version**: tuple, 2 numbers in form of (x,y): application version to be embedded within .fap file. Default value is (0,1), meaning version "0.1". * **fap_icon**: name of a .png file, 1-bit color depth, 10x10px, to be embedded within .fap file. * **fap_libs**: list of extra libraries to link application against. Provides access to extra functions that are not exported as a part of main firmware at expense of increased .fap file size and RAM consumption. * **fap_category**: string, may be empty. App subcategory, also works as path of FAP within apps folder in the file system. -* **fap_description**: string, may be empty. Short application descriotion. +* **fap_description**: string, may be empty. Short application description. * **fap_author**: string, may be empty. Application's author. * **fap_weburl**: string, may be empty. Application's homepage. +* **fap_icon_assets**: string. If present, defines a folder name to be used for gathering image assets for this application. These images will be preprocessed and built alongside the application. See [FAP assets](./AppsOnSDCard.md#fap-assets) for details. +* **fap_extbuild**: provides support for parts of application sources to be build by external tools. Contains a list of `ExtFile(path="file name", command="shell command")` definitions. **`fbt`** will run the specified command for each file in the list. +Note that commands are executed at the firmware root folder's root, and all intermediate files must be placed in a application's temporary build folder. For that, you can use pattern expansion by **`fbt`**: `${FAP_WORK_DIR}` will be replaced with the path to the application's temporary build folder, and `${FAP_SRC_DIR}` will be replaced with the path to the application's source folder. You can also use other variables defined internally by **`fbt`**. + +Example for building an app from Rust sources: + +```python + sources=["target/thumbv7em-none-eabihf/release/libhello_rust.a"], + fap_extbuild=( + ExtFile( + path="${FAP_WORK_DIR}/target/thumbv7em-none-eabihf/release/libhello_rust.a", + command="cargo build --release --verbose --target thumbv7em-none-eabihf --target-dir ${FAP_WORK_DIR}/target --manifest-path ${FAP_SRC_DIR}/Cargo.toml", + ), + ), +``` + +* **fap_private_libs**: list of additional libraries that are distributed as sources alongside the application. These libraries will be built as a part of the application build process. +Library sources must be placed in a subfolder of "`lib`" folder within the application's source folder. +Each library is defined as a call to `Lib()` function, accepting the following parameters: + + - **name**: name of library's folder. Required. + - **fap_include_paths**: list of library's relative paths to add to parent fap's include path list. Default value is `["."]` meaning library's source root. + - **sources**: list of filename masks to be used for gathering include files for this library. Default value is `["*.c*"]`. + - **cflags**: list of additional compiler flags to be used for building this library. Default value is `[]`. + - **cdefines**: list of additional preprocessor definitions to be used for building this library. Default value is `[]`. + - **cincludes**: list of additional include paths to be used for building this library. Can be used for providing external search paths for this library's code - for configuration headers. Default value is `[]`. + +Example for building an app with a private library: + +```python + fap_private_libs=[ + Lib( + name="mbedtls", + fap_include_paths=["include"], + sources=[ + "library/des.c", + "library/sha1.c", + "library/platform_util.c", + ], + cdefines=["MBEDTLS_ERROR_C"], + ), + Lib( + name="loclass", + cflags=["-Wno-error"], + ), + ], +``` + +For that snippet, **`fbt`** will build 2 libraries: one from sources in `lib/mbedtls` folder, and another from sources in `lib/loclass` folder. For `mbedtls` library, **`fbt`** will add `lib/mbedtls/include` to the list of include paths for the application and compile only the files specified in `sources` list. Additionally, **`fbt`** will enable `MBEDTLS_ERROR_C` preprocessor definition for `mbedtls` sources. +For `loclass` library, **`fbt`** will add `lib/loclass` to the list of include paths for the application and build all sources in that folder. Also **`fbt`** will disable treating compiler warnings as errors for `loclass` library specifically - that can be useful when compiling large 3rd-party codebases. + +Both libraries will be linked into the application. ## .fam file contents diff --git a/documentation/AppsOnSDCard.md b/documentation/AppsOnSDCard.md index 525821530..aff8314dc 100644 --- a/documentation/AppsOnSDCard.md +++ b/documentation/AppsOnSDCard.md @@ -2,7 +2,7 @@ [fbt](./fbt.md) has support for building applications as FAP files. FAP are essentially .elf executables with extra metadata and resources bundled in. -FAPs are built with `firmware_extapps` (or `plugin_dist`) **`fbt`** targets. +FAPs are built with `faps` **`fbt`** target. They can also be deployed to `dist` folder with `plugin_dist` **`fbt`** target. FAPs do not depend on being run on a specific firmware version. Compatibility is determined by the FAP's metadata, which includes the required [API version](#api-versioning). @@ -13,11 +13,22 @@ FAPs are created and developed the same way as internal applications that are pa To build your application as a FAP, just create a folder with your app's source code in `applications_user`, then write its code the way you'd do when creating a regular built-in application. Then configure its `application.fam` manifest — and set its *apptype* to FlipperAppType.EXTERNAL. See [Application Manifests](./AppManifests.md#application-definition) for more details. - * To build your application, run `./fbt firmware_{APPID}`, where APPID is your application's ID in its manifest. + * To build your application, run `./fbt fap_{APPID}`, where APPID is your application's ID in its manifest. * To build your app, then upload it over USB & run it on Flipper, use `./fbt launch_app APPSRC=applications/path/to/app`. This command is configured in default [VSCode profile](../.vscode/ReadMe.md) as "Launch App on Flipper" build action (Ctrl+Shift+B menu). * To build all FAPs, run `./fbt plugin_dist`. +## FAP assets + +FAPs can include static and animated images as private assets. They will be automatically compiled alongside application sources and can be referenced the same way as assets from the main firmware. + +To use that feature, put your images in a subfolder inside your application's folder, then reference that folder in your application's manifest in `fap_icon_assets` field. See [Application Manifests](./AppManifests.md#application-definition) for more details. + +To use these assets in your application, put `#include "{APPID}_icons.h"` in your application's source code, where `{APPID}` is the `appid` value field from your application's manifest. Then you can use all icons from your application's assets the same way as if they were a part of `assets_icons.h` of the main firmware. + +Images and animated icons must follow the same [naming convention](../assets/ReadMe.md#asset-naming-rules) as those from the main firmware. + + ## Debugging FAPs **`fbt`** includes a script for gdb-py to provide debugging support for FAPs, `debug/flipperapps.py`. It is loaded in default debugging configurations by **`fbt`** and stock VSCode configurations. @@ -53,13 +64,13 @@ App loader allocates memory for the application and copies it to RAM, processing Not all parts of firmware are available for external applications. A subset of available functions and variables is defined in "api_symbols.csv" file, which is a part of firmware target definition in `firmware/targets/` directory. -**`fbt`** uses semantic versioning for API versioning. Major version is incremented when there are breaking changes in the API, minor version is incremented when there are new features added. +**`fbt`** uses semantic versioning for API. Major version is incremented when there are breaking changes in the API, minor version is incremented when new features are added. Breaking changes include: - removal of a function or a global variable; - changing the signature of a function. -API versioning is mostly automated by **`fbt`**. When rebuilding the firmware, **`fbt`** checks if there are any changes in the API exposed by headers gathered from `SDK_HEADERS`. If there are, it stops the build, adjusts the API version and asks the user to go through the changes in .csv file. New entries are marked with "`?`" mark, and the user is supposed to change the mark to "`+`" for the entry to be exposed for FAPs, "`-`" for it to be unavailable. +API versioning is mostly automated by **`fbt`**. When rebuilding the firmware, **`fbt`** checks if there are any changes in the API exposed by headers gathered from `SDK_HEADERS`. If so, it stops the build, adjusts the API version and asks the user to go through the changes in .csv file. New entries are marked with "`?`" mark, and the user is supposed to change the mark to "`+`" for the entry to be exposed for FAPs, "`-`" for it to be unavailable. **`fbt`** will not allow building a firmware until all "`?`" entries are changed to "`+`" or "`-`". diff --git a/documentation/fbt.md b/documentation/fbt.md index 090ff78f0..e20d43177 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -59,10 +59,11 @@ To run cleanup (think of `make clean`) for specified targets, add `-c` option. ### Firmware targets -- `firmware_extapps` - build all plug-ins as separate .elf files - - `firmware_snake_game`, etc - build single plug-in as .elf by its name - - Check out `--extra-ext-apps` for force adding extra apps to external build - - `firmware_snake_game_list`, etc - generate source + assembler listing for app's .elf +- `faps` - build all external & plugin apps as [.faps](./AppsOnSDCard.md#fap-flipper-application-package). +- **`fbt`** also defines per-app targets. For example, for an app with `appid=snake_game` target names are: + - `fap_snake_game`, etc - build single app as .fap by its application ID. + - Check out [`--extra-ext-apps`](#command-line-parameters) for force adding extra apps to external build + - `fap_snake_game_list`, etc - generate source + assembler listing for app's .fap - `flash`, `firmware_flash` - flash current version to attached device with OpenOCD over ST-Link - `jflash` - flash current version to attached device with JFlash using J-Link probe. JFlash executable must be on your $PATH - `flash_blackmagic` - flash current version to attached device with Blackmagic probe @@ -83,9 +84,9 @@ To run cleanup (think of `make clean`) for specified targets, add `-c` option. ## Command-line parameters - `--options optionfile.py` (default value `fbt_options.py`) - load file with multiple configuration values -- `--with-updater` - enables updater-related targets and dependency tracking. Enabling this option introduces extra startup time costs, so use it when bundling update packages. _Explicily enabling this should no longer be required, **`fbt`** now has specific handling for updater-related targets_ - `--extra-int-apps=app1,app2,appN` - forces listed apps to be built as internal with `firmware` target - `--extra-ext-apps=app1,app2,appN` - forces listed apps to be built as external with `firmware_extapps` target +- `--proxy-env=VAR1,VAR2` - additional environment variables to expose to subprocesses spawned by `fbt`. By default, `fbt` sanitizes execution environment and doesn't forward all inherited environment variables. You can find list of variables that are always forwarded in `environ.scons` file. ## Configuration diff --git a/firmware.scons b/firmware.scons index 530634ef2..dd13b6b3d 100644 --- a/firmware.scons +++ b/firmware.scons @@ -1,5 +1,6 @@ Import("ENV", "fw_build_meta") +from SCons.Errors import UserError import itertools from fbt.util import ( @@ -96,6 +97,7 @@ if not env["VERBOSE"]: SDKSYM_GENERATOR_COMSTR="\tSDKSYM\t${TARGET}", APPMETA_COMSTR="\tAPPMETA\t${TARGET}", APPMETAEMBED_COMSTR="\tFAP\t${TARGET}", + APPCHECK_COMSTR="\tAPPCHK\t${SOURCE}", ) @@ -163,13 +165,25 @@ apps_c = fwenv.ApplicationsC( # Adding dependency on manifest files so apps.c is rebuilt when any manifest is changed for app_dir, _ in env["APPDIRS"]: app_dir_node = env.Dir("#").Dir(app_dir) - fwenv.Depends(apps_c, fwenv.GlobRecursive("*.fam", app_dir_node)) + fwenv.Depends(apps_c, app_dir_node.glob("*/application.fam")) + +# Sanity check - certain external apps are using features that are not available in base firmware +if advanced_faps := list( + filter( + lambda app: app.fap_extbuild or app.fap_private_libs or app.fap_icon_assets, + fwenv["APPBUILD"].get_builtin_apps(), + ) +): + raise UserError( + "An Application that is using fap-specific features cannot be built into base firmware." + f" Offending app(s): {', '.join(app.appid for app in advanced_faps)}" + ) sources = [apps_c] # Gather sources only from app folders in current configuration sources.extend( itertools.chain.from_iterable( - fwenv.GlobRecursive(source_type, appdir.relpath) + fwenv.GlobRecursive(source_type, appdir.relpath, exclude="lib") for appdir, source_type in fwenv["APPBUILD"].get_builtin_app_folders() ) ) @@ -258,18 +272,18 @@ fw_artifacts = fwenv["FW_ARTIFACTS"] = [ fwenv["FW_VERSION_JSON"], ] + +fwcdb = fwenv.CompilationDatabase() +# without filtering, both updater & firmware commands would be generated in same file +fwenv.Replace(COMPILATIONDB_PATH_FILTER=fwenv.subst("*${FW_FLAVOR}*")) +AlwaysBuild(fwcdb) +Precious(fwcdb) +NoClean(fwcdb) +Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb) + # If current configuration was explicitly requested, generate compilation database # and link its directory as build/latest if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS): - fwcdb = fwenv.CompilationDatabase() - # without filtering, both updater & firmware commands would be generated - fwenv.Replace(COMPILATIONDB_PATH_FILTER=fwenv.subst("*${FW_FLAVOR}*")) - AlwaysBuild(fwcdb) - Precious(fwcdb) - NoClean(fwcdb) - Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb) - AlwaysBuild(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb) - Alias(fwcdb, "") fw_artifacts.append(fwcdb) # Adding as a phony target, so folder link is updated even if elf didn't change diff --git a/firmware/targets/f7/Src/update.c b/firmware/targets/f7/Src/update.c index 36204829e..722a7b616 100644 --- a/firmware/targets/f7/Src/update.c +++ b/firmware/targets/f7/Src/update.c @@ -54,20 +54,21 @@ static bool flipper_update_init() { return flipper_update_mount_sd(); } -static bool flipper_update_load_stage(const string_t work_dir, UpdateManifest* manifest) { +static bool flipper_update_load_stage(const FuriString* work_dir, UpdateManifest* manifest) { FIL file; FILINFO stat; - string_t loader_img_path; - string_init_set(loader_img_path, work_dir); - path_append(loader_img_path, string_get_cstr(manifest->staged_loader_file)); + FuriString* loader_img_path; + loader_img_path = furi_string_alloc_set(work_dir); + path_append(loader_img_path, furi_string_get_cstr(manifest->staged_loader_file)); - if((f_stat(string_get_cstr(loader_img_path), &stat) != FR_OK) || - (f_open(&file, string_get_cstr(loader_img_path), FA_OPEN_EXISTING | FA_READ) != FR_OK)) { - string_clear(loader_img_path); + if((f_stat(furi_string_get_cstr(loader_img_path), &stat) != FR_OK) || + (f_open(&file, furi_string_get_cstr(loader_img_path), FA_OPEN_EXISTING | FA_READ) != + FR_OK)) { + furi_string_free(loader_img_path); return false; } - string_clear(loader_img_path); + furi_string_free(loader_img_path); void* img = malloc(stat.fsize); uint32_t bytes_read = 0; @@ -110,13 +111,13 @@ static bool flipper_update_load_stage(const string_t work_dir, UpdateManifest* m return false; } -static bool flipper_update_get_manifest_path(string_t out_path) { +static bool flipper_update_get_manifest_path(FuriString* out_path) { FIL file; FILINFO stat; uint16_t size_read = 0; char manifest_name_buf[UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN] = {0}; - string_reset(out_path); + furi_string_reset(out_path); CHECK_FRESULT(f_stat(UPDATE_POINTER_FILE_PATH, &stat)); CHECK_FRESULT(f_open(&file, UPDATE_POINTER_FILE_PATH, FA_OPEN_EXISTING | FA_READ)); do { @@ -128,19 +129,19 @@ static bool flipper_update_get_manifest_path(string_t out_path) { if((size_read == 0) || (size_read == UPDATE_OPERATION_MAX_MANIFEST_PATH_LEN)) { break; } - string_set_str(out_path, manifest_name_buf); - string_right(out_path, strlen(STORAGE_EXT_PATH_PREFIX)); + furi_string_set(out_path, manifest_name_buf); + furi_string_right(out_path, strlen(STORAGE_EXT_PATH_PREFIX)); } while(0); f_close(&file); - return !string_empty_p(out_path); + return !furi_string_empty(out_path); } -static UpdateManifest* flipper_update_process_manifest(const string_t manifest_path) { +static UpdateManifest* flipper_update_process_manifest(const FuriString* manifest_path) { FIL file; FILINFO stat; - CHECK_FRESULT(f_stat(string_get_cstr(manifest_path), &stat)); - CHECK_FRESULT(f_open(&file, string_get_cstr(manifest_path), FA_OPEN_EXISTING | FA_READ)); + CHECK_FRESULT(f_stat(furi_string_get_cstr(manifest_path), &stat)); + CHECK_FRESULT(f_open(&file, furi_string_get_cstr(manifest_path), FA_OPEN_EXISTING | FA_READ)); uint8_t* manifest_data = malloc(stat.fsize); uint32_t bytes_read = 0; @@ -177,9 +178,9 @@ void flipper_boot_update_exec() { return; } - string_t work_dir, manifest_path; - string_init(work_dir); - string_init(manifest_path); + FuriString* work_dir = furi_string_alloc(); + FuriString* manifest_path = furi_string_alloc(); + do { if(!flipper_update_get_manifest_path(manifest_path)) { break; @@ -190,12 +191,12 @@ void flipper_boot_update_exec() { break; } - path_extract_dirname(string_get_cstr(manifest_path), work_dir); + path_extract_dirname(furi_string_get_cstr(manifest_path), work_dir); if(!flipper_update_load_stage(work_dir, manifest)) { update_manifest_free(manifest); } } while(false); - string_clear(manifest_path); - string_clear(work_dir); + furi_string_free(manifest_path); + furi_string_free(work_dir); free(pfs); } diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index c18780acb..c9e2371f4 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,1.12,, +Version,+,2.2,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -42,6 +42,7 @@ Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_types.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_idle_timer.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_interrupt.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_os.h,, +Header,+,firmware/targets/f7/furi_hal/furi_hal_pwm.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_resources.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_spi_config.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_spi_types.h,, @@ -439,12 +440,12 @@ Function,-,arc4random,__uint32_t, Function,-,arc4random_buf,void,"void*, size_t" Function,-,arc4random_uniform,__uint32_t,__uint32_t Function,+,args_char_to_hex,_Bool,"char, char, uint8_t*" -Function,+,args_get_first_word_length,size_t,string_t -Function,+,args_length,size_t,string_t -Function,+,args_read_hex_bytes,_Bool,"string_t, uint8_t*, size_t" -Function,+,args_read_int_and_trim,_Bool,"string_t, int*" -Function,+,args_read_probably_quoted_string_and_trim,_Bool,"string_t, string_t" -Function,+,args_read_string_and_trim,_Bool,"string_t, string_t" +Function,+,args_get_first_word_length,size_t,FuriString* +Function,+,args_length,size_t,FuriString* +Function,+,args_read_hex_bytes,_Bool,"FuriString*, uint8_t*, size_t" +Function,+,args_read_int_and_trim,_Bool,"FuriString*, int*" +Function,+,args_read_probably_quoted_string_and_trim,_Bool,"FuriString*, FuriString*" +Function,+,args_read_string_and_trim,_Bool,"FuriString*, FuriString*" Function,-,asin,double,double Function,-,asinf,float,float Function,-,asinh,double,double @@ -641,7 +642,7 @@ Function,+,dialog_ex_set_result_callback,void,"DialogEx*, DialogExResultCallback Function,+,dialog_ex_set_right_button_text,void,"DialogEx*, const char*" Function,+,dialog_ex_set_text,void,"DialogEx*, const char*, uint8_t, uint8_t, Align, Align" Function,+,dialog_file_browser_set_basic_options,void,"DialogsFileBrowserOptions*, const char*, const Icon*" -Function,+,dialog_file_browser_show,_Bool,"DialogsApp*, string_ptr, string_ptr, const DialogsFileBrowserOptions*" +Function,+,dialog_file_browser_show,_Bool,"DialogsApp*, FuriString*, FuriString*, const DialogsFileBrowserOptions*" Function,+,dialog_message_alloc,DialogMessage*, Function,+,dialog_message_free,void,DialogMessage* Function,+,dialog_message_set_buttons,void,"DialogMessage*, const char*, const char*, const char*" @@ -664,7 +665,7 @@ Function,+,dir_walk_close,void,DirWalk* Function,+,dir_walk_free,void,DirWalk* Function,+,dir_walk_get_error,FS_Error,DirWalk* Function,+,dir_walk_open,_Bool,"DirWalk*, const char*" -Function,+,dir_walk_read,DirWalkResult,"DirWalk*, string_t, FileInfo*" +Function,+,dir_walk_read,DirWalkResult,"DirWalk*, FuriString*, FileInfo*" Function,+,dir_walk_set_filter_cb,void,"DirWalk*, DirWalkFilterCb, void*" Function,+,dir_walk_set_recursive,void,"DirWalk*, _Bool" Function,-,div,div_t,"int, int" @@ -697,7 +698,7 @@ Function,+,elements_scrollbar,void,"Canvas*, uint16_t, uint16_t" Function,+,elements_scrollbar_pos,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint16_t, uint16_t" Function,+,elements_slightly_rounded_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t" Function,+,elements_slightly_rounded_frame,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t" -Function,+,elements_string_fit_width,void,"Canvas*, string_t, uint8_t" +Function,+,elements_string_fit_width,void,"Canvas*, FuriString*, uint8_t" Function,+,elements_text_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, Align, Align, const char*, _Bool" Function,+,empty_screen_alloc,EmptyScreen*, Function,+,empty_screen_free,void,EmptyScreen* @@ -745,22 +746,22 @@ Function,-,fgetc_unlocked,int,FILE* Function,-,fgetpos,int,"FILE*, fpos_t*" Function,-,fgets,char*,"char*, int, FILE*" Function,-,fgets_unlocked,char*,"char*, int, FILE*" -Function,+,file_browser_alloc,FileBrowser*,string_ptr +Function,+,file_browser_alloc,FileBrowser*,FuriString* Function,+,file_browser_configure,void,"FileBrowser*, const char*, _Bool, const Icon*, _Bool" Function,+,file_browser_free,void,FileBrowser* Function,+,file_browser_get_view,View*,FileBrowser* Function,+,file_browser_set_callback,void,"FileBrowser*, FileBrowserCallback, void*" Function,+,file_browser_set_item_callback,void,"FileBrowser*, FileBrowserLoadItemCallback, void*" -Function,+,file_browser_start,void,"FileBrowser*, string_t" +Function,+,file_browser_start,void,"FileBrowser*, FuriString*" Function,+,file_browser_stop,void,FileBrowser* -Function,+,file_browser_worker_alloc,BrowserWorker*,"string_t, const char*, _Bool" -Function,+,file_browser_worker_folder_enter,void,"BrowserWorker*, string_t, int32_t" +Function,+,file_browser_worker_alloc,BrowserWorker*,"FuriString*, const char*, _Bool" +Function,+,file_browser_worker_folder_enter,void,"BrowserWorker*, FuriString*, int32_t" Function,+,file_browser_worker_folder_exit,void,BrowserWorker* Function,+,file_browser_worker_folder_refresh,void,"BrowserWorker*, int32_t" Function,+,file_browser_worker_free,void,BrowserWorker* Function,+,file_browser_worker_load,void,"BrowserWorker*, uint32_t, uint32_t" Function,+,file_browser_worker_set_callback_context,void,"BrowserWorker*, void*" -Function,+,file_browser_worker_set_config,void,"BrowserWorker*, string_t, const char*, _Bool" +Function,+,file_browser_worker_set_config,void,"BrowserWorker*, FuriString*, const char*, _Bool" Function,+,file_browser_worker_set_folder_callback,void,"BrowserWorker*, BrowserWorkerFolderOpenCallback" Function,+,file_browser_worker_set_item_callback,void,"BrowserWorker*, BrowserWorkerListItemCallback" Function,+,file_browser_worker_set_list_callback,void,"BrowserWorker*, BrowserWorkerListLoadCallback" @@ -805,17 +806,17 @@ Function,+,flipper_format_insert_or_update_bool,_Bool,"FlipperFormat*, const cha Function,+,flipper_format_insert_or_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t" Function,+,flipper_format_insert_or_update_hex,_Bool,"FlipperFormat*, const char*, const uint8_t*, const uint16_t" Function,+,flipper_format_insert_or_update_int32,_Bool,"FlipperFormat*, const char*, const int32_t*, const uint16_t" -Function,+,flipper_format_insert_or_update_string,_Bool,"FlipperFormat*, const char*, string_t" +Function,+,flipper_format_insert_or_update_string,_Bool,"FlipperFormat*, const char*, FuriString*" Function,+,flipper_format_insert_or_update_string_cstr,_Bool,"FlipperFormat*, const char*, const char*" Function,+,flipper_format_insert_or_update_uint32,_Bool,"FlipperFormat*, const char*, const uint32_t*, const uint16_t" Function,+,flipper_format_key_exist,_Bool,"FlipperFormat*, const char*" Function,+,flipper_format_read_bool,_Bool,"FlipperFormat*, const char*, _Bool*, const uint16_t" Function,+,flipper_format_read_float,_Bool,"FlipperFormat*, const char*, float*, const uint16_t" -Function,+,flipper_format_read_header,_Bool,"FlipperFormat*, string_t, uint32_t*" +Function,+,flipper_format_read_header,_Bool,"FlipperFormat*, FuriString*, uint32_t*" Function,+,flipper_format_read_hex,_Bool,"FlipperFormat*, const char*, uint8_t*, const uint16_t" Function,+,flipper_format_read_hex_uint64,_Bool,"FlipperFormat*, const char*, uint64_t*, const uint16_t" Function,+,flipper_format_read_int32,_Bool,"FlipperFormat*, const char*, int32_t*, const uint16_t" -Function,+,flipper_format_read_string,_Bool,"FlipperFormat*, const char*, string_t" +Function,+,flipper_format_read_string,_Bool,"FlipperFormat*, const char*, FuriString*" Function,+,flipper_format_read_uint32,_Bool,"FlipperFormat*, const char*, uint32_t*, const uint16_t" Function,+,flipper_format_rewind,_Bool,FlipperFormat* Function,+,flipper_format_seek_to_end,_Bool,FlipperFormat* @@ -825,19 +826,19 @@ Function,+,flipper_format_update_bool,_Bool,"FlipperFormat*, const char*, const Function,+,flipper_format_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t" Function,+,flipper_format_update_hex,_Bool,"FlipperFormat*, const char*, const uint8_t*, const uint16_t" Function,+,flipper_format_update_int32,_Bool,"FlipperFormat*, const char*, const int32_t*, const uint16_t" -Function,+,flipper_format_update_string,_Bool,"FlipperFormat*, const char*, string_t" +Function,+,flipper_format_update_string,_Bool,"FlipperFormat*, const char*, FuriString*" Function,+,flipper_format_update_string_cstr,_Bool,"FlipperFormat*, const char*, const char*" Function,+,flipper_format_update_uint32,_Bool,"FlipperFormat*, const char*, const uint32_t*, const uint16_t" Function,+,flipper_format_write_bool,_Bool,"FlipperFormat*, const char*, const _Bool*, const uint16_t" -Function,+,flipper_format_write_comment,_Bool,"FlipperFormat*, string_t" +Function,+,flipper_format_write_comment,_Bool,"FlipperFormat*, FuriString*" Function,+,flipper_format_write_comment_cstr,_Bool,"FlipperFormat*, const char*" Function,+,flipper_format_write_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t" -Function,+,flipper_format_write_header,_Bool,"FlipperFormat*, string_t, const uint32_t" +Function,+,flipper_format_write_header,_Bool,"FlipperFormat*, FuriString*, const uint32_t" Function,+,flipper_format_write_header_cstr,_Bool,"FlipperFormat*, const char*, const uint32_t" Function,+,flipper_format_write_hex,_Bool,"FlipperFormat*, const char*, const uint8_t*, const uint16_t" Function,+,flipper_format_write_hex_uint64,_Bool,"FlipperFormat*, const char*, const uint64_t*, const uint16_t" Function,+,flipper_format_write_int32,_Bool,"FlipperFormat*, const char*, const int32_t*, const uint16_t" -Function,+,flipper_format_write_string,_Bool,"FlipperFormat*, const char*, string_t" +Function,+,flipper_format_write_string,_Bool,"FlipperFormat*, const char*, FuriString*" Function,+,flipper_format_write_string_cstr,_Bool,"FlipperFormat*, const char*, const char*" Function,+,flipper_format_write_uint32,_Bool,"FlipperFormat*, const char*, const uint32_t*, const uint16_t" Function,-,flockfile,void,FILE* @@ -898,7 +899,7 @@ Function,+,furi_event_flag_wait,uint32_t,"FuriEventFlag*, uint32_t, uint32_t, ui Function,+,furi_get_tick,uint32_t, Function,+,furi_hal_bt_change_app,_Bool,"FuriHalBtProfile, GapEventCallback, void*" Function,+,furi_hal_bt_clear_white_list,_Bool, -Function,+,furi_hal_bt_dump_state,void,string_t +Function,+,furi_hal_bt_dump_state,void,FuriString* Function,+,furi_hal_bt_ensure_c2_mode,_Bool,BleGlueC2Mode Function,+,furi_hal_bt_get_key_storage_buff,void,"uint8_t**, uint16_t*" Function,+,furi_hal_bt_get_radio_stack,FuriHalBtStack, @@ -954,6 +955,8 @@ Function,+,furi_hal_cdc_set_callbacks,void,"uint8_t, CdcCallbacks*, void*" Function,+,furi_hal_clock_deinit_early,void, Function,-,furi_hal_clock_init,void, Function,-,furi_hal_clock_init_early,void, +Function,+,furi_hal_clock_mco_disable,void, +Function,+,furi_hal_clock_mco_enable,void,"FuriHalClockMcoSourceId, FuriHalClockMcoDivisorId" Function,-,furi_hal_clock_resume_tick,void, Function,-,furi_hal_clock_suspend_tick,void, Function,-,furi_hal_clock_switch_to_hsi,void, @@ -1150,6 +1153,9 @@ Function,+,furi_hal_power_sleep,void, Function,+,furi_hal_power_sleep_available,_Bool, Function,+,furi_hal_power_suppress_charge_enter,void, Function,+,furi_hal_power_suppress_charge_exit,void, +Function,+,furi_hal_pwm_set_params,void,"FuriHalPwmOutputId, uint32_t, uint8_t" +Function,+,furi_hal_pwm_start,void,"FuriHalPwmOutputId, uint32_t, uint8_t" +Function,+,furi_hal_pwm_stop,void,FuriHalPwmOutputId Function,+,furi_hal_random_fill_buf,void,"uint8_t*, uint32_t" Function,+,furi_hal_random_get,uint32_t, Function,+,furi_hal_region_get,const FuriHalRegion*, @@ -1336,6 +1342,70 @@ Function,+,furi_semaphore_alloc,FuriSemaphore*,"uint32_t, uint32_t" Function,+,furi_semaphore_free,void,FuriSemaphore* Function,+,furi_semaphore_get_count,uint32_t,FuriSemaphore* Function,+,furi_semaphore_release,FuriStatus,FuriSemaphore* +Function,+,furi_stream_buffer_alloc,FuriStreamBuffer*,"size_t, size_t" +Function,+,furi_stream_buffer_bytes_available,size_t,FuriStreamBuffer* +Function,+,furi_stream_buffer_free,void,FuriStreamBuffer* +Function,+,furi_stream_buffer_is_empty,_Bool,FuriStreamBuffer* +Function,+,furi_stream_buffer_is_full,_Bool,FuriStreamBuffer* +Function,+,furi_stream_buffer_receive,size_t,"FuriStreamBuffer*, void*, size_t, uint32_t" +Function,+,furi_stream_buffer_reset,FuriStatus,FuriStreamBuffer* +Function,+,furi_stream_buffer_send,size_t,"FuriStreamBuffer*, const void*, size_t, uint32_t" +Function,+,furi_stream_buffer_spaces_available,size_t,FuriStreamBuffer* +Function,+,furi_stream_set_trigger_level,_Bool,"FuriStreamBuffer*, size_t" +Function,+,furi_string_alloc,FuriString*, +Function,+,furi_string_alloc_move,FuriString*,FuriString* +Function,+,furi_string_alloc_printf,FuriString*,"const char[], ..." +Function,+,furi_string_alloc_set,FuriString*,const FuriString* +Function,+,furi_string_alloc_set_str,FuriString*,const char[] +Function,+,furi_string_alloc_vprintf,FuriString*,"const char[], va_list" +Function,+,furi_string_cat,void,"FuriString*, const FuriString*" +Function,+,furi_string_cat_printf,int,"FuriString*, const char[], ..." +Function,+,furi_string_cat_str,void,"FuriString*, const char[]" +Function,+,furi_string_cat_vprintf,int,"FuriString*, const char[], va_list" +Function,+,furi_string_cmp,int,"const FuriString*, const FuriString*" +Function,+,furi_string_cmp_str,int,"const FuriString*, const char[]" +Function,+,furi_string_cmpi,int,"const FuriString*, const FuriString*" +Function,+,furi_string_cmpi_str,int,"const FuriString*, const char[]" +Function,+,furi_string_empty,_Bool,const FuriString* +Function,+,furi_string_end_with,_Bool,"const FuriString*, const FuriString*" +Function,+,furi_string_end_with_str,_Bool,"const FuriString*, const char[]" +Function,+,furi_string_equal,_Bool,"const FuriString*, const FuriString*" +Function,+,furi_string_equal_str,_Bool,"const FuriString*, const char[]" +Function,+,furi_string_free,void,FuriString* +Function,+,furi_string_get_char,char,"const FuriString*, size_t" +Function,+,furi_string_get_cstr,const char*,const FuriString* +Function,+,furi_string_hash,size_t,const FuriString* +Function,+,furi_string_left,void,"FuriString*, size_t" +Function,+,furi_string_mid,void,"FuriString*, size_t, size_t" +Function,+,furi_string_move,void,"FuriString*, FuriString*" +Function,+,furi_string_printf,int,"FuriString*, const char[], ..." +Function,+,furi_string_push_back,void,"FuriString*, char" +Function,+,furi_string_replace,size_t,"FuriString*, FuriString*, FuriString*, size_t" +Function,+,furi_string_replace_all,void,"FuriString*, const FuriString*, const FuriString*" +Function,+,furi_string_replace_all_str,void,"FuriString*, const char[], const char[]" +Function,+,furi_string_replace_at,void,"FuriString*, size_t, size_t, const char[]" +Function,+,furi_string_replace_str,size_t,"FuriString*, const char[], const char[], size_t" +Function,+,furi_string_reserve,void,"FuriString*, size_t" +Function,+,furi_string_reset,void,FuriString* +Function,+,furi_string_right,void,"FuriString*, size_t" +Function,+,furi_string_search,size_t,"const FuriString*, const FuriString*, size_t" +Function,+,furi_string_search_char,size_t,"const FuriString*, char, size_t" +Function,+,furi_string_search_rchar,size_t,"const FuriString*, char, size_t" +Function,+,furi_string_search_str,size_t,"const FuriString*, const char[], size_t" +Function,+,furi_string_set,void,"FuriString*, FuriString*" +Function,+,furi_string_set_char,void,"FuriString*, size_t, const char" +Function,+,furi_string_set_n,void,"FuriString*, const FuriString*, size_t, size_t" +Function,+,furi_string_set_str,void,"FuriString*, const char[]" +Function,+,furi_string_set_strn,void,"FuriString*, const char[], size_t" +Function,+,furi_string_size,size_t,const FuriString* +Function,+,furi_string_start_with,_Bool,"const FuriString*, const FuriString*" +Function,+,furi_string_start_with_str,_Bool,"const FuriString*, const char[]" +Function,+,furi_string_swap,void,"FuriString*, FuriString*" +Function,+,furi_string_trim,void,"FuriString*, const char[]" +Function,+,furi_string_utf8_decode,void,"char, FuriStringUTF8State*, FuriStringUnicodeValue*" +Function,+,furi_string_utf8_length,size_t,FuriString* +Function,+,furi_string_utf8_push,void,"FuriString*, FuriStringUnicodeValue" +Function,+,furi_string_vprintf,int,"FuriString*, const char[], va_list" Function,+,furi_thread_alloc,FuriThread*, Function,+,furi_thread_catch,void, Function,-,furi_thread_disable_heap_trace,void,FuriThread* @@ -1678,14 +1748,14 @@ Function,+,onewire_slave_set_result_callback,void,"OneWireSlave*, OneWireSlaveRe Function,+,onewire_slave_start,void,OneWireSlave* Function,+,onewire_slave_stop,void,OneWireSlave* Function,-,open_memstream,FILE*,"char**, size_t*" -Function,+,path_append,void,"string_t, const char*" -Function,+,path_concat,void,"const char*, const char*, string_t" +Function,+,path_append,void,"FuriString*, const char*" +Function,+,path_concat,void,"const char*, const char*, FuriString*" Function,+,path_contains_only_ascii,_Bool,const char* -Function,+,path_extract_basename,void,"const char*, string_t" -Function,+,path_extract_dirname,void,"const char*, string_t" -Function,+,path_extract_extension,void,"string_t, char*, size_t" -Function,+,path_extract_filename,void,"string_t, string_t, _Bool" -Function,+,path_extract_filename_no_ext,void,"const char*, string_t" +Function,+,path_extract_basename,void,"const char*, FuriString*" +Function,+,path_extract_dirname,void,"const char*, FuriString*" +Function,+,path_extract_extension,void,"FuriString*, char*, size_t" +Function,+,path_extract_filename,void,"FuriString*, FuriString*, _Bool" +Function,+,path_extract_filename_no_ext,void,"const char*, FuriString*" Function,-,pcTaskGetName,char*,TaskHandle_t Function,-,pcTimerGetName,const char*,TimerHandle_t Function,-,pclose,int,FILE* @@ -1739,8 +1809,8 @@ Function,+,protocol_dict_get_name,const char*,"ProtocolDict*, size_t" Function,+,protocol_dict_get_protocol_by_name,ProtocolId,"ProtocolDict*, const char*" Function,+,protocol_dict_get_validate_count,uint32_t,"ProtocolDict*, size_t" Function,+,protocol_dict_get_write_data,_Bool,"ProtocolDict*, size_t, void*" -Function,+,protocol_dict_render_brief_data,void,"ProtocolDict*, string_t, size_t" -Function,+,protocol_dict_render_data,void,"ProtocolDict*, string_t, size_t" +Function,+,protocol_dict_render_brief_data,void,"ProtocolDict*, FuriString*, size_t" +Function,+,protocol_dict_render_data,void,"ProtocolDict*, FuriString*, size_t" Function,+,protocol_dict_set_data,void,"ProtocolDict*, size_t, const uint8_t*, size_t" Function,-,pselect,int,"int, fd_set*, fd_set*, fd_set*, const timespec*, const sigset_t*" Function,-,putc,int,"int, FILE*" @@ -2067,7 +2137,7 @@ Function,-,storage_file_sync,_Bool,File* Function,+,storage_file_tell,uint64_t,File* Function,+,storage_file_truncate,_Bool,File* Function,+,storage_file_write,uint16_t,"File*, const void*, uint16_t" -Function,+,storage_get_next_filename,void,"Storage*, const char*, const char*, const char*, string_t, uint8_t" +Function,+,storage_get_next_filename,void,"Storage*, const char*, const char*, const char*, FuriString*, uint8_t" Function,+,storage_get_pubsub,FuriPubSub*,Storage* Function,+,storage_int_backup,FS_Error,"Storage*, const char*" Function,+,storage_int_restore,FS_Error,"Storage*, const char*, Storage_name_converter" @@ -2100,7 +2170,7 @@ Function,+,stream_delete_and_insert,_Bool,"Stream*, size_t, StreamWriteCB, const Function,+,stream_delete_and_insert_char,_Bool,"Stream*, size_t, char" Function,+,stream_delete_and_insert_cstring,_Bool,"Stream*, size_t, const char*" Function,+,stream_delete_and_insert_format,_Bool,"Stream*, size_t, const char*, ..." -Function,+,stream_delete_and_insert_string,_Bool,"Stream*, size_t, string_t" +Function,+,stream_delete_and_insert_string,_Bool,"Stream*, size_t, FuriString*" Function,+,stream_delete_and_insert_vaformat,_Bool,"Stream*, size_t, const char*, va_list" Function,+,stream_dump_data,void,Stream* Function,+,stream_eof,_Bool,Stream* @@ -2109,11 +2179,11 @@ Function,+,stream_insert,_Bool,"Stream*, const uint8_t*, size_t" Function,+,stream_insert_char,_Bool,"Stream*, char" Function,+,stream_insert_cstring,_Bool,"Stream*, const char*" Function,+,stream_insert_format,_Bool,"Stream*, const char*, ..." -Function,+,stream_insert_string,_Bool,"Stream*, string_t" +Function,+,stream_insert_string,_Bool,"Stream*, FuriString*" Function,+,stream_insert_vaformat,_Bool,"Stream*, const char*, va_list" Function,+,stream_load_from_file,size_t,"Stream*, Storage*, const char*" Function,+,stream_read,size_t,"Stream*, uint8_t*, size_t" -Function,+,stream_read_line,_Bool,"Stream*, string_t" +Function,+,stream_read_line,_Bool,"Stream*, FuriString*" Function,+,stream_rewind,_Bool,Stream* Function,+,stream_save_to_file,size_t,"Stream*, Storage*, const char*, FS_OpenMode" Function,+,stream_seek,_Bool,"Stream*, int32_t, StreamOffset" @@ -2124,7 +2194,7 @@ Function,+,stream_write,size_t,"Stream*, const uint8_t*, size_t" Function,+,stream_write_char,size_t,"Stream*, char" Function,+,stream_write_cstring,size_t,"Stream*, const char*" Function,+,stream_write_format,size_t,"Stream*, const char*, ..." -Function,+,stream_write_string,size_t,"Stream*, string_t" +Function,+,stream_write_string,size_t,"Stream*, FuriString*" Function,+,stream_write_vaformat,size_t,"Stream*, const char*, va_list" Function,-,strerror,char*,int Function,-,strerror_l,char*,"int, locale_t" @@ -2185,14 +2255,14 @@ Function,-,subghz_keystore_raw_get_data,_Bool,"const char*, size_t, uint8_t*, si Function,-,subghz_keystore_save,_Bool,"SubGhzKeystore*, const char*, uint8_t*" Function,-,subghz_protocol_decoder_base_deserialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*" Function,-,subghz_protocol_decoder_base_get_hash_data,uint8_t,SubGhzProtocolDecoderBase* -Function,-,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, string_t" +Function,-,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, FuriString*" Function,+,subghz_protocol_decoder_base_serialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*, SubGhzPresetDefinition*" Function,-,subghz_protocol_decoder_base_set_decoder_callback,void,"SubGhzProtocolDecoderBase*, SubGhzProtocolDecoderBaseRxCallback, void*" Function,+,subghz_protocol_decoder_raw_alloc,void*,SubGhzEnvironment* Function,+,subghz_protocol_decoder_raw_deserialize,_Bool,"void*, FlipperFormat*" Function,+,subghz_protocol_decoder_raw_feed,void,"void*, _Bool, uint32_t" Function,+,subghz_protocol_decoder_raw_free,void,void* -Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, string_t" +Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, FuriString*" Function,+,subghz_protocol_decoder_raw_reset,void,void* Function,+,subghz_protocol_encoder_raw_alloc,void*,SubGhzEnvironment* Function,+,subghz_protocol_encoder_raw_deserialize,_Bool,"void*, FlipperFormat*" @@ -2263,6 +2333,7 @@ Function,+,tar_archive_get_entries_count,int32_t,TarArchive* Function,+,tar_archive_open,_Bool,"TarArchive*, const char*, TarOpenMode" Function,+,tar_archive_set_file_callback,void,"TarArchive*, tar_unpack_file_cb, void*" Function,+,tar_archive_store_data,_Bool,"TarArchive*, const char*, const uint8_t*, const int32_t" +Function,+,tar_archive_unpack_file,_Bool,"TarArchive*, const char*, const char*" Function,+,tar_archive_unpack_to,_Bool,"TarArchive*, const char*, Storage_name_converter" Function,-,tempnam,char*,"const char*, const char*" Function,+,text_box_alloc,TextBox*, @@ -2382,7 +2453,7 @@ Function,-,vTimerSetReloadMode,void,"TimerHandle_t, const UBaseType_t" Function,-,vTimerSetTimerID,void,"TimerHandle_t, void*" Function,-,vTimerSetTimerNumber,void,"TimerHandle_t, UBaseType_t" Function,+,validator_is_file_alloc_init,ValidatorIsFile*,"const char*, const char*, const char*" -Function,+,validator_is_file_callback,_Bool,"const char*, string_t, void*" +Function,+,validator_is_file_callback,_Bool,"const char*, FuriString*, void*" Function,+,validator_is_file_free,void,ValidatorIsFile* Function,+,variable_item_get_context,void*,VariableItem* Function,+,variable_item_get_current_value_index,uint8_t,VariableItem* @@ -2632,6 +2703,8 @@ Variable,+,I_Lock_7x8,const Icon, Variable,+,I_Lock_8x8,const Icon, Variable,+,I_MHz_25x11,const Icon, Variable,+,I_Medium_chip_22x21,const Icon, +Variable,+,I_Modern_reader_18x34,const Icon, +Variable,+,I_Move_flipper_26x39,const Icon, Variable,+,I_Mute_25x27,const Icon, Variable,+,I_Mute_hvr_25x27,const Icon, Variable,+,I_NFC_manual_60x50,const Icon, @@ -2659,12 +2732,17 @@ Variable,+,I_RFIDDolphinReceive_97x61,const Icon, Variable,+,I_RFIDDolphinSend_97x61,const Icon, Variable,+,I_RFIDDolphinSuccess_108x57,const Icon, Variable,+,I_Reader_detect_43x40,const Icon, +Variable,+,I_Release_arrow_18x15,const Icon, Variable,+,I_Restoring_38x32,const Icon, Variable,+,I_Right_mouse_icon_9x9,const Icon, Variable,+,I_SDQuestion_35x43,const Icon, Variable,+,I_SDcardFail_11x8,const Icon, Variable,+,I_SDcardMounted_11x8,const Icon, Variable,+,I_Scanning_123x52,const Icon, +Variable,+,I_SmallArrowDown_3x5,const Icon, +Variable,+,I_SmallArrowDown_4x7,const Icon, +Variable,+,I_SmallArrowUp_3x5,const Icon, +Variable,+,I_SmallArrowUp_4x7,const Icon, Variable,+,I_Smile_18x18,const Icon, Variable,+,I_Space_65x18,const Icon, Variable,+,I_Tap_reader_36x38,const Icon, diff --git a/firmware/targets/f7/ble_glue/dev_info_service.c b/firmware/targets/f7/ble_glue/dev_info_service.c index ecfa08b17..8bdb2eea8 100755 --- a/firmware/targets/f7/ble_glue/dev_info_service.c +++ b/firmware/targets/f7/ble_glue/dev_info_service.c @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -16,7 +15,7 @@ typedef struct { uint16_t firmware_rev_char_handle; uint16_t software_rev_char_handle; uint16_t rpc_version_char_handle; - string_t version_string; + FuriString* version_string; char hardware_revision[4]; } DevInfoSvc; @@ -31,8 +30,7 @@ static const uint8_t dev_info_rpc_version_uuid[] = void dev_info_svc_start() { dev_info_svc = malloc(sizeof(DevInfoSvc)); - string_init_printf( - dev_info_svc->version_string, + dev_info_svc->version_string = furi_string_alloc_printf( "%s %s %s %s", version_get_githash(NULL), version_get_gitbranch(NULL), @@ -104,7 +102,7 @@ void dev_info_svc_start() { dev_info_svc->service_handle, UUID_TYPE_16, (Char_UUID_t*)&uuid, - string_size(dev_info_svc->version_string), + furi_string_size(dev_info_svc->version_string), CHAR_PROP_READ, ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, @@ -161,8 +159,8 @@ void dev_info_svc_start() { dev_info_svc->service_handle, dev_info_svc->software_rev_char_handle, 0, - string_size(dev_info_svc->version_string), - (uint8_t*)string_get_cstr(dev_info_svc->version_string)); + furi_string_size(dev_info_svc->version_string), + (uint8_t*)furi_string_get_cstr(dev_info_svc->version_string)); if(status) { FURI_LOG_E(TAG, "Failed to update software revision char: %d", status); } @@ -180,7 +178,7 @@ void dev_info_svc_start() { void dev_info_svc_stop() { tBleStatus status; if(dev_info_svc) { - string_clear(dev_info_svc->version_string); + furi_string_free(dev_info_svc->version_string); // Delete service characteristics status = aci_gatt_del_char(dev_info_svc->service_handle, dev_info_svc->man_name_char_handle); diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 62db30fee..aa8cd2c90 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -184,7 +184,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)) { FURI_LOG_I(TAG, "Pass key request event. Pin: ******"); } else { - FURI_LOG_I(TAG, "Pass key request event. Pin: %06d", pin); + FURI_LOG_I(TAG, "Pass key request event. Pin: %06ld", pin); } GapEvent event = {.type = GapEventTypePinCodeShow, .data.pin_code = pin}; gap->on_event_cb(event, gap->context); @@ -227,7 +227,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: { uint32_t pin = ((aci_gap_numeric_comparison_value_event_rp0*)(blue_evt->data))->Numeric_Value; - FURI_LOG_I(TAG, "Verify numeric comparison: %06d", pin); + FURI_LOG_I(TAG, "Verify numeric comparison: %06ld", pin); GapEvent event = {.type = GapEventTypePinCodeVerify, .data.pin_code = pin}; bool result = gap->on_event_cb(event, gap->context); aci_gap_numeric_comparison_value_confirm_yesno(gap->service.connection_handle, result); diff --git a/firmware/targets/f7/ble_glue/serial_service.c b/firmware/targets/f7/ble_glue/serial_service.c index eb58ae0ec..536557cce 100644 --- a/firmware/targets/f7/ble_glue/serial_service.c +++ b/firmware/targets/f7/ble_glue/serial_service.c @@ -63,13 +63,13 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { .size = attribute_modified->Attr_Data_Length, }}; uint32_t buff_free_size = serial_svc->callback(event, serial_svc->context); - FURI_LOG_D(TAG, "Available buff size: %d", buff_free_size); + FURI_LOG_D(TAG, "Available buff size: %ld", buff_free_size); furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk); } ret = SVCCTL_EvtAckFlowEnable; } } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { - FURI_LOG_T(TAG, "Ack received", blecore_evt->ecode); + FURI_LOG_T(TAG, "Ack received"); if(serial_svc->callback) { SerialServiceEvent event = { .event = SerialServiceEventTypeDataSent, diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 1a2b436d2..fc1c25c7e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -340,7 +340,7 @@ bool furi_hal_bt_clear_white_list() { return status != BLE_STATUS_SUCCESS; } -void furi_hal_bt_dump_state(string_t buffer) { +void furi_hal_bt_dump_state(FuriString* buffer) { if(furi_hal_bt_is_alive()) { uint8_t HCI_Version; uint16_t HCI_Revision; @@ -351,7 +351,7 @@ void furi_hal_bt_dump_state(string_t buffer) { tBleStatus ret = hci_read_local_version_information( &HCI_Version, &HCI_Revision, &LMP_PAL_Version, &Manufacturer_Name, &LMP_PAL_Subversion); - string_cat_printf( + furi_string_cat_printf( buffer, "Ret: %d, HCI_Version: %d, HCI_Revision: %d, LMP_PAL_Version: %d, Manufacturer_Name: %d, LMP_PAL_Subversion: %d", ret, @@ -361,7 +361,7 @@ void furi_hal_bt_dump_state(string_t buffer) { Manufacturer_Name, LMP_PAL_Subversion); } else { - string_cat_printf(buffer, "BLE not ready"); + furi_string_cat_printf(buffer, "BLE not ready"); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index a7c9b4d03..cf19451ec 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -236,3 +237,63 @@ void furi_hal_clock_suspend_tick() { void furi_hal_clock_resume_tick() { SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk); } + +void furi_hal_clock_mco_enable(FuriHalClockMcoSourceId source, FuriHalClockMcoDivisorId div) { + if(source == FuriHalClockMcoLse) { + LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_LSE, div); + } else if(source == FuriHalClockMcoSysclk) { + LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_SYSCLK, div); + } else { + LL_RCC_MSI_Enable(); + while(LL_RCC_MSI_IsReady() != 1) + ; + switch(source) { + case FuriHalClockMcoMsi100k: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_0); + break; + case FuriHalClockMcoMsi200k: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_1); + break; + case FuriHalClockMcoMsi400k: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_2); + break; + case FuriHalClockMcoMsi800k: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_3); + break; + case FuriHalClockMcoMsi1m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_4); + break; + case FuriHalClockMcoMsi2m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_5); + break; + case FuriHalClockMcoMsi4m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6); + break; + case FuriHalClockMcoMsi8m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_7); + break; + case FuriHalClockMcoMsi16m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_8); + break; + case FuriHalClockMcoMsi24m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_9); + break; + case FuriHalClockMcoMsi32m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_10); + break; + case FuriHalClockMcoMsi48m: + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_11); + break; + default: + break; + } + LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_MSI, div); + } +} + +void furi_hal_clock_mco_disable() { + LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_NOCLOCK, FuriHalClockMcoDiv1); + LL_RCC_MSI_Disable(); + while(LL_RCC_MSI_IsReady() != 0) + ; +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.h b/firmware/targets/f7/furi_hal/furi_hal_clock.h index 6cebb20c6..5e651bbd3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.h +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.h @@ -4,6 +4,33 @@ extern "C" { #endif +#include + +typedef enum { + FuriHalClockMcoLse, + FuriHalClockMcoSysclk, + FuriHalClockMcoMsi100k, + FuriHalClockMcoMsi200k, + FuriHalClockMcoMsi400k, + FuriHalClockMcoMsi800k, + FuriHalClockMcoMsi1m, + FuriHalClockMcoMsi2m, + FuriHalClockMcoMsi4m, + FuriHalClockMcoMsi8m, + FuriHalClockMcoMsi16m, + FuriHalClockMcoMsi24m, + FuriHalClockMcoMsi32m, + FuriHalClockMcoMsi48m, +} FuriHalClockMcoSourceId; + +typedef enum { + FuriHalClockMcoDiv1 = LL_RCC_MCO1_DIV_1, + FuriHalClockMcoDiv2 = LL_RCC_MCO1_DIV_2, + FuriHalClockMcoDiv4 = LL_RCC_MCO1_DIV_4, + FuriHalClockMcoDiv8 = LL_RCC_MCO1_DIV_8, + FuriHalClockMcoDiv16 = LL_RCC_MCO1_DIV_16, +} FuriHalClockMcoDivisorId; + /** Early initialization */ void furi_hal_clock_init_early(); @@ -25,6 +52,16 @@ void furi_hal_clock_suspend_tick(); /** Continue SysTick counter operation */ void furi_hal_clock_resume_tick(); +/** Enable clock output on MCO pin + * + * @param source MCO clock source + * @param div MCO clock division +*/ +void furi_hal_clock_mco_enable(FuriHalClockMcoSourceId source, FuriHalClockMcoDivisorId div); + +/** Disable clock output on MCO pin */ +void furi_hal_clock_mco_disable(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_console.c b/firmware/targets/f7/furi_hal/furi_hal_console.c index e5db927bf..2bdc57250 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_console.c +++ b/firmware/targets/f7/furi_hal/furi_hal_console.c @@ -4,7 +4,6 @@ #include #include #include -#include #include @@ -88,13 +87,13 @@ void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size } void furi_hal_console_printf(const char format[], ...) { - string_t string; + FuriString* string; va_list args; va_start(args, format); - string_init_vprintf(string, format, args); + string = furi_string_alloc_vprintf(format, args); va_end(args); - furi_hal_console_tx((const uint8_t*)string_get_cstr(string), string_size(string)); - string_clear(string); + furi_hal_console_tx((const uint8_t*)furi_string_get_cstr(string), furi_string_size(string)); + furi_string_free(string); } void furi_hal_console_puts(const char* data) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_console.h b/firmware/targets/f7/furi_hal/furi_hal_console.h index 104515ce9..ce31a66b3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_console.h +++ b/firmware/targets/f7/furi_hal/furi_hal_console.h @@ -2,6 +2,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -27,7 +28,7 @@ void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size * @param format * @param ... */ -void furi_hal_console_printf(const char format[], ...); +void furi_hal_console_printf(const char format[], ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); void furi_hal_console_puts(const char* data); diff --git a/firmware/targets/f7/furi_hal/furi_hal_cortex.c b/firmware/targets/f7/furi_hal/furi_hal_cortex.c index 2b4ea6e99..c9c8400a7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_cortex.c +++ b/firmware/targets/f7/furi_hal/furi_hal_cortex.c @@ -6,6 +6,9 @@ void furi_hal_cortex_init_early() { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; DWT->CYCCNT = 0U; + + /* Enable instruction prefetch */ + SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN); } void furi_hal_cortex_delay_us(uint32_t microseconds) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index f99cf8c3d..e49cd5f29 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -83,7 +83,7 @@ void furi_hal_flash_init() { // WRITE_REG(FLASH->SR, FLASH_SR_OPTVERR); /* Actually, reset all error flags on start */ if(READ_BIT(FLASH->SR, FURI_HAL_FLASH_SR_ERRORS)) { - FURI_LOG_E(TAG, "FLASH->SR 0x%08X", FLASH->SR); + FURI_LOG_E(TAG, "FLASH->SR 0x%08lX", FLASH->SR); WRITE_REG(FLASH->SR, FURI_HAL_FLASH_SR_ERRORS); } } @@ -514,10 +514,10 @@ bool furi_hal_flash_ob_set_word(size_t word_idx, const uint32_t value) { FURI_LOG_W( TAG, - "Setting OB reg %d for word %d (addr 0x%08X) to 0x%08X", + "Setting OB reg %d for word %d (addr 0x%08lX) to 0x%08lX", reg_def->ob_reg, word_idx, - reg_def->ob_register_address, + (uint32_t)reg_def->ob_register_address, value); /* 1. Clear OPTLOCK option lock bit with the clearing sequence */ diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c index 25ea42bb6..15ce41a20 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_info.c +++ b/firmware/targets/f7/furi_hal/furi_hal_info.c @@ -5,12 +5,12 @@ #include #include -#include +#include #include void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); // Device Info version out("device_info_major", "2", false, context); @@ -20,36 +20,36 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("hardware_model", furi_hal_version_get_model_name(), false, context); // Unique ID - string_reset(value); + furi_string_reset(value); const uint8_t* uid = furi_hal_version_uid(); for(size_t i = 0; i < furi_hal_version_uid_size(); i++) { - string_cat_printf(value, "%02X", uid[i]); + furi_string_cat_printf(value, "%02X", uid[i]); } - out("hardware_uid", string_get_cstr(value), false, context); + out("hardware_uid", furi_string_get_cstr(value), false, context); // OTP Revision - string_printf(value, "%d", furi_hal_version_get_otp_version()); - out("hardware_otp_ver", string_get_cstr(value), false, context); - string_printf(value, "%lu", furi_hal_version_get_hw_timestamp()); - out("hardware_timestamp", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_otp_version()); + out("hardware_otp_ver", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%lu", furi_hal_version_get_hw_timestamp()); + out("hardware_timestamp", furi_string_get_cstr(value), false, context); // Board Revision - string_printf(value, "%d", furi_hal_version_get_hw_version()); - out("hardware_ver", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_target()); - out("hardware_target", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_body()); - out("hardware_body", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_connect()); - out("hardware_connect", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_display()); - out("hardware_display", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_version()); + out("hardware_ver", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_target()); + out("hardware_target", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_body()); + out("hardware_body", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_connect()); + out("hardware_connect", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_display()); + out("hardware_display", furi_string_get_cstr(value), false, context); // Board Personification - string_printf(value, "%d", furi_hal_version_get_hw_color()); - out("hardware_color", string_get_cstr(value), false, context); - string_printf(value, "%d", furi_hal_version_get_hw_region()); - out("hardware_region", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_color()); + out("hardware_color", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", furi_hal_version_get_hw_region()); + out("hardware_region", furi_string_get_cstr(value), false, context); out("hardware_region_provisioned", furi_hal_region_get_name(), false, context); const char* name = furi_hal_version_get_name_ptr(); if(name) { @@ -68,8 +68,8 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("firmware_branch_num", version_get_gitbranchnum(firmware_version), false, context); out("firmware_version", version_get_version(firmware_version), false, context); out("firmware_build_date", version_get_builddate(firmware_version), false, context); - string_printf(value, "%d", version_get_target(firmware_version)); - out("firmware_target", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", version_get_target(firmware_version)); + out("firmware_target", furi_string_get_cstr(value), false, context); } if(furi_hal_bt_is_alive()) { @@ -78,64 +78,64 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { out("radio_mode", ble_c2_info->mode == BleGlueC2ModeFUS ? "FUS" : "Stack", false, context); // FUS Info - string_printf(value, "%d", ble_c2_info->FusVersionMajor); - out("radio_fus_major", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->FusVersionMinor); - out("radio_fus_minor", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->FusVersionSub); - out("radio_fus_sub", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->FusMemorySizeSram2B); - out("radio_fus_sram2b", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->FusMemorySizeSram2A); - out("radio_fus_sram2a", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->FusMemorySizeFlash * 4); - out("radio_fus_flash", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->FusVersionMajor); + out("radio_fus_major", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->FusVersionMinor); + out("radio_fus_minor", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->FusVersionSub); + out("radio_fus_sub", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->FusMemorySizeSram2B); + out("radio_fus_sram2b", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->FusMemorySizeSram2A); + out("radio_fus_sram2a", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->FusMemorySizeFlash * 4); + out("radio_fus_flash", furi_string_get_cstr(value), false, context); // Stack Info - string_printf(value, "%d", ble_c2_info->StackType); - out("radio_stack_type", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionMajor); - out("radio_stack_major", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionMinor); - out("radio_stack_minor", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionSub); - out("radio_stack_sub", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionBranch); - out("radio_stack_branch", string_get_cstr(value), false, context); - string_printf(value, "%d", ble_c2_info->VersionReleaseType); - out("radio_stack_release", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->MemorySizeSram2B); - out("radio_stack_sram2b", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->MemorySizeSram2A); - out("radio_stack_sram2a", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->MemorySizeSram1); - out("radio_stack_sram1", string_get_cstr(value), false, context); - string_printf(value, "%dK", ble_c2_info->MemorySizeFlash * 4); - out("radio_stack_flash", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->StackType); + out("radio_stack_type", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionMajor); + out("radio_stack_major", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionMinor); + out("radio_stack_minor", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionSub); + out("radio_stack_sub", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionBranch); + out("radio_stack_branch", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%d", ble_c2_info->VersionReleaseType); + out("radio_stack_release", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->MemorySizeSram2B); + out("radio_stack_sram2b", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->MemorySizeSram2A); + out("radio_stack_sram2a", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->MemorySizeSram1); + out("radio_stack_sram1", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%dK", ble_c2_info->MemorySizeFlash * 4); + out("radio_stack_flash", furi_string_get_cstr(value), false, context); // Mac address - string_reset(value); + furi_string_reset(value); const uint8_t* ble_mac = furi_hal_version_get_ble_mac(); for(size_t i = 0; i < 6; i++) { - string_cat_printf(value, "%02X", ble_mac[i]); + furi_string_cat_printf(value, "%02X", ble_mac[i]); } - out("radio_ble_mac", string_get_cstr(value), false, context); + out("radio_ble_mac", furi_string_get_cstr(value), false, context); // Signature verification uint8_t enclave_keys = 0; uint8_t enclave_valid_keys = 0; bool enclave_valid = furi_hal_crypto_verify_enclave(&enclave_keys, &enclave_valid_keys); - string_printf(value, "%d", enclave_valid_keys); - out("enclave_valid_keys", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", enclave_valid_keys); + out("enclave_valid_keys", furi_string_get_cstr(value), false, context); out("enclave_valid", enclave_valid ? "true" : "false", false, context); } else { out("radio_alive", "false", false, context); } - string_printf(value, "%u", PROTOBUF_MAJOR_VERSION); - out("protobuf_version_major", string_get_cstr(value), false, context); - string_printf(value, "%u", PROTOBUF_MINOR_VERSION); - out("protobuf_version_minor", string_get_cstr(value), true, context); + furi_string_printf(value, "%u", PROTOBUF_MAJOR_VERSION); + out("protobuf_version_major", furi_string_get_cstr(value), false, context); + furi_string_printf(value, "%u", PROTOBUF_MINOR_VERSION); + out("protobuf_version_minor", furi_string_get_cstr(value), true, context); - string_clear(value); + furi_string_free(value); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_memory.c b/firmware/targets/f7/furi_hal/furi_hal_memory.c index 43dc56f11..9cf2c3120 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_memory.c +++ b/firmware/targets/f7/furi_hal/furi_hal_memory.c @@ -55,9 +55,9 @@ void furi_hal_memory_init() { memory->region[SRAM_B].size = sram2b_unprotected_size; FURI_LOG_I( - TAG, "SRAM2A: 0x%p, %d", memory->region[SRAM_A].start, memory->region[SRAM_A].size); + TAG, "SRAM2A: 0x%p, %ld", memory->region[SRAM_A].start, memory->region[SRAM_A].size); FURI_LOG_I( - TAG, "SRAM2B: 0x%p, %d", memory->region[SRAM_B].start, memory->region[SRAM_B].size); + TAG, "SRAM2B: 0x%p, %ld", memory->region[SRAM_B].start, memory->region[SRAM_B].size); if((memory->region[SRAM_A].size > 0) || (memory->region[SRAM_B].size > 0)) { if((memory->region[SRAM_A].size > 0)) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index de67bbc35..069ac4ea4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -743,7 +742,8 @@ void furi_hal_nfc_sleep() { rfalLowPowerModeStart(); } -FuriHalNfcReturn furi_hal_nfc_ll_set_mode(FuriHalNfcMode mode, FuriHalNfcBitrate txBR, FuriHalNfcBitrate rxBR) { +FuriHalNfcReturn + furi_hal_nfc_ll_set_mode(FuriHalNfcMode mode, FuriHalNfcBitrate txBR, FuriHalNfcBitrate rxBR) { return rfalSetMode((rfalMode)mode, (rfalBitRate)txBR, (rfalBitRate)rxBR); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 524fae0b1..86505c573 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -529,8 +529,8 @@ void furi_hal_power_suppress_charge_exit() { void furi_hal_power_info_get(FuriHalPowerInfoCallback out, void* context) { furi_assert(out); - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); // Power Info version out("power_info_major", "1", false, context); @@ -538,45 +538,45 @@ void furi_hal_power_info_get(FuriHalPowerInfoCallback out, void* context) { uint8_t charge = furi_hal_power_get_pct(); - string_printf(value, "%u", charge); - out("charge_level", string_get_cstr(value), false, context); + furi_string_printf(value, "%u", charge); + out("charge_level", furi_string_get_cstr(value), false, context); if(furi_hal_power_is_charging()) { if(charge < 100) { - string_printf(value, "charging"); + furi_string_printf(value, "charging"); } else { - string_printf(value, "charged"); + furi_string_printf(value, "charged"); } } else { - string_printf(value, "discharging"); + furi_string_printf(value, "discharging"); } - out("charge_state", string_get_cstr(value), false, context); + out("charge_state", furi_string_get_cstr(value), false, context); uint16_t voltage = (uint16_t)(furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge) * 1000.f); - string_printf(value, "%u", voltage); - out("battery_voltage", string_get_cstr(value), false, context); + furi_string_printf(value, "%u", voltage); + out("battery_voltage", furi_string_get_cstr(value), false, context); int16_t current = (int16_t)(furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge) * 1000.f); - string_printf(value, "%d", current); - out("battery_current", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", current); + out("battery_current", furi_string_get_cstr(value), false, context); int16_t temperature = (int16_t)furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge); - string_printf(value, "%d", temperature); - out("gauge_temp", string_get_cstr(value), false, context); + furi_string_printf(value, "%d", temperature); + out("gauge_temp", furi_string_get_cstr(value), false, context); - string_printf(value, "%u", furi_hal_power_get_bat_health_pct()); - out("battery_health", string_get_cstr(value), false, context); + furi_string_printf(value, "%u", furi_hal_power_get_bat_health_pct()); + out("battery_health", furi_string_get_cstr(value), false, context); - string_printf(value, "%u", furi_hal_power_get_battery_remaining_capacity()); - out("capacity_remain", string_get_cstr(value), false, context); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_remaining_capacity()); + out("capacity_remain", furi_string_get_cstr(value), false, context); - string_printf(value, "%u", furi_hal_power_get_battery_full_capacity()); - out("capacity_full", string_get_cstr(value), false, context); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_full_capacity()); + out("capacity_full", furi_string_get_cstr(value), false, context); - string_printf(value, "%u", furi_hal_power_get_battery_design_capacity()); - out("capacity_design", string_get_cstr(value), true, context); + furi_string_printf(value, "%lu", furi_hal_power_get_battery_design_capacity()); + out("capacity_design", furi_string_get_cstr(value), true, context); - string_clear(value); + furi_string_free(value); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_pwm.c b/firmware/targets/f7/furi_hal/furi_hal_pwm.c new file mode 100644 index 000000000..e484808d5 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_pwm.c @@ -0,0 +1,138 @@ +#include "furi_hal_pwm.h" +#include +#include + +#include +#include +#include +#include + +#include + +const uint32_t lptim_psc_table[] = { + LL_LPTIM_PRESCALER_DIV1, + LL_LPTIM_PRESCALER_DIV2, + LL_LPTIM_PRESCALER_DIV4, + LL_LPTIM_PRESCALER_DIV8, + LL_LPTIM_PRESCALER_DIV16, + LL_LPTIM_PRESCALER_DIV32, + LL_LPTIM_PRESCALER_DIV64, + LL_LPTIM_PRESCALER_DIV128, +}; + +void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty) { + if(channel == FuriHalPwmOutputIdTim1PA7) { + furi_hal_gpio_init_ex( + &gpio_ext_pa7, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn1TIM1); + + FURI_CRITICAL_ENTER(); + LL_TIM_DeInit(TIM1); + FURI_CRITICAL_EXIT(); + + LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP); + LL_TIM_SetRepetitionCounter(TIM1, 0); + LL_TIM_SetClockDivision(TIM1, LL_TIM_CLOCKDIVISION_DIV1); + LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_EnableARRPreload(TIM1); + + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_PWM1); + LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); + LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N); + + LL_TIM_EnableAllOutputs(TIM1); + + furi_hal_pwm_set_params(channel, freq, duty); + + LL_TIM_EnableCounter(TIM1); + } else if(channel == FuriHalPwmOutputIdLptim2PA4) { + furi_hal_gpio_init_ex( + &gpio_ext_pa4, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn14LPTIM2); + + FURI_CRITICAL_ENTER(); + LL_LPTIM_DeInit(LPTIM2); + FURI_CRITICAL_EXIT(); + + LL_LPTIM_SetUpdateMode(LPTIM2, LL_LPTIM_UPDATE_MODE_ENDOFPERIOD); + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK1); + LL_LPTIM_SetClockSource(LPTIM2, LL_LPTIM_CLK_SOURCE_INTERNAL); + LL_LPTIM_ConfigOutput( + LPTIM2, LL_LPTIM_OUTPUT_WAVEFORM_PWM, LL_LPTIM_OUTPUT_POLARITY_INVERSE); + LL_LPTIM_SetCounterMode(LPTIM2, LL_LPTIM_COUNTER_MODE_INTERNAL); + + LL_LPTIM_Enable(LPTIM2); + + furi_hal_pwm_set_params(channel, freq, duty); + + LL_LPTIM_StartCounter(LPTIM2, LL_LPTIM_OPERATING_MODE_CONTINUOUS); + } +} + +void furi_hal_pwm_stop(FuriHalPwmOutputId channel) { + if(channel == FuriHalPwmOutputIdTim1PA7) { + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); + FURI_CRITICAL_ENTER(); + LL_TIM_DeInit(TIM1); + FURI_CRITICAL_EXIT(); + } else if(channel == FuriHalPwmOutputIdLptim2PA4) { + furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); + FURI_CRITICAL_ENTER(); + LL_LPTIM_DeInit(LPTIM2); + FURI_CRITICAL_EXIT(); + } +} + +void furi_hal_pwm_set_params(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty) { + furi_assert(freq > 0); + uint32_t freq_div = 64000000LU / freq; + + if(channel == FuriHalPwmOutputIdTim1PA7) { + uint32_t prescaler = freq_div / 0x10000LU; + uint32_t period = freq_div / (prescaler + 1); + uint32_t compare = period * duty / 100; + + LL_TIM_SetPrescaler(TIM1, prescaler); + LL_TIM_SetAutoReload(TIM1, period - 1); + LL_TIM_OC_SetCompareCH1(TIM1, compare); + } else if(channel == FuriHalPwmOutputIdLptim2PA4) { + uint32_t prescaler = 0; + uint32_t period = 0; + + bool clock_lse = false; + + do { + period = freq_div / (1 << prescaler); + if(period <= 0xFFFF) { + break; + } + prescaler++; + if(prescaler > 7) { + prescaler = 0; + clock_lse = true; + period = 32768LU / freq; + break; + } + } while(1); + + uint32_t compare = period * duty / 100; + + LL_LPTIM_SetPrescaler(LPTIM2, lptim_psc_table[prescaler]); + LL_LPTIM_SetAutoReload(LPTIM2, period); + LL_LPTIM_SetCompare(LPTIM2, compare); + + if(clock_lse) { + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE); + } else { + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK1); + } + } +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_pwm.h b/firmware/targets/f7/furi_hal/furi_hal_pwm.h new file mode 100644 index 000000000..a8682c5fb --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_pwm.h @@ -0,0 +1,42 @@ +/** + * @file furi_hal_pwm.h + * PWM contol HAL + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef enum { + FuriHalPwmOutputIdTim1PA7, + FuriHalPwmOutputIdLptim2PA4, +} FuriHalPwmOutputId; + +/** Enable PWM channel and set parameters + * + * @param[in] channel PWM channel (FuriHalPwmOutputId) + * @param[in] freq Frequency in Hz + * @param[in] duty Duty cycle value in % +*/ +void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty); + +/** Disable PWM channel + * + * @param[in] channel PWM channel (FuriHalPwmOutputId) +*/ +void furi_hal_pwm_stop(FuriHalPwmOutputId channel); + +/** Set PWM channel parameters + * + * @param[in] channel PWM channel (FuriHalPwmOutputId) + * @param[in] freq Frequency in Hz + * @param[in] duty Duty cycle value in % +*/ +void furi_hal_pwm_set_params(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index b73d074fd..5eeb4e9a5 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -173,7 +173,7 @@ void furi_hal_subghz_load_custom_preset(uint8_t* preset_data) { i += 2; } for(uint8_t y = i; y < i + 10; y++) { - FURI_LOG_D(TAG, "PA[%lu]: %02X", y, preset_data[y]); + FURI_LOG_D(TAG, "PA[%u]: %02X", y, preset_data[y]); } } } diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h index 3f1169d16..800fc3fe3 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt.h @@ -5,7 +5,7 @@ #pragma once -#include +#include #include #include #include @@ -122,9 +122,9 @@ void furi_hal_bt_stop_advertising(); /** Get BT/BLE system component state * - * @param[in] buffer string_t buffer to write to + * @param[in] buffer FuriString* buffer to write to */ -void furi_hal_bt_dump_state(string_t buffer); +void furi_hal_bt_dump_state(FuriString* buffer); /** Get BT/BLE system component state * diff --git a/firmware/targets/furi_hal_include/furi_hal_power.h b/firmware/targets/furi_hal_include/furi_hal_power.h index f8eaa5c3a..e94877afc 100644 --- a/firmware/targets/furi_hal_include/furi_hal_power.h +++ b/firmware/targets/furi_hal_include/furi_hal_power.h @@ -7,7 +7,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/furi/core/check.c b/furi/core/check.c index 3d0cd7a04..613b52f46 100644 --- a/furi/core/check.c +++ b/furi/core/check.c @@ -9,6 +9,7 @@ #include #include #include +#include extern size_t xPortGetTotalHeapSize(void); extern size_t xPortGetFreeHeapSize(void); diff --git a/furi/core/kernel.h b/furi/core/kernel.h index 28afffd45..f30f109bb 100644 --- a/furi/core/kernel.h +++ b/furi/core/kernel.h @@ -1,5 +1,5 @@ /** - * @file kenrel.h + * @file kernel.h * Furi Kernel primitives */ #pragma once diff --git a/furi/core/log.c b/furi/core/log.c index 8a36a930b..bb163c956 100644 --- a/furi/core/log.c +++ b/furi/core/log.c @@ -25,8 +25,8 @@ void furi_log_init() { void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...) { if(level <= furi_log.log_level && furi_mutex_acquire(furi_log.mutex, FuriWaitForever) == FuriStatusOk) { - string_t string; - string_init(string); + FuriString* string; + string = furi_string_alloc(); const char* color = FURI_LOG_CLR_RESET; const char* log_letter = " "; @@ -56,23 +56,23 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form } // Timestamp - string_printf( + furi_string_printf( string, "%lu %s[%s][%s] " FURI_LOG_CLR_RESET, furi_log.timetamp(), color, log_letter, tag); - furi_log.puts(string_get_cstr(string)); - string_reset(string); + furi_log.puts(furi_string_get_cstr(string)); + furi_string_reset(string); va_list args; va_start(args, format); - string_vprintf(string, format, args); + furi_string_vprintf(string, format, args); va_end(args); - furi_log.puts(string_get_cstr(string)); - string_clear(string); + furi_log.puts(furi_string_get_cstr(string)); + furi_string_free(string); furi_log.puts("\r\n"); diff --git a/furi/core/log.h b/furi/core/log.h index 30026fc44..cb8b3d9cc 100644 --- a/furi/core/log.h +++ b/furi/core/log.h @@ -51,7 +51,8 @@ void furi_log_init(); * @param format * @param ... */ -void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...); +void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); /** Set log level * diff --git a/furi/core/record.c b/furi/core/record.c index 63dfdbe47..773585e7e 100644 --- a/furi/core/record.c +++ b/furi/core/record.c @@ -4,7 +4,6 @@ #include "mutex.h" #include "event_flag.h" -#include #include #include diff --git a/furi/core/stream_buffer.c b/furi/core/stream_buffer.c new file mode 100644 index 000000000..b9d0629fe --- /dev/null +++ b/furi/core/stream_buffer.c @@ -0,0 +1,77 @@ +#include "base.h" +#include "stream_buffer.h" +#include "common_defines.h" +#include +#include + +FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level) { + return xStreamBufferCreate(size, trigger_level); +}; + +void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer) { + vStreamBufferDelete(stream_buffer); +}; + +bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level) { + return xStreamBufferSetTriggerLevel(stream_buffer, trigger_level) == pdTRUE; +}; + +size_t furi_stream_buffer_send( + FuriStreamBuffer* stream_buffer, + const void* data, + size_t length, + uint32_t timeout) { + size_t ret; + + if(FURI_IS_IRQ_MODE() != 0U) { + BaseType_t yield; + ret = xStreamBufferSendFromISR(stream_buffer, data, length, &yield); + portYIELD_FROM_ISR(yield); + } else { + ret = xStreamBufferSend(stream_buffer, data, length, timeout); + } + + return ret; +}; + +size_t furi_stream_buffer_receive( + FuriStreamBuffer* stream_buffer, + void* data, + size_t length, + uint32_t timeout) { + size_t ret; + + if(FURI_IS_IRQ_MODE() != 0U) { + BaseType_t yield; + ret = xStreamBufferReceiveFromISR(stream_buffer, data, length, &yield); + portYIELD_FROM_ISR(yield); + } else { + ret = xStreamBufferReceive(stream_buffer, data, length, timeout); + } + + return ret; +} + +size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer) { + return xStreamBufferBytesAvailable(stream_buffer); +}; + +size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer) { + return xStreamBufferSpacesAvailable(stream_buffer); +}; + +bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer) { + return xStreamBufferIsFull(stream_buffer) == pdTRUE; +}; + +bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer) { + return (xStreamBufferIsEmpty(stream_buffer) == pdTRUE); +}; + +FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer) { + if(xStreamBufferReset(stream_buffer) == pdPASS) { + return FuriStatusOk; + } else { + return FuriStatusError; + } +} \ No newline at end of file diff --git a/furi/core/stream_buffer.h b/furi/core/stream_buffer.h new file mode 100644 index 000000000..d07f7e60b --- /dev/null +++ b/furi/core/stream_buffer.h @@ -0,0 +1,152 @@ +/** + * @file stream_buffer.h + * Furi stream buffer primitive. + * + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Stream buffer implementation assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). + */ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void FuriStreamBuffer; + +/** + * @brief Allocate stream buffer instance. + * Stream buffer implementation assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). + * + * @param size The total number of bytes the stream buffer will be able to hold at any one time. + * @param trigger_level The number of bytes that must be in the stream buffer + * before a task that is blocked on the stream buffer to wait for data is moved out of the blocked state. + * @return The stream buffer instance. + */ +FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level); + +/** + * @brief Free stream buffer instance + * + * @param stream_buffer The stream buffer instance. + */ +void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer); + +/** + * @brief Set trigger level for stream buffer. + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. + * + * @param stream_buffer The stream buffer instance + * @param trigger_level The new trigger level for the stream buffer. + * @return true if trigger level can be be updated (new trigger level was less than or equal to the stream buffer's length). + * @return false if trigger level can't be be updated (new trigger level was greater than the stream buffer's length). + */ +bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level); + +/** + * @brief Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * Wakes up task waiting for data to become available if called from ISR. + * + * @param stream_buffer The stream buffer instance. + * @param data A pointer to the data that is to be copied into the stream buffer. + * @param length The maximum number of bytes to copy from data into the stream buffer. + * @param timeout The maximum amount of time the task should remain in the + * Blocked state to wait for space to become available if the stream buffer is full. + * Will return immediately if timeout is zero. + * Setting timeout to FuriWaitForever will cause the task to wait indefinitely. + * Ignored if called from ISR. + * @return The number of bytes actually written to the stream buffer. + */ +size_t furi_stream_buffer_send( + FuriStreamBuffer* stream_buffer, + const void* data, + size_t length, + uint32_t timeout); + +/** + * @brief Receives bytes from a stream buffer. + * Wakes up task waiting for space to become available if called from ISR. + * + * @param stream_buffer The stream buffer instance. + * @param data A pointer to the buffer into which the received bytes will be + * copied. + * @param length The length of the buffer pointed to by the data parameter. + * @param timeout The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is empty. + * Will return immediately if timeout is zero. + * Setting timeout to FuriWaitForever will cause the task to wait indefinitely. + * Ignored if called from ISR. + * @return The number of bytes read from the stream buffer, if any. + */ +size_t furi_stream_buffer_receive( + FuriStreamBuffer* stream_buffer, + void* data, + size_t length, + uint32_t timeout); + +/** + * @brief Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param stream_buffer The stream buffer instance. + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + */ +size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param stream_buffer The stream buffer instance. + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + */ +size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see if it is full. + * + * @param stream_buffer stream buffer instance. + * @return true if the stream buffer is full. + * @return false if the stream buffer is not full. + */ +bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer); + +/** + * @brief Queries a stream buffer to see if it is empty. + * + * @param stream_buffer The stream buffer instance. + * @return true if the stream buffer is empty. + * @return false if the stream buffer is not empty. + */ +bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer); + +/** + * @brief Resets a stream buffer to its initial, empty, state. Any data that was + * in the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream buffer. + * + * @param stream_buffer The stream buffer instance. + * @return FuriStatusOk if the stream buffer is reset. + * @return FuriStatusError if there was a task blocked waiting to send to or read + * from the stream buffer then the stream buffer is not reset. + */ +FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/furi/core/string.c b/furi/core/string.c new file mode 100644 index 000000000..099f70c11 --- /dev/null +++ b/furi/core/string.c @@ -0,0 +1,302 @@ +#include "string.h" +#include + +struct FuriString { + string_t string; +}; + +#undef furi_string_alloc_set +#undef furi_string_set +#undef furi_string_cmp +#undef furi_string_cmpi +#undef furi_string_search +#undef furi_string_search_str +#undef furi_string_equal +#undef furi_string_replace +#undef furi_string_replace_str +#undef furi_string_replace_all +#undef furi_string_start_with +#undef furi_string_end_with +#undef furi_string_search_char +#undef furi_string_search_rchar +#undef furi_string_trim +#undef furi_string_cat + +FuriString* furi_string_alloc() { + FuriString* string = malloc(sizeof(FuriString)); + string_init(string->string); + return string; +} + +FuriString* furi_string_alloc_set(const FuriString* s) { + FuriString* string = malloc(sizeof(FuriString)); + string_init_set(string->string, s->string); + return string; +} + +FuriString* furi_string_alloc_set_str(const char cstr[]) { + FuriString* string = malloc(sizeof(FuriString)); + string_init_set(string->string, cstr); + return string; +} + +FuriString* furi_string_alloc_printf(const char format[], ...) { + va_list args; + va_start(args, format); + FuriString* string = furi_string_alloc_vprintf(format, args); + va_end(args); + return string; +} + +FuriString* furi_string_alloc_vprintf(const char format[], va_list args) { + FuriString* string = malloc(sizeof(FuriString)); + string_init_vprintf(string->string, format, args); + return string; +} + +FuriString* furi_string_alloc_move(FuriString* s) { + FuriString* string = malloc(sizeof(FuriString)); + string_init_move(string->string, s->string); + free(s); + return string; +} + +void furi_string_free(FuriString* s) { + string_clear(s->string); + free(s); +} + +void furi_string_reserve(FuriString* s, size_t alloc) { + string_reserve(s->string, alloc); +} + +void furi_string_reset(FuriString* s) { + string_reset(s->string); +} + +void furi_string_swap(FuriString* v1, FuriString* v2) { + string_swap(v1->string, v2->string); +} + +void furi_string_move(FuriString* v1, FuriString* v2) { + string_clear(v1->string); + string_init_move(v1->string, v2->string); + free(v2); +} + +size_t furi_string_hash(const FuriString* v) { + return string_hash(v->string); +} + +char furi_string_get_char(const FuriString* v, size_t index) { + return string_get_char(v->string, index); +} + +const char* furi_string_get_cstr(const FuriString* s) { + return string_get_cstr(s->string); +} + +void furi_string_set(FuriString* s, FuriString* source) { + string_set(s->string, source->string); +} + +void furi_string_set_str(FuriString* s, const char cstr[]) { + string_set(s->string, cstr); +} + +void furi_string_set_strn(FuriString* s, const char str[], size_t n) { + string_set_strn(s->string, str, n); +} + +void furi_string_set_char(FuriString* s, size_t index, const char c) { + string_set_char(s->string, index, c); +} + +int furi_string_cmp(const FuriString* s1, const FuriString* s2) { + return string_cmp(s1->string, s2->string); +} + +int furi_string_cmp_str(const FuriString* s1, const char str[]) { + return string_cmp(s1->string, str); +} + +int furi_string_cmpi(const FuriString* v1, const FuriString* v2) { + return string_cmpi(v1->string, v2->string); +} + +int furi_string_cmpi_str(const FuriString* v1, const char p2[]) { + return string_cmpi_str(v1->string, p2); +} + +size_t furi_string_search(const FuriString* v, const FuriString* needle, size_t start) { + return string_search(v->string, needle->string, start); +} + +size_t furi_string_search_str(const FuriString* v, const char needle[], size_t start) { + return string_search(v->string, needle, start); +} + +bool furi_string_equal(const FuriString* v1, const FuriString* v2) { + return string_equal_p(v1->string, v2->string); +} + +bool furi_string_equal_str(const FuriString* v1, const char v2[]) { + return string_equal_p(v1->string, v2); +} + +void furi_string_push_back(FuriString* v, char c) { + string_push_back(v->string, c); +} + +size_t furi_string_size(const FuriString* s) { + return string_size(s->string); +} + +int furi_string_printf(FuriString* v, const char format[], ...) { + va_list args; + va_start(args, format); + int result = furi_string_vprintf(v, format, args); + va_end(args); + return result; +} + +int furi_string_vprintf(FuriString* v, const char format[], va_list args) { + return string_vprintf(v->string, format, args); +} + +int furi_string_cat_printf(FuriString* v, const char format[], ...) { + va_list args; + va_start(args, format); + int result = furi_string_cat_vprintf(v, format, args); + va_end(args); + return result; +} + +int furi_string_cat_vprintf(FuriString* v, const char format[], va_list args) { + FuriString* string = furi_string_alloc(); + int ret = furi_string_vprintf(string, format, args); + furi_string_cat(v, string); + furi_string_free(string); + return ret; +} + +bool furi_string_empty(const FuriString* v) { + return string_empty_p(v->string); +} + +void furi_string_replace_at(FuriString* v, size_t pos, size_t len, const char str2[]) { + string_replace_at(v->string, pos, len, str2); +} + +size_t + furi_string_replace(FuriString* string, FuriString* needle, FuriString* replace, size_t start) { + return string_replace(string->string, needle->string, replace->string, start); +} + +size_t furi_string_replace_str(FuriString* v, const char str1[], const char str2[], size_t start) { + return string_replace_str(v->string, str1, str2, start); +} + +void furi_string_replace_all_str(FuriString* v, const char str1[], const char str2[]) { + string_replace_all_str(v->string, str1, str2); +} + +void furi_string_replace_all(FuriString* v, const FuriString* str1, const FuriString* str2) { + string_replace_all(v->string, str1->string, str2->string); +} + +bool furi_string_start_with(const FuriString* v, const FuriString* v2) { + return string_start_with_string_p(v->string, v2->string); +} + +bool furi_string_start_with_str(const FuriString* v, const char str[]) { + return string_start_with_str_p(v->string, str); +} + +bool furi_string_end_with(const FuriString* v, const FuriString* v2) { + return string_end_with_string_p(v->string, v2->string); +} + +bool furi_string_end_with_str(const FuriString* v, const char str[]) { + return string_end_with_str_p(v->string, str); +} + +size_t furi_string_search_char(const FuriString* v, char c, size_t start) { + return string_search_char(v->string, c, start); +} + +size_t furi_string_search_rchar(const FuriString* v, char c, size_t start) { + return string_search_rchar(v->string, c, start); +} + +void furi_string_left(FuriString* v, size_t index) { + string_left(v->string, index); +} + +void furi_string_right(FuriString* v, size_t index) { + string_right(v->string, index); +} + +void furi_string_mid(FuriString* v, size_t index, size_t size) { + string_mid(v->string, index, size); +} + +void furi_string_trim(FuriString* v, const char charac[]) { + string_strim(v->string, charac); +} + +void furi_string_cat(FuriString* v, const FuriString* v2) { + string_cat(v->string, v2->string); +} + +void furi_string_cat_str(FuriString* v, const char str[]) { + string_cat(v->string, str); +} + +void furi_string_set_n(FuriString* v, const FuriString* ref, size_t offset, size_t length) { + string_set_n(v->string, ref->string, offset, length); +} + +size_t furi_string_utf8_length(FuriString* str) { + return string_length_u(str->string); +} + +void furi_string_utf8_push(FuriString* str, FuriStringUnicodeValue u) { + string_push_u(str->string, u); +} + +static m_str1ng_utf8_state_e furi_state_to_state(FuriStringUTF8State state) { + switch(state) { + case FuriStringUTF8StateStarting: + return M_STRING_UTF8_STARTING; + case FuriStringUTF8StateDecoding1: + return M_STRING_UTF8_DECODING_1; + case FuriStringUTF8StateDecoding2: + return M_STRING_UTF8_DECODING_2; + case FuriStringUTF8StateDecoding3: + return M_STRING_UTF8_DOCODING_3; + default: + return M_STRING_UTF8_ERROR; + } +} + +static FuriStringUTF8State state_to_furi_state(m_str1ng_utf8_state_e state) { + switch(state) { + case M_STRING_UTF8_STARTING: + return FuriStringUTF8StateStarting; + case M_STRING_UTF8_DECODING_1: + return FuriStringUTF8StateDecoding1; + case M_STRING_UTF8_DECODING_2: + return FuriStringUTF8StateDecoding2; + case M_STRING_UTF8_DOCODING_3: + return FuriStringUTF8StateDecoding3; + default: + return FuriStringUTF8StateError; + } +} + +void furi_string_utf8_decode(char c, FuriStringUTF8State* state, FuriStringUnicodeValue* unicode) { + m_str1ng_utf8_state_e m_state = furi_state_to_state(*state); + m_str1ng_utf8_decode(c, &m_state, unicode); + *state = state_to_furi_state(m_state); +} \ No newline at end of file diff --git a/furi/core/string.h b/furi/core/string.h new file mode 100644 index 000000000..01b26cce1 --- /dev/null +++ b/furi/core/string.h @@ -0,0 +1,741 @@ +/** + * @file string.h + * Furi string primitive + */ +#pragma once + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Furi string failure constant. + */ +#define FURI_STRING_FAILURE ((size_t)-1) + +/** + * @brief Furi string primitive. + */ +typedef struct FuriString FuriString; + +//--------------------------------------------------------------------------- +// Constructors +//--------------------------------------------------------------------------- + +/** + * @brief Allocate new FuriString. + * @return FuriString* + */ +FuriString* furi_string_alloc(); + +/** + * @brief Allocate new FuriString and set it to string. + * Allocate & Set the string a to the string. + * @param source + * @return FuriString* + */ +FuriString* furi_string_alloc_set(const FuriString* source); + +/** + * @brief Allocate new FuriString and set it to C string. + * Allocate & Set the string a to the C string. + * @param cstr_source + * @return FuriString* + */ +FuriString* furi_string_alloc_set_str(const char cstr_source[]); + +/** + * @brief Allocate new FuriString and printf to it. + * Initialize and set a string to the given formatted value. + * @param format + * @param ... + * @return FuriString* + */ +FuriString* furi_string_alloc_printf(const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 1, 2))); + +/** + * @brief Allocate new FuriString and printf to it. + * Initialize and set a string to the given formatted value. + * @param format + * @param args + * @return FuriString* + */ +FuriString* furi_string_alloc_vprintf(const char format[], va_list args); + +/** + * @brief Allocate new FuriString and move source string content to it. + * Allocate the string, set it to the other one, and destroy the other one. + * @param source + * @return FuriString* + */ +FuriString* furi_string_alloc_move(FuriString* source); + +//--------------------------------------------------------------------------- +// Destructors +//--------------------------------------------------------------------------- + +/** + * @brief Free FuriString. + * @param string + */ +void furi_string_free(FuriString* string); + +//--------------------------------------------------------------------------- +// String memory management +//--------------------------------------------------------------------------- + +/** + * @brief Reserve memory for string. + * Modify the string capacity to be able to handle at least 'alloc' characters (including final null char). + * @param string + * @param size + */ +void furi_string_reserve(FuriString* string, size_t size); + +/** + * @brief Reset string. + * Make the string empty. + * @param s + */ +void furi_string_reset(FuriString* string); + +/** + * @brief Swap two strings. + * Swap the two strings string_1 and string_2. + * @param string_1 + * @param string_2 + */ +void furi_string_swap(FuriString* string_1, FuriString* string_2); + +/** + * @brief Move string_2 content to string_1. + * Set the string to the other one, and destroy the other one. + * @param string_1 + * @param string_2 + */ +void furi_string_move(FuriString* string_1, FuriString* string_2); + +/** + * @brief Compute a hash for the string. + * @param string + * @return size_t + */ +size_t furi_string_hash(const FuriString* string); + +/** + * @brief Get string size (usually length, but not for UTF-8) + * @param string + * @return size_t + */ +size_t furi_string_size(const FuriString* string); + +/** + * @brief Check that string is empty or not + * @param string + * @return bool + */ +bool furi_string_empty(const FuriString* string); + +//--------------------------------------------------------------------------- +// Getters +//--------------------------------------------------------------------------- + +/** + * @brief Get the character at the given index. + * Return the selected character of the string. + * @param string + * @param index + * @return char + */ +char furi_string_get_char(const FuriString* string, size_t index); + +/** + * @brief Return the string view a classic C string. + * @param string + * @return const char* + */ +const char* furi_string_get_cstr(const FuriString* string); + +//--------------------------------------------------------------------------- +// Setters +//--------------------------------------------------------------------------- + +/** + * @brief Set the string to the other string. + * Set the string to the source string. + * @param string + * @param source + */ +void furi_string_set(FuriString* string, FuriString* source); + +/** + * @brief Set the string to the other C string. + * Set the string to the source C string. + * @param string + * @param source + */ +void furi_string_set_str(FuriString* string, const char source[]); + +/** + * @brief Set the string to the n first characters of the C string. + * @param string + * @param source + * @param length + */ +void furi_string_set_strn(FuriString* string, const char source[], size_t length); + +/** + * @brief Set the character at the given index. + * @param string + * @param index + * @param c + */ +void furi_string_set_char(FuriString* string, size_t index, const char c); + +/** + * @brief Set the string to the n first characters of other one. + * @param string + * @param source + * @param offset + * @param length + */ +void furi_string_set_n(FuriString* string, const FuriString* source, size_t offset, size_t length); + +/** + * @brief Format in the string the given printf format + * @param string + * @param format + * @param ... + * @return int + */ +int furi_string_printf(FuriString* string, const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); + +/** + * @brief Format in the string the given printf format + * @param string + * @param format + * @param args + * @return int + */ +int furi_string_vprintf(FuriString* string, const char format[], va_list args); + +//--------------------------------------------------------------------------- +// Appending +//--------------------------------------------------------------------------- + +/** + * @brief Append a character to the string. + * @param string + * @param c + */ +void furi_string_push_back(FuriString* string, char c); + +/** + * @brief Append a string to the string. + * Concatenate the string with the other string. + * @param string_1 + * @param string_2 + */ +void furi_string_cat(FuriString* string_1, const FuriString* string_2); + +/** + * @brief Append a C string to the string. + * Concatenate the string with the C string. + * @param string_1 + * @param cstring_2 + */ +void furi_string_cat_str(FuriString* string_1, const char cstring_2[]); + +/** + * @brief Append to the string the formatted string of the given printf format. + * @param string + * @param format + * @param ... + * @return int + */ +int furi_string_cat_printf(FuriString* string, const char format[], ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); + +/** + * @brief Append to the string the formatted string of the given printf format. + * @param string + * @param format + * @param args + * @return int + */ +int furi_string_cat_vprintf(FuriString* string, const char format[], va_list args); + +//--------------------------------------------------------------------------- +// Comparators +//--------------------------------------------------------------------------- + +/** + * @brief Compare two strings and return the sort order. + * @param string_1 + * @param string_2 + * @return int + */ +int furi_string_cmp(const FuriString* string_1, const FuriString* string_2); + +/** + * @brief Compare string with C string and return the sort order. + * @param string_1 + * @param cstring_2 + * @return int + */ +int furi_string_cmp_str(const FuriString* string_1, const char cstring_2[]); + +/** + * @brief Compare two strings (case insensitive according to the current locale) and return the sort order. + * Note: doesn't work with UTF-8 strings. + * @param string_1 + * @param string_2 + * @return int + */ +int furi_string_cmpi(const FuriString* string_1, const FuriString* string_2); + +/** + * @brief Compare string with C string (case insensitive according to the current locale) and return the sort order. + * Note: doesn't work with UTF-8 strings. + * @param string_1 + * @param cstring_2 + * @return int + */ +int furi_string_cmpi_str(const FuriString* string_1, const char cstring_2[]); + +//--------------------------------------------------------------------------- +// Search +//--------------------------------------------------------------------------- + +/** + * @brief Search the first occurrence of the needle in the string from the position start. + * Return STRING_FAILURE if not found. + * By default, start is zero. + * @param string + * @param needle + * @param start + * @return size_t + */ +size_t furi_string_search(const FuriString* string, const FuriString* needle, size_t start); + +/** + * @brief Search the first occurrence of the needle in the string from the position start. + * Return STRING_FAILURE if not found. + * @param string + * @param needle + * @param start + * @return size_t + */ +size_t furi_string_search_str(const FuriString* string, const char needle[], size_t start); + +/** + * @brief Search for the position of the character c from the position start (include) in the string. + * Return STRING_FAILURE if not found. + * By default, start is zero. + * @param string + * @param c + * @param start + * @return size_t + */ +size_t furi_string_search_char(const FuriString* string, char c, size_t start); + +/** + * @brief Reverse search for the position of the character c from the position start (include) in the string. + * Return STRING_FAILURE if not found. + * By default, start is zero. + * @param string + * @param c + * @param start + * @return size_t + */ +size_t furi_string_search_rchar(const FuriString* string, char c, size_t start); + +//--------------------------------------------------------------------------- +// Equality +//--------------------------------------------------------------------------- + +/** + * @brief Test if two strings are equal. + * @param string_1 + * @param string_2 + * @return bool + */ +bool furi_string_equal(const FuriString* string_1, const FuriString* string_2); + +/** + * @brief Test if the string is equal to the C string. + * @param string_1 + * @param cstring_2 + * @return bool + */ +bool furi_string_equal_str(const FuriString* string_1, const char cstring_2[]); + +//--------------------------------------------------------------------------- +// Replace +//--------------------------------------------------------------------------- + +/** + * @brief Replace in the string the sub-string at position 'pos' for 'len' bytes into the C string 'replace'. + * @param string + * @param pos + * @param len + * @param replace + */ +void furi_string_replace_at(FuriString* string, size_t pos, size_t len, const char replace[]); + +/** + * @brief Replace a string 'needle' to string 'replace' in a string from 'start' position. + * By default, start is zero. + * Return STRING_FAILURE if 'needle' not found or replace position. + * @param string + * @param needle + * @param replace + * @param start + * @return size_t + */ +size_t + furi_string_replace(FuriString* string, FuriString* needle, FuriString* replace, size_t start); + +/** + * @brief Replace a C string 'needle' to C string 'replace' in a string from 'start' position. + * By default, start is zero. + * Return STRING_FAILURE if 'needle' not found or replace position. + * @param string + * @param needle + * @param replace + * @param start + * @return size_t + */ +size_t furi_string_replace_str( + FuriString* string, + const char needle[], + const char replace[], + size_t start); + +/** + * @brief Replace all occurrences of 'needle' string into 'replace' string. + * @param string + * @param needle + * @param replace + */ +void furi_string_replace_all( + FuriString* string, + const FuriString* needle, + const FuriString* replace); + +/** + * @brief Replace all occurrences of 'needle' C string into 'replace' C string. + * @param string + * @param needle + * @param replace + */ +void furi_string_replace_all_str(FuriString* string, const char needle[], const char replace[]); + +//--------------------------------------------------------------------------- +// Start / End tests +//--------------------------------------------------------------------------- + +/** + * @brief Test if the string starts with the given string. + * @param string + * @param start + * @return bool + */ +bool furi_string_start_with(const FuriString* string, const FuriString* start); + +/** + * @brief Test if the string starts with the given C string. + * @param string + * @param start + * @return bool + */ +bool furi_string_start_with_str(const FuriString* string, const char start[]); + +/** + * @brief Test if the string ends with the given string. + * @param string + * @param end + * @return bool + */ +bool furi_string_end_with(const FuriString* string, const FuriString* end); + +/** + * @brief Test if the string ends with the given C string. + * @param string + * @param end + * @return bool + */ +bool furi_string_end_with_str(const FuriString* string, const char end[]); + +//--------------------------------------------------------------------------- +// Trim +//--------------------------------------------------------------------------- + +/** + * @brief Trim the string left to the first 'index' bytes. + * @param string + * @param index + */ +void furi_string_left(FuriString* string, size_t index); + +/** + * @brief Trim the string right from the 'index' position to the last position. + * @param string + * @param index + */ +void furi_string_right(FuriString* string, size_t index); + +/** + * @brief Trim the string from position index to size bytes. + * See also furi_string_set_n. + * @param string + * @param index + * @param size + */ +void furi_string_mid(FuriString* string, size_t index, size_t size); + +/** + * @brief Trim a string from the given set of characters (default is " \n\r\t"). + * @param string + * @param chars + */ +void furi_string_trim(FuriString* string, const char chars[]); + +//--------------------------------------------------------------------------- +// UTF8 +//--------------------------------------------------------------------------- + +/** + * @brief An unicode value. + */ +typedef unsigned int FuriStringUnicodeValue; + +/** + * @brief Compute the length in UTF8 characters in the string. + * @param string + * @return size_t + */ +size_t furi_string_utf8_length(FuriString* string); + +/** + * @brief Push unicode into string, encoding it in UTF8. + * @param string + * @param unicode + */ +void furi_string_utf8_push(FuriString* string, FuriStringUnicodeValue unicode); + +/** + * @brief State of the UTF8 decoding machine state. + */ +typedef enum { + FuriStringUTF8StateStarting, + FuriStringUTF8StateDecoding1, + FuriStringUTF8StateDecoding2, + FuriStringUTF8StateDecoding3, + FuriStringUTF8StateError +} FuriStringUTF8State; + +/** + * @brief Main generic UTF8 decoder. + * It takes a character, and the previous state and the previous value of the unicode value. + * It updates the state and the decoded unicode value. + * A decoded unicode encoded value is valid only when the state is FuriStringUTF8StateStarting. + * @param c + * @param state + * @param unicode + */ +void furi_string_utf8_decode(char c, FuriStringUTF8State* state, FuriStringUnicodeValue* unicode); + +//--------------------------------------------------------------------------- +// Lasciate ogne speranza, voi ch’entrate +//--------------------------------------------------------------------------- + +/** + * + * Select either the string function or the str function depending on + * the b operand to the function. + * func1 is the string function / func2 is the str function. + */ + +/** + * @brief Select for 1 argument + */ +#define FURI_STRING_SELECT1(func1, func2, a) \ + _Generic((a), char* : func2, const char* : func2, FuriString* : func1, const FuriString* : func1)(a) + +/** + * @brief Select for 2 arguments + */ +#define FURI_STRING_SELECT2(func1, func2, a, b) \ + _Generic((b), char* : func2, const char* : func2, FuriString* : func1, const FuriString* : func1)(a, b) + +/** + * @brief Select for 3 arguments + */ +#define FURI_STRING_SELECT3(func1, func2, a, b, c) \ + _Generic((b), char* : func2, const char* : func2, FuriString* : func1, const FuriString* : func1)(a, b, c) + +/** + * @brief Select for 4 arguments + */ +#define FURI_STRING_SELECT4(func1, func2, a, b, c, d) \ + _Generic((b), char* : func2, const char* : func2, FuriString* : func1, const FuriString* : func1)(a, b, c, d) + +/** + * @brief Allocate new FuriString and set it content to string (or C string). + * ([c]string) + */ +#define furi_string_alloc_set(a) \ + FURI_STRING_SELECT1(furi_string_alloc_set, furi_string_alloc_set_str, a) + +/** + * @brief Set the string content to string (or C string). + * (string, [c]string) + */ +#define furi_string_set(a, b) FURI_STRING_SELECT2(furi_string_set, furi_string_set_str, a, b) + +/** + * @brief Compare string with string (or C string) and return the sort order. + * Note: doesn't work with UTF-8 strings. + * (string, [c]string) + */ +#define furi_string_cmp(a, b) FURI_STRING_SELECT2(furi_string_cmp, furi_string_cmp_str, a, b) + +/** + * @brief Compare string with string (or C string) (case insensitive according to the current locale) and return the sort order. + * Note: doesn't work with UTF-8 strings. + * (string, [c]string) + */ +#define furi_string_cmpi(a, b) FURI_STRING_SELECT2(furi_string_cmpi, furi_string_cmpi_str, a, b) + +/** + * @brief Test if the string is equal to the string (or C string). + * (string, [c]string) + */ +#define furi_string_equal(a, b) FURI_STRING_SELECT2(furi_string_equal, furi_string_equal_str, a, b) + +/** + * @brief Replace all occurrences of string into string (or C string to another C string) in a string. + * (string, [c]string, [c]string) + */ +#define furi_string_replace_all(a, b, c) \ + FURI_STRING_SELECT3(furi_string_replace_all, furi_string_replace_all_str, a, b, c) + +/** + * @brief Search for a string (or C string) in a string + * (string, [c]string[, start=0]) + */ +#define furi_string_search(v, ...) \ + M_APPLY( \ + FURI_STRING_SELECT3, \ + furi_string_search, \ + furi_string_search_str, \ + v, \ + M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Search for a C string in a string + * (string, cstring[, start=0]) + */ +#define furi_string_search_str(v, ...) \ + M_APPLY(furi_string_search_str, v, M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Test if the string starts with the given string (or C string). + * (string, [c]string) + */ +#define furi_string_start_with(a, b) \ + FURI_STRING_SELECT2(furi_string_start_with, furi_string_start_with_str, a, b) + +/** + * @brief Test if the string ends with the given string (or C string). + * (string, [c]string) + */ +#define furi_string_end_with(a, b) \ + FURI_STRING_SELECT2(furi_string_end_with, furi_string_end_with_str, a, b) + +/** + * @brief Append a string (or C string) to the string. + * (string, [c]string) + */ +#define furi_string_cat(a, b) FURI_STRING_SELECT2(furi_string_cat, furi_string_cat_str, a, b) + +/** + * @brief Trim a string from the given set of characters (default is " \n\r\t"). + * (string[, set=" \n\r\t"]) + */ +#define furi_string_trim(...) M_APPLY(furi_string_trim, M_IF_DEFAULT1(" \n\r\t", __VA_ARGS__)) + +/** + * @brief Search for a character in a string. + * (string, character[, start=0]) + */ +#define furi_string_search_char(v, ...) \ + M_APPLY(furi_string_search_char, v, M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Reverse Search for a character in a string. + * (string, character[, start=0]) + */ +#define furi_string_search_rchar(v, ...) \ + M_APPLY(furi_string_search_rchar, v, M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Replace a string to another string (or C string to another C string) in a string. + * (string, [c]string, [c]string[, start=0]) + */ +#define furi_string_replace(a, b, ...) \ + M_APPLY( \ + FURI_STRING_SELECT4, \ + furi_string_replace, \ + furi_string_replace_str, \ + a, \ + b, \ + M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief Replace a C string to another C string in a string. + * (string, cstring, cstring[, start=0]) + */ +#define furi_string_replace_str(a, b, ...) \ + M_APPLY(furi_string_replace_str, a, b, M_IF_DEFAULT1(0, __VA_ARGS__)) + +/** + * @brief INIT OPLIST for FuriString. + */ +#define F_STR_INIT(a) ((a) = furi_string_alloc()) + +/** + * @brief INIT SET OPLIST for FuriString. + */ +#define F_STR_INIT_SET(a, b) ((a) = furi_string_alloc_set(b)) + +/** + * @brief OPLIST for FuriString. + */ +#define FURI_STRING_OPLIST \ + (INIT(F_STR_INIT), \ + INIT_SET(F_STR_INIT_SET), \ + SET(furi_string_set), \ + INIT_MOVE(furi_string_alloc_move), \ + MOVE(furi_string_move), \ + SWAP(furi_string_swap), \ + RESET(furi_string_reset), \ + EMPTY_P(furi_string_empty), \ + CLEAR(furi_string_free), \ + HASH(furi_string_hash), \ + EQUAL(furi_string_equal), \ + CMP(furi_string_cmp), \ + TYPE(FuriString*)) + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/furi/core/thread.c b/furi/core/thread.c index 58cb9bc09..508146f63 100644 --- a/furi/core/thread.c +++ b/furi/core/thread.c @@ -5,10 +5,10 @@ #include "check.h" #include "common_defines.h" #include "mutex.h" +#include "string.h" #include #include "log.h" -#include #include #include @@ -18,7 +18,7 @@ typedef struct FuriThreadStdout FuriThreadStdout; struct FuriThreadStdout { FuriThreadStdoutWriteCallback write_callback; - string_t buffer; + FuriString* buffer; }; struct FuriThread { @@ -85,7 +85,6 @@ static void furi_thread_body(void* context) { } furi_assert(thread->state == FuriThreadStateRunning); - furi_thread_set_state(thread, FuriThreadStateStopped); if(thread->is_service) { FURI_LOG_E( @@ -94,18 +93,24 @@ static void furi_thread_body(void* context) { thread->name ? thread->name : ""); } - // clear thread local storage + // flush stdout __furi_thread_stdout_flush(thread); + + // from here we can't use thread pointer + furi_thread_set_state(thread, FuriThreadStateStopped); + + // clear thread local storage furi_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) != NULL); vTaskSetThreadLocalStoragePointer(NULL, 0, NULL); - vTaskDelete(thread->task_handle); + thread->task_handle = NULL; + vTaskDelete(NULL); furi_thread_catch(); } FuriThread* furi_thread_alloc() { FuriThread* thread = malloc(sizeof(FuriThread)); - string_init(thread->output.buffer); + thread->output.buffer = furi_string_alloc(); thread->is_service = false; return thread; } @@ -115,7 +120,7 @@ void furi_thread_free(FuriThread* thread) { furi_assert(thread->state == FuriThreadStateStopped); if(thread->name) free((void*)thread->name); - string_clear(thread->output.buffer); + furi_string_free(thread->output.buffer); free(thread); } @@ -205,11 +210,14 @@ void furi_thread_start(FuriThread* thread) { bool furi_thread_join(FuriThread* thread) { furi_assert(thread); - while(thread->state != FuriThreadStateStopped) { + furi_check(furi_thread_get_current() != thread); + + // Wait for thread to stop + while(thread->task_handle) { furi_delay_ms(10); } - return FuriStatusOk; + return true; } FuriThreadId furi_thread_get_id(FuriThread* thread) { @@ -473,11 +481,11 @@ static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, s } static int32_t __furi_thread_stdout_flush(FuriThread* thread) { - string_ptr buffer = thread->output.buffer; - size_t size = string_size(buffer); + FuriString* buffer = thread->output.buffer; + size_t size = furi_string_size(buffer); if(size > 0) { - __furi_thread_stdout_write(thread, string_get_cstr(buffer), size); - string_reset(buffer); + __furi_thread_stdout_write(thread, furi_string_get_cstr(buffer), size); + furi_string_reset(buffer); } return 0; } @@ -504,7 +512,7 @@ size_t furi_thread_stdout_write(const char* data, size_t size) { } else { // string_cat doesn't work here because we need to write the exact size data for(size_t i = 0; i < size; i++) { - string_push_back(thread->output.buffer, data[i]); + furi_string_push_back(thread->output.buffer, data[i]); if(data[i] == '\n') { __furi_thread_stdout_flush(thread); } diff --git a/furi/furi.h b/furi/furi.h index 68914b502..3ce834227 100644 --- a/furi/furi.h +++ b/furi/furi.h @@ -2,21 +2,23 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "core/check.h" +#include "core/common_defines.h" +#include "core/event_flag.h" +#include "core/kernel.h" +#include "core/log.h" +#include "core/memmgr.h" +#include "core/memmgr_heap.h" +#include "core/message_queue.h" +#include "core/mutex.h" +#include "core/pubsub.h" +#include "core/record.h" +#include "core/semaphore.h" +#include "core/thread.h" +#include "core/timer.h" +#include "core/valuemutex.h" +#include "core/string.h" +#include "core/stream_buffer.h" #include diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c index e26165495..3fe57162f 100644 --- a/lib/flipper_application/elf/elf_file.c +++ b/lib/flipper_application/elf/elf_file.c @@ -57,11 +57,26 @@ static ELFSection* elf_file_get_section(ELFFile* elf, const char* name) { return ELFSectionDict_get(elf->sections, name); } -static void elf_file_put_section(ELFFile* elf, const char* name, ELFSection* section) { - ELFSectionDict_set_at(elf->sections, strdup(name), *section); +static ELFSection* elf_file_get_or_put_section(ELFFile* elf, const char* name) { + ELFSection* section_p = elf_file_get_section(elf, name); + if(!section_p) { + ELFSectionDict_set_at( + elf->sections, + strdup(name), + (ELFSection){ + .data = NULL, + .sec_idx = 0, + .size = 0, + .rel_count = 0, + .rel_offset = 0, + }); + section_p = elf_file_get_section(elf, name); + } + + return section_p; } -static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t name) { +static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, FuriString* name) { bool result = false; off_t old = storage_file_tell(elf->fd); @@ -74,7 +89,7 @@ static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t nam while(true) { uint16_t read = storage_file_read(elf->fd, buffer, ELF_NAME_BUFFER_LEN); - string_cat_str(name, buffer); + furi_string_cat(name, buffer); if(strlen(buffer) < ELF_NAME_BUFFER_LEN) { result = true; break; @@ -89,11 +104,11 @@ static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t nam return result; } -static bool elf_read_section_name(ELFFile* elf, off_t offset, string_t name) { +static bool elf_read_section_name(ELFFile* elf, off_t offset, FuriString* name) { return elf_read_string_from_offset(elf, elf->section_table_strings + offset, name); } -static bool elf_read_symbol_name(ELFFile* elf, off_t offset, string_t name) { +static bool elf_read_symbol_name(ELFFile* elf, off_t offset, FuriString* name) { return elf_read_string_from_offset(elf, elf->symbol_table_strings + offset, name); } @@ -103,8 +118,11 @@ static bool elf_read_section_header(ELFFile* elf, size_t section_idx, Elf32_Shdr storage_file_read(elf->fd, section_header, sizeof(Elf32_Shdr)) == sizeof(Elf32_Shdr); } -static bool - elf_read_section(ELFFile* elf, size_t section_idx, Elf32_Shdr* section_header, string_t name) { +static bool elf_read_section( + ELFFile* elf, + size_t section_idx, + Elf32_Shdr* section_header, + FuriString* name) { if(!elf_read_section_header(elf, section_idx, section_header)) { return false; } @@ -116,7 +134,7 @@ static bool return true; } -static bool elf_read_symbol(ELFFile* elf, int n, Elf32_Sym* sym, string_t name) { +static bool elf_read_symbol(ELFFile* elf, int n, Elf32_Sym* sym, FuriString* name) { bool success = false; off_t old = storage_file_tell(elf->fd); off_t pos = elf->symbol_table + n * sizeof(Elf32_Sym); @@ -276,19 +294,17 @@ static void elf_relocate_mov(Elf32_Addr relAddr, int type, Elf32_Addr symAddr) { int32_t addend = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; /* imm16 */ uint32_t addr = (symAddr + addend); - if (type == R_ARM_THM_MOVT_ABS) { + if(type == R_ARM_THM_MOVT_ABS) { addr >>= 16; /* upper 16 bits */ } else { addr &= 0x0000FFFF; /* lower 16 bits */ } /* Re-encode */ - ((uint16_t*)relAddr)[0] = (upper_insn & 0xFBF0) - | (((addr >> 11) & 1) << 10) /* i */ - | ((addr >> 12) & 0x000F); /* imm4 */ - ((uint16_t*)relAddr)[1] = (lower_insn & 0x8F00) - | (((addr >> 8) & 0x7) << 12) /* imm3 */ - | (addr & 0x00FF); /* imm8 */ + ((uint16_t*)relAddr)[0] = (upper_insn & 0xFBF0) | (((addr >> 11) & 1) << 10) /* i */ + | ((addr >> 12) & 0x000F); /* imm4 */ + ((uint16_t*)relAddr)[1] = (lower_insn & 0x8F00) | (((addr >> 8) & 0x7) << 12) /* imm3 */ + | (addr & 0x00FF); /* imm8 */ } static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf32_Addr symAddr) { @@ -307,7 +323,10 @@ static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf3 case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: elf_relocate_mov(relAddr, type, symAddr); - FURI_LOG_D(TAG, " R_ARM_THM_MOVW_ABS_NC/MOVT_ABS relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr)); + FURI_LOG_D( + TAG, + " R_ARM_THM_MOVW_ABS_NC/MOVT_ABS relocated is 0x%08X", + (unsigned int)*((uint32_t*)relAddr)); break; default: FURI_LOG_E(TAG, " Undefined relocation %d", type); @@ -316,17 +335,17 @@ static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf3 return true; } -static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { +static bool elf_relocate(ELFFile* elf, ELFSection* s) { if(s->data) { Elf32_Rel rel; - size_t relEntries = h->sh_size / sizeof(rel); + size_t relEntries = s->rel_count; size_t relCount; - (void)storage_file_seek(elf->fd, h->sh_offset, true); + (void)storage_file_seek(elf->fd, s->rel_offset, true); FURI_LOG_D(TAG, " Offset Info Type Name"); int relocate_result = true; - string_t symbol_name; - string_init(symbol_name); + FuriString* symbol_name; + symbol_name = furi_string_alloc(); for(relCount = 0; relCount < relEntries; relCount++) { if(relCount % RESOLVER_THREAD_YIELD_STEP == 0) { @@ -336,7 +355,7 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { if(storage_file_read(elf->fd, &rel, sizeof(Elf32_Rel)) != sizeof(Elf32_Rel)) { FURI_LOG_E(TAG, " reloc read fail"); - string_clear(symbol_name); + furi_string_free(symbol_name); return false; } @@ -348,10 +367,10 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { if(!address_cache_get(elf->relocation_cache, symEntry, &symAddr)) { Elf32_Sym sym; - string_reset(symbol_name); + furi_string_reset(symbol_name); if(!elf_read_symbol(elf, symEntry, &sym, symbol_name)) { FURI_LOG_E(TAG, " symbol read fail"); - string_clear(symbol_name); + furi_string_free(symbol_name); return false; } @@ -361,9 +380,9 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { (unsigned int)rel.r_offset, (unsigned int)rel.r_info, elf_reloc_type_to_str(relType), - string_get_cstr(symbol_name)); + furi_string_get_cstr(symbol_name)); - symAddr = elf_address_of(elf, &sym, string_get_cstr(symbol_name)); + symAddr = elf_address_of(elf, &sym, furi_string_get_cstr(symbol_name)); address_cache_put(elf->relocation_cache, symEntry, symAddr); } @@ -377,11 +396,11 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { relocate_result = false; } } else { - FURI_LOG_E(TAG, " No symbol address of %s", string_get_cstr(symbol_name)); + FURI_LOG_E(TAG, " No symbol address of %s", furi_string_get_cstr(symbol_name)); relocate_result = false; } } - string_clear(symbol_name); + furi_string_free(symbol_name); return relocate_result; } else { @@ -391,14 +410,6 @@ static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) { return false; } -/**************************************************************************************************/ -/********************************************* MISC ***********************************************/ -/**************************************************************************************************/ - -static bool cstr_prefix(const char* prefix, const char* string) { - return strncmp(prefix, string, strlen(prefix)) == 0; -} - /**************************************************************************************************/ /************************************ Internal FAP interfaces *************************************/ /**************************************************************************************************/ @@ -441,81 +452,137 @@ static bool elf_load_debug_link(ELFFile* elf, Elf32_Shdr* section_header) { section_header->sh_size; } +static bool str_prefix(const char* str, const char* prefix) { + return strncmp(prefix, str, strlen(prefix)) == 0; +} + +static bool elf_load_section_data(ELFFile* elf, ELFSection* section, Elf32_Shdr* section_header) { + if(section_header->sh_size == 0) { + FURI_LOG_D(TAG, "No data for section"); + return true; + } + + section->data = aligned_malloc(section_header->sh_size, section_header->sh_addralign); + section->size = section_header->sh_size; + + if(section_header->sh_type == SHT_NOBITS) { + // BSS section, no data to load + return true; + } + + if((!storage_file_seek(elf->fd, section_header->sh_offset, true)) || + (storage_file_read(elf->fd, section->data, section_header->sh_size) != + section_header->sh_size)) { + FURI_LOG_E(TAG, " seek/read fail"); + return false; + } + + FURI_LOG_D(TAG, "0x%X", section->data); + return true; +} + static SectionType elf_preload_section( ELFFile* elf, size_t section_idx, Elf32_Shdr* section_header, - string_t name_string, + FuriString* name_string, FlipperApplicationManifest* manifest) { - const char* name = string_get_cstr(name_string); + const char* name = furi_string_get_cstr(name_string); - const struct { - const char* prefix; - SectionType type; - } lookup_sections[] = { - {".text", SectionTypeData}, - {".rodata", SectionTypeData}, - {".data", SectionTypeData}, - {".bss", SectionTypeData}, - {".preinit_array", SectionTypeData}, - {".init_array", SectionTypeData}, - {".fini_array", SectionTypeData}, - {".rel.text", SectionTypeRelData}, - {".rel.rodata", SectionTypeRelData}, - {".rel.data", SectionTypeRelData}, - {".rel.preinit_array", SectionTypeRelData}, - {".rel.init_array", SectionTypeRelData}, - {".rel.fini_array", SectionTypeRelData}, - }; +#ifdef ELF_DEBUG_LOG + // log section name, type and flags + FuriString* flags_string = furi_string_alloc(); + if(section_header->sh_flags & SHF_WRITE) furi_string_cat(flags_string, "W"); + if(section_header->sh_flags & SHF_ALLOC) furi_string_cat(flags_string, "A"); + if(section_header->sh_flags & SHF_EXECINSTR) furi_string_cat(flags_string, "X"); + if(section_header->sh_flags & SHF_MERGE) furi_string_cat(flags_string, "M"); + if(section_header->sh_flags & SHF_STRINGS) furi_string_cat(flags_string, "S"); + if(section_header->sh_flags & SHF_INFO_LINK) furi_string_cat(flags_string, "I"); + if(section_header->sh_flags & SHF_LINK_ORDER) furi_string_cat(flags_string, "L"); + if(section_header->sh_flags & SHF_OS_NONCONFORMING) furi_string_cat(flags_string, "O"); + if(section_header->sh_flags & SHF_GROUP) furi_string_cat(flags_string, "G"); + if(section_header->sh_flags & SHF_TLS) furi_string_cat(flags_string, "T"); + if(section_header->sh_flags & SHF_COMPRESSED) furi_string_cat(flags_string, "T"); + if(section_header->sh_flags & SHF_MASKOS) furi_string_cat(flags_string, "o"); + if(section_header->sh_flags & SHF_MASKPROC) furi_string_cat(flags_string, "p"); + if(section_header->sh_flags & SHF_ORDERED) furi_string_cat(flags_string, "R"); + if(section_header->sh_flags & SHF_EXCLUDE) furi_string_cat(flags_string, "E"); - for(size_t i = 0; i < COUNT_OF(lookup_sections); i++) { - if(cstr_prefix(lookup_sections[i].prefix, name)) { - FURI_LOG_D(TAG, "Found section %s", lookup_sections[i].prefix); + FURI_LOG_I( + TAG, + "Section %s: type: %ld, flags: %s", + name, + section_header->sh_type, + furi_string_get_cstr(flags_string)); + furi_string_free(flags_string); +#endif - if(lookup_sections[i].type == SectionTypeRelData) { - name = name + strlen(".rel"); - } + // ignore .ARM and .rel.ARM sections + // TODO: how to do it not by name? + // .ARM: type 0x70000001, flags SHF_ALLOC | SHF_LINK_ORDER + // .rel.ARM: type 0x9, flags SHT_REL + if(str_prefix(name, ".ARM.") || str_prefix(name, ".rel.ARM.")) { + FURI_LOG_D(TAG, "Ignoring ARM section"); + return SectionTypeUnused; + } - ELFSection* section_p = elf_file_get_section(elf, name); - if(!section_p) { - ELFSection section = { - .data = NULL, - .sec_idx = 0, - .rel_sec_idx = 0, - .size = 0, - }; + // Load allocable section + if(section_header->sh_flags & SHF_ALLOC) { + ELFSection* section_p = elf_file_get_or_put_section(elf, name); + section_p->sec_idx = section_idx; - elf_file_put_section(elf, name, §ion); - section_p = elf_file_get_section(elf, name); - } + if(section_header->sh_type == SHT_PREINIT_ARRAY) { + elf->preinit_array = section_p; + } else if(section_header->sh_type == SHT_INIT_ARRAY) { + elf->init_array = section_p; + } else if(section_header->sh_type == SHT_FINI_ARRAY) { + elf->fini_array = section_p; + } - if(lookup_sections[i].type == SectionTypeRelData) { - section_p->rel_sec_idx = section_idx; - } else { - section_p->sec_idx = section_idx; - } - - return lookup_sections[i].type; + if(!elf_load_section_data(elf, section_p, section_header)) { + FURI_LOG_E(TAG, "Error loading section '%s'", name); + return SectionTypeERROR; + } else { + return SectionTypeData; } } + // Load link info section + if(section_header->sh_flags & SHF_INFO_LINK) { + name = name + strlen(".rel"); + ELFSection* section_p = elf_file_get_or_put_section(elf, name); + section_p->rel_count = section_header->sh_size / sizeof(Elf32_Rel); + section_p->rel_offset = section_header->sh_offset; + return SectionTypeRelData; + } + + // Load symbol table if(strcmp(name, ".symtab") == 0) { FURI_LOG_D(TAG, "Found .symtab section"); elf->symbol_table = section_header->sh_offset; elf->symbol_count = section_header->sh_size / sizeof(Elf32_Sym); return SectionTypeSymTab; - } else if(strcmp(name, ".strtab") == 0) { + } + + // Load string table + if(strcmp(name, ".strtab") == 0) { FURI_LOG_D(TAG, "Found .strtab section"); elf->symbol_table_strings = section_header->sh_offset; return SectionTypeStrTab; - } else if(strcmp(name, ".fapmeta") == 0) { + } + + // Load manifest section + if(strcmp(name, ".fapmeta") == 0) { FURI_LOG_D(TAG, "Found .fapmeta section"); if(elf_load_metadata(elf, section_header, manifest)) { return SectionTypeManifest; } else { return SectionTypeERROR; } - } else if(strcmp(name, ".gnu_debuglink") == 0) { + } + + // Load debug link section + if(strcmp(name, ".gnu_debuglink") == 0) { FURI_LOG_D(TAG, "Found .gnu_debuglink section"); if(elf_load_debug_link(elf, section_header)) { return SectionTypeDebugLink; @@ -527,61 +594,17 @@ static SectionType elf_preload_section( return SectionTypeUnused; } -static bool elf_load_section_data(ELFFile* elf, ELFSection* section) { - Elf32_Shdr section_header; - if(section->sec_idx == 0) { - FURI_LOG_D(TAG, "Section is not present"); - return true; - } - - if(!elf_read_section_header(elf, section->sec_idx, §ion_header)) { - return false; - } - - if(section_header.sh_size == 0) { - FURI_LOG_D(TAG, "No data for section"); - return true; - } - - section->data = aligned_malloc(section_header.sh_size, section_header.sh_addralign); - section->size = section_header.sh_size; - - if(section_header.sh_type == SHT_NOBITS) { - /* section is empty (.bss?) */ - /* no need to memset - allocator already did that */ - return true; - } - - if((!storage_file_seek(elf->fd, section_header.sh_offset, true)) || - (storage_file_read(elf->fd, section->data, section_header.sh_size) != - section_header.sh_size)) { - FURI_LOG_E(TAG, " seek/read fail"); - return false; - } - - FURI_LOG_D(TAG, "0x%X", section->data); - return true; -} - static bool elf_relocate_section(ELFFile* elf, ELFSection* section) { - Elf32_Shdr section_header; - if(section->rel_sec_idx) { + if(section->rel_count) { FURI_LOG_D(TAG, "Relocating section"); - if(elf_read_section_header(elf, section->rel_sec_idx, §ion_header)) - return elf_relocate(elf, §ion_header, section); - else { - FURI_LOG_E(TAG, "Error reading section header"); - return false; - } + return elf_relocate(elf, section); } else { FURI_LOG_D(TAG, "No relocation index"); /* Not an error */ } return true; } -static void elf_file_call_section_list(ELFFile* elf, const char* name, bool reverse_order) { - ELFSection* section = elf_file_get_section(elf, name); - +static void elf_file_call_section_list(ELFSection* section, bool reverse_order) { if(section && section->size) { const uint32_t* start = section->data; const uint32_t* end = section->data + section->size; @@ -670,19 +693,19 @@ bool elf_file_open(ELFFile* elf, const char* path) { bool elf_file_load_manifest(ELFFile* elf, FlipperApplicationManifest* manifest) { bool result = false; - string_t name; - string_init(name); + FuriString* name; + name = furi_string_alloc(); FURI_LOG_D(TAG, "Looking for manifest section"); for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) { Elf32_Shdr section_header; - string_reset(name); + furi_string_reset(name); if(!elf_read_section(elf, section_idx, §ion_header, name)) { break; } - if(string_cmp(name, ".fapmeta") == 0) { + if(furi_string_cmp(name, ".fapmeta") == 0) { if(elf_load_metadata(elf, §ion_header, manifest)) { FURI_LOG_D(TAG, "Load manifest done"); result = true; @@ -693,26 +716,27 @@ bool elf_file_load_manifest(ELFFile* elf, FlipperApplicationManifest* manifest) } } - string_clear(name); + furi_string_free(name); return result; } bool elf_file_load_section_table(ELFFile* elf, FlipperApplicationManifest* manifest) { SectionType loaded_sections = SectionTypeERROR; - string_t name; - string_init(name); + FuriString* name; + name = furi_string_alloc(); FURI_LOG_D(TAG, "Scan ELF indexs..."); for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) { Elf32_Shdr section_header; - string_reset(name); + furi_string_reset(name); if(!elf_read_section(elf, section_idx, §ion_header, name)) { loaded_sections = SectionTypeERROR; break; } - FURI_LOG_D(TAG, "Preloading data for section #%d %s", section_idx, string_get_cstr(name)); + FURI_LOG_D( + TAG, "Preloading data for section #%d %s", section_idx, furi_string_get_cstr(name)); SectionType section_type = elf_preload_section(elf, section_idx, §ion_header, name, manifest); loaded_sections |= section_type; @@ -723,8 +747,7 @@ bool elf_file_load_section_table(ELFFile* elf, FlipperApplicationManifest* manif } } - string_clear(name); - FURI_LOG_D(TAG, "Load symbols done"); + furi_string_free(name); return IS_FLAGS_SET(loaded_sections, SectionTypeValid); } @@ -734,16 +757,6 @@ ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) { ELFSectionDict_it_t it; AddressCache_init(elf->relocation_cache); - size_t start = furi_get_tick(); - - for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it); ELFSectionDict_next(it)) { - ELFSectionDict_itref_t* itref = ELFSectionDict_ref(it); - FURI_LOG_D(TAG, "Loading section '%s'", itref->key); - if(!elf_load_section_data(elf, &itref->value)) { - FURI_LOG_E(TAG, "Error loading section '%s'", itref->key); - status = ELFFileLoadStatusUnspecifiedError; - } - } if(status == ELFFileLoadStatusSuccess) { for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it); @@ -772,14 +785,13 @@ ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) { FURI_LOG_D(TAG, "Relocation cache size: %u", AddressCache_size(elf->relocation_cache)); FURI_LOG_D(TAG, "Trampoline cache size: %u", AddressCache_size(elf->trampoline_cache)); AddressCache_clear(elf->relocation_cache); - FURI_LOG_I(TAG, "Loaded in %ums", (size_t)(furi_get_tick() - start)); return status; } void elf_file_pre_run(ELFFile* elf) { - elf_file_call_section_list(elf, ".preinit_array", false); - elf_file_call_section_list(elf, ".init_array", false); + elf_file_call_section_list(elf->preinit_array, false); + elf_file_call_section_list(elf->init_array, false); } int32_t elf_file_run(ELFFile* elf, void* args) { @@ -789,7 +801,7 @@ int32_t elf_file_run(ELFFile* elf, void* args) { } void elf_file_post_run(ELFFile* elf) { - elf_file_call_section_list(elf, ".fini_array", true); + elf_file_call_section_list(elf->fini_array, true); } const ElfApiInterface* elf_file_get_api_interface(ELFFile* elf_file) { diff --git a/lib/flipper_application/elf/elf_file_i.h b/lib/flipper_application/elf/elf_file_i.h index 1df075f06..9b38540b7 100644 --- a/lib/flipper_application/elf/elf_file_i.h +++ b/lib/flipper_application/elf/elf_file_i.h @@ -16,8 +16,10 @@ typedef int32_t(entry_t)(void*); typedef struct { void* data; uint16_t sec_idx; - uint16_t rel_sec_idx; Elf32_Word size; + + size_t rel_count; + Elf32_Off rel_offset; } ELFSection; DICT_DEF2(ELFSectionDict, const char*, M_CSTR_OPLIST, ELFSection, M_POD_OPLIST) @@ -39,6 +41,10 @@ struct ELFFile { File* fd; const ElfApiInterface* api_interface; ELFDebugLinkInfo debug_link_info; + + ELFSection* preinit_array; + ELFSection* init_array; + ELFSection* fini_array; }; #ifdef __cplusplus diff --git a/lib/flipper_format/flipper_format.c b/lib/flipper_format/flipper_format.c index 620051276..292dab5f1 100644 --- a/lib/flipper_format/flipper_format.c +++ b/lib/flipper_format/flipper_format.c @@ -137,7 +137,7 @@ bool flipper_format_key_exist(FlipperFormat* flipper_format, const char* key) { bool flipper_format_read_header( FlipperFormat* flipper_format, - string_t filetype, + FuriString* filetype, uint32_t* version) { furi_assert(flipper_format); return flipper_format_read_string(flipper_format, flipper_format_filetype_key, filetype) && @@ -146,10 +146,11 @@ bool flipper_format_read_header( bool flipper_format_write_header( FlipperFormat* flipper_format, - string_t filetype, + FuriString* filetype, const uint32_t version) { furi_assert(flipper_format); - return flipper_format_write_header_cstr(flipper_format, string_get_cstr(filetype), version); + return flipper_format_write_header_cstr( + flipper_format, furi_string_get_cstr(filetype), version); } bool flipper_format_write_header_cstr( @@ -171,18 +172,18 @@ bool flipper_format_get_value_count( flipper_format->stream, key, count, flipper_format->strict_mode); } -bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, string_t data) { +bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, FuriString* data) { furi_assert(flipper_format); return flipper_format_stream_read_value_line( flipper_format->stream, key, FlipperStreamValueStr, data, 1, flipper_format->strict_mode); } -bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, string_t data) { +bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, FuriString* data) { furi_assert(flipper_format); FlipperStreamWriteData write_data = { .key = key, .type = FlipperStreamValueStr, - .data = string_get_cstr(data), + .data = furi_string_get_cstr(data), .data_size = 1, }; bool result = flipper_format_stream_write_value_line(flipper_format->stream, &write_data); @@ -386,9 +387,9 @@ bool flipper_format_write_hex( return result; } -bool flipper_format_write_comment(FlipperFormat* flipper_format, string_t data) { +bool flipper_format_write_comment(FlipperFormat* flipper_format, FuriString* data) { furi_assert(flipper_format); - return flipper_format_write_comment_cstr(flipper_format, string_get_cstr(data)); + return flipper_format_write_comment_cstr(flipper_format, furi_string_get_cstr(data)); } bool flipper_format_write_comment_cstr(FlipperFormat* flipper_format, const char* data) { @@ -409,12 +410,12 @@ bool flipper_format_delete_key(FlipperFormat* flipper_format, const char* key) { return result; } -bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, string_t data) { +bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, FuriString* data) { furi_assert(flipper_format); FlipperStreamWriteData write_data = { .key = key, .type = FlipperStreamValueStr, - .data = string_get_cstr(data), + .data = furi_string_get_cstr(data), .data_size = 1, }; bool result = flipper_format_stream_delete_key_and_write( @@ -522,7 +523,7 @@ bool flipper_format_update_hex( bool flipper_format_insert_or_update_string( FlipperFormat* flipper_format, const char* key, - string_t data) { + FuriString* data) { bool result = false; if(!flipper_format_key_exist(flipper_format, key)) { diff --git a/lib/flipper_format/flipper_format.h b/lib/flipper_format/flipper_format.h index 9e82bb311..743918e3b 100644 --- a/lib/flipper_format/flipper_format.h +++ b/lib/flipper_format/flipper_format.h @@ -70,13 +70,13 @@ * * do { * uint32_t version = 1; - * string_t file_type; - * string_t string_value; + * FuriString* file_type; + * FuriString* string_value; * uint32_t uint32_value = 1; * uint16_t array_size = 4; * uint8_t* array[array_size] = {0}; - * string_init(file_type); - * string_init(string_value); + * file_type = furi_string_alloc(); + * string_value = furi_string_alloc(); * * if(!flipper_format_file_open_existing(file, EXT_PATH("flipper_format_test"))) break; * if(!flipper_format_read_header(file, file_type, &version)) break; @@ -94,7 +94,6 @@ #pragma once #include -#include #include #ifdef __cplusplus @@ -227,7 +226,7 @@ bool flipper_format_key_exist(FlipperFormat* flipper_format, const char* key); */ bool flipper_format_read_header( FlipperFormat* flipper_format, - string_t filetype, + FuriString* filetype, uint32_t* version); /** @@ -239,7 +238,7 @@ bool flipper_format_read_header( */ bool flipper_format_write_header( FlipperFormat* flipper_format, - string_t filetype, + FuriString* filetype, const uint32_t version); /** @@ -273,7 +272,7 @@ bool flipper_format_get_value_count( * @param data Value * @return True on success */ -bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, string_t data); +bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, FuriString* data); /** * Write key and string @@ -282,7 +281,7 @@ bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, * @param data Value * @return True on success */ -bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, string_t data); +bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, FuriString* data); /** * Write key and string. Plain C string version. @@ -470,7 +469,7 @@ bool flipper_format_write_hex( * @param data Comment text * @return True on success */ -bool flipper_format_write_comment(FlipperFormat* flipper_format, string_t data); +bool flipper_format_write_comment(FlipperFormat* flipper_format, FuriString* data); /** * Write comment. Plain C string version. @@ -495,7 +494,7 @@ bool flipper_format_delete_key(FlipperFormat* flipper_format, const char* key); * @param data Value * @return True on success */ -bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, string_t data); +bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, FuriString* data); /** * Updates the value of the first matching key to a string value. Plain C version. Sets the RW pointer to a position at the end of inserted data. @@ -585,7 +584,7 @@ bool flipper_format_update_hex( bool flipper_format_insert_or_update_string( FlipperFormat* flipper_format, const char* key, - string_t data); + FuriString* data); /** * Updates the value of the first matching key to a string value, or adds the key and value if the key did not exist. diff --git a/lib/flipper_format/flipper_format_stream.c b/lib/flipper_format/flipper_format_stream.c index e4b7b3003..41934a3b1 100644 --- a/lib/flipper_format/flipper_format_stream.c +++ b/lib/flipper_format/flipper_format_stream.c @@ -4,6 +4,10 @@ #include "flipper_format_stream.h" #include "flipper_format_stream_i.h" +static inline bool flipper_format_stream_is_space(char c) { + return c == ' ' || c == '\t' || c == flipper_format_eolr; +} + static bool flipper_format_stream_write(Stream* stream, const void* data, size_t data_size) { size_t bytes_written = stream_write(stream, data, data_size); return bytes_written == data_size; @@ -26,8 +30,8 @@ bool flipper_format_stream_write_eol(Stream* stream) { return flipper_format_stream_write(stream, &flipper_format_eoln, 1); } -static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { - string_reset(key); +static bool flipper_format_stream_read_valid_key(Stream* stream, FuriString* key) { + furi_string_reset(key); const size_t buffer_size = 32; uint8_t buffer[buffer_size]; @@ -44,7 +48,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { uint8_t data = buffer[i]; if(data == flipper_format_eoln) { // EOL found, clean data, start accumulating data and set the new_line flag - string_reset(key); + furi_string_reset(key); accumulate = true; new_line = true; } else if(data == flipper_format_eolr) { @@ -60,7 +64,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { // this can only be if we have previously found some kind of key, so // clear the data, set the flag that we no longer want to accumulate data // and reset the new_line flag - string_reset(key); + furi_string_reset(key); accumulate = false; new_line = false; } else { @@ -82,7 +86,7 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { new_line = false; if(accumulate) { // and accumulate data if we want - string_push_back(key, data); + furi_string_push_back(key, data); } } } @@ -95,13 +99,13 @@ static bool flipper_format_stream_read_valid_key(Stream* stream, string_t key) { bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool strict_mode) { bool found = false; - string_t read_key; + FuriString* read_key; - string_init(read_key); + read_key = furi_string_alloc(); while(!stream_eof(stream)) { if(flipper_format_stream_read_valid_key(stream, read_key)) { - if(string_cmp_str(read_key, key) == 0) { + if(furi_string_cmp_str(read_key, key) == 0) { if(!stream_seek(stream, 2, StreamOffsetFromCurrent)) break; found = true; @@ -112,61 +116,70 @@ bool flipper_format_stream_seek_to_key(Stream* stream, const char* key, bool str } } } - string_clear(read_key); + furi_string_free(read_key); return found; } -static bool flipper_format_stream_read_value(Stream* stream, string_t value, bool* last) { - string_reset(value); +static bool flipper_format_stream_read_value(Stream* stream, FuriString* value, bool* last) { + enum { LeadingSpace, ReadValue, TrailingSpace } state = LeadingSpace; const size_t buffer_size = 32; uint8_t buffer[buffer_size]; bool result = false; bool error = false; + furi_string_reset(value); + while(true) { size_t was_read = stream_read(stream, buffer, buffer_size); if(was_read == 0) { - // check EOF - if(stream_eof(stream) && string_size(value) > 0) { + if(state != LeadingSpace && stream_eof(stream)) { result = true; *last = true; - break; + } else { + error = true; } } for(uint16_t i = 0; i < was_read; i++) { - uint8_t data = buffer[i]; - if(data == flipper_format_eoln) { - if(string_size(value) > 0) { - if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { - error = true; - break; - } + const uint8_t data = buffer[i]; - result = true; - *last = true; + if(state == LeadingSpace) { + if(flipper_format_stream_is_space(data)) { + continue; + } else if(data == flipper_format_eoln) { + stream_seek(stream, i - was_read, StreamOffsetFromCurrent); + error = true; break; } else { - error = true; + state = ReadValue; + furi_string_push_back(value, data); } - } else if(data == ' ') { - if(string_size(value) > 0) { + } else if(state == ReadValue) { + if(flipper_format_stream_is_space(data)) { + state = TrailingSpace; + } else if(data == flipper_format_eoln) { if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { error = true; - break; + } else { + result = true; + *last = true; } - - result = true; - *last = false; break; + } else { + furi_string_push_back(value, data); } - - } else if(data == flipper_format_eolr) { - // Ignore - } else { - string_push_back(value, data); + } else if(state == TrailingSpace) { + if(flipper_format_stream_is_space(data)) { + continue; + } else if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) { + error = true; + } else { + *last = (data == flipper_format_eoln); + result = true; + } + break; } } @@ -176,8 +189,8 @@ static bool flipper_format_stream_read_value(Stream* stream, string_t value, boo return result; } -static bool flipper_format_stream_read_line(Stream* stream, string_t str_result) { - string_reset(str_result); +static bool flipper_format_stream_read_line(Stream* stream, FuriString* str_result) { + furi_string_reset(str_result); const size_t buffer_size = 32; uint8_t buffer[buffer_size]; @@ -201,7 +214,7 @@ static bool flipper_format_stream_read_line(Stream* stream, string_t str_result) } else if(data == flipper_format_eolr) { // Ignore } else { - string_push_back(str_result, data); + furi_string_push_back(str_result, data); } } @@ -210,7 +223,7 @@ static bool flipper_format_stream_read_line(Stream* stream, string_t str_result) } } while(true); - return string_size(str_result) != 0; + return furi_string_size(str_result) != 0; } static bool flipper_format_stream_seek_to_next_line(Stream* stream) { @@ -254,8 +267,8 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa if(write_data->type == FlipperStreamValueIgnore) { result = true; } else { - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); do { if(!flipper_format_stream_write_key(stream, write_data->key)) break; @@ -267,45 +280,45 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa switch(write_data->type) { case FlipperStreamValueStr: { const char* data = write_data->data; - string_printf(value, "%s", data); + furi_string_printf(value, "%s", data); }; break; case FlipperStreamValueHex: { const uint8_t* data = write_data->data; - string_printf(value, "%02X", data[i]); + furi_string_printf(value, "%02X", data[i]); }; break; #ifndef FLIPPER_STREAM_LITE case FlipperStreamValueFloat: { const float* data = write_data->data; - string_printf(value, "%f", (double)data[i]); + furi_string_printf(value, "%f", (double)data[i]); }; break; #endif case FlipperStreamValueInt32: { const int32_t* data = write_data->data; - string_printf(value, "%" PRIi32, data[i]); + furi_string_printf(value, "%" PRIi32, data[i]); }; break; case FlipperStreamValueUint32: { const uint32_t* data = write_data->data; - string_printf(value, "%" PRId32, data[i]); + furi_string_printf(value, "%" PRId32, data[i]); }; break; case FlipperStreamValueHexUint64: { const uint64_t* data = write_data->data; - string_printf( + furi_string_printf( value, "%08lX%08lX", (uint32_t)(data[i] >> 32), (uint32_t)data[i]); }; break; case FlipperStreamValueBool: { const bool* data = write_data->data; - string_printf(value, data[i] ? "true" : "false"); + furi_string_printf(value, data[i] ? "true" : "false"); }; break; default: furi_crash("Unknown FF type"); } if((size_t)(i + 1) < write_data->data_size) { - string_cat(value, " "); + furi_string_cat(value, " "); } if(!flipper_format_stream_write( - stream, string_get_cstr(value), string_size(value))) { + stream, furi_string_get_cstr(value), furi_string_size(value))) { cycle_error = true; break; } @@ -316,7 +329,7 @@ bool flipper_format_stream_write_value_line(Stream* stream, FlipperStreamWriteDa result = true; } while(false); - string_clear(value); + furi_string_free(value); } return result; @@ -335,15 +348,15 @@ bool flipper_format_stream_read_value_line( if(!flipper_format_stream_seek_to_key(stream, key, strict_mode)) break; if(type == FlipperStreamValueStr) { - string_ptr data = (string_ptr)_data; + FuriString* data = (FuriString*)_data; if(flipper_format_stream_read_line(stream, data)) { result = true; break; } } else { result = true; - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); for(size_t i = 0; i < data_size; i++) { bool last = false; @@ -354,11 +367,11 @@ bool flipper_format_stream_read_value_line( switch(type) { case FlipperStreamValueHex: { uint8_t* data = _data; - if(string_size(value) >= 2) { + if(furi_string_size(value) >= 2) { // sscanf "%02X" does not work here if(hex_char_to_uint8( - string_get_char(value, 0), - string_get_char(value, 1), + furi_string_get_char(value, 0), + furi_string_get_char(value, 1), &data[i])) { scan_values = 1; } @@ -368,9 +381,9 @@ bool flipper_format_stream_read_value_line( case FlipperStreamValueFloat: { float* data = _data; // newlib-nano does not have sscanf for floats - // scan_values = sscanf(string_get_cstr(value), "%f", &data[i]); + // scan_values = sscanf(furi_string_get_cstr(value), "%f", &data[i]); char* end_char; - data[i] = strtof(string_get_cstr(value), &end_char); + data[i] = strtof(furi_string_get_cstr(value), &end_char); if(*end_char == 0) { // most likely ok scan_values = 1; @@ -379,23 +392,23 @@ bool flipper_format_stream_read_value_line( #endif case FlipperStreamValueInt32: { int32_t* data = _data; - scan_values = sscanf(string_get_cstr(value), "%" PRIi32, &data[i]); + scan_values = sscanf(furi_string_get_cstr(value), "%" PRIi32, &data[i]); }; break; case FlipperStreamValueUint32: { uint32_t* data = _data; - scan_values = sscanf(string_get_cstr(value), "%" PRId32, &data[i]); + scan_values = sscanf(furi_string_get_cstr(value), "%" PRId32, &data[i]); }; break; case FlipperStreamValueHexUint64: { uint64_t* data = _data; - if(string_size(value) >= 16) { - if(hex_chars_to_uint64(string_get_cstr(value), &data[i])) { + if(furi_string_size(value) >= 16) { + if(hex_chars_to_uint64(furi_string_get_cstr(value), &data[i])) { scan_values = 1; } } }; break; case FlipperStreamValueBool: { bool* data = _data; - data[i] = !string_cmpi_str(value, "true"); + data[i] = !furi_string_cmpi(value, "true"); scan_values = 1; }; break; default: @@ -416,7 +429,7 @@ bool flipper_format_stream_read_value_line( } } - string_clear(value); + furi_string_free(value); } } while(false); @@ -431,8 +444,8 @@ bool flipper_format_stream_get_value_count( bool result = false; bool last = false; - string_t value; - string_init(value); + FuriString* value; + value = furi_string_alloc(); uint32_t position = stream_tell(stream); do { @@ -456,7 +469,7 @@ bool flipper_format_stream_get_value_count( result = false; } - string_clear(value); + furi_string_free(value); return result; } diff --git a/lib/flipper_format/flipper_format_stream.h b/lib/flipper_format/flipper_format_stream.h index 75eaef20e..88b096b22 100644 --- a/lib/flipper_format/flipper_format_stream.h +++ b/lib/flipper_format/flipper_format_stream.h @@ -2,7 +2,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index 2b4e3cdbb..86b19114c 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -9,7 +9,6 @@ #include #include -#include #define INFRARED_WORKER_RX_TIMEOUT INFRARED_RAW_RX_TIMING_DELAY_US @@ -50,7 +49,7 @@ struct InfraredWorkerSignal { struct InfraredWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; InfraredWorkerSignal signal; InfraredWorkerState state; @@ -100,15 +99,13 @@ static void infrared_worker_rx_timeout_callback(void* context) { static void infrared_worker_rx_callback(void* context, bool level, uint32_t duration) { InfraredWorker* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; furi_assert(duration != 0); LevelDuration level_duration = level_duration_make(level, duration); - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); uint32_t events = (ret == sizeof(LevelDuration)) ? INFRARED_WORKER_RX_RECEIVED : INFRARED_WORKER_OVERRUN; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); uint32_t flags_set = furi_thread_flags_set(furi_thread_get_id(instance->thread), events); furi_check(flags_set & events); @@ -179,7 +176,7 @@ static int32_t infrared_worker_rx_thread(void* thread_context) { if(instance->signal.timings_cnt == 0) notification_message(instance->notification, &sequence_display_backlight_on); while(sizeof(LevelDuration) == - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream, &level_duration, sizeof(LevelDuration), 0)) { if(!instance->rx.overrun) { bool level = level_duration_get_level(level_duration); @@ -232,7 +229,7 @@ InfraredWorker* infrared_worker_alloc() { size_t buffer_size = MAX(sizeof(InfraredWorkerTiming) * (MAX_TIMINGS_AMOUNT + 1), sizeof(LevelDuration) * MAX_TIMINGS_AMOUNT); - instance->stream = xStreamBufferCreate(buffer_size, sizeof(InfraredWorkerTiming)); + instance->stream = furi_stream_buffer_alloc(buffer_size, sizeof(InfraredWorkerTiming)); instance->infrared_decoder = infrared_alloc_decoder(); instance->infrared_encoder = infrared_alloc_encoder(); instance->blink_enable = false; @@ -249,7 +246,7 @@ void infrared_worker_free(InfraredWorker* instance) { furi_record_close(RECORD_NOTIFICATION); infrared_free_decoder(instance->infrared_decoder); infrared_free_encoder(instance->infrared_encoder); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); free(instance); @@ -259,7 +256,7 @@ void infrared_worker_rx_start(InfraredWorker* instance) { furi_assert(instance); furi_assert(instance->state == InfraredWorkerStateIdle); - xStreamBufferSetTriggerLevel(instance->stream, sizeof(LevelDuration)); + furi_stream_set_trigger_level(instance->stream, sizeof(LevelDuration)); furi_thread_set_callback(instance->thread, infrared_worker_rx_thread); furi_thread_start(instance->thread); @@ -285,9 +282,9 @@ void infrared_worker_rx_stop(InfraredWorker* instance) { furi_thread_flags_set(furi_thread_get_id(instance->thread), INFRARED_WORKER_EXIT); furi_thread_join(instance->thread); - BaseType_t xReturn = xStreamBufferReset(instance->stream); - furi_assert(xReturn == pdPASS); - (void)xReturn; + FuriStatus status = furi_stream_buffer_reset(instance->stream); + furi_assert(status == FuriStatusOk); + (void)status; instance->state = InfraredWorkerStateIdle; } @@ -325,7 +322,7 @@ void infrared_worker_tx_start(InfraredWorker* instance) { furi_assert(instance->tx.get_signal_callback); // size have to be greater than api hal infrared async tx buffer size - xStreamBufferSetTriggerLevel(instance->stream, sizeof(InfraredWorkerTiming)); + furi_stream_set_trigger_level(instance->stream, sizeof(InfraredWorkerTiming)); furi_thread_set_callback(instance->thread, infrared_worker_tx_thread); @@ -358,7 +355,7 @@ static FuriHalInfraredTxGetDataState FuriHalInfraredTxGetDataState state; if(sizeof(InfraredWorkerTiming) == - xStreamBufferReceiveFromISR(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0)) { + furi_stream_buffer_receive(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0)) { *level = timing.level; *duration = timing.duration; state = timing.state; @@ -420,7 +417,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) { InfraredWorkerTiming timing; InfraredStatus status = InfraredStatusError; - while(!xStreamBufferIsFull(instance->stream) && !instance->tx.need_reinitialization && + while(!furi_stream_buffer_is_full(instance->stream) && !instance->tx.need_reinitialization && new_data_available) { if(instance->signal.decoded) { status = infrared_encode(instance->infrared_encoder, &timing.duration, &timing.level); @@ -454,7 +451,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) { furi_assert(0); } uint32_t written_size = - xStreamBufferSend(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0); + furi_stream_buffer_send(instance->stream, &timing, sizeof(InfraredWorkerTiming), 0); furi_assert(sizeof(InfraredWorkerTiming) == written_size); (void)written_size; } @@ -564,10 +561,9 @@ void infrared_worker_tx_stop(InfraredWorker* instance) { furi_hal_infrared_async_tx_set_signal_sent_isr_callback(NULL, NULL); instance->signal.timings_cnt = 0; - BaseType_t xReturn = pdFAIL; - xReturn = xStreamBufferReset(instance->stream); - furi_assert(xReturn == pdPASS); - (void)xReturn; + FuriStatus status = furi_stream_buffer_reset(instance->stream); + furi_assert(status == FuriStatusOk); + (void)status; instance->state = InfraredWorkerStateIdle; } diff --git a/lib/lfrfid/lfrfid_dict_file.c b/lib/lfrfid/lfrfid_dict_file.c index bb6af39a4..7ae84f8b6 100644 --- a/lib/lfrfid/lfrfid_dict_file.c +++ b/lib/lfrfid/lfrfid_dict_file.c @@ -143,8 +143,8 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) { FlipperFormat* file = flipper_format_file_alloc(storage); ProtocolId result = PROTOCOL_NO; uint8_t* data = malloc(protocol_dict_get_max_data_size(dict)); - string_t str_result; - string_init(str_result); + FuriString* str_result; + str_result = furi_string_alloc(); do { if(!flipper_format_file_open_existing(file, filename)) break; @@ -152,16 +152,16 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) { // header uint32_t version; if(!flipper_format_read_header(file, str_result, &version)) break; - if(string_cmp_str(str_result, LFRFID_DICT_FILETYPE) != 0) break; + if(furi_string_cmp_str(str_result, LFRFID_DICT_FILETYPE) != 0) break; if(version != 1) break; // type if(!flipper_format_read_string(file, "Key type", str_result)) break; ProtocolId protocol; - protocol = protocol_dict_get_protocol_by_name(dict, string_get_cstr(str_result)); + protocol = protocol_dict_get_protocol_by_name(dict, furi_string_get_cstr(str_result)); if(protocol == PROTOCOL_NO) { - protocol = lfrfid_dict_protocol_fallback(dict, string_get_cstr(str_result), file); + protocol = lfrfid_dict_protocol_fallback(dict, furi_string_get_cstr(str_result), file); if(protocol == PROTOCOL_NO) break; } else { // data @@ -174,7 +174,7 @@ ProtocolId lfrfid_dict_file_load(ProtocolDict* dict, const char* filename) { } while(false); free(data); - string_clear(str_result); + furi_string_free(str_result); flipper_format_free(file); furi_record_close(RECORD_STORAGE); diff --git a/lib/lfrfid/lfrfid_raw_worker.c b/lib/lfrfid/lfrfid_raw_worker.c index 4050a8ca8..1547d20f9 100644 --- a/lib/lfrfid/lfrfid_raw_worker.c +++ b/lib/lfrfid/lfrfid_raw_worker.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "lfrfid_raw_worker.h" #include "lfrfid_raw_file.h" #include "tools/varint_pair.h" @@ -16,7 +15,7 @@ // emulate mode typedef struct { size_t overrun_count; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; } RfidEmulateCtx; typedef struct { @@ -40,7 +39,7 @@ typedef struct { // main worker struct LFRFIDRawWorker { - string_t file_path; + FuriString* file_path; FuriThread* thread; FuriEventFlag* events; @@ -69,14 +68,14 @@ LFRFIDRawWorker* lfrfid_raw_worker_alloc() { worker->events = furi_event_flag_alloc(NULL); - string_init(worker->file_path); + worker->file_path = furi_string_alloc(); return worker; } void lfrfid_raw_worker_free(LFRFIDRawWorker* worker) { furi_thread_free(worker->thread); furi_event_flag_free(worker->events); - string_clear(worker->file_path); + furi_string_free(worker->file_path); free(worker); } @@ -89,7 +88,7 @@ void lfrfid_raw_worker_start_read( void* context) { furi_check(furi_thread_get_state(worker->thread) == FuriThreadStateStopped); - string_set(worker->file_path, file_path); + furi_string_set(worker->file_path, file_path); worker->frequency = freq; worker->duty_cycle = duty_cycle; @@ -107,7 +106,7 @@ void lfrfid_raw_worker_start_emulate( LFRFIDWorkerEmulateRawCallback callback, void* context) { furi_check(furi_thread_get_state(worker->thread) == FuriThreadStateStopped); - string_set(worker->file_path, file_path); + furi_string_set(worker->file_path, file_path); worker->emulate_callback = callback; worker->context = context; furi_thread_set_callback(worker->thread, lfrfid_raw_emulate_worker_thread); @@ -126,20 +125,13 @@ void lfrfid_raw_worker_stop(LFRFIDRawWorker* worker) { static void lfrfid_raw_worker_capture(bool level, uint32_t duration, void* context) { LFRFIDRawWorkerReadData* ctx = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - bool need_to_send = varint_pair_pack(ctx->pair, level, duration); if(need_to_send) { buffer_stream_send_from_isr( - ctx->stream, - varint_pair_get_data(ctx->pair), - varint_pair_get_size(ctx->pair), - &xHigherPriorityTaskWoken); + ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair)); varint_pair_reset(ctx->pair); } - - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } static int32_t lfrfid_raw_read_worker_thread(void* thread_context) { @@ -147,7 +139,7 @@ static int32_t lfrfid_raw_read_worker_thread(void* thread_context) { Storage* storage = furi_record_open(RECORD_STORAGE); LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage); - const char* filename = string_get_cstr(worker->file_path); + const char* filename = furi_string_get_cstr(worker->file_path); bool file_valid = lfrfid_raw_file_open_write(file, filename); LFRFIDRawWorkerReadData* data = malloc(sizeof(LFRFIDRawWorkerReadData)); @@ -236,7 +228,7 @@ static void rfid_emulate_dma_isr(bool half, void* context) { RfidEmulateCtx* ctx = context; uint32_t flag = half ? HalfTransfer : TransferComplete; - size_t len = xStreamBufferSendFromISR(ctx->stream, &flag, sizeof(uint32_t), pdFALSE); + size_t len = furi_stream_buffer_send(ctx->stream, &flag, sizeof(uint32_t), 0); if(len != sizeof(uint32_t)) { ctx->overrun_count++; } @@ -251,12 +243,12 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { Storage* storage = furi_record_open(RECORD_STORAGE); data->ctx.overrun_count = 0; - data->ctx.stream = xStreamBufferCreate(sizeof(uint32_t), sizeof(uint32_t)); + data->ctx.stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t)); LFRFIDRawFile* file = lfrfid_raw_file_alloc(storage); do { - file_valid = lfrfid_raw_file_open_read(file, string_get_cstr(worker->file_path)); + file_valid = lfrfid_raw_file_open_read(file, furi_string_get_cstr(worker->file_path)); if(!file_valid) break; file_valid = lfrfid_raw_file_read_header(file, &worker->frequency, &worker->duty_cycle); if(!file_valid) break; @@ -287,7 +279,8 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { uint32_t flag = 0; while(true) { - size_t size = xStreamBufferReceive(data->ctx.stream, &flag, sizeof(uint32_t), 100); + size_t size = + furi_stream_buffer_receive(data->ctx.stream, &flag, sizeof(uint32_t), 100); if(size == sizeof(uint32_t)) { size_t start = 0; @@ -345,10 +338,10 @@ static int32_t lfrfid_raw_emulate_worker_thread(void* thread_context) { } if(data->ctx.overrun_count) { - FURI_LOG_E(TAG_EMULATE, "overruns: %lu", data->ctx.overrun_count); + FURI_LOG_E(TAG_EMULATE, "overruns: %u", data->ctx.overrun_count); } - vStreamBufferDelete(data->ctx.stream); + furi_stream_buffer_free(data->ctx.stream); lfrfid_raw_file_free(file); furi_record_close(RECORD_STORAGE); free(data); diff --git a/lib/lfrfid/lfrfid_worker_modes.c b/lib/lfrfid/lfrfid_worker_modes.c index 16936cca1..1fbae04c8 100644 --- a/lib/lfrfid/lfrfid_worker_modes.c +++ b/lib/lfrfid/lfrfid_worker_modes.c @@ -2,7 +2,6 @@ #include #include "lfrfid_worker_i.h" #include "tools/t5577.h" -#include #include #include #include "tools/varint_pair.h" @@ -81,17 +80,12 @@ static void lfrfid_worker_read_capture(bool level, uint32_t duration, void* cont furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_VALUE, level); #endif - BaseType_t xHigherPriorityTaskWoken = pdFALSE; bool need_to_send = varint_pair_pack(ctx->pair, level, duration); if(need_to_send) { buffer_stream_send_from_isr( - ctx->stream, - varint_pair_get_data(ctx->pair), - varint_pair_get_size(ctx->pair), - &xHigherPriorityTaskWoken); + ctx->stream, varint_pair_get_data(ctx->pair), varint_pair_get_size(ctx->pair)); varint_pair_reset(ctx->pair); } - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } typedef enum { @@ -270,14 +264,14 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal( } if(furi_log_get_level() >= FuriLogLevelDebug) { - string_t string_info; - string_init(string_info); + FuriString* string_info; + string_info = furi_string_alloc(); for(uint8_t i = 0; i < protocol_data_size; i++) { if(i != 0) { - string_cat_printf(string_info, " "); + furi_string_cat_printf(string_info, " "); } - string_cat_printf(string_info, "%02X", protocol_data[i]); + furi_string_cat_printf(string_info, "%02X", protocol_data[i]); } FURI_LOG_D( @@ -285,8 +279,8 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal( "%s, %d, [%s]", protocol_dict_get_name(worker->protocols, protocol), last_read_count, - string_get_cstr(string_info)); - string_clear(string_info); + furi_string_get_cstr(string_info)); + furi_string_free(string_info); } protocol_dict_decoders_start(worker->protocols); @@ -407,14 +401,14 @@ typedef enum { } LFRFIDWorkerEmulateDMAEvent; static void lfrfid_worker_emulate_dma_isr(bool half, void* context) { - StreamBufferHandle_t stream = context; + FuriStreamBuffer* stream = context; uint32_t flag = half ? HalfTransfer : TransferComplete; - xStreamBufferSendFromISR(stream, &flag, sizeof(uint32_t), pdFALSE); + furi_stream_buffer_send(stream, &flag, sizeof(uint32_t), 0); } static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { LFRFIDWorkerEmulateBuffer* buffer = malloc(sizeof(LFRFIDWorkerEmulateBuffer)); - StreamBufferHandle_t stream = xStreamBufferCreate(sizeof(uint32_t), sizeof(uint32_t)); + FuriStreamBuffer* stream = furi_stream_buffer_alloc(sizeof(uint32_t), sizeof(uint32_t)); LFRFIDProtocol protocol = worker->protocol; PulseGlue* pulse_glue = pulse_glue_alloc(); @@ -449,7 +443,7 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { while(true) { uint32_t flag = 0; - size_t size = xStreamBufferReceive(stream, &flag, sizeof(uint32_t), 100); + size_t size = furi_stream_buffer_receive(stream, &flag, sizeof(uint32_t), 100); #ifdef LFRFID_WORKER_READ_DEBUG_GPIO furi_hal_gpio_write(LFRFID_WORKER_READ_DEBUG_GPIO_LOAD, true); @@ -497,7 +491,7 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) { #endif free(buffer); - vStreamBufferDelete(stream); + furi_stream_buffer_free(stream); pulse_glue_free(pulse_glue); } diff --git a/lib/lfrfid/protocols/protocol_awid.c b/lib/lfrfid/protocols/protocol_awid.c index 7131d30dc..88093900e 100644 --- a/lib/lfrfid/protocols/protocol_awid.c +++ b/lib/lfrfid/protocols/protocol_awid.c @@ -147,7 +147,7 @@ LevelDuration protocol_awid_encoder_yield(ProtocolAwid* protocol) { return level_duration_make(level, duration); }; -void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) { +void protocol_awid_render_data(ProtocolAwid* protocol, FuriString* result) { // Index map // 0 10 20 30 40 50 60 // | | | | | | | @@ -164,7 +164,7 @@ void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) { uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - string_cat_printf(result, "Format: %d\r\n", format_length); + furi_string_cat_printf(result, "Format: %d\r\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 9); @@ -172,22 +172,22 @@ void protocol_awid_render_data(ProtocolAwid* protocol, string_t result) { uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 17); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 25); - string_cat_printf(result, "Facility: %d\r\n", facility); - string_cat_printf(result, "Card: %d", card_id); + furi_string_cat_printf(result, "Facility: %d\r\n", facility); + furi_string_cat_printf(result, "Card: %d", card_id); } else { // print 66 bits as hex - string_cat_printf(result, "Data: "); + furi_string_cat_printf(result, "Data: "); for(size_t i = 0; i < AWID_DECODED_DATA_SIZE; i++) { - string_cat_printf(result, "%02X", decoded_data[i]); + furi_string_cat_printf(result, "%02X", decoded_data[i]); } } }; -void protocol_awid_render_brief_data(ProtocolAwid* protocol, string_t result) { +void protocol_awid_render_brief_data(ProtocolAwid* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - string_cat_printf(result, "Format: %d\r\n", format_length); + furi_string_cat_printf(result, "Format: %d\r\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 9); @@ -195,9 +195,9 @@ void protocol_awid_render_brief_data(ProtocolAwid* protocol, string_t result) { uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 17); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 25); - string_cat_printf(result, "ID: %03u,%05u", facility, card_id); + furi_string_cat_printf(result, "ID: %03u,%05u", facility, card_id); } else { - string_cat_printf(result, "Data: unknown"); + furi_string_cat_printf(result, "Data: unknown"); } }; @@ -205,8 +205,15 @@ bool protocol_awid_write_data(ProtocolAwid* protocol, void* data) { LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data; bool result = false; + // Fix incorrect length byte + if(protocol->data[0] != 26 && protocol->data[0] != 50 && protocol->data[0] != 37 && + protocol->data[0] != 34) { + protocol->data[0] = 26; + } + // Correct protocol data by redecoding protocol_awid_encode(protocol->data, (uint8_t*)protocol->encoded_data); + bit_lib_remove_bit_every_nth((uint8_t*)protocol->encoded_data, 8, 88, 4); protocol_awid_decode(protocol->encoded_data, protocol->data); protocol_awid_encode(protocol->data, (uint8_t*)protocol->encoded_data); diff --git a/lib/lfrfid/protocols/protocol_em4100.c b/lib/lfrfid/protocols/protocol_em4100.c index 6959f753b..4b720dffd 100644 --- a/lib/lfrfid/protocols/protocol_em4100.c +++ b/lib/lfrfid/protocols/protocol_em4100.c @@ -251,10 +251,10 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) { // Correct protocol data by redecoding protocol_em4100_encoder_start(protocol); em4100_decode( - (uint8_t*)&protocol->encoded_data, - sizeof(EM4100DecodedData), - protocol->data, - EM4100_DECODED_DATA_SIZE); + (uint8_t*)&protocol->encoded_data, + sizeof(EM4100DecodedData), + protocol->data, + EM4100_DECODED_DATA_SIZE); protocol_em4100_encoder_start(protocol); @@ -270,9 +270,10 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) { return result; }; -void protocol_em4100_render_data(ProtocolEM4100* protocol, string_t result) { +void protocol_em4100_render_data(ProtocolEM4100* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf(result, "FC: %03u, Card: %05u", data[2], (uint16_t)((data[3] << 8) | (data[4]))); + furi_string_printf( + result, "FC: %03u, Card: %05u", data[2], (uint16_t)((data[3] << 8) | (data[4]))); }; const ProtocolBase protocol_em4100 = { diff --git a/lib/lfrfid/protocols/protocol_fdx_a.c b/lib/lfrfid/protocols/protocol_fdx_a.c index 554b9071e..87daa0eb6 100644 --- a/lib/lfrfid/protocols/protocol_fdx_a.c +++ b/lib/lfrfid/protocols/protocol_fdx_a.c @@ -79,6 +79,14 @@ static bool protocol_fdx_a_decode(const uint8_t* from, uint8_t* to) { return true; } +static void protocol_fdx_a_fix_parity(ProtocolFDXA* protocol) { + for(size_t i = 0; i < FDXA_DECODED_DATA_SIZE; i++) { + if(bit_lib_test_parity_32(protocol->data[i], BitLibParityOdd)) { + protocol->data[i] ^= (1 << 7); + } + } +} + static bool protocol_fdx_a_can_be_decoded(const uint8_t* data) { // check preamble if(data[0] != FDXA_PREAMBLE_0 || data[1] != FDXA_PREAMBLE_1 || data[12] != FDXA_PREAMBLE_0 || @@ -179,6 +187,7 @@ bool protocol_fdx_a_write_data(ProtocolFDXA* protocol, void* data) { bool result = false; // Correct protocol data by redecoding + protocol_fdx_a_fix_parity(protocol); protocol_fdx_a_encoder_start(protocol); protocol_fdx_a_decode(protocol->encoded_data, protocol->data); @@ -196,7 +205,7 @@ bool protocol_fdx_a_write_data(ProtocolFDXA* protocol, void* data) { return result; }; -void protocol_fdx_a_render_data(ProtocolFDXA* protocol, string_t result) { +void protocol_fdx_a_render_data(ProtocolFDXA* protocol, FuriString* result) { uint8_t data[FDXA_DECODED_DATA_SIZE]; memcpy(data, protocol->data, FDXA_DECODED_DATA_SIZE); @@ -206,7 +215,7 @@ void protocol_fdx_a_render_data(ProtocolFDXA* protocol, string_t result) { data[i] &= 0x7F; } - string_printf( + furi_string_printf( result, "ID: %02X%02X%02X%02X%02X\r\n" "Parity: %s", diff --git a/lib/lfrfid/protocols/protocol_fdx_b.c b/lib/lfrfid/protocols/protocol_fdx_b.c index f42b4ed93..855356f2a 100644 --- a/lib/lfrfid/protocols/protocol_fdx_b.c +++ b/lib/lfrfid/protocols/protocol_fdx_b.c @@ -273,7 +273,7 @@ static bool protocol_fdx_b_get_temp(const uint8_t* data, float* temp) { } } -void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) { +void protocol_fdx_b_render_data(ProtocolFDXB* protocol, FuriString* result) { // 38 bits of national code uint64_t national_code = protocol_fdx_b_get_national_code(protocol->data); @@ -287,19 +287,19 @@ void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) { uint8_t replacement_number = bit_lib_get_bits(protocol->data, 60, 3); bool animal_flag = bit_lib_get_bit(protocol->data, 63); - string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); - string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); + furi_string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); + furi_string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); float temperature; if(protocol_fdx_b_get_temp(protocol->data, &temperature)) { float temperature_c = (temperature - 32) / 1.8; - string_cat_printf( + furi_string_cat_printf( result, "T: %.2fF, %.2fC\r\n", (double)temperature, (double)temperature_c); } else { - string_cat_printf(result, "T: ---\r\n"); + furi_string_cat_printf(result, "T: ---\r\n"); } - string_cat_printf( + furi_string_cat_printf( result, "Bits: %X-%X-%X-%X-%X", block_status, @@ -309,7 +309,7 @@ void protocol_fdx_b_render_data(ProtocolFDXB* protocol, string_t result) { replacement_number); }; -void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, string_t result) { +void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, FuriString* result) { // 38 bits of national code uint64_t national_code = protocol_fdx_b_get_national_code(protocol->data); @@ -318,15 +318,15 @@ void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, string_t result) { bool animal_flag = bit_lib_get_bit(protocol->data, 63); - string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); - string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); + furi_string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); + furi_string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); float temperature; if(protocol_fdx_b_get_temp(protocol->data, &temperature)) { float temperature_c = (temperature - 32) / 1.8; - string_cat_printf(result, "T: %.2fC", (double)temperature_c); + furi_string_cat_printf(result, "T: %.2fC", (double)temperature_c); } else { - string_cat_printf(result, "T: ---"); + furi_string_cat_printf(result, "T: ---"); } }; diff --git a/lib/lfrfid/protocols/protocol_gallagher.c b/lib/lfrfid/protocols/protocol_gallagher.c index 5d8245301..4720d3a4d 100644 --- a/lib/lfrfid/protocols/protocol_gallagher.c +++ b/lib/lfrfid/protocols/protocol_gallagher.c @@ -268,15 +268,15 @@ bool protocol_gallagher_write_data(ProtocolGallagher* protocol, void* data) { return result; }; -void protocol_gallagher_render_data(ProtocolGallagher* protocol, string_t result) { +void protocol_gallagher_render_data(ProtocolGallagher* protocol, FuriString* result) { UNUSED(protocol); uint8_t rc = bit_lib_get_bits(protocol->data, 0, 4); uint8_t il = bit_lib_get_bits(protocol->data, 4, 4); uint32_t fc = bit_lib_get_bits_32(protocol->data, 8, 24); uint32_t card_id = bit_lib_get_bits_32(protocol->data, 32, 32); - string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il); - string_cat_printf(result, "FC: %u, C: %lu\r\n", fc, card_id); + furi_string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il); + furi_string_cat_printf(result, "FC: %lu, C: %lu\r\n", fc, card_id); }; const ProtocolBase protocol_gallagher = { diff --git a/lib/lfrfid/protocols/protocol_h10301.c b/lib/lfrfid/protocols/protocol_h10301.c index 6c50c667a..2d7a3e669 100644 --- a/lib/lfrfid/protocols/protocol_h10301.c +++ b/lib/lfrfid/protocols/protocol_h10301.c @@ -340,7 +340,7 @@ bool protocol_h10301_write_data(ProtocolH10301* protocol, void* data) { // Correct protocol data by redecoding protocol_h10301_encoder_start(protocol); protocol_h10301_decode(protocol->encoded_data, protocol->data); - + protocol_h10301_encoder_start(protocol); if(request->write_type == LFRFIDWriteTypeT5577) { @@ -355,9 +355,9 @@ bool protocol_h10301_write_data(ProtocolH10301* protocol, void* data) { return result; }; -void protocol_h10301_render_data(ProtocolH10301* protocol, string_t result) { +void protocol_h10301_render_data(ProtocolH10301* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf( + furi_string_printf( result, "FC: %u\r\n" "Card: %u", diff --git a/lib/lfrfid/protocols/protocol_hid_ex_generic.c b/lib/lfrfid/protocols/protocol_hid_ex_generic.c index 17b75528c..240128cbe 100644 --- a/lib/lfrfid/protocols/protocol_hid_ex_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_ex_generic.c @@ -192,10 +192,10 @@ bool protocol_hid_ex_generic_write_data(ProtocolHIDEx* protocol, void* data) { return result; }; -void protocol_hid_ex_generic_render_data(ProtocolHIDEx* protocol, string_t result) { +void protocol_hid_ex_generic_render_data(ProtocolHIDEx* protocol, FuriString* result) { // TODO: parser and render functions UNUSED(protocol); - string_printf(result, "Generic HID Extended\r\nData: Unknown"); + furi_string_printf(result, "Generic HID Extended\r\nData: Unknown"); }; const ProtocolBase protocol_hid_ex_generic = { diff --git a/lib/lfrfid/protocols/protocol_hid_generic.c b/lib/lfrfid/protocols/protocol_hid_generic.c index da5f5b7c8..e07021403 100644 --- a/lib/lfrfid/protocols/protocol_hid_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_generic.c @@ -221,25 +221,29 @@ bool protocol_hid_generic_write_data(ProtocolHID* protocol, void* data) { return result; }; -static void protocol_hid_generic_string_cat_protocol_bits(ProtocolHID* protocol, uint8_t protocol_size, string_t result) { +static void protocol_hid_generic_string_cat_protocol_bits( + ProtocolHID* protocol, + uint8_t protocol_size, + FuriString* result) { // round up to the nearest nibble const uint8_t hex_character_count = (protocol_size + 3) / 4; const uint8_t protocol_bit_index = HID_DECODED_BIT_SIZE - protocol_size; for(size_t i = 0; i < hex_character_count; i++) { - uint8_t nibble = - i == 0 ? bit_lib_get_bits( - protocol->data, protocol_bit_index, protocol_size % 4 == 0 ? 4 : protocol_size % 4) : - bit_lib_get_bits(protocol->data, protocol_bit_index + i * 4, 4); - string_cat_printf(result, "%X", nibble & 0xF); + uint8_t nibble = i == 0 ? bit_lib_get_bits( + protocol->data, + protocol_bit_index, + protocol_size % 4 == 0 ? 4 : protocol_size % 4) : + bit_lib_get_bits(protocol->data, protocol_bit_index + i * 4, 4); + furi_string_cat_printf(result, "%X", nibble & 0xF); } } -void protocol_hid_generic_render_data(ProtocolHID* protocol, string_t result) { +void protocol_hid_generic_render_data(ProtocolHID* protocol, FuriString* result) { const uint8_t protocol_size = protocol_hid_generic_decode_protocol_size(protocol); if(protocol_size == HID_PROTOCOL_SIZE_UNKNOWN) { - string_printf( + furi_string_printf( result, "Generic HID Proximity\r\n" "Data: %02X%02X%02X%02X%02X%X", @@ -250,7 +254,7 @@ void protocol_hid_generic_render_data(ProtocolHID* protocol, string_t result) { protocol->data[4], protocol->data[5] >> 4); } else { - string_printf( + furi_string_printf( result, "%hhu-bit HID Proximity\r\n" "Data: ", diff --git a/lib/lfrfid/protocols/protocol_indala26.c b/lib/lfrfid/protocols/protocol_indala26.c index 136ececf8..cafc58489 100644 --- a/lib/lfrfid/protocols/protocol_indala26.c +++ b/lib/lfrfid/protocols/protocol_indala26.c @@ -236,7 +236,10 @@ static uint16_t get_cn(const uint8_t* data) { return cn; } -void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t result, bool brief) { +void protocol_indala26_render_data_internal( + ProtocolIndala* protocol, + FuriString* result, + bool brief) { bool wiegand_correct = true; bool checksum_correct = true; @@ -284,7 +287,7 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r if(odd_parity_sum % 2 != odd_parity) wiegand_correct = false; if(brief) { - string_printf( + furi_string_printf( result, "FC: %u\r\nCard: %u, Parity:%s%s", fc, @@ -292,7 +295,7 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r (checksum_correct ? "+" : "-"), (wiegand_correct ? "+" : "-")); } else { - string_printf( + furi_string_printf( result, "FC: %u\r\n" "Card: %u\r\n" @@ -304,10 +307,10 @@ void protocol_indala26_render_data_internal(ProtocolIndala* protocol, string_t r (wiegand_correct ? "+" : "-")); } } -void protocol_indala26_render_data(ProtocolIndala* protocol, string_t result) { +void protocol_indala26_render_data(ProtocolIndala* protocol, FuriString* result) { protocol_indala26_render_data_internal(protocol, result, false); } -void protocol_indala26_render_brief_data(ProtocolIndala* protocol, string_t result) { +void protocol_indala26_render_brief_data(ProtocolIndala* protocol, FuriString* result) { protocol_indala26_render_data_internal(protocol, result, true); } diff --git a/lib/lfrfid/protocols/protocol_io_prox_xsf.c b/lib/lfrfid/protocols/protocol_io_prox_xsf.c index f53eac686..713148568 100644 --- a/lib/lfrfid/protocols/protocol_io_prox_xsf.c +++ b/lib/lfrfid/protocols/protocol_io_prox_xsf.c @@ -232,9 +232,9 @@ LevelDuration protocol_io_prox_xsf_encoder_yield(ProtocolIOProxXSF* protocol) { return level_duration_make(level, duration); }; -void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, string_t result) { +void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf( + furi_string_printf( result, "FC: %u\r\n" "VС: %u\r\n" @@ -244,9 +244,9 @@ void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, string_t resu (uint16_t)((data[2] << 8) | (data[3]))); } -void protocol_io_prox_xsf_render_brief_data(ProtocolIOProxXSF* protocol, string_t result) { +void protocol_io_prox_xsf_render_brief_data(ProtocolIOProxXSF* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf( + furi_string_printf( result, "FC: %u, VС: %u\r\n" "Card: %u", diff --git a/lib/lfrfid/protocols/protocol_jablotron.c b/lib/lfrfid/protocols/protocol_jablotron.c index 89a59a2d7..d2c7ea79f 100644 --- a/lib/lfrfid/protocols/protocol_jablotron.c +++ b/lib/lfrfid/protocols/protocol_jablotron.c @@ -160,9 +160,9 @@ LevelDuration protocol_jablotron_encoder_yield(ProtocolJablotron* protocol) { return level_duration_make(protocol->last_level, duration); }; -void protocol_jablotron_render_data(ProtocolJablotron* protocol, string_t result) { +void protocol_jablotron_render_data(ProtocolJablotron* protocol, FuriString* result) { uint64_t id = protocol_jablotron_card_id(protocol->data); - string_printf(result, "ID: %llX\r\n", id); + furi_string_printf(result, "ID: %llX\r\n", id); }; bool protocol_jablotron_write_data(ProtocolJablotron* protocol, void* data) { diff --git a/lib/lfrfid/protocols/protocol_keri.c b/lib/lfrfid/protocols/protocol_keri.c index 7e6625546..f0a12863e 100644 --- a/lib/lfrfid/protocols/protocol_keri.c +++ b/lib/lfrfid/protocols/protocol_keri.c @@ -170,6 +170,7 @@ bool protocol_keri_encoder_start(ProtocolKeri* protocol) { memset(protocol->encoded_data, 0, KERI_ENCODED_DATA_SIZE); *(uint32_t*)&protocol->encoded_data[0] = 0b00000000000000000000000011100000; bit_lib_copy_bits(protocol->encoded_data, 32, 32, protocol->data, 0); + bit_lib_set_bits(protocol->encoded_data, 32, 1, 1); protocol->encoder.last_bit = bit_lib_get_bit(protocol->encoded_data, KERI_ENCODED_BIT_SIZE - 1); @@ -211,19 +212,21 @@ LevelDuration protocol_keri_encoder_yield(ProtocolKeri* protocol) { return level_duration; }; -void protocol_keri_render_data(ProtocolKeri* protocol, string_t result) { +void protocol_keri_render_data(ProtocolKeri* protocol, FuriString* result) { uint32_t data = bit_lib_get_bits_32(protocol->data, 0, 32); uint32_t internal_id = data & 0x7FFFFFFF; uint32_t fc = 0; uint32_t cn = 0; protocol_keri_descramble(&fc, &cn, &data); - string_printf(result, "Internal ID: %u\r\nFC: %u, Card: %u\r\n", internal_id, fc, cn); + furi_string_printf(result, "Internal ID: %lu\r\nFC: %lu, Card: %lu\r\n", internal_id, fc, cn); } bool protocol_keri_write_data(ProtocolKeri* protocol, void* data) { LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data; bool result = false; + // Start bit should be always set + protocol->data[0] |= (1 << 7); protocol_keri_encoder_start(protocol); if(request->write_type == LFRFIDWriteTypeT5577) { diff --git a/lib/lfrfid/protocols/protocol_pac_stanley.c b/lib/lfrfid/protocols/protocol_pac_stanley.c index b5e1ebddc..59aaf1e6a 100644 --- a/lib/lfrfid/protocols/protocol_pac_stanley.c +++ b/lib/lfrfid/protocols/protocol_pac_stanley.c @@ -57,31 +57,31 @@ static void protocol_pac_stanley_decode(ProtocolPACStanley* protocol) { } static bool protocol_pac_stanley_can_be_decoded(ProtocolPACStanley* protocol) { - // Check preamble - if(bit_lib_get_bits(protocol->encoded_data, 0, 8) != 0b11111111) return false; - if(bit_lib_get_bit(protocol->encoded_data, 8) != 0) return false; - if(bit_lib_get_bit(protocol->encoded_data, 9) != 0) return false; - if(bit_lib_get_bit(protocol->encoded_data, 10) != 1) return false; - if(bit_lib_get_bits(protocol->encoded_data, 11, 8) != 0b00000010) return false; + // Check preamble + if(bit_lib_get_bits(protocol->encoded_data, 0, 8) != 0b11111111) return false; + if(bit_lib_get_bit(protocol->encoded_data, 8) != 0) return false; + if(bit_lib_get_bit(protocol->encoded_data, 9) != 0) return false; + if(bit_lib_get_bit(protocol->encoded_data, 10) != 1) return false; + if(bit_lib_get_bits(protocol->encoded_data, 11, 8) != 0b00000010) return false; - // Check next preamble - if(bit_lib_get_bits(protocol->encoded_data, 128, 8) != 0b11111111) return false; + // Check next preamble + if(bit_lib_get_bits(protocol->encoded_data, 128, 8) != 0b11111111) return false; - // Checksum - uint8_t checksum = 0; - uint8_t stripped_byte; - for(size_t idx = 0; idx < 9; idx++) { - uint8_t byte = bit_lib_reverse_8_fast(bit_lib_get_bits( - protocol->encoded_data, - PAC_STANLEY_DATA_START_INDEX + (PAC_STANLEY_BYTE_LENGTH * idx), - 8)); - stripped_byte = byte & 0x7F; // discard the parity bit - if(bit_lib_test_parity_32(stripped_byte, BitLibParityOdd) != (byte & 0x80) >> 7) { - return false; - } - if(idx < 8) checksum ^= stripped_byte; + // Checksum + uint8_t checksum = 0; + uint8_t stripped_byte; + for(size_t idx = 0; idx < 9; idx++) { + uint8_t byte = bit_lib_reverse_8_fast(bit_lib_get_bits( + protocol->encoded_data, + PAC_STANLEY_DATA_START_INDEX + (PAC_STANLEY_BYTE_LENGTH * idx), + 8)); + stripped_byte = byte & 0x7F; // discard the parity bit + if(bit_lib_test_parity_32(stripped_byte, BitLibParityOdd) != (byte & 0x80) >> 7) { + return false; } - if(stripped_byte != checksum) return false; + if(idx < 8) checksum ^= stripped_byte; + } + if(stripped_byte != checksum) return false; return true; } @@ -201,9 +201,9 @@ bool protocol_pac_stanley_write_data(ProtocolPACStanley* protocol, void* data) { return result; } -void protocol_pac_stanley_render_data(ProtocolPACStanley* protocol, string_t result) { +void protocol_pac_stanley_render_data(ProtocolPACStanley* protocol, FuriString* result) { uint8_t* data = protocol->data; - string_printf(result, "CIN: %02X%02X%02X%02X", data[0], data[1], data[2], data[3]); + furi_string_printf(result, "CIN: %02X%02X%02X%02X", data[0], data[1], data[2], data[3]); } const ProtocolBase protocol_pac_stanley = { diff --git a/lib/lfrfid/protocols/protocol_paradox.c b/lib/lfrfid/protocols/protocol_paradox.c index b0b3e71d6..7e029f1de 100644 --- a/lib/lfrfid/protocols/protocol_paradox.c +++ b/lib/lfrfid/protocols/protocol_paradox.c @@ -136,26 +136,26 @@ LevelDuration protocol_paradox_encoder_yield(ProtocolParadox* protocol) { return level_duration_make(level, duration); }; -void protocol_paradox_render_data(ProtocolParadox* protocol, string_t result) { +void protocol_paradox_render_data(ProtocolParadox* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t fc = bit_lib_get_bits(decoded_data, 10, 8); uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16); - string_cat_printf(result, "Facility: %u\r\n", fc); - string_cat_printf(result, "Card: %lu\r\n", card_id); - string_cat_printf(result, "Data: "); + furi_string_cat_printf(result, "Facility: %u\r\n", fc); + furi_string_cat_printf(result, "Card: %u\r\n", card_id); + furi_string_cat_printf(result, "Data: "); for(size_t i = 0; i < PARADOX_DECODED_DATA_SIZE; i++) { - string_cat_printf(result, "%02X", decoded_data[i]); + furi_string_cat_printf(result, "%02X", decoded_data[i]); } }; -void protocol_paradox_render_brief_data(ProtocolParadox* protocol, string_t result) { +void protocol_paradox_render_brief_data(ProtocolParadox* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t fc = bit_lib_get_bits(decoded_data, 10, 8); uint16_t card_id = bit_lib_get_bits_16(decoded_data, 18, 16); - string_cat_printf(result, "FC: %03u, Card: %05u", fc, card_id); + furi_string_cat_printf(result, "FC: %03u, Card: %05u", fc, card_id); }; bool protocol_paradox_write_data(ProtocolParadox* protocol, void* data) { diff --git a/lib/lfrfid/protocols/protocol_pyramid.c b/lib/lfrfid/protocols/protocol_pyramid.c index 1bba98718..974bb6da6 100644 --- a/lib/lfrfid/protocols/protocol_pyramid.c +++ b/lib/lfrfid/protocols/protocol_pyramid.c @@ -221,6 +221,7 @@ bool protocol_pyramid_write_data(ProtocolPyramid* protocol, void* data) { // Correct protocol data by redecoding protocol_pyramid_encode(protocol); + bit_lib_remove_bit_every_nth(protocol->encoded_data, 8, 15 * 8, 8); protocol_pyramid_decode(protocol); protocol_pyramid_encoder_start(protocol); @@ -238,11 +239,11 @@ bool protocol_pyramid_write_data(ProtocolPyramid* protocol, void* data) { return result; }; -void protocol_pyramid_render_data(ProtocolPyramid* protocol, string_t result) { +void protocol_pyramid_render_data(ProtocolPyramid* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - string_cat_printf(result, "Format: 26\r\n", format_length); + furi_string_cat_printf(result, "Format: %d\r\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 8); @@ -250,9 +251,9 @@ void protocol_pyramid_render_data(ProtocolPyramid* protocol, string_t result) { uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 16); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 24); - string_cat_printf(result, "FC: %03u, Card: %05u", facility, card_id); + furi_string_cat_printf(result, "FC: %03u, Card: %05u", facility, card_id); } else { - string_cat_printf(result, "Data: unknown"); + furi_string_cat_printf(result, "Data: unknown"); } }; diff --git a/lib/lfrfid/protocols/protocol_viking.c b/lib/lfrfid/protocols/protocol_viking.c index f252cc2c3..8083f6d91 100644 --- a/lib/lfrfid/protocols/protocol_viking.c +++ b/lib/lfrfid/protocols/protocol_viking.c @@ -175,9 +175,9 @@ bool protocol_viking_write_data(ProtocolViking* protocol, void* data) { return result; }; -void protocol_viking_render_data(ProtocolViking* protocol, string_t result) { +void protocol_viking_render_data(ProtocolViking* protocol, FuriString* result) { uint32_t id = bit_lib_get_bits_32(protocol->data, 0, 32); - string_printf(result, "ID: %08lX\r\n", id); + furi_string_printf(result, "ID: %08lX\r\n", id); }; const ProtocolBase protocol_viking = { diff --git a/lib/nfc/helpers/mf_classic_dict.c b/lib/nfc/helpers/mf_classic_dict.c index 5bb67145a..a842ed921 100644 --- a/lib/nfc/helpers/mf_classic_dict.c +++ b/lib/nfc/helpers/mf_classic_dict.c @@ -66,19 +66,28 @@ MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) { } // Read total amount of keys - string_t next_line; - string_init(next_line); + FuriString* next_line; + next_line = furi_string_alloc(); while(true) { - if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + if(!stream_read_line(dict->stream, next_line)) { + FURI_LOG_T(TAG, "No keys left in dict"); + break; + } + furi_string_trim(next_line); + FURI_LOG_T( + TAG, + "Read line: %s, len: %d", + furi_string_get_cstr(next_line), + furi_string_size(next_line)); + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN - 1) continue; dict->total_keys++; } - string_clear(next_line); + furi_string_free(next_line); stream_rewind(dict->stream); dict_loaded = true; - FURI_LOG_I(TAG, "Loaded dictionary with %d keys", dict->total_keys); + FURI_LOG_I(TAG, "Loaded dictionary with %ld keys", dict->total_keys); } while(false); if(!dict_loaded) { @@ -99,20 +108,20 @@ void mf_classic_dict_free(MfClassicDict* dict) { free(dict); } -static void mf_classic_dict_int_to_str(uint8_t* key_int, string_t key_str) { - string_reset(key_str); +static void mf_classic_dict_int_to_str(uint8_t* key_int, FuriString* key_str) { + furi_string_reset(key_str); for(size_t i = 0; i < 6; i++) { - string_cat_printf(key_str, "%02X", key_int[i]); + furi_string_cat_printf(key_str, "%02X", key_int[i]); } } -static void mf_classic_dict_str_to_int(string_t key_str, uint64_t* key_int) { +static void mf_classic_dict_str_to_int(FuriString* key_str, uint64_t* key_int) { uint8_t key_byte_tmp; *key_int = 0ULL; for(uint8_t i = 0; i < 12; i += 2) { args_char_to_hex( - string_get_char(key_str, i), string_get_char(key_str, i + 1), &key_byte_tmp); + furi_string_get_char(key_str, i), furi_string_get_char(key_str, i + 1), &key_byte_tmp); *key_int |= (uint64_t)key_byte_tmp << 8 * (5 - i / 2); } } @@ -130,17 +139,17 @@ bool mf_classic_dict_rewind(MfClassicDict* dict) { return stream_rewind(dict->stream); } -bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, string_t key) { +bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key) { furi_assert(dict); furi_assert(dict->stream); bool key_read = false; - string_reset(key); + furi_string_reset(key); while(!key_read) { if(!stream_read_line(dict->stream, key)) break; - if(string_get_char(key, 0) == '#') continue; - if(string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue; - string_left(key, 12); + if(furi_string_get_char(key, 0) == '#') continue; + if(furi_string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue; + furi_string_left(key, 12); key_read = true; } @@ -151,53 +160,53 @@ bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key) { furi_assert(dict); furi_assert(dict->stream); - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); bool key_read = mf_classic_dict_get_next_key_str(dict, temp_key); if(key_read) { mf_classic_dict_str_to_int(temp_key, key); } - string_clear(temp_key); + furi_string_free(temp_key); return key_read; } -bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, string_t key) { +bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key) { furi_assert(dict); furi_assert(dict->stream); - string_t next_line; - string_init(next_line); + FuriString* next_line; + next_line = furi_string_alloc(); bool key_found = false; stream_rewind(dict->stream); while(!key_found) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - string_left(next_line, 12); - if(!string_equal_p(key, next_line)) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + furi_string_left(next_line, 12); + if(!furi_string_equal(key, next_line)) continue; key_found = true; } - string_clear(next_line); + furi_string_free(next_line); return key_found; } bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key) { - string_t temp_key; + FuriString* temp_key; - string_init(temp_key); + temp_key = furi_string_alloc(); mf_classic_dict_int_to_str(key, temp_key); bool key_found = mf_classic_dict_is_key_present_str(dict, temp_key); - string_clear(temp_key); + furi_string_free(temp_key); return key_found; } -bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key) { +bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key) { furi_assert(dict); furi_assert(dict->stream); - string_cat_printf(key, "\n"); + furi_string_cat_printf(key, "\n"); bool key_added = false; do { @@ -207,7 +216,7 @@ bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key) { key_added = true; } while(false); - string_left(key, 12); + furi_string_left(key, 12); return key_added; } @@ -215,35 +224,35 @@ bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key) { furi_assert(dict); furi_assert(dict->stream); - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); mf_classic_dict_int_to_str(key, temp_key); bool key_added = mf_classic_dict_add_key_str(dict, temp_key); - string_clear(temp_key); + furi_string_free(temp_key); return key_added; } -bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, string_t key, uint32_t target) { +bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target) { furi_assert(dict); furi_assert(dict->stream); - string_t next_line; + FuriString* next_line; uint32_t index = 0; - string_init(next_line); - string_reset(key); + next_line = furi_string_alloc(); + furi_string_reset(key); bool key_found = false; while(!key_found) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; if(index++ != target) continue; - string_set_n(key, next_line, 0, 12); + furi_string_set_n(key, next_line, 0, 12); key_found = true; } - string_clear(next_line); + furi_string_free(next_line); return key_found; } @@ -251,37 +260,37 @@ bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32 furi_assert(dict); furi_assert(dict->stream); - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); bool key_found = mf_classic_dict_get_key_at_index_str(dict, temp_key, target); if(key_found) { mf_classic_dict_str_to_int(temp_key, key); } - string_clear(temp_key); + furi_string_free(temp_key); return key_found; } -bool mf_classic_dict_find_index_str(MfClassicDict* dict, string_t key, uint32_t* target) { +bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target) { furi_assert(dict); furi_assert(dict->stream); - string_t next_line; - string_init(next_line); + FuriString* next_line; + next_line = furi_string_alloc(); bool key_found = false; uint32_t index = 0; stream_rewind(dict->stream); while(!key_found) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; - string_left(next_line, 12); - if(!string_equal_p(key, next_line)) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + furi_string_left(next_line, 12); + if(!furi_string_equal(key, next_line)) continue; key_found = true; *target = index; } - string_clear(next_line); + furi_string_free(next_line); return key_found; } @@ -289,12 +298,12 @@ bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* tar furi_assert(dict); furi_assert(dict->stream); - string_t temp_key; - string_init(temp_key); + FuriString* temp_key; + temp_key = furi_string_alloc(); mf_classic_dict_int_to_str(key, temp_key); bool key_found = mf_classic_dict_find_index_str(dict, temp_key, target); - string_clear(temp_key); + furi_string_free(temp_key); return key_found; } @@ -302,15 +311,15 @@ bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) { furi_assert(dict); furi_assert(dict->stream); - string_t next_line; - string_init(next_line); + FuriString* next_line; + next_line = furi_string_alloc(); uint32_t index = 0; bool key_removed = false; while(!key_removed) { if(!stream_read_line(dict->stream, next_line)) break; - if(string_get_char(next_line, 0) == '#') continue; - if(string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; + if(furi_string_get_char(next_line, 0) == '#') continue; + if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue; if(index++ != target) continue; stream_seek(dict->stream, -NFC_MF_CLASSIC_KEY_LEN, StreamOffsetFromCurrent); if(!stream_delete(dict->stream, NFC_MF_CLASSIC_KEY_LEN)) break; @@ -318,6 +327,6 @@ bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) { key_removed = true; } - string_clear(next_line); + furi_string_free(next_line); return key_removed; } diff --git a/lib/nfc/helpers/mf_classic_dict.h b/lib/nfc/helpers/mf_classic_dict.h index 9241a37b9..5b0ee312a 100644 --- a/lib/nfc/helpers/mf_classic_dict.h +++ b/lib/nfc/helpers/mf_classic_dict.h @@ -48,11 +48,11 @@ bool mf_classic_dict_rewind(MfClassicDict* dict); bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key); -bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, string_t key); +bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key); bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key); -bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, string_t key); +bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key); /** Get key at target offset as uint64_t * @@ -72,7 +72,7 @@ bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32 * * @return true on success */ -bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, string_t key, uint32_t target); +bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target); bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key); @@ -83,11 +83,11 @@ bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key); * * @return true on success */ -bool mf_classic_dict_add_key_str(MfClassicDict* dict, string_t key); +bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key); bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* target); -bool mf_classic_dict_find_index_str(MfClassicDict* dict, string_t key, uint32_t* target); +bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target); /** Delete key at target offset * diff --git a/lib/nfc/helpers/mfkey32.c b/lib/nfc/helpers/mfkey32.c index 64b06e259..47e7e9f6b 100644 --- a/lib/nfc/helpers/mfkey32.c +++ b/lib/nfc/helpers/mfkey32.c @@ -91,10 +91,8 @@ void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, } static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) { - string_t str; - string_init_printf( - str, - "Sector %d key %c cuid %08x nt0 %08x nr0 %08x ar0 %08x nt1 %08x nr1 %08x ar1 %08x\n", + FuriString* str = furi_string_alloc_printf( + "Sec %d key %c cuid %08lx nt0 %08lx nr0 %08lx ar0 %08lx nt1 %08lx nr1 %08lx ar1 %08lx\n", params->sector, params->key == MfClassicKeyA ? 'A' : 'B', params->cuid, @@ -105,7 +103,7 @@ static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) { params->nr1, params->ar1); bool write_success = stream_write_string(instance->file_stream, str); - string_clear(str); + furi_string_free(str); return write_success; } @@ -199,14 +197,14 @@ void mfkey32_process_data( } } -uint16_t mfkey32_get_auth_sectors(string_t data_str) { +uint16_t mfkey32_get_auth_sectors(FuriString* data_str) { furi_assert(data_str); uint16_t nonces_num = 0; Storage* storage = furi_record_open(RECORD_STORAGE); Stream* file_stream = buffered_file_stream_alloc(storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { if(!buffered_file_stream_open( @@ -214,17 +212,17 @@ uint16_t mfkey32_get_auth_sectors(string_t data_str) { break; while(true) { if(!stream_read_line(file_stream, temp_str)) break; - size_t uid_pos = string_search_str(temp_str, "cuid"); - string_left(temp_str, uid_pos); - string_push_back(temp_str, '\n'); - string_cat(data_str, temp_str); + size_t uid_pos = furi_string_search(temp_str, "cuid"); + furi_string_left(temp_str, uid_pos); + furi_string_push_back(temp_str, '\n'); + furi_string_cat(data_str, temp_str); nonces_num++; } } while(false); buffered_file_stream_close(file_stream); stream_free(file_stream); - string_clear(temp_str); + furi_string_free(temp_str); return nonces_num; } diff --git a/lib/nfc/helpers/mfkey32.h b/lib/nfc/helpers/mfkey32.h index c4f13cc2c..e1f472e50 100644 --- a/lib/nfc/helpers/mfkey32.h +++ b/lib/nfc/helpers/mfkey32.h @@ -1,7 +1,6 @@ #pragma once #include -#include typedef struct Mfkey32 Mfkey32; @@ -24,4 +23,4 @@ void mfkey32_process_data( void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, void* context); -uint16_t mfkey32_get_auth_sectors(string_t string); +uint16_t mfkey32_get_auth_sectors(FuriString* string); diff --git a/lib/nfc/helpers/nfc_debug_log.c b/lib/nfc/helpers/nfc_debug_log.c index 1cbc5224f..0bfbc2c62 100644 --- a/lib/nfc/helpers/nfc_debug_log.c +++ b/lib/nfc/helpers/nfc_debug_log.c @@ -1,6 +1,5 @@ #include "nfc_debug_log.h" -#include #include #include @@ -10,7 +9,7 @@ struct NfcDebugLog { Stream* file_stream; - string_t data_str; + FuriString* data_str; }; NfcDebugLog* nfc_debug_log_alloc() { @@ -30,7 +29,7 @@ NfcDebugLog* nfc_debug_log_alloc() { free(instance); instance = NULL; } else { - string_init(instance->data_str); + instance->data_str = furi_string_alloc(); } furi_record_close(RECORD_STORAGE); @@ -44,7 +43,7 @@ void nfc_debug_log_free(NfcDebugLog* instance) { buffered_file_stream_close(instance->file_stream); stream_free(instance->file_stream); - string_clear(instance->data_str); + furi_string_free(instance->data_str); free(instance); } @@ -61,12 +60,12 @@ void nfc_debug_log_process_data( furi_assert(data); UNUSED(crc_dropped); - string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T'); + furi_string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T'); uint16_t data_len = len; for(size_t i = 0; i < data_len; i++) { - string_cat_printf(instance->data_str, " %02x", data[i]); + furi_string_cat_printf(instance->data_str, " %02x", data[i]); } - string_push_back(instance->data_str, '\n'); + furi_string_push_back(instance->data_str, '\n'); stream_write_string(instance->file_stream, instance->data_str); } diff --git a/lib/nfc/helpers/reader_analyzer.c b/lib/nfc/helpers/reader_analyzer.c index 680b8cef9..0ba657a2e 100644 --- a/lib/nfc/helpers/reader_analyzer.c +++ b/lib/nfc/helpers/reader_analyzer.c @@ -1,5 +1,4 @@ #include "reader_analyzer.h" -#include #include #include #include @@ -26,7 +25,7 @@ struct ReaderAnalyzer { FuriHalNfcDevData nfc_data; bool alive; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; FuriThread* thread; ReaderAnalyzerParseDataCallback callback; @@ -86,8 +85,8 @@ int32_t reader_analyzer_thread(void* context) { ReaderAnalyzer* reader_analyzer = context; uint8_t buffer[READER_ANALYZER_MAX_BUFF_SIZE] = {}; - while(reader_analyzer->alive || !xStreamBufferIsEmpty(reader_analyzer->stream)) { - size_t ret = xStreamBufferReceive( + while(reader_analyzer->alive || !furi_stream_buffer_is_empty(reader_analyzer->stream)) { + size_t ret = furi_stream_buffer_receive( reader_analyzer->stream, buffer, READER_ANALYZER_MAX_BUFF_SIZE, 50); if(ret) { reader_analyzer_parse(reader_analyzer, buffer, ret); @@ -103,7 +102,7 @@ ReaderAnalyzer* reader_analyzer_alloc() { instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic]; instance->alive = false; instance->stream = - xStreamBufferCreate(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader)); + furi_stream_buffer_alloc(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader)); instance->thread = furi_thread_alloc(); furi_thread_set_name(instance->thread, "ReaderAnalyzerWorker"); @@ -129,7 +128,7 @@ static void reader_analyzer_mfkey_callback(Mfkey32Event event, void* context) { void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode) { furi_assert(instance); - xStreamBufferReset(instance->stream); + furi_stream_buffer_reset(instance->stream); if(mode & ReaderAnalyzerModeDebugLog) { instance->debug_log = nfc_debug_log_alloc(); } @@ -171,7 +170,7 @@ void reader_analyzer_free(ReaderAnalyzer* instance) { reader_analyzer_stop(instance); furi_thread_free(instance->thread); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); free(instance); } @@ -215,12 +214,12 @@ static void reader_analyzer_write( ReaderAnalyzerHeader header = { .reader_to_tag = reader_to_tag, .crc_dropped = crc_dropped, .len = len}; size_t data_sent = 0; - data_sent = xStreamBufferSend( + data_sent = furi_stream_buffer_send( instance->stream, &header, sizeof(ReaderAnalyzerHeader), FuriWaitForever); if(data_sent != sizeof(ReaderAnalyzerHeader)) { FURI_LOG_W(TAG, "Sent %d out of %d bytes", data_sent, sizeof(ReaderAnalyzerHeader)); } - data_sent = xStreamBufferSend(instance->stream, data, len, FuriWaitForever); + data_sent = furi_stream_buffer_send(instance->stream, data, len, FuriWaitForever); if(data_sent != len) { FURI_LOG_W(TAG, "Sent %d out of %d bytes", data_sent, len); } diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index dd78e2daf..f28d4d5bd 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -1,6 +1,5 @@ #include "nfc_device.h" #include "assets_icons.h" -#include "m-string.h" #include "nfc_types.h" #include @@ -25,8 +24,8 @@ NfcDevice* nfc_device_alloc() { NfcDevice* nfc_dev = malloc(sizeof(NfcDevice)); nfc_dev->storage = furi_record_open(RECORD_STORAGE); nfc_dev->dialogs = furi_record_open(RECORD_DIALOGS); - string_init(nfc_dev->load_path); - string_init(nfc_dev->dev_data.parsed_data); + nfc_dev->load_path = furi_string_alloc(); + nfc_dev->dev_data.parsed_data = furi_string_alloc(); return nfc_dev; } @@ -35,53 +34,53 @@ void nfc_device_free(NfcDevice* nfc_dev) { nfc_device_clear(nfc_dev); furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_DIALOGS); - string_clear(nfc_dev->load_path); - string_clear(nfc_dev->dev_data.parsed_data); + furi_string_free(nfc_dev->load_path); + furi_string_free(nfc_dev->dev_data.parsed_data); free(nfc_dev); } -static void nfc_device_prepare_format_string(NfcDevice* dev, string_t format_string) { +static void nfc_device_prepare_format_string(NfcDevice* dev, FuriString* format_string) { if(dev->format == NfcDeviceSaveFormatUid) { - string_set_str(format_string, "UID"); + furi_string_set(format_string, "UID"); } else if(dev->format == NfcDeviceSaveFormatBankCard) { - string_set_str(format_string, "Bank card"); + furi_string_set(format_string, "Bank card"); } else if(dev->format == NfcDeviceSaveFormatMifareUl) { - string_set_str(format_string, nfc_mf_ul_type(dev->dev_data.mf_ul_data.type, true)); + furi_string_set(format_string, nfc_mf_ul_type(dev->dev_data.mf_ul_data.type, true)); } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { - string_set_str(format_string, "Mifare Classic"); + furi_string_set(format_string, "Mifare Classic"); } else if(dev->format == NfcDeviceSaveFormatMifareDesfire) { - string_set_str(format_string, "Mifare DESFire"); + furi_string_set(format_string, "Mifare DESFire"); } else { - string_set_str(format_string, "Unknown"); + furi_string_set(format_string, "Unknown"); } } -static bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_string) { - if(string_start_with_str_p(format_string, "UID")) { +static bool nfc_device_parse_format_string(NfcDevice* dev, FuriString* format_string) { + if(furi_string_start_with_str(format_string, "UID")) { dev->format = NfcDeviceSaveFormatUid; dev->dev_data.protocol = NfcDeviceProtocolUnknown; return true; } - if(string_start_with_str_p(format_string, "Bank card")) { + if(furi_string_start_with_str(format_string, "Bank card")) { dev->format = NfcDeviceSaveFormatBankCard; dev->dev_data.protocol = NfcDeviceProtocolEMV; return true; } // Check Mifare Ultralight types for(MfUltralightType type = MfUltralightTypeUnknown; type < MfUltralightTypeNum; type++) { - if(string_equal_str_p(format_string, nfc_mf_ul_type(type, true))) { + if(furi_string_equal(format_string, nfc_mf_ul_type(type, true))) { dev->format = NfcDeviceSaveFormatMifareUl; dev->dev_data.protocol = NfcDeviceProtocolMifareUl; dev->dev_data.mf_ul_data.type = type; return true; } } - if(string_start_with_str_p(format_string, "Mifare Classic")) { + if(furi_string_start_with_str(format_string, "Mifare Classic")) { dev->format = NfcDeviceSaveFormatMifareClassic; dev->dev_data.protocol = NfcDeviceProtocolMifareClassic; return true; } - if(string_start_with_str_p(format_string, "Mifare DESFire")) { + if(furi_string_start_with_str(format_string, "Mifare DESFire")) { dev->format = NfcDeviceSaveFormatMifareDesfire; dev->dev_data.protocol = NfcDeviceProtocolMifareDesfire; return true; @@ -92,8 +91,8 @@ static bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_strin static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { bool saved = false; MfUltralightData* data = &dev->dev_data.mf_ul_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); // Save Mifare Ultralight specific data do { @@ -109,14 +108,15 @@ static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) // Write conters and tearing flags data bool counters_saved = true; for(uint8_t i = 0; i < 3; i++) { - string_printf(temp_str, "Counter %d", i); + furi_string_printf(temp_str, "Counter %d", i); if(!flipper_format_write_uint32( - file, string_get_cstr(temp_str), &data->counter[i], 1)) { + file, furi_string_get_cstr(temp_str), &data->counter[i], 1)) { counters_saved = false; break; } - string_printf(temp_str, "Tearing %d", i); - if(!flipper_format_write_hex(file, string_get_cstr(temp_str), &data->tearing[i], 1)) { + furi_string_printf(temp_str, "Tearing %d", i); + if(!flipper_format_write_hex( + file, furi_string_get_cstr(temp_str), &data->tearing[i], 1)) { counters_saved = false; break; } @@ -129,8 +129,8 @@ static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) if(!flipper_format_write_uint32(file, "Pages read", &pages_read, 1)) break; bool pages_saved = true; for(uint16_t i = 0; i < data->data_size; i += 4) { - string_printf(temp_str, "Page %d", i / 4); - if(!flipper_format_write_hex(file, string_get_cstr(temp_str), &data->data[i], 4)) { + furi_string_printf(temp_str, "Page %d", i / 4); + if(!flipper_format_write_hex(file, furi_string_get_cstr(temp_str), &data->data[i], 4)) { pages_saved = false; break; } @@ -145,15 +145,15 @@ static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) saved = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return saved; } bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; MfUltralightData* data = &dev->dev_data.mf_ul_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t data_format_version = 0; do { @@ -172,13 +172,15 @@ bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { // Read counters and tearing flags bool counters_parsed = true; for(uint8_t i = 0; i < 3; i++) { - string_printf(temp_str, "Counter %d", i); - if(!flipper_format_read_uint32(file, string_get_cstr(temp_str), &data->counter[i], 1)) { + furi_string_printf(temp_str, "Counter %d", i); + if(!flipper_format_read_uint32( + file, furi_string_get_cstr(temp_str), &data->counter[i], 1)) { counters_parsed = false; break; } - string_printf(temp_str, "Tearing %d", i); - if(!flipper_format_read_hex(file, string_get_cstr(temp_str), &data->tearing[i], 1)) { + furi_string_printf(temp_str, "Tearing %d", i); + if(!flipper_format_read_hex( + file, furi_string_get_cstr(temp_str), &data->tearing[i], 1)) { counters_parsed = false; break; } @@ -198,8 +200,9 @@ bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { if(data->data_size > MF_UL_MAX_DUMP_SIZE || data->data_read > MF_UL_MAX_DUMP_SIZE) break; bool pages_parsed = true; for(uint16_t i = 0; i < pages_total; i++) { - string_printf(temp_str, "Page %d", i); - if(!flipper_format_read_hex(file, string_get_cstr(temp_str), &data->data[i * 4], 4)) { + furi_string_printf(temp_str, "Page %d", i); + if(!flipper_format_read_hex( + file, furi_string_get_cstr(temp_str), &data->data[i * 4], 4)) { pages_parsed = false; break; } @@ -214,7 +217,7 @@ bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { parsed = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return parsed; } @@ -223,38 +226,40 @@ static bool nfc_device_save_mifare_df_key_settings( MifareDesfireKeySettings* ks, const char* prefix) { bool saved = false; - string_t key; - string_init(key); + FuriString* key; + key = furi_string_alloc(); do { - string_printf(key, "%s Change Key ID", prefix); - if(!flipper_format_write_hex(file, string_get_cstr(key), &ks->change_key_id, 1)) break; - string_printf(key, "%s Config Changeable", prefix); - if(!flipper_format_write_bool(file, string_get_cstr(key), &ks->config_changeable, 1)) + furi_string_printf(key, "%s Change Key ID", prefix); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &ks->change_key_id, 1)) break; - string_printf(key, "%s Free Create Delete", prefix); - if(!flipper_format_write_bool(file, string_get_cstr(key), &ks->free_create_delete, 1)) + furi_string_printf(key, "%s Config Changeable", prefix); + if(!flipper_format_write_bool(file, furi_string_get_cstr(key), &ks->config_changeable, 1)) break; - string_printf(key, "%s Free Directory List", prefix); - if(!flipper_format_write_bool(file, string_get_cstr(key), &ks->free_directory_list, 1)) + furi_string_printf(key, "%s Free Create Delete", prefix); + if(!flipper_format_write_bool(file, furi_string_get_cstr(key), &ks->free_create_delete, 1)) break; - string_printf(key, "%s Key Changeable", prefix); - if(!flipper_format_write_bool(file, string_get_cstr(key), &ks->master_key_changeable, 1)) + furi_string_printf(key, "%s Free Directory List", prefix); + if(!flipper_format_write_bool(file, furi_string_get_cstr(key), &ks->free_directory_list, 1)) + break; + furi_string_printf(key, "%s Key Changeable", prefix); + if(!flipper_format_write_bool( + file, furi_string_get_cstr(key), &ks->master_key_changeable, 1)) break; if(ks->flags) { - string_printf(key, "%s Flags", prefix); - if(!flipper_format_write_hex(file, string_get_cstr(key), &ks->flags, 1)) break; + furi_string_printf(key, "%s Flags", prefix); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &ks->flags, 1)) break; } - string_printf(key, "%s Max Keys", prefix); - if(!flipper_format_write_hex(file, string_get_cstr(key), &ks->max_keys, 1)) break; + furi_string_printf(key, "%s Max Keys", prefix); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &ks->max_keys, 1)) break; for(MifareDesfireKeyVersion* kv = ks->key_version_head; kv; kv = kv->next) { - string_printf(key, "%s Key %d Version", prefix, kv->id); - if(!flipper_format_write_hex(file, string_get_cstr(key), &kv->version, 1)) break; + furi_string_printf(key, "%s Key %d Version", prefix, kv->id); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &kv->version, 1)) break; } saved = true; } while(false); - string_clear(key); + furi_string_free(key); return saved; } @@ -263,36 +268,38 @@ bool nfc_device_load_mifare_df_key_settings( MifareDesfireKeySettings* ks, const char* prefix) { bool parsed = false; - string_t key; - string_init(key); + FuriString* key; + key = furi_string_alloc(); do { - string_printf(key, "%s Change Key ID", prefix); - if(!flipper_format_read_hex(file, string_get_cstr(key), &ks->change_key_id, 1)) break; - string_printf(key, "%s Config Changeable", prefix); - if(!flipper_format_read_bool(file, string_get_cstr(key), &ks->config_changeable, 1)) break; - string_printf(key, "%s Free Create Delete", prefix); - if(!flipper_format_read_bool(file, string_get_cstr(key), &ks->free_create_delete, 1)) + furi_string_printf(key, "%s Change Key ID", prefix); + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &ks->change_key_id, 1)) break; + furi_string_printf(key, "%s Config Changeable", prefix); + if(!flipper_format_read_bool(file, furi_string_get_cstr(key), &ks->config_changeable, 1)) break; - string_printf(key, "%s Free Directory List", prefix); - if(!flipper_format_read_bool(file, string_get_cstr(key), &ks->free_directory_list, 1)) + furi_string_printf(key, "%s Free Create Delete", prefix); + if(!flipper_format_read_bool(file, furi_string_get_cstr(key), &ks->free_create_delete, 1)) break; - string_printf(key, "%s Key Changeable", prefix); - if(!flipper_format_read_bool(file, string_get_cstr(key), &ks->master_key_changeable, 1)) + furi_string_printf(key, "%s Free Directory List", prefix); + if(!flipper_format_read_bool(file, furi_string_get_cstr(key), &ks->free_directory_list, 1)) break; - string_printf(key, "%s Flags", prefix); - if(flipper_format_key_exist(file, string_get_cstr(key))) { - if(!flipper_format_read_hex(file, string_get_cstr(key), &ks->flags, 1)) break; + furi_string_printf(key, "%s Key Changeable", prefix); + if(!flipper_format_read_bool( + file, furi_string_get_cstr(key), &ks->master_key_changeable, 1)) + break; + furi_string_printf(key, "%s Flags", prefix); + if(flipper_format_key_exist(file, furi_string_get_cstr(key))) { + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &ks->flags, 1)) break; } - string_printf(key, "%s Max Keys", prefix); - if(!flipper_format_read_hex(file, string_get_cstr(key), &ks->max_keys, 1)) break; + furi_string_printf(key, "%s Max Keys", prefix); + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &ks->max_keys, 1)) break; ks->flags |= ks->max_keys >> 4; ks->max_keys &= 0xF; MifareDesfireKeyVersion** kv_head = &ks->key_version_head; for(int key_id = 0; key_id < ks->max_keys; key_id++) { - string_printf(key, "%s Key %d Version", prefix, key_id); + furi_string_printf(key, "%s Key %d Version", prefix, key_id); uint8_t version; - if(flipper_format_read_hex(file, string_get_cstr(key), &version, 1)) { + if(flipper_format_read_hex(file, furi_string_get_cstr(key), &version, 1)) { MifareDesfireKeyVersion* kv = malloc(sizeof(MifareDesfireKeyVersion)); memset(kv, 0, sizeof(MifareDesfireKeyVersion)); kv->id = key_id; @@ -304,21 +311,22 @@ bool nfc_device_load_mifare_df_key_settings( parsed = true; } while(false); - string_clear(key); + furi_string_free(key); return parsed; } static bool nfc_device_save_mifare_df_app(FlipperFormat* file, MifareDesfireApplication* app) { bool saved = false; - string_t prefix, key; - string_init_printf(prefix, "Application %02x%02x%02x", app->id[0], app->id[1], app->id[2]); - string_init(key); + FuriString *prefix, *key; + prefix = + furi_string_alloc_printf("Application %02x%02x%02x", app->id[0], app->id[1], app->id[2]); + key = furi_string_alloc(); uint8_t* tmp = NULL; do { if(app->key_settings) { if(!nfc_device_save_mifare_df_key_settings( - file, app->key_settings, string_get_cstr(prefix))) + file, app->key_settings, furi_string_get_cstr(prefix))) break; } if(!app->file_head) break; @@ -331,68 +339,75 @@ static bool nfc_device_save_mifare_df_app(FlipperFormat* file, MifareDesfireAppl for(MifareDesfireFile* f = app->file_head; f; f = f->next) { tmp[i++] = f->id; } - string_printf(key, "%s File IDs", string_get_cstr(prefix)); - if(!flipper_format_write_hex(file, string_get_cstr(key), tmp, n_files)) break; + furi_string_printf(key, "%s File IDs", furi_string_get_cstr(prefix)); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), tmp, n_files)) break; bool saved_files = true; for(MifareDesfireFile* f = app->file_head; f; f = f->next) { saved_files = false; - string_printf(key, "%s File %d Type", string_get_cstr(prefix), f->id); - if(!flipper_format_write_hex(file, string_get_cstr(key), &f->type, 1)) break; - string_printf( - key, "%s File %d Communication Settings", string_get_cstr(prefix), f->id); - if(!flipper_format_write_hex(file, string_get_cstr(key), &f->comm, 1)) break; - string_printf(key, "%s File %d Access Rights", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Type", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &f->type, 1)) break; + furi_string_printf( + key, "%s File %d Communication Settings", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), &f->comm, 1)) break; + furi_string_printf( + key, "%s File %d Access Rights", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_hex( - file, string_get_cstr(key), (uint8_t*)&f->access_rights, 2)) + file, furi_string_get_cstr(key), (uint8_t*)&f->access_rights, 2)) break; uint16_t size = 0; if(f->type == MifareDesfireFileTypeStandard || f->type == MifareDesfireFileTypeBackup) { size = f->settings.data.size; - string_printf(key, "%s File %d Size", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Size", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.data.size, 1)) + file, furi_string_get_cstr(key), &f->settings.data.size, 1)) break; } else if(f->type == MifareDesfireFileTypeValue) { - string_printf(key, "%s File %d Hi Limit", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Hi Limit", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.value.hi_limit, 1)) + file, furi_string_get_cstr(key), &f->settings.value.hi_limit, 1)) break; - string_printf(key, "%s File %d Lo Limit", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Lo Limit", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.value.lo_limit, 1)) + file, furi_string_get_cstr(key), &f->settings.value.lo_limit, 1)) break; - string_printf( - key, "%s File %d Limited Credit Value", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Limited Credit Value", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.value.limited_credit_value, 1)) + file, furi_string_get_cstr(key), &f->settings.value.limited_credit_value, 1)) break; - string_printf( - key, "%s File %d Limited Credit Enabled", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Limited Credit Enabled", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_bool( - file, string_get_cstr(key), &f->settings.value.limited_credit_enabled, 1)) + file, + furi_string_get_cstr(key), + &f->settings.value.limited_credit_enabled, + 1)) break; size = 4; } else if( f->type == MifareDesfireFileTypeLinearRecord || f->type == MifareDesfireFileTypeCyclicRecord) { - string_printf(key, "%s File %d Size", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Size", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.record.size, 1)) + file, furi_string_get_cstr(key), &f->settings.record.size, 1)) break; - string_printf(key, "%s File %d Max", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Max", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.record.max, 1)) + file, furi_string_get_cstr(key), &f->settings.record.max, 1)) break; - string_printf(key, "%s File %d Cur", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Cur", furi_string_get_cstr(prefix), f->id); if(!flipper_format_write_uint32( - file, string_get_cstr(key), &f->settings.record.cur, 1)) + file, furi_string_get_cstr(key), &f->settings.record.cur, 1)) break; size = f->settings.record.size * f->settings.record.cur; } if(f->contents) { - string_printf(key, "%s File %d", string_get_cstr(prefix), f->id); - if(!flipper_format_write_hex(file, string_get_cstr(key), f->contents, size)) break; + furi_string_printf(key, "%s File %d", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_write_hex(file, furi_string_get_cstr(key), f->contents, size)) + break; } saved_files = true; } @@ -403,16 +418,17 @@ static bool nfc_device_save_mifare_df_app(FlipperFormat* file, MifareDesfireAppl } while(false); free(tmp); - string_clear(prefix); - string_clear(key); + furi_string_free(prefix); + furi_string_free(key); return saved; } bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication* app) { bool parsed = false; - string_t prefix, key; - string_init_printf(prefix, "Application %02x%02x%02x", app->id[0], app->id[1], app->id[2]); - string_init(key); + FuriString *prefix, *key; + prefix = + furi_string_alloc_printf("Application %02x%02x%02x", app->id[0], app->id[1], app->id[2]); + key = furi_string_alloc(); uint8_t* tmp = NULL; MifareDesfireFile* f = NULL; @@ -420,16 +436,16 @@ bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication app->key_settings = malloc(sizeof(MifareDesfireKeySettings)); memset(app->key_settings, 0, sizeof(MifareDesfireKeySettings)); if(!nfc_device_load_mifare_df_key_settings( - file, app->key_settings, string_get_cstr(prefix))) { + file, app->key_settings, furi_string_get_cstr(prefix))) { free(app->key_settings); app->key_settings = NULL; break; } - string_printf(key, "%s File IDs", string_get_cstr(prefix)); + furi_string_printf(key, "%s File IDs", furi_string_get_cstr(prefix)); uint32_t n_files; - if(!flipper_format_get_value_count(file, string_get_cstr(key), &n_files)) break; + if(!flipper_format_get_value_count(file, furi_string_get_cstr(key), &n_files)) break; tmp = malloc(n_files); - if(!flipper_format_read_hex(file, string_get_cstr(key), tmp, n_files)) break; + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), tmp, n_files)) break; MifareDesfireFile** file_head = &app->file_head; bool parsed_files = true; for(uint32_t i = 0; i < n_files; i++) { @@ -437,61 +453,69 @@ bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication f = malloc(sizeof(MifareDesfireFile)); memset(f, 0, sizeof(MifareDesfireFile)); f->id = tmp[i]; - string_printf(key, "%s File %d Type", string_get_cstr(prefix), f->id); - if(!flipper_format_read_hex(file, string_get_cstr(key), &f->type, 1)) break; - string_printf( - key, "%s File %d Communication Settings", string_get_cstr(prefix), f->id); - if(!flipper_format_read_hex(file, string_get_cstr(key), &f->comm, 1)) break; - string_printf(key, "%s File %d Access Rights", string_get_cstr(prefix), f->id); - if(!flipper_format_read_hex(file, string_get_cstr(key), (uint8_t*)&f->access_rights, 2)) + furi_string_printf(key, "%s File %d Type", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &f->type, 1)) break; + furi_string_printf( + key, "%s File %d Communication Settings", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), &f->comm, 1)) break; + furi_string_printf( + key, "%s File %d Access Rights", furi_string_get_cstr(prefix), f->id); + if(!flipper_format_read_hex( + file, furi_string_get_cstr(key), (uint8_t*)&f->access_rights, 2)) break; if(f->type == MifareDesfireFileTypeStandard || f->type == MifareDesfireFileTypeBackup) { - string_printf(key, "%s File %d Size", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Size", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.data.size, 1)) + file, furi_string_get_cstr(key), &f->settings.data.size, 1)) break; } else if(f->type == MifareDesfireFileTypeValue) { - string_printf(key, "%s File %d Hi Limit", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Hi Limit", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.value.hi_limit, 1)) + file, furi_string_get_cstr(key), &f->settings.value.hi_limit, 1)) break; - string_printf(key, "%s File %d Lo Limit", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Lo Limit", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.value.lo_limit, 1)) + file, furi_string_get_cstr(key), &f->settings.value.lo_limit, 1)) break; - string_printf( - key, "%s File %d Limited Credit Value", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Limited Credit Value", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.value.limited_credit_value, 1)) + file, furi_string_get_cstr(key), &f->settings.value.limited_credit_value, 1)) break; - string_printf( - key, "%s File %d Limited Credit Enabled", string_get_cstr(prefix), f->id); + furi_string_printf( + key, "%s File %d Limited Credit Enabled", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_bool( - file, string_get_cstr(key), &f->settings.value.limited_credit_enabled, 1)) + file, + furi_string_get_cstr(key), + &f->settings.value.limited_credit_enabled, + 1)) break; } else if( f->type == MifareDesfireFileTypeLinearRecord || f->type == MifareDesfireFileTypeCyclicRecord) { - string_printf(key, "%s File %d Size", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Size", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.record.size, 1)) + file, furi_string_get_cstr(key), &f->settings.record.size, 1)) break; - string_printf(key, "%s File %d Max", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Max", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.record.max, 1)) + file, furi_string_get_cstr(key), &f->settings.record.max, 1)) break; - string_printf(key, "%s File %d Cur", string_get_cstr(prefix), f->id); + furi_string_printf(key, "%s File %d Cur", furi_string_get_cstr(prefix), f->id); if(!flipper_format_read_uint32( - file, string_get_cstr(key), &f->settings.record.cur, 1)) + file, furi_string_get_cstr(key), &f->settings.record.cur, 1)) break; } - string_printf(key, "%s File %d", string_get_cstr(prefix), f->id); - if(flipper_format_key_exist(file, string_get_cstr(key))) { + furi_string_printf(key, "%s File %d", furi_string_get_cstr(prefix), f->id); + if(flipper_format_key_exist(file, furi_string_get_cstr(key))) { uint32_t size; - if(!flipper_format_get_value_count(file, string_get_cstr(key), &size)) break; + if(!flipper_format_get_value_count(file, furi_string_get_cstr(key), &size)) break; f->contents = malloc(size); - if(!flipper_format_read_hex(file, string_get_cstr(key), f->contents, size)) break; + if(!flipper_format_read_hex(file, furi_string_get_cstr(key), f->contents, size)) + break; } *file_head = f; file_head = &f->next; @@ -509,8 +533,8 @@ bool nfc_device_load_mifare_df_app(FlipperFormat* file, MifareDesfireApplication free(f); } free(tmp); - string_clear(prefix); - string_clear(key); + furi_string_free(prefix); + furi_string_free(key); return parsed; } @@ -646,8 +670,8 @@ bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { EmvData* data = &dev->dev_data.emv_data; memset(data, 0, sizeof(EmvData)); uint32_t data_cnt = 0; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { // Load essential data @@ -655,7 +679,7 @@ bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { data->aid_len = data_cnt; if(!flipper_format_read_hex(file, "AID", data->aid, data->aid_len)) break; if(!flipper_format_read_string(file, "Name", temp_str)) break; - strlcpy(data->name, string_get_cstr(temp_str), sizeof(data->name)); + strlcpy(data->name, furi_string_get_cstr(temp_str), sizeof(data->name)); if(!flipper_format_get_value_count(file, "Number", &data_cnt)) break; data->number_len = data_cnt; if(!flipper_format_read_hex(file, "Number", data->number, data->number_len)) break; @@ -674,15 +698,15 @@ bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { } } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return parsed; } static void nfc_device_write_mifare_classic_block( - string_t block_str, + FuriString* block_str, MfClassicData* data, uint8_t block_num) { - string_reset(block_str); + furi_string_reset(block_str); bool is_sec_trailer = mf_classic_is_sector_trailer(block_num); if(is_sec_trailer) { uint8_t sector_num = mf_classic_get_sector_by_block(block_num); @@ -690,45 +714,45 @@ static void nfc_device_write_mifare_classic_block( // Write key A for(size_t i = 0; i < sizeof(sec_tr->key_a); i++) { if(mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) { - string_cat_printf(block_str, "%02X ", sec_tr->key_a[i]); + furi_string_cat_printf(block_str, "%02X ", sec_tr->key_a[i]); } else { - string_cat_printf(block_str, "?? "); + furi_string_cat_printf(block_str, "?? "); } } // Write Access bytes for(size_t i = 0; i < MF_CLASSIC_ACCESS_BYTES_SIZE; i++) { if(mf_classic_is_block_read(data, block_num)) { - string_cat_printf(block_str, "%02X ", sec_tr->access_bits[i]); + furi_string_cat_printf(block_str, "%02X ", sec_tr->access_bits[i]); } else { - string_cat_printf(block_str, "?? "); + furi_string_cat_printf(block_str, "?? "); } } // Write key B for(size_t i = 0; i < sizeof(sec_tr->key_b); i++) { if(mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) { - string_cat_printf(block_str, "%02X ", sec_tr->key_b[i]); + furi_string_cat_printf(block_str, "%02X ", sec_tr->key_b[i]); } else { - string_cat_printf(block_str, "?? "); + furi_string_cat_printf(block_str, "?? "); } } } else { // Write data block for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) { if(mf_classic_is_block_read(data, block_num)) { - string_cat_printf(block_str, "%02X ", data->block[block_num].value[i]); + furi_string_cat_printf(block_str, "%02X ", data->block[block_num].value[i]); } else { - string_cat_printf(block_str, "?? "); + furi_string_cat_printf(block_str, "?? "); } } } - string_strim(block_str); + furi_string_trim(block_str); } static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) { bool saved = false; MfClassicData* data = &dev->dev_data.mf_classic_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint16_t blocks = 0; // Save Mifare Classic specific data @@ -749,39 +773,39 @@ static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* file, "Mifare Classic blocks, \'??\' means unknown data")) break; bool block_saved = true; - string_t block_str; - string_init(block_str); + FuriString* block_str; + block_str = furi_string_alloc(); for(size_t i = 0; i < blocks; i++) { - string_printf(temp_str, "Block %d", i); + furi_string_printf(temp_str, "Block %d", i); nfc_device_write_mifare_classic_block(block_str, data, i); - if(!flipper_format_write_string(file, string_get_cstr(temp_str), block_str)) { + if(!flipper_format_write_string(file, furi_string_get_cstr(temp_str), block_str)) { block_saved = false; break; } } - string_clear(block_str); + furi_string_free(block_str); if(!block_saved) break; saved = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return saved; } static void nfc_device_load_mifare_classic_block( - string_t block_str, + FuriString* block_str, MfClassicData* data, uint8_t block_num) { - string_strim(block_str); + furi_string_trim(block_str); MfClassicBlock block_tmp = {}; bool is_sector_trailer = mf_classic_is_sector_trailer(block_num); uint8_t sector_num = mf_classic_get_sector_by_block(block_num); uint16_t block_unknown_bytes_mask = 0; - string_strim(block_str); + furi_string_trim(block_str); for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) { - char hi = string_get_char(block_str, 3 * i); - char low = string_get_char(block_str, 3 * i + 1); + char hi = furi_string_get_char(block_str, 3 * i); + char low = furi_string_get_char(block_str, 3 * i + 1); uint8_t byte = 0; if(hex_char_to_uint8(hi, low, &byte)) { block_tmp.value[i] = byte; @@ -824,19 +848,19 @@ static void nfc_device_load_mifare_classic_block( static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; MfClassicData* data = &dev->dev_data.mf_classic_data; - string_t temp_str; + FuriString* temp_str; uint32_t data_format_version = 0; - string_init(temp_str); + temp_str = furi_string_alloc(); uint16_t data_blocks = 0; memset(data, 0, sizeof(MfClassicData)); do { // Read Mifare Classic type if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; - if(!string_cmp_str(temp_str, "1K")) { + if(!furi_string_cmp(temp_str, "1K")) { data->type = MfClassicType1k; data_blocks = 64; - } else if(!string_cmp_str(temp_str, "4K")) { + } else if(!furi_string_cmp(temp_str, "4K")) { data->type = MfClassicType4k; data_blocks = 256; } else { @@ -857,17 +881,17 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* // Read Mifare Classic blocks bool block_read = true; - string_t block_str; - string_init(block_str); + FuriString* block_str; + block_str = furi_string_alloc(); for(size_t i = 0; i < data_blocks; i++) { - string_printf(temp_str, "Block %d", i); - if(!flipper_format_read_string(file, string_get_cstr(temp_str), block_str)) { + furi_string_printf(temp_str, "Block %d", i); + if(!flipper_format_read_string(file, furi_string_get_cstr(temp_str), block_str)) { block_read = false; break; } nfc_device_load_mifare_classic_block(block_str, data, i); } - string_clear(block_str); + furi_string_free(block_str); if(!block_read) break; // Set keys and blocks as unknown for backward compatibility @@ -880,32 +904,32 @@ static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* parsed = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return parsed; } -static void nfc_device_get_key_cache_file_path(NfcDevice* dev, string_t file_path) { +static void nfc_device_get_key_cache_file_path(NfcDevice* dev, FuriString* file_path) { uint8_t* uid = dev->dev_data.nfc_data.uid; uint8_t uid_len = dev->dev_data.nfc_data.uid_len; - string_set_str(file_path, NFC_DEVICE_KEYS_FOLDER "/"); + furi_string_set(file_path, NFC_DEVICE_KEYS_FOLDER "/"); for(size_t i = 0; i < uid_len; i++) { - string_cat_printf(file_path, "%02X", uid[i]); + furi_string_cat_printf(file_path, "%02X", uid[i]); } - string_cat_printf(file_path, NFC_DEVICE_KEYS_EXTENSION); + furi_string_cat_printf(file_path, NFC_DEVICE_KEYS_EXTENSION); } static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) { FlipperFormat* file = flipper_format_file_alloc(dev->storage); MfClassicData* data = &dev->dev_data.mf_classic_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); nfc_device_get_key_cache_file_path(dev, temp_str); bool save_success = false; do { if(!storage_simply_mkdir(dev->storage, NFC_DEVICE_KEYS_FOLDER)) break; - if(!storage_simply_remove(dev->storage, string_get_cstr(temp_str))) break; - if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; if(!flipper_format_write_header_cstr(file, nfc_keys_file_header, nfc_keys_file_version)) break; if(data->type == MfClassicType1k) { @@ -920,29 +944,29 @@ static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) { for(size_t i = 0; (i < sector_num) && (key_save_success); i++) { MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); if(FURI_BIT(data->key_a_mask, i)) { - string_printf(temp_str, "Key A sector %d", i); - key_save_success = - flipper_format_write_hex(file, string_get_cstr(temp_str), sec_tr->key_a, 6); + furi_string_printf(temp_str, "Key A sector %d", i); + key_save_success = flipper_format_write_hex( + file, furi_string_get_cstr(temp_str), sec_tr->key_a, 6); } if(!key_save_success) break; if(FURI_BIT(data->key_a_mask, i)) { - string_printf(temp_str, "Key B sector %d", i); - key_save_success = - flipper_format_write_hex(file, string_get_cstr(temp_str), sec_tr->key_b, 6); + furi_string_printf(temp_str, "Key B sector %d", i); + key_save_success = flipper_format_write_hex( + file, furi_string_get_cstr(temp_str), sec_tr->key_b, 6); } } save_success = key_save_success; } while(false); flipper_format_free(file); - string_clear(temp_str); + furi_string_free(temp_str); return save_success; } bool nfc_device_load_key_cache(NfcDevice* dev) { furi_assert(dev); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); MfClassicData* data = &dev->dev_data.mf_classic_data; nfc_device_get_key_cache_file_path(dev, temp_str); @@ -950,16 +974,17 @@ bool nfc_device_load_key_cache(NfcDevice* dev) { bool load_success = false; do { - if(storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) != FSE_OK) break; - if(!flipper_format_file_open_existing(file, string_get_cstr(temp_str))) break; + if(storage_common_stat(dev->storage, furi_string_get_cstr(temp_str), NULL) != FSE_OK) + break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(temp_str))) break; uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, nfc_keys_file_header)) break; + if(furi_string_cmp_str(temp_str, nfc_keys_file_header)) break; if(version != nfc_keys_file_version) break; if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break; - if(!string_cmp_str(temp_str, "1K")) { + if(!furi_string_cmp(temp_str, "1K")) { data->type = MfClassicType1k; - } else if(!string_cmp_str(temp_str, "4K")) { + } else if(!furi_string_cmp(temp_str, "4K")) { data->type = MfClassicType4k; } else { break; @@ -971,21 +996,21 @@ bool nfc_device_load_key_cache(NfcDevice* dev) { for(size_t i = 0; (i < sectors) && (key_read_success); i++) { MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i); if(FURI_BIT(data->key_a_mask, i)) { - string_printf(temp_str, "Key A sector %d", i); - key_read_success = - flipper_format_read_hex(file, string_get_cstr(temp_str), sec_tr->key_a, 6); + furi_string_printf(temp_str, "Key A sector %d", i); + key_read_success = flipper_format_read_hex( + file, furi_string_get_cstr(temp_str), sec_tr->key_a, 6); } if(!key_read_success) break; if(FURI_BIT(data->key_b_mask, i)) { - string_printf(temp_str, "Key B sector %d", i); - key_read_success = - flipper_format_read_hex(file, string_get_cstr(temp_str), sec_tr->key_b, 6); + furi_string_printf(temp_str, "Key B sector %d", i); + key_read_success = flipper_format_read_hex( + file, furi_string_get_cstr(temp_str), sec_tr->key_b, 6); } } load_success = key_read_success; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return load_success; @@ -997,16 +1022,16 @@ void nfc_device_set_name(NfcDevice* dev, const char* name) { strlcpy(dev->dev_name, name, NFC_DEV_NAME_MAX_LEN); } -static void nfc_device_get_path_without_ext(string_t orig_path, string_t shadow_path) { +static void nfc_device_get_path_without_ext(FuriString* orig_path, FuriString* shadow_path) { // TODO: this won't work if there is ".nfc" anywhere in the path other than // at the end - size_t ext_start = string_search_str(orig_path, NFC_APP_EXTENSION); - string_set_n(shadow_path, orig_path, 0, ext_start); + size_t ext_start = furi_string_search(orig_path, NFC_APP_EXTENSION); + furi_string_set_n(shadow_path, orig_path, 0, ext_start); } -static void nfc_device_get_shadow_path(string_t orig_path, string_t shadow_path) { +static void nfc_device_get_shadow_path(FuriString* orig_path, FuriString* shadow_path) { nfc_device_get_path_without_ext(orig_path, shadow_path); - string_cat_printf(shadow_path, "%s", NFC_APP_SHADOW_EXTENSION); + furi_string_cat_printf(shadow_path, "%s", NFC_APP_SHADOW_EXTENSION); } static bool nfc_device_save_file( @@ -1020,25 +1045,25 @@ static bool nfc_device_save_file( bool saved = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); FuriHalNfcDevData* data = &dev->dev_data.nfc_data; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { - if(use_load_path && !string_empty_p(dev->load_path)) { + if(use_load_path && !furi_string_empty(dev->load_path)) { // Get directory name - path_extract_dirname(string_get_cstr(dev->load_path), temp_str); + path_extract_dirname(furi_string_get_cstr(dev->load_path), temp_str); // Create nfc directory if necessary - if(!storage_simply_mkdir(dev->storage, string_get_cstr(temp_str))) break; + if(!storage_simply_mkdir(dev->storage, furi_string_get_cstr(temp_str))) break; // Make path to file to save - string_cat_printf(temp_str, "/%s%s", dev_name, extension); + furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension); } else { // Create nfc directory if necessary if(!storage_simply_mkdir(dev->storage, NFC_APP_FOLDER)) break; // First remove nfc device file if it was saved - string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); + furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); } // Open file - if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; // Write header if(!flipper_format_write_header_cstr(file, nfc_file_header, nfc_file_version)) break; // Write nfc device type @@ -1072,7 +1097,7 @@ static bool nfc_device_save_file( if(!saved) { dialog_message_show_storage_error(dev->dialogs, "Can not save\nkey file"); } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return saved; } @@ -1086,13 +1111,13 @@ bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name) { return nfc_device_save_file(dev, dev_name, NFC_APP_FOLDER, NFC_APP_SHADOW_EXTENSION, true); } -static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog) { +static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dialog) { bool parsed = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); FuriHalNfcDevData* data = &dev->dev_data.nfc_data; uint32_t data_cnt = 0; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); bool deprecated_version = false; if(dev->loading_cb) { @@ -1103,17 +1128,17 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog // Check existance of shadow file nfc_device_get_shadow_path(path, temp_str); dev->shadow_file_exist = - storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) == FSE_OK; + storage_common_stat(dev->storage, furi_string_get_cstr(temp_str), NULL) == FSE_OK; // Open shadow file if it exists. If not - open original if(dev->shadow_file_exist) { - if(!flipper_format_file_open_existing(file, string_get_cstr(temp_str))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(temp_str))) break; } else { - if(!flipper_format_file_open_existing(file, string_get_cstr(path))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(path))) break; } // Read and verify file header uint32_t version = 0; if(!flipper_format_read_header(file, temp_str, &version)) break; - if(string_cmp_str(temp_str, nfc_file_header) || (version != nfc_file_version)) { + if(furi_string_cmp_str(temp_str, nfc_file_header) || (version != nfc_file_version)) { deprecated_version = true; break; } @@ -1152,7 +1177,7 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path, bool show_dialog } } - string_clear(temp_str); + furi_string_free(temp_str); flipper_format_free(file); return parsed; } @@ -1162,15 +1187,15 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path, bool show_dialog) { furi_assert(file_path); // Load device data - string_set_str(dev->load_path, file_path); + furi_string_set(dev->load_path, file_path); bool dev_load = nfc_device_load_data(dev, dev->load_path, show_dialog); if(dev_load) { // Set device name - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_filename_no_ext(file_path, filename); - nfc_device_set_name(dev, string_get_cstr(filename)); - string_clear(filename); + nfc_device_set_name(dev, furi_string_get_cstr(filename)); + furi_string_free(filename); } return dev_load; @@ -1180,8 +1205,8 @@ bool nfc_file_select(NfcDevice* dev) { furi_assert(dev); // Input events and views are managed by file_browser - string_t nfc_app_folder; - string_init_set_str(nfc_app_folder, NFC_APP_FOLDER); + FuriString* nfc_app_folder; + nfc_app_folder = furi_string_alloc_set(NFC_APP_FOLDER); const DialogsFileBrowserOptions browser_options = { .extension = NFC_APP_EXTENSION, @@ -1195,17 +1220,17 @@ bool nfc_file_select(NfcDevice* dev) { bool res = dialog_file_browser_show(dev->dialogs, dev->load_path, nfc_app_folder, &browser_options); - string_clear(nfc_app_folder); + furi_string_free(nfc_app_folder); if(res) { - string_t filename; - string_init(filename); + FuriString* filename; + filename = furi_string_alloc(); path_extract_filename(dev->load_path, filename, true); - strncpy(dev->dev_name, string_get_cstr(filename), NFC_DEV_NAME_MAX_LEN); + strncpy(dev->dev_name, furi_string_get_cstr(filename), NFC_DEV_NAME_MAX_LEN); res = nfc_device_load_data(dev, dev->load_path, true); if(res) { nfc_device_set_name(dev, dev->dev_name); } - string_clear(filename); + furi_string_free(filename); } return res; @@ -1223,7 +1248,7 @@ void nfc_device_data_clear(NfcDeviceData* dev_data) { } memset(&dev_data->nfc_data, 0, sizeof(FuriHalNfcDevData)); dev_data->protocol = NfcDeviceProtocolUnknown; - string_reset(dev_data->parsed_data); + furi_string_reset(dev_data->parsed_data); } void nfc_device_clear(NfcDevice* dev) { @@ -1232,33 +1257,34 @@ void nfc_device_clear(NfcDevice* dev) { nfc_device_set_name(dev, ""); nfc_device_data_clear(&dev->dev_data); dev->format = NfcDeviceSaveFormatUid; - string_reset(dev->load_path); + furi_string_reset(dev->load_path); } bool nfc_device_delete(NfcDevice* dev, bool use_load_path) { furi_assert(dev); bool deleted = false; - string_t file_path; - string_init(file_path); + FuriString* file_path; + file_path = furi_string_alloc(); do { // Delete original file - if(use_load_path && !string_empty_p(dev->load_path)) { - string_set(file_path, dev->load_path); + if(use_load_path && !furi_string_empty(dev->load_path)) { + furi_string_set(file_path, dev->load_path); } else { - string_printf(file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); + furi_string_printf( + file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); } - if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; // Delete shadow file if it exists if(dev->shadow_file_exist) { - if(use_load_path && !string_empty_p(dev->load_path)) { + if(use_load_path && !furi_string_empty(dev->load_path)) { nfc_device_get_shadow_path(dev->load_path, file_path); } else { - string_printf( + furi_string_printf( file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION); } - if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; } deleted = true; } while(0); @@ -1267,7 +1293,7 @@ bool nfc_device_delete(NfcDevice* dev, bool use_load_path) { dialog_message_show_storage_error(dev->dialogs, "Can not remove file"); } - string_clear(file_path); + furi_string_free(file_path); return deleted; } @@ -1276,29 +1302,29 @@ bool nfc_device_restore(NfcDevice* dev, bool use_load_path) { furi_assert(dev->shadow_file_exist); bool restored = false; - string_t path; + FuriString* path; - string_init(path); + path = furi_string_alloc(); do { - if(use_load_path && !string_empty_p(dev->load_path)) { + if(use_load_path && !furi_string_empty(dev->load_path)) { nfc_device_get_shadow_path(dev->load_path, path); } else { - string_printf( + furi_string_printf( path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION); } - if(!storage_simply_remove(dev->storage, string_get_cstr(path))) break; + if(!storage_simply_remove(dev->storage, furi_string_get_cstr(path))) break; dev->shadow_file_exist = false; - if(use_load_path && !string_empty_p(dev->load_path)) { - string_set(path, dev->load_path); + if(use_load_path && !furi_string_empty(dev->load_path)) { + furi_string_set(path, dev->load_path); } else { - string_printf(path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); + furi_string_printf(path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION); } if(!nfc_device_load_data(dev, path, true)) break; restored = true; } while(0); - string_clear(path); + furi_string_free(path); return restored; } diff --git a/lib/nfc/nfc_device.h b/lib/nfc/nfc_device.h index 5a143ebd4..309f9c999 100644 --- a/lib/nfc/nfc_device.h +++ b/lib/nfc/nfc_device.h @@ -63,7 +63,7 @@ typedef struct { MfClassicData mf_classic_data; MifareDesfireData mf_df_data; }; - string_t parsed_data; + FuriString* parsed_data; } NfcDeviceData; typedef struct { @@ -71,7 +71,7 @@ typedef struct { DialogsApp* dialogs; NfcDeviceData dev_data; char dev_name[NFC_DEV_NAME_MAX_LEN + 1]; - string_t load_path; + FuriString* load_path; NfcDeviceSaveFormat format; bool shadow_file_exist; diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 7efdda5da..ac71224e0 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -502,6 +502,54 @@ void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) { } } +static void nfc_worker_mf_classic_key_attack( + NfcWorker* nfc_worker, + uint64_t key, + FuriHalNfcTxRxContext* tx_rx, + uint16_t start_sector) { + furi_assert(nfc_worker); + + MfClassicData* data = &nfc_worker->dev_data->mf_classic_data; + uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type); + + furi_assert(start_sector < total_sectors); + + // Check every sector's A and B keys with the given key + for(size_t i = start_sector; i < total_sectors; i++) { + uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); + if(mf_classic_is_sector_read(data, i)) continue; + if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { + FURI_LOG_D( + TAG, + "Trying A key for sector %d, key: %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) { + mf_classic_set_key_found(data, i, MfClassicKeyA, key); + FURI_LOG_D(TAG, "Key found"); + nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + } + } + if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { + FURI_LOG_D( + TAG, + "Trying B key for sector %d, key: %04lx%08lx", + i, + (uint32_t)(key >> 32), + (uint32_t)key); + if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) { + mf_classic_set_key_found(data, i, MfClassicKeyB, key); + FURI_LOG_D(TAG, "Key found"); + nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); + } + } + if(mf_classic_is_sector_read(data, i)) continue; + mf_classic_read_sector(tx_rx, data, i); + if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; + } +} + void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { furi_assert(nfc_worker); furi_assert(nfc_worker->callback); @@ -523,7 +571,8 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { return; } - FURI_LOG_D(TAG, "Start Dictionary attack, Key Count %d", mf_classic_dict_get_total_keys(dict)); + FURI_LOG_D( + TAG, "Start Dictionary attack, Key Count %ld", mf_classic_dict_get_total_keys(dict)); for(size_t i = 0; i < total_sectors; i++) { FURI_LOG_I(TAG, "Sector %d", i); nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context); @@ -533,6 +582,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { bool is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); uint16_t key_index = 0; while(mf_classic_dict_get_next_key(dict, &key)) { + FURI_LOG_T(TAG, "Key %d", key_index); if(++key_index % NFC_DICT_KEY_BATCH_SIZE == 0) { nfc_worker->callback(NfcWorkerEventNewDictKeyBatch, nfc_worker->context); } @@ -554,15 +604,19 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA); if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyA)) { mf_classic_set_key_found(data, i, MfClassicKeyA, key); + FURI_LOG_D(TAG, "Key found"); nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); + nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); } furi_hal_nfc_sleep(); } if(!is_key_b_found) { is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); if(mf_classic_authenticate(&tx_rx, block_num, key, MfClassicKeyB)) { + FURI_LOG_D(TAG, "Key found"); mf_classic_set_key_found(data, i, MfClassicKeyB, key); nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); + nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); } } if(is_key_a_found && is_key_b_found) break; @@ -696,7 +750,8 @@ static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void* furi_assert(context); NfcWorker* nfc_worker = context; - if(event == ReaderAnalyzerEventMfkeyCollected) { + if((nfc_worker->state == NfcWorkerStateAnalyzeReader) && + (event == ReaderAnalyzerEventMfkeyCollected)) { if(nfc_worker->callback) { nfc_worker->callback(NfcWorkerEventDetectReaderMfkeyCollected, nfc_worker->context); } @@ -704,6 +759,9 @@ static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void* } void nfc_worker_analyze_reader(NfcWorker* nfc_worker) { + furi_assert(nfc_worker); + furi_assert(nfc_worker->callback); + FuriHalNfcTxRxContext tx_rx = {}; ReaderAnalyzer* reader_analyzer = nfc_worker->reader_analyzer; @@ -722,17 +780,32 @@ void nfc_worker_analyze_reader(NfcWorker* nfc_worker) { rfal_platform_spi_acquire(); FURI_LOG_D(TAG, "Start reader analyzer"); + + uint8_t reader_no_data_received_cnt = 0; + bool reader_no_data_notified = true; + while(nfc_worker->state == NfcWorkerStateAnalyzeReader) { furi_hal_nfc_stop_cmd(); furi_delay_ms(5); furi_hal_nfc_listen_start(nfc_data); if(furi_hal_nfc_listen_rx(&tx_rx, 300)) { + if(reader_no_data_notified) { + nfc_worker->callback(NfcWorkerEventDetectReaderDetected, nfc_worker->context); + } + reader_no_data_received_cnt = 0; + reader_no_data_notified = false; NfcProtocol protocol = reader_analyzer_guess_protocol(reader_analyzer, tx_rx.rx_data, tx_rx.rx_bits / 8); if(protocol == NfcDeviceProtocolMifareClassic) { mf_classic_emulator(&emulator, &tx_rx); } } else { + reader_no_data_received_cnt++; + if(!reader_no_data_notified && (reader_no_data_received_cnt > 5)) { + nfc_worker->callback(NfcWorkerEventDetectReaderLost, nfc_worker->context); + reader_no_data_received_cnt = 0; + reader_no_data_notified = true; + } FURI_LOG_D(TAG, "No data from reader"); continue; } diff --git a/lib/nfc/nfc_worker.h b/lib/nfc/nfc_worker.h index df0f53176..d463a96b3 100644 --- a/lib/nfc/nfc_worker.h +++ b/lib/nfc/nfc_worker.h @@ -57,6 +57,8 @@ typedef enum { NfcWorkerEventFoundKeyB, // Detect Reader events + NfcWorkerEventDetectReaderDetected, + NfcWorkerEventDetectReaderLost, NfcWorkerEventDetectReaderMfkeyCollected, // Mifare Ultralight events diff --git a/lib/nfc/parsers/all_in_one.c b/lib/nfc/parsers/all_in_one.c index b49a32f7c..05cfe5764 100644 --- a/lib/nfc/parsers/all_in_one.c +++ b/lib/nfc/parsers/all_in_one.c @@ -107,7 +107,7 @@ bool all_in_one_parser_parse(NfcDeviceData* dev_data) { dev_data->mf_ul_data.data[4 * 4 + 5] << 4 | (dev_data->mf_ul_data.data[4 * 4 + 6] >> 4); // Format string for rides count - string_printf( - dev_data->parsed_data, "\e#All-In-One\nNumber: %u\nRides left: %u", serial, ride_count); + furi_string_printf( + dev_data->parsed_data, "\e#All-In-One\nNumber: %lu\nRides left: %u", serial, ride_count); return true; } \ No newline at end of file diff --git a/lib/nfc/parsers/nfc_supported_card.h b/lib/nfc/parsers/nfc_supported_card.h index d34b5794a..4af59aded 100644 --- a/lib/nfc/parsers/nfc_supported_card.h +++ b/lib/nfc/parsers/nfc_supported_card.h @@ -4,8 +4,6 @@ #include "../nfc_worker.h" #include "../nfc_device.h" -#include - typedef enum { NfcSupportedCardTypePlantain, NfcSupportedCardTypeTroika, diff --git a/lib/nfc/parsers/plantain_4k_parser.c b/lib/nfc/parsers/plantain_4k_parser.c index 77387707b..348b5a64c 100644 --- a/lib/nfc/parsers/plantain_4k_parser.c +++ b/lib/nfc/parsers/plantain_4k_parser.c @@ -1,5 +1,4 @@ #include "nfc_supported_card.h" -#include "plantain_parser.h" // For luhn and string_push_uint64 #include #include @@ -118,36 +117,25 @@ bool plantain_4k_parser_parse(NfcDeviceData* dev_data) { card_number = (card_number << 8) | card_number_arr[i]; } // Convert card number to string - string_t card_number_str; - string_init(card_number_str); + FuriString* card_number_str; + card_number_str = furi_string_alloc(); // Should look like "361301047292848684" - // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead - string_push_uint64(card_number, card_number_str); + furi_string_printf(card_number_str, "%llu", card_number); // Add suffix with luhn checksum (1 digit) to the card number string - string_t card_number_suffix; - string_init(card_number_suffix); + FuriString* card_number_suffix; + card_number_suffix = furi_string_alloc(); - // The number to calculate the checksum on doesn't fit into uint64_t, idk - //uint8_t luhn_checksum = plantain_calculate_luhn(card_number); - - // // Convert luhn checksum to string - // string_t luhn_checksum_str; - // string_init(luhn_checksum_str); - // string_push_uint64(luhn_checksum, luhn_checksum_str); - - string_cat_printf(card_number_suffix, "-"); - // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); - string_cat_printf(card_number_str, string_get_cstr(card_number_suffix)); + furi_string_cat_printf(card_number_suffix, "-"); + furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings - string_clear(card_number_suffix); - // string_clear(luhn_checksum_str); + furi_string_free(card_number_suffix); - string_printf( + furi_string_printf( dev_data->parsed_data, - "\e#Plantain\nN:%s\nBalance:%d\n", - string_get_cstr(card_number_str), + "\e#Plantain\nN:%s\nBalance:%ld\n", + furi_string_get_cstr(card_number_str), balance); - string_clear(card_number_str); + furi_string_free(card_number_str); return true; } diff --git a/lib/nfc/parsers/plantain_parser.c b/lib/nfc/parsers/plantain_parser.c index ff81b8e9b..5328b5c4f 100644 --- a/lib/nfc/parsers/plantain_parser.c +++ b/lib/nfc/parsers/plantain_parser.c @@ -55,28 +55,6 @@ bool plantain_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { return mf_classic_read_card(tx_rx, &reader, &nfc_worker->dev_data->mf_classic_data) == 16; } -void string_push_uint64(uint64_t input, string_t output) { - const uint8_t base = 10; - - do { - char c = input % base; - input /= base; - - if(c < 10) - c += '0'; - else - c += 'A' - 10; - string_push_back(output, c); - } while(input); - - // reverse string - for(uint8_t i = 0; i < string_size(output) / 2; i++) { - char c = string_get_char(output, i); - string_set_char(output, i, string_get_char(output, string_size(output) - i - 1)); - string_set_char(output, string_size(output) - i - 1, c); - } -} - uint8_t plantain_calculate_luhn(uint64_t number) { // No. UNUSED(number); @@ -112,36 +90,25 @@ bool plantain_parser_parse(NfcDeviceData* dev_data) { card_number = (card_number << 8) | card_number_arr[i]; } // Convert card number to string - string_t card_number_str; - string_init(card_number_str); + FuriString* card_number_str; + card_number_str = furi_string_alloc(); // Should look like "361301047292848684" - // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead - string_push_uint64(card_number, card_number_str); + furi_string_printf(card_number_str, "%llu", card_number); // Add suffix with luhn checksum (1 digit) to the card number string - string_t card_number_suffix; - string_init(card_number_suffix); + FuriString* card_number_suffix; + card_number_suffix = furi_string_alloc(); - // The number to calculate the checksum on doesn't fit into uint64_t, idk - //uint8_t luhn_checksum = plantain_calculate_luhn(card_number); - - // // Convert luhn checksum to string - // string_t luhn_checksum_str; - // string_init(luhn_checksum_str); - // string_push_uint64(luhn_checksum, luhn_checksum_str); - - string_cat_printf(card_number_suffix, "-"); - // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); - string_cat_printf(card_number_str, string_get_cstr(card_number_suffix)); + furi_string_cat_printf(card_number_suffix, "-"); + furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings - string_clear(card_number_suffix); - // string_clear(luhn_checksum_str); + furi_string_free(card_number_suffix); - string_printf( + furi_string_printf( dev_data->parsed_data, - "\e#Plantain\nN:%s\nBalance:%d\n", - string_get_cstr(card_number_str), + "\e#Plantain\nN:%s\nBalance:%ld\n", + furi_string_get_cstr(card_number_str), balance); - string_clear(card_number_str); + furi_string_free(card_number_str); return true; } diff --git a/lib/nfc/parsers/plantain_parser.h b/lib/nfc/parsers/plantain_parser.h index d37f0dd48..1af8c5065 100644 --- a/lib/nfc/parsers/plantain_parser.h +++ b/lib/nfc/parsers/plantain_parser.h @@ -8,6 +8,4 @@ bool plantain_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx); bool plantain_parser_parse(NfcDeviceData* dev_data); -void string_push_uint64(uint64_t input, string_t output); - uint8_t plantain_calculate_luhn(uint64_t number); diff --git a/lib/nfc/parsers/troika_4k_parser.c b/lib/nfc/parsers/troika_4k_parser.c index 8c32381f2..d87b4eba7 100644 --- a/lib/nfc/parsers/troika_4k_parser.c +++ b/lib/nfc/parsers/troika_4k_parser.c @@ -98,7 +98,8 @@ bool troika_4k_parser_parse(NfcDeviceData* dev_data) { } number >>= 4; - string_printf(dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance); + furi_string_printf( + dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance); return true; } diff --git a/lib/nfc/parsers/troika_parser.c b/lib/nfc/parsers/troika_parser.c index f396b1680..9c16296f3 100644 --- a/lib/nfc/parsers/troika_parser.c +++ b/lib/nfc/parsers/troika_parser.c @@ -78,7 +78,7 @@ bool troika_parser_parse(NfcDeviceData* dev_data) { } number >>= 4; - string_printf( + furi_string_printf( dev_data->parsed_data, "\e#Troika\nNum: %ld\nBalance: %d rur.", number, balance); troika_parsed = true; } while(false); diff --git a/lib/nfc/parsers/two_cities.c b/lib/nfc/parsers/two_cities.c index d052dff19..2c6184a71 100644 --- a/lib/nfc/parsers/two_cities.c +++ b/lib/nfc/parsers/two_cities.c @@ -118,29 +118,18 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) { card_number = (card_number << 8) | card_number_arr[i]; } // Convert card number to string - string_t card_number_str; - string_init(card_number_str); + FuriString* card_number_str; + card_number_str = furi_string_alloc(); // Should look like "361301047292848684" - // %llu doesn't work for some reason in sprintf, so we use string_push_uint64 instead - string_push_uint64(card_number, card_number_str); + furi_string_printf(card_number_str, "%llu", card_number); // Add suffix with luhn checksum (1 digit) to the card number string - string_t card_number_suffix; - string_init(card_number_suffix); + FuriString* card_number_suffix; + card_number_suffix = furi_string_alloc(); - // The number to calculate the checksum on doesn't fit into uint64_t, idk - //uint8_t luhn_checksum = two_cities_calculate_luhn(card_number); - - // // Convert luhn checksum to string - // string_t luhn_checksum_str; - // string_init(luhn_checksum_str); - // string_push_uint64(luhn_checksum, luhn_checksum_str); - - string_cat_printf(card_number_suffix, "-"); - // FURI_LOG_D("plant4k", "Card checksum: %d", luhn_checksum); - string_cat_printf(card_number_str, string_get_cstr(card_number_suffix)); + furi_string_cat_printf(card_number_suffix, "-"); + furi_string_cat_printf(card_number_str, furi_string_get_cstr(card_number_suffix)); // Free all not needed strings - string_clear(card_number_suffix); - // string_clear(luhn_checksum_str); + furi_string_free(card_number_suffix); // ===== // --PLANTAIN-- @@ -158,14 +147,14 @@ bool two_cities_parser_parse(NfcDeviceData* dev_data) { } troika_number >>= 4; - string_printf( + furi_string_printf( dev_data->parsed_data, - "\e#Troika+Plantain\nPN: %s\nPB: %d rur.\nTN: %d\nTB: %d rur.\n", - string_get_cstr(card_number_str), + "\e#Troika+Plantain\nPN: %s\nPB: %ld rur.\nTN: %ld\nTB: %d rur.\n", + furi_string_get_cstr(card_number_str), balance, troika_number, troika_balance); - string_clear(card_number_str); + furi_string_free(card_number_str); return true; } diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c index 3b5343932..783202451 100644 --- a/lib/nfc/protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -847,7 +847,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ FURI_LOG_D( TAG, - "%08x key%c block %d nt/nr/ar: %08x %08x %08x", + "%08lx key%c block %d nt/nr/ar: %08lx %08lx %08lx", emulator->cuid, access_key == MfClassicKeyA ? 'A' : 'B', sector_trailer_block, @@ -858,7 +858,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ crypto1_word(&emulator->crypto, nr, 1); uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0); if(cardRr != prng_successor(nonce, 64)) { - FURI_LOG_T(TAG, "Wrong AUTH! %08X != %08X", cardRr, prng_successor(nonce, 64)); + FURI_LOG_T(TAG, "Wrong AUTH! %08lX != %08lX", cardRr, prng_successor(nonce, 64)); // Don't send NACK, as the tag doesn't send it command_processed = true; break; diff --git a/lib/nfc/protocols/mifare_desfire.c b/lib/nfc/protocols/mifare_desfire.c index f969cdde6..b2247bf20 100644 --- a/lib/nfc/protocols/mifare_desfire.c +++ b/lib/nfc/protocols/mifare_desfire.c @@ -42,14 +42,14 @@ void mf_df_clear(MifareDesfireData* data) { data->app_head = NULL; } -void mf_df_cat_data(MifareDesfireData* data, string_t out) { +void mf_df_cat_data(MifareDesfireData* data, FuriString* out) { mf_df_cat_card_info(data, out); for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { mf_df_cat_application(app, out); } } -void mf_df_cat_card_info(MifareDesfireData* data, string_t out) { +void mf_df_cat_card_info(MifareDesfireData* data, FuriString* out) { mf_df_cat_version(&data->version, out); if(data->free_memory) { mf_df_cat_free_mem(data->free_memory, out); @@ -59,8 +59,8 @@ void mf_df_cat_card_info(MifareDesfireData* data, string_t out) { } } -void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { - string_cat_printf( +void mf_df_cat_version(MifareDesfireVersion* version, FuriString* out) { + furi_string_cat_printf( out, "%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", version->uid[0], @@ -70,7 +70,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { version->uid[4], version->uid[5], version->uid[6]); - string_cat_printf( + furi_string_cat_printf( out, "hw %02x type %02x sub %02x\n" " maj %02x min %02x\n" @@ -82,7 +82,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { version->hw_minor, version->hw_storage, version->hw_proto); - string_cat_printf( + furi_string_cat_printf( out, "sw %02x type %02x sub %02x\n" " maj %02x min %02x\n" @@ -94,7 +94,7 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { version->sw_minor, version->sw_storage, version->sw_proto); - string_cat_printf( + furi_string_cat_printf( out, "batch %02x:%02x:%02x:%02x:%02x\n" "week %d year %d\n", @@ -107,40 +107,40 @@ void mf_df_cat_version(MifareDesfireVersion* version, string_t out) { version->prod_year); } -void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, string_t out) { - string_cat_printf(out, "freeMem %d\n", free_mem->bytes); +void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, FuriString* out) { + furi_string_cat_printf(out, "freeMem %ld\n", free_mem->bytes); } -void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, string_t out) { - string_cat_printf(out, "changeKeyID %d\n", ks->change_key_id); - string_cat_printf(out, "configChangeable %d\n", ks->config_changeable); - string_cat_printf(out, "freeCreateDelete %d\n", ks->free_create_delete); - string_cat_printf(out, "freeDirectoryList %d\n", ks->free_directory_list); - string_cat_printf(out, "masterChangeable %d\n", ks->master_key_changeable); +void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, FuriString* out) { + furi_string_cat_printf(out, "changeKeyID %d\n", ks->change_key_id); + furi_string_cat_printf(out, "configChangeable %d\n", ks->config_changeable); + furi_string_cat_printf(out, "freeCreateDelete %d\n", ks->free_create_delete); + furi_string_cat_printf(out, "freeDirectoryList %d\n", ks->free_directory_list); + furi_string_cat_printf(out, "masterChangeable %d\n", ks->master_key_changeable); if(ks->flags) { - string_cat_printf(out, "flags %d\n", ks->flags); + furi_string_cat_printf(out, "flags %d\n", ks->flags); } - string_cat_printf(out, "maxKeys %d\n", ks->max_keys); + furi_string_cat_printf(out, "maxKeys %d\n", ks->max_keys); for(MifareDesfireKeyVersion* kv = ks->key_version_head; kv; kv = kv->next) { - string_cat_printf(out, "key %d version %d\n", kv->id, kv->version); + furi_string_cat_printf(out, "key %d version %d\n", kv->id, kv->version); } } -void mf_df_cat_application_info(MifareDesfireApplication* app, string_t out) { - string_cat_printf(out, "Application %02x%02x%02x\n", app->id[0], app->id[1], app->id[2]); +void mf_df_cat_application_info(MifareDesfireApplication* app, FuriString* out) { + furi_string_cat_printf(out, "Application %02x%02x%02x\n", app->id[0], app->id[1], app->id[2]); if(app->key_settings) { mf_df_cat_key_settings(app->key_settings, out); } } -void mf_df_cat_application(MifareDesfireApplication* app, string_t out) { +void mf_df_cat_application(MifareDesfireApplication* app, FuriString* out) { mf_df_cat_application_info(app, out); for(MifareDesfireFile* file = app->file_head; file; file = file->next) { mf_df_cat_file(file, out); } } -void mf_df_cat_file(MifareDesfireFile* file, string_t out) { +void mf_df_cat_file(MifareDesfireFile* file, FuriString* out) { char* type = "unknown"; switch(file->type) { case MifareDesfireFileTypeStandard: @@ -171,9 +171,9 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) { comm = "enciphered"; break; } - string_cat_printf(out, "File %d\n", file->id); - string_cat_printf(out, "%s %s\n", type, comm); - string_cat_printf( + furi_string_cat_printf(out, "File %d\n", file->id); + furi_string_cat_printf(out, "%s %s\n", type, comm); + furi_string_cat_printf( out, "r %d w %d rw %d c %d\n", file->access_rights >> 12 & 0xF, @@ -186,15 +186,15 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) { case MifareDesfireFileTypeStandard: case MifareDesfireFileTypeBackup: size = file->settings.data.size; - string_cat_printf(out, "size %d\n", size); + furi_string_cat_printf(out, "size %d\n", size); break; case MifareDesfireFileTypeValue: size = 4; - string_cat_printf( - out, "lo %d hi %d\n", file->settings.value.lo_limit, file->settings.value.hi_limit); - string_cat_printf( + furi_string_cat_printf( + out, "lo %ld hi %ld\n", file->settings.value.lo_limit, file->settings.value.hi_limit); + furi_string_cat_printf( out, - "limit %d enabled %d\n", + "limit %ld enabled %d\n", file->settings.value.limited_credit_value, file->settings.value.limited_credit_enabled); break; @@ -202,33 +202,33 @@ void mf_df_cat_file(MifareDesfireFile* file, string_t out) { case MifareDesfireFileTypeCyclicRecord: size = file->settings.record.size; num = file->settings.record.cur; - string_cat_printf(out, "size %d\n", size); - string_cat_printf(out, "num %d max %d\n", num, file->settings.record.max); + furi_string_cat_printf(out, "size %d\n", size); + furi_string_cat_printf(out, "num %d max %ld\n", num, file->settings.record.max); break; } uint8_t* data = file->contents; if(data) { for(int rec = 0; rec < num; rec++) { - string_cat_printf(out, "record %d\n", rec); + furi_string_cat_printf(out, "record %d\n", rec); for(int ch = 0; ch < size; ch += 4) { - string_cat_printf(out, "%03x|", ch); + furi_string_cat_printf(out, "%03x|", ch); for(int i = 0; i < 4; i++) { if(ch + i < size) { - string_cat_printf(out, "%02x ", data[rec * size + ch + i]); + furi_string_cat_printf(out, "%02x ", data[rec * size + ch + i]); } else { - string_cat_printf(out, " "); + furi_string_cat_printf(out, " "); } } for(int i = 0; i < 4 && ch + i < size; i++) { if(isprint(data[rec * size + ch + i])) { - string_cat_printf(out, "%c", data[rec * size + ch + i]); + furi_string_cat_printf(out, "%c", data[rec * size + ch + i]); } else { - string_cat_printf(out, "."); + furi_string_cat_printf(out, "."); } } - string_cat_printf(out, "\n"); + furi_string_cat_printf(out, "\n"); } - string_cat_printf(out, " \n"); + furi_string_cat_printf(out, " \n"); } } } diff --git a/lib/nfc/protocols/mifare_desfire.h b/lib/nfc/protocols/mifare_desfire.h index e59743a2f..963a18f58 100644 --- a/lib/nfc/protocols/mifare_desfire.h +++ b/lib/nfc/protocols/mifare_desfire.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -120,14 +119,14 @@ typedef struct { void mf_df_clear(MifareDesfireData* data); -void mf_df_cat_data(MifareDesfireData* data, string_t out); -void mf_df_cat_card_info(MifareDesfireData* data, string_t out); -void mf_df_cat_version(MifareDesfireVersion* version, string_t out); -void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, string_t out); -void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, string_t out); -void mf_df_cat_application_info(MifareDesfireApplication* app, string_t out); -void mf_df_cat_application(MifareDesfireApplication* app, string_t out); -void mf_df_cat_file(MifareDesfireFile* file, string_t out); +void mf_df_cat_data(MifareDesfireData* data, FuriString* out); +void mf_df_cat_card_info(MifareDesfireData* data, FuriString* out); +void mf_df_cat_version(MifareDesfireVersion* version, FuriString* out); +void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, FuriString* out); +void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, FuriString* out); +void mf_df_cat_application_info(MifareDesfireApplication* app, FuriString* out); +void mf_df_cat_application(MifareDesfireApplication* app, FuriString* out); +void mf_df_cat_file(MifareDesfireFile* file, FuriString* out); bool mf_df_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); diff --git a/lib/nfc/protocols/mifare_ultralight.c b/lib/nfc/protocols/mifare_ultralight.c index b3d80deb3..a8d1f5548 100644 --- a/lib/nfc/protocols/mifare_ultralight.c +++ b/lib/nfc/protocols/mifare_ultralight.c @@ -4,7 +4,6 @@ #include "nfc_util.h" #include #include "furi_hal_nfc.h" -#include #define TAG "MfUltralight" @@ -194,7 +193,7 @@ bool mf_ultralight_authenticate(FuriHalNfcTxRxContext* tx_rx, uint32_t key, uint *pack = (tx_rx->rx_data[1] << 8) | tx_rx->rx_data[0]; } - FURI_LOG_I(TAG, "Auth success. Password: %08X. PACK: %04X", key, *pack); + FURI_LOG_I(TAG, "Auth success. Password: %08lX. PACK: %04X", key, *pack); authenticated = true; } while(false); @@ -1005,7 +1004,7 @@ static bool mf_ul_check_lock(MfUltralightEmulator* emulator, int16_t write_page) return (dynamic_lock_bytes & (1 << shift)) == 0; } -static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str) { +static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, FuriString* str) { // Locals to improve readability uint8_t mirror_page = emulator->config->mirror_page; uint8_t mirror_byte = emulator->config->mirror.mirror_byte; @@ -1020,14 +1019,14 @@ static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str if(mirror_conf == MfUltralightMirrorUid) return; // NTAG21x has the peculiar behavior when UID+counter selected, if UID does not fit but // counter will fit, it will actually mirror the counter - string_cat_str(str, " "); + furi_string_cat(str, " "); } else { for(int i = 0; i < 3; ++i) { - string_cat_printf(str, "%02X", emulator->data.data[i]); + furi_string_cat_printf(str, "%02X", emulator->data.data[i]); } // Skip BCC0 for(int i = 4; i < 8; ++i) { - string_cat_printf(str, "%02X", emulator->data.data[i]); + furi_string_cat_printf(str, "%02X", emulator->data.data[i]); } uid_printed = true; } @@ -1049,9 +1048,9 @@ static void mf_ul_make_ascii_mirror(MfUltralightEmulator* emulator, string_t str if(mirror_page == last_user_page_index - 1 && mirror_byte > 2) return; if(mirror_conf == MfUltralightMirrorUidCounter) - string_cat_str(str, uid_printed ? "x" : " "); + furi_string_cat(str, uid_printed ? "x" : " "); - string_cat_printf(str, "%06X", emulator->data.counter[2]); + furi_string_cat_printf(str, "%06lX", emulator->data.counter[2]); } } } @@ -1267,14 +1266,14 @@ bool mf_ul_prepare_emulation_response( bool reset_idle = false; #ifdef FURI_DEBUG - string_t debug_buf; - string_init(debug_buf); + FuriString* debug_buf; + debug_buf = furi_string_alloc(); for(int i = 0; i < (buff_rx_len + 7) / 8; ++i) { - string_cat_printf(debug_buf, "%02x ", buff_rx[i]); + furi_string_cat_printf(debug_buf, "%02x ", buff_rx[i]); } - string_strim(debug_buf); - FURI_LOG_T(TAG, "Emu RX (%d): %s", buff_rx_len, string_get_cstr(debug_buf)); - string_reset(debug_buf); + furi_string_trim(debug_buf); + FURI_LOG_T(TAG, "Emu RX (%d): %s", buff_rx_len, furi_string_get_cstr(debug_buf)); + furi_string_reset(debug_buf); #endif // Check composite commands @@ -1328,7 +1327,7 @@ bool mf_ul_prepare_emulation_response( uint8_t src_page = start_page; uint8_t last_page_plus_one = start_page + 4; uint8_t pwd_page = emulator->page_num - 2; - string_t ascii_mirror; + FuriString* ascii_mirror = NULL; size_t ascii_mirror_len = 0; const char* ascii_mirror_cptr = NULL; uint8_t ascii_mirror_curr_page = 0; @@ -1353,10 +1352,10 @@ bool mf_ul_prepare_emulation_response( if(last_page_plus_one > ascii_mirror_curr_page && start_page + 3 >= ascii_mirror_curr_page && start_page <= ascii_mirror_curr_page + 6) { - string_init(ascii_mirror); + ascii_mirror = furi_string_alloc(); mf_ul_make_ascii_mirror(emulator, ascii_mirror); - ascii_mirror_len = string_length_u(ascii_mirror); - ascii_mirror_cptr = string_get_cstr(ascii_mirror); + ascii_mirror_len = furi_string_utf8_length(ascii_mirror); + ascii_mirror_cptr = furi_string_get_cstr(ascii_mirror); // Move pointer to where it should be to start copying if(ascii_mirror_len > 0 && ascii_mirror_curr_page < start_page && @@ -1414,8 +1413,8 @@ bool mf_ul_prepare_emulation_response( ++src_page; if(src_page >= last_page_plus_one) src_page = 0; } - if(ascii_mirror_cptr != NULL) { - string_clear(ascii_mirror); + if(ascii_mirror != NULL) { + furi_string_free(ascii_mirror); } *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; @@ -1512,12 +1511,13 @@ bool mf_ul_prepare_emulation_response( // Copy ASCII mirror // Less stringent check here, because expecting FAST_READ to // only be issued once rather than repeatedly - string_t ascii_mirror; - string_init(ascii_mirror); + FuriString* ascii_mirror; + ascii_mirror = furi_string_alloc(); mf_ul_make_ascii_mirror(emulator, ascii_mirror); - size_t ascii_mirror_len = string_length_u(ascii_mirror); + size_t ascii_mirror_len = + furi_string_utf8_length(ascii_mirror); const char* ascii_mirror_cptr = - string_get_cstr(ascii_mirror); + furi_string_get_cstr(ascii_mirror); int16_t mirror_start_offset = (emulator->config->mirror_page - start_page) * 4 + emulator->config->mirror.mirror_byte; @@ -1547,7 +1547,7 @@ bool mf_ul_prepare_emulation_response( ++ascii_mirror_cptr; } } - string_clear(ascii_mirror); + furi_string_free(ascii_mirror); } if(emulator->supported_features & MfUltralightSupportAuth) { @@ -1851,11 +1851,11 @@ bool mf_ul_prepare_emulation_response( } else if(*buff_tx_len > 0) { int count = (*buff_tx_len + 7) / 8; for(int i = 0; i < count; ++i) { - string_cat_printf(debug_buf, "%02x ", buff_tx[i]); + furi_string_cat_printf(debug_buf, "%02x ", buff_tx[i]); } - string_strim(debug_buf); - FURI_LOG_T(TAG, "Emu TX (%d): %s", *buff_tx_len, string_get_cstr(debug_buf)); - string_clear(debug_buf); + furi_string_trim(debug_buf); + FURI_LOG_T(TAG, "Emu TX (%d): %s", *buff_tx_len, furi_string_get_cstr(debug_buf)); + furi_string_free(debug_buf); } else { FURI_LOG_T(TAG, "Emu TX: HALT"); } diff --git a/lib/one_wire/ibutton/ibutton_worker_modes.c b/lib/one_wire/ibutton/ibutton_worker_modes.c index d585e27f4..691aea9ee 100644 --- a/lib/one_wire/ibutton/ibutton_worker_modes.c +++ b/lib/one_wire/ibutton/ibutton_worker_modes.c @@ -2,7 +2,6 @@ #include #include "ibutton_worker_i.h" #include "ibutton_key_command.h" -#include void ibutton_worker_mode_idle_start(iButtonWorker* worker); void ibutton_worker_mode_idle_tick(iButtonWorker* worker); @@ -65,7 +64,7 @@ void ibutton_worker_mode_idle_stop(iButtonWorker* worker) { typedef struct { uint32_t last_dwt_value; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; } iButtonReadContext; void ibutton_worker_comparator_callback(bool level, void* context) { @@ -75,7 +74,7 @@ void ibutton_worker_comparator_callback(bool level, void* context) { LevelDuration data = level_duration_make(level, current_dwt_value - read_context->last_dwt_value); - xStreamBufferSend(read_context->stream, &data, sizeof(LevelDuration), 0); + furi_stream_buffer_send(read_context->stream, &data, sizeof(LevelDuration), 0); read_context->last_dwt_value = current_dwt_value; } @@ -91,7 +90,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { iButtonReadContext read_context = { .last_dwt_value = DWT->CYCCNT, - .stream = xStreamBufferCreate(sizeof(LevelDuration) * 512, 1), + .stream = furi_stream_buffer_alloc(sizeof(LevelDuration) * 512, 1), }; furi_hal_rfid_comp_set_callback(ibutton_worker_comparator_callback, &read_context); @@ -100,7 +99,8 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { uint32_t tick_start = furi_get_tick(); while(true) { LevelDuration level; - size_t ret = xStreamBufferReceive(read_context.stream, &level, sizeof(LevelDuration), 100); + size_t ret = + furi_stream_buffer_receive(read_context.stream, &level, sizeof(LevelDuration), 100); if((furi_get_tick() - tick_start) > 100) { break; @@ -141,7 +141,7 @@ bool ibutton_worker_read_comparator(iButtonWorker* worker) { furi_hal_rfid_comp_set_callback(NULL, NULL); furi_hal_rfid_pins_reset(); - vStreamBufferDelete(read_context.stream); + furi_stream_buffer_free(read_context.stream); return result; } diff --git a/lib/print/printf_tiny.h b/lib/print/printf_tiny.h index 8f292819e..58f6a673b 100644 --- a/lib/print/printf_tiny.h +++ b/lib/print/printf_tiny.h @@ -34,6 +34,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -54,7 +55,7 @@ void _putchar(char character); * \param format A string that specifies the format of the output * \return The number of characters that are written into the array, not counting the terminating null character */ -int printf_(const char* format, ...); +int printf_(const char* format, ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); /** * Tiny sprintf implementation @@ -63,7 +64,7 @@ int printf_(const char* format, ...); * \param format A string that specifies the format of the output * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character */ -int sprintf_(char* buffer, const char* format, ...); +int sprintf_(char* buffer, const char* format, ...) _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Tiny snprintf/vsnprintf implementation @@ -75,7 +76,8 @@ int sprintf_(char* buffer, const char* format, ...); * null character. A value equal or larger than count indicates truncation. Only when the returned value * is non-negative and less than count, the string has been completely written. */ -int snprintf_(char* buffer, size_t count, const char* format, ...); +int snprintf_(char* buffer, size_t count, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); /** @@ -94,7 +96,8 @@ int vprintf_(const char* format, va_list va); * \param format A string that specifies the format of the output * \return The number of characters that are sent to the output function, not counting the terminating null character */ -int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); #ifdef __cplusplus } diff --git a/lib/subghz/blocks/generic.c b/lib/subghz/blocks/generic.c index 353ff18bf..7496aea3d 100644 --- a/lib/subghz/blocks/generic.c +++ b/lib/subghz/blocks/generic.c @@ -4,7 +4,7 @@ #define TAG "SubGhzBlockGeneric" -void subghz_block_generic_get_preset_name(const char* preset_name, string_t preset_str) { +void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) { const char* preset_name_temp; if(!strcmp(preset_name, "AM270")) { preset_name_temp = "FuriHalSubGhzPresetOok270Async"; @@ -17,7 +17,7 @@ void subghz_block_generic_get_preset_name(const char* preset_name, string_t pres } else { preset_name_temp = "FuriHalSubGhzPresetCustom"; } - string_set(preset_str, preset_name_temp); + furi_string_set(preset_str, preset_name_temp); } bool subghz_block_generic_serialize( @@ -26,8 +26,8 @@ bool subghz_block_generic_serialize( SubGhzPresetDefinition* preset) { furi_assert(instance); bool res = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { stream_clean(flipper_format_get_raw_stream(flipper_format)); if(!flipper_format_write_header_cstr( @@ -41,12 +41,13 @@ bool subghz_block_generic_serialize( break; } - subghz_block_generic_get_preset_name(string_get_cstr(preset->name), temp_str); - if(!flipper_format_write_string_cstr(flipper_format, "Preset", string_get_cstr(temp_str))) { + subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); + if(!flipper_format_write_string_cstr( + flipper_format, "Preset", furi_string_get_cstr(temp_str))) { FURI_LOG_E(TAG, "Unable to add Preset"); break; } - if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { if(!flipper_format_write_string_cstr( flipper_format, "Custom_preset_module", "CC1101")) { FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); @@ -79,15 +80,15 @@ bool subghz_block_generic_serialize( } res = true; } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return res; } bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format) { furi_assert(instance); bool res = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); uint32_t temp_data = 0; do { @@ -113,7 +114,7 @@ bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperForma res = true; } while(0); - string_clear(temp_str); + furi_string_free(temp_str); return res; } diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index 56a7fc2d3..300807daa 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -25,7 +25,7 @@ struct SubGhzBlockGeneric { * @param preset_name name preset * @param preset_str Output name preset */ -void subghz_block_generic_get_preset_name(const char* preset_name, string_t preset_str); +void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str); /** * Serialize data SubGhzBlockGeneric. diff --git a/lib/subghz/protocols/base.c b/lib/subghz/protocols/base.c index 06542f5eb..4ee7a3f8a 100644 --- a/lib/subghz/protocols/base.c +++ b/lib/subghz/protocols/base.c @@ -11,7 +11,7 @@ void subghz_protocol_decoder_base_set_decoder_callback( bool subghz_protocol_decoder_base_get_string( SubGhzProtocolDecoderBase* decoder_base, - string_t output) { + FuriString* output) { bool status = false; if(decoder_base->protocol && decoder_base->protocol->decoder && diff --git a/lib/subghz/protocols/base.h b/lib/subghz/protocols/base.h index fdd135671..47b4e482b 100644 --- a/lib/subghz/protocols/base.h +++ b/lib/subghz/protocols/base.h @@ -11,8 +11,9 @@ typedef struct SubGhzProtocolDecoderBase SubGhzProtocolDecoderBase; typedef void ( *SubGhzProtocolDecoderBaseRxCallback)(SubGhzProtocolDecoderBase* instance, void* context); -typedef void ( - *SubGhzProtocolDecoderBaseSerialize)(SubGhzProtocolDecoderBase* decoder_base, string_t output); +typedef void (*SubGhzProtocolDecoderBaseSerialize)( + SubGhzProtocolDecoderBase* decoder_base, + FuriString* output); struct SubGhzProtocolDecoderBase { // Decoder general section @@ -41,7 +42,7 @@ void subghz_protocol_decoder_base_set_decoder_callback( */ bool subghz_protocol_decoder_base_get_string( SubGhzProtocolDecoderBase* decoder_base, - string_t output); + FuriString* output); /** * Serialize data SubGhzProtocolDecoderBase. diff --git a/lib/subghz/protocols/bett.c b/lib/subghz/protocols/bett.c index c80702577..605a922c6 100644 --- a/lib/subghz/protocols/bett.c +++ b/lib/subghz/protocols/bett.c @@ -323,11 +323,11 @@ bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flip return ret; } -void subghz_protocol_decoder_bett_get_string(void* context, string_t output) { +void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderBETT* instance = context; uint32_t data = (uint32_t)(instance->generic.data & 0x3FFFF); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%05lX\r\n" diff --git a/lib/subghz/protocols/bett.h b/lib/subghz/protocols/bett.h index 48f32b3e0..04bf46b56 100644 --- a/lib/subghz/protocols/bett.h +++ b/lib/subghz/protocols/bett.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flip * @param context Pointer to a SubGhzProtocolDecoderBETT instance * @param output Resulting text */ -void subghz_protocol_decoder_bett_get_string(void* context, string_t output); +void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index 53d3d0788..7c037bd12 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -322,7 +322,7 @@ bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flip return ret; } -void subghz_protocol_decoder_came_get_string(void* context, string_t output) { +void subghz_protocol_decoder_came_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderCame* instance = context; @@ -333,7 +333,7 @@ void subghz_protocol_decoder_came_get_string(void* context, string_t output) { uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" diff --git a/lib/subghz/protocols/came.h b/lib/subghz/protocols/came.h index c2648c057..d1ac76286 100644 --- a/lib/subghz/protocols/came.h +++ b/lib/subghz/protocols/came.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flip * @param context Pointer to a SubGhzProtocolDecoderCame instance * @param output Resulting text */ -void subghz_protocol_decoder_came_get_string(void* context, string_t output); +void subghz_protocol_decoder_came_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 0c3cdd8ad..8c2a542c2 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -325,7 +325,7 @@ bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat return ret; } -void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t output) { +void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderCameAtomo* instance = context; subghz_protocol_came_atomo_remote_controller( @@ -333,12 +333,12 @@ void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t outpu uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%03X\r\n", + "Cnt:0x%03lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/came_atomo.h b/lib/subghz/protocols/came_atomo.h index 70a79eca1..aa1cffd05 100644 --- a/lib/subghz/protocols/came_atomo.h +++ b/lib/subghz/protocols/came_atomo.h @@ -69,4 +69,4 @@ bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance * @param output Resulting text */ -void subghz_protocol_decoder_came_atomo_get_string(void* context, string_t output); +void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index b5b409c59..3d5029ec9 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -446,18 +446,18 @@ bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_came_twee_get_string(void* context, string_t output) { +void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderCameTwee* instance = context; subghz_protocol_came_twee_remote_controller(&instance->generic); uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" - "Btn:%lX\r\n" + "Btn:%X\r\n" "DIP:" DIP_PATTERN "\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/came_twee.h b/lib/subghz/protocols/came_twee.h index 42e6ddaf3..aa1f0e0db 100644 --- a/lib/subghz/protocols/came_twee.h +++ b/lib/subghz/protocols/came_twee.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance * @param output Resulting text */ -void subghz_protocol_decoder_came_twee_get_string(void* context, string_t output); +void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/chamberlain_code.c b/lib/subghz/protocols/chamberlain_code.c index 66d230d13..d2d19af25 100644 --- a/lib/subghz/protocols/chamberlain_code.c +++ b/lib/subghz/protocols/chamberlain_code.c @@ -451,7 +451,7 @@ bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat return ret; } -void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t output) { +void subghz_protocol_decoder_chamb_code_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderChamb_Code* instance = context; @@ -462,7 +462,7 @@ void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t outpu uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%03lX\r\n" @@ -474,19 +474,19 @@ void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t outpu switch(instance->generic.data_count_bit) { case 7: - string_cat_printf( + furi_string_cat_printf( output, "DIP:" CHAMBERLAIN_7_CODE_DIP_PATTERN "\r\n", CHAMBERLAIN_7_CODE_DATA_TO_DIP(code_found_lo)); break; case 8: - string_cat_printf( + furi_string_cat_printf( output, "DIP:" CHAMBERLAIN_8_CODE_DIP_PATTERN "\r\n", CHAMBERLAIN_8_CODE_DATA_TO_DIP(code_found_lo)); break; case 9: - string_cat_printf( + furi_string_cat_printf( output, "DIP:" CHAMBERLAIN_9_CODE_DIP_PATTERN "\r\n", CHAMBERLAIN_9_CODE_DATA_TO_DIP(code_found_lo)); diff --git a/lib/subghz/protocols/chamberlain_code.h b/lib/subghz/protocols/chamberlain_code.h index 1ac2f9f96..923a3151b 100644 --- a/lib/subghz/protocols/chamberlain_code.h +++ b/lib/subghz/protocols/chamberlain_code.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance * @param output Resulting text */ -void subghz_protocol_decoder_chamb_code_get_string(void* context, string_t output); +void subghz_protocol_decoder_chamb_code_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/clemsa.c b/lib/subghz/protocols/clemsa.c index 337346934..dbee0ac94 100644 --- a/lib/subghz/protocols/clemsa.c +++ b/lib/subghz/protocols/clemsa.c @@ -343,12 +343,12 @@ bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* fl return ret; } -void subghz_protocol_decoder_clemsa_get_string(void* context, string_t output) { +void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderClemsa* instance = context; subghz_protocol_clemsa_check_remote_controller(&instance->generic); //uint32_t data = (uint32_t)(instance->generic.data & 0xFFFFFF); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%05lX Btn %X\r\n" diff --git a/lib/subghz/protocols/clemsa.h b/lib/subghz/protocols/clemsa.h index a83983122..8287af234 100644 --- a/lib/subghz/protocols/clemsa.h +++ b/lib/subghz/protocols/clemsa.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* fl * @param context Pointer to a SubGhzProtocolDecoderClemsa instance * @param output Resulting text */ -void subghz_protocol_decoder_clemsa_get_string(void* context, string_t output); +void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/doitrand.c b/lib/subghz/protocols/doitrand.c index 9122c1935..5c3402144 100644 --- a/lib/subghz/protocols/doitrand.c +++ b/lib/subghz/protocols/doitrand.c @@ -337,15 +337,15 @@ bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_doitrand_get_string(void* context, string_t output) { +void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderDoitrand* instance = context; subghz_protocol_doitrand_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%02lX%08lX\r\n" - "Btn:%lX\r\n" + "Btn:%X\r\n" "DIP:" DIP_PATTERN "\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/doitrand.h b/lib/subghz/protocols/doitrand.h index f94d73899..c96946a13 100644 --- a/lib/subghz/protocols/doitrand.h +++ b/lib/subghz/protocols/doitrand.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance * @param output Resulting text */ -void subghz_protocol_decoder_doitrand_get_string(void* context, string_t output); +void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 8b90f471c..b54435902 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -207,7 +207,7 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output) { +void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderFaacSLH* instance = context; subghz_protocol_faac_slh_check_remote_controller(&instance->generic); @@ -216,13 +216,13 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output) uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; uint32_t code_hop = (code_found_reverse >> 32) & 0xFFFFFFFF; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%lX%08lX\r\n" "Fix:%08lX \r\n" "Hop:%08lX \r\n" - "Sn:%07lX Btn:%lX\r\n", + "Sn:%07lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/faac_slh.h b/lib/subghz/protocols/faac_slh.h index fe7a79265..9b18f5eab 100644 --- a/lib/subghz/protocols/faac_slh.h +++ b/lib/subghz/protocols/faac_slh.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance * @param output Resulting text */ -void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output); +void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c index 56c224aef..5cf3a8714 100644 --- a/lib/subghz/protocols/gate_tx.c +++ b/lib/subghz/protocols/gate_tx.c @@ -317,15 +317,15 @@ bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* f return ret; } -void subghz_protocol_decoder_gate_tx_get_string(void* context, string_t output) { +void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderGateTx* instance = context; subghz_protocol_gate_tx_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%06lX\r\n" - "Sn:%05lX Btn:%lX\r\n", + "Sn:%05lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data & 0xFFFFFF), diff --git a/lib/subghz/protocols/gate_tx.h b/lib/subghz/protocols/gate_tx.h index 171576816..36eeb9a99 100644 --- a/lib/subghz/protocols/gate_tx.h +++ b/lib/subghz/protocols/gate_tx.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* f * @param context Pointer to a SubGhzProtocolDecoderGateTx instance * @param output Resulting text */ -void subghz_protocol_decoder_gate_tx_get_string(void* context, string_t output); +void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/holtek.c b/lib/subghz/protocols/holtek.c index 5cd160633..230f4cfef 100644 --- a/lib/subghz/protocols/holtek.c +++ b/lib/subghz/protocols/holtek.c @@ -350,12 +350,12 @@ bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* fl return ret; } -void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) { +void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderHoltek* instance = context; subghz_protocol_holtek_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" @@ -368,8 +368,8 @@ void subghz_protocol_decoder_holtek_get_string(void* context, string_t output) { instance->generic.btn >> 4); if((instance->generic.btn & 0xF) == 0xE) { - string_cat_printf(output, "ON\r\n"); + furi_string_cat_printf(output, "ON\r\n"); } else if(((instance->generic.btn & 0xF) == 0xB)) { - string_cat_printf(output, "OFF\r\n"); + furi_string_cat_printf(output, "OFF\r\n"); } } diff --git a/lib/subghz/protocols/holtek.h b/lib/subghz/protocols/holtek.h index df7dd6448..1dac783b1 100644 --- a/lib/subghz/protocols/holtek.h +++ b/lib/subghz/protocols/holtek.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* fl * @param context Pointer to a SubGhzProtocolDecoderHoltek instance * @param output Resulting text */ -void subghz_protocol_decoder_holtek_get_string(void* context, string_t output); +void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/honeywell_wdb.c b/lib/subghz/protocols/honeywell_wdb.c index 451a13f50..3cd62698d 100644 --- a/lib/subghz/protocols/honeywell_wdb.c +++ b/lib/subghz/protocols/honeywell_wdb.c @@ -374,18 +374,18 @@ bool subghz_protocol_decoder_honeywell_wdb_deserialize( return ret; } -void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, string_t output) { +void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderHoneywell_WDB* instance = context; subghz_protocol_honeywell_wdb_check_remote_controller(instance); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%05lX\r\n" "DT:%s Al:%s\r\n" - "SK:%01lX R:%01lX LBat:%01lX\r\n", + "SK:%01X R:%01X LBat:%01X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)((instance->generic.data >> 32) & 0xFFFFFFFF), diff --git a/lib/subghz/protocols/honeywell_wdb.h b/lib/subghz/protocols/honeywell_wdb.h index 012b36996..c61aa822f 100644 --- a/lib/subghz/protocols/honeywell_wdb.h +++ b/lib/subghz/protocols/honeywell_wdb.h @@ -108,4 +108,4 @@ bool subghz_protocol_decoder_honeywell_wdb_deserialize( * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance * @param output Resulting text */ -void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, string_t output); +void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index d78bc9273..d8438604f 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -338,12 +338,12 @@ bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* f return ret; } -void subghz_protocol_decoder_hormann_get_string(void* context, string_t output) { +void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderHormann* instance = context; subghz_protocol_hormann_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s\r\n" "%dbit\r\n" diff --git a/lib/subghz/protocols/hormann.h b/lib/subghz/protocols/hormann.h index 45d6eb223..743ad0b38 100644 --- a/lib/subghz/protocols/hormann.h +++ b/lib/subghz/protocols/hormann.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* f * @param context Pointer to a SubGhzProtocolDecoderHormann instance * @param output Resulting text */ -void subghz_protocol_decoder_hormann_get_string(void* context, string_t output); +void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/ido.c b/lib/subghz/protocols/ido.c index 914468445..6cc60bde8 100644 --- a/lib/subghz/protocols/ido.c +++ b/lib/subghz/protocols/ido.c @@ -205,7 +205,7 @@ bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipp return ret; } -void subghz_protocol_decoder_ido_get_string(void* context, string_t output) { +void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderIDo* instance = context; @@ -215,13 +215,13 @@ void subghz_protocol_decoder_ido_get_string(void* context, string_t output) { uint32_t code_fix = code_found_reverse & 0xFFFFFF; uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFFF; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" "Fix:%06lX \r\n" "Hop:%06lX \r\n" - "Sn:%05lX Btn:%lX\r\n", + "Sn:%05lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/ido.h b/lib/subghz/protocols/ido.h index 4fe4e740a..67d2b4d8f 100644 --- a/lib/subghz/protocols/ido.h +++ b/lib/subghz/protocols/ido.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipp * @param context Pointer to a SubGhzProtocolDecoderIDo instance * @param output Resulting text */ -void subghz_protocol_decoder_ido_get_string(void* context, string_t output); +void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/intertechno_v3.c b/lib/subghz/protocols/intertechno_v3.c index ffe52e875..14e137cab 100644 --- a/lib/subghz/protocols/intertechno_v3.c +++ b/lib/subghz/protocols/intertechno_v3.c @@ -434,13 +434,13 @@ bool subghz_protocol_decoder_intertechno_v3_deserialize( return ret; } -void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t output) { +void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderIntertechno_V3* instance = context; subghz_protocol_intertechno_v3_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%.11s %db\r\n" "Key:0x%08llX\r\n" @@ -453,17 +453,17 @@ void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t o if(instance->generic.data_count_bit == subghz_protocol_intertechno_v3_const.min_count_bit_for_found) { if(instance->generic.cnt >> 5) { - string_cat_printf( + furi_string_cat_printf( output, "Ch: All Btn:%s\r\n", (instance->generic.btn ? "On" : "Off")); } else { - string_cat_printf( + furi_string_cat_printf( output, "Ch:" CH_PATTERN " Btn:%s\r\n", CNT_TO_CH(instance->generic.cnt), (instance->generic.btn ? "On" : "Off")); } } else if(instance->generic.data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) { - string_cat_printf( + furi_string_cat_printf( output, "Ch:" CH_PATTERN " Dimm:%d%%\r\n", CNT_TO_CH(instance->generic.cnt), diff --git a/lib/subghz/protocols/intertechno_v3.h b/lib/subghz/protocols/intertechno_v3.h index 65d6f61d1..078d03978 100644 --- a/lib/subghz/protocols/intertechno_v3.h +++ b/lib/subghz/protocols/intertechno_v3.h @@ -108,4 +108,4 @@ bool subghz_protocol_decoder_intertechno_v3_deserialize( * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance * @param output Resulting text */ -void subghz_protocol_decoder_intertechno_v3_get_string(void* context, string_t output); +void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index cfb92fe8b..039d97a6a 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -2,7 +2,6 @@ #include "keeloq_common.h" #include "../subghz_keystore.h" -#include #include #include "../blocks/const.h" @@ -131,7 +130,7 @@ static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instanc for M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name); + res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name); if(res == 0) { switch(manufacture_code->type) { case KEELOQ_LEARNING_SIMPLE: @@ -489,7 +488,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( // Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -499,7 +498,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -508,7 +507,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, seed, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -517,7 +516,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -526,7 +525,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -534,7 +533,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( // Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -548,7 +547,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -558,7 +557,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -566,7 +565,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -575,7 +574,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, seed, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -583,7 +582,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_secure_learning(fix, seed, man_rev); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -592,7 +591,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } @@ -600,7 +599,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( man = subghz_protocol_keeloq_common_magic_xor_type1_learning(fix, man_rev); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -683,7 +682,7 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl return res; } -void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output) { +void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderKeeloq* instance = context; subghz_protocol_keeloq_check_remote_controller( @@ -697,12 +696,12 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output) { uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04X\r\n" - "Hop:0x%08lX Btn:%01lX\r\n" + "Fix:0x%08lX Cnt:%04lX\r\n" + "Hop:0x%08lX Btn:%01X\r\n" "MF:%s\r\n" "Sn:0x%07lX \r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/keeloq.h b/lib/subghz/protocols/keeloq.h index e1485e5ef..c0575bd96 100644 --- a/lib/subghz/protocols/keeloq.h +++ b/lib/subghz/protocols/keeloq.h @@ -124,4 +124,4 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance * @param output Resulting text */ -void subghz_protocol_decoder_keeloq_get_string(void* context, string_t output); +void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/keeloq_common.c b/lib/subghz/protocols/keeloq_common.c index 4c0c1d4ef..6c9bc461e 100644 --- a/lib/subghz/protocols/keeloq_common.c +++ b/lib/subghz/protocols/keeloq_common.c @@ -2,7 +2,6 @@ #include -#include #include #define bit(x, n) (((x) >> (n)) & 1) diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index 6fc106170..d46838661 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -256,7 +256,7 @@ bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipp return ret; } -void subghz_protocol_decoder_kia_get_string(void* context, string_t output) { +void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderKIA* instance = context; @@ -264,11 +264,11 @@ void subghz_protocol_decoder_kia_get_string(void* context, string_t output) { uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Sn:%07lX Btn:%lX Cnt:%04X\r\n", + "Sn:%07lX Btn:%X Cnt:%04lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, code_found_hi, diff --git a/lib/subghz/protocols/kia.h b/lib/subghz/protocols/kia.h index 743ab7cbd..cf1869219 100644 --- a/lib/subghz/protocols/kia.h +++ b/lib/subghz/protocols/kia.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipp * @param context Pointer to a SubGhzProtocolDecoderKIA instance * @param output Resulting text */ -void subghz_protocol_decoder_kia_get_string(void* context, string_t output); +void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/linear.c b/lib/subghz/protocols/linear.c index 8f7aed794..582c4aaf3 100644 --- a/lib/subghz/protocols/linear.c +++ b/lib/subghz/protocols/linear.c @@ -327,7 +327,7 @@ bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* fl return ret; } -void subghz_protocol_decoder_linear_get_string(void* context, string_t output) { +void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderLinear* instance = context; @@ -338,7 +338,7 @@ void subghz_protocol_decoder_linear_get_string(void* context, string_t output) { uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" diff --git a/lib/subghz/protocols/linear.h b/lib/subghz/protocols/linear.h index 035b130c4..6111ad85c 100644 --- a/lib/subghz/protocols/linear.h +++ b/lib/subghz/protocols/linear.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* fl * @param context Pointer to a SubGhzProtocolDecoderLinear instance * @param output Resulting text */ -void subghz_protocol_decoder_linear_get_string(void* context, string_t output); +void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/magellen.c b/lib/subghz/protocols/magellen.c index 6dcc83e56..160ec4a2c 100644 --- a/lib/subghz/protocols/magellen.c +++ b/lib/subghz/protocols/magellen.c @@ -375,8 +375,8 @@ static void subghz_protocol_magellen_check_remote_controller(SubGhzBlockGeneric* instance->btn = (data_rev >> 16) & 0xFF; } -static void subghz_protocol_magellen_get_event_serialize(uint8_t event, string_t output) { - string_cat_printf( +static void subghz_protocol_magellen_get_event_serialize(uint8_t event, FuriString* output) { + furi_string_cat_printf( output, "%s%s%s%s%s%s%s%s", ((event >> 4) & 0x1 ? (event & 0x1 ? " Open" : " Close") : @@ -424,15 +424,15 @@ bool subghz_protocol_decoder_magellen_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_magellen_get_string(void* context, string_t output) { +void subghz_protocol_decoder_magellen_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderMagellen* instance = context; subghz_protocol_magellen_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" - "Sn:%03d%03d, Event:0x%02X\r\n" + "Sn:%03ld%03ld, Event:0x%02X\r\n" "Stat:", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/magellen.h b/lib/subghz/protocols/magellen.h index 224f79011..226919c8d 100644 --- a/lib/subghz/protocols/magellen.h +++ b/lib/subghz/protocols/magellen.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_magellen_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderMagellen instance * @param output Resulting text */ -void subghz_protocol_decoder_magellen_get_string(void* context, string_t output); +void subghz_protocol_decoder_magellen_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index bdce6593d..a72238a41 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -373,17 +373,17 @@ bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_marantec_get_string(void* context, string_t output) { +void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderMarantec* instance = context; subghz_protocol_marantec_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Btn:%lX\r\n", + "Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), diff --git a/lib/subghz/protocols/marantec.h b/lib/subghz/protocols/marantec.h index 2da3c88a5..5fc042e77 100644 --- a/lib/subghz/protocols/marantec.h +++ b/lib/subghz/protocols/marantec.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderMarantec instance * @param output Resulting text */ -void subghz_protocol_decoder_marantec_get_string(void* context, string_t output); +void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c index 1501580d8..baa8188d3 100644 --- a/lib/subghz/protocols/megacode.c +++ b/lib/subghz/protocols/megacode.c @@ -408,17 +408,17 @@ bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_megacode_get_string(void* context, string_t output) { +void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderMegaCode* instance = context; subghz_protocol_megacode_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%06lX\r\n" - "Sn:0x%04lX - %d\r\n" - "Facility:%X Btn:%X\r\n", + "Sn:0x%04lX - %ld\r\n" + "Facility:%lX Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)instance->generic.data, diff --git a/lib/subghz/protocols/megacode.h b/lib/subghz/protocols/megacode.h index c8010665b..0fafddb6b 100644 --- a/lib/subghz/protocols/megacode.h +++ b/lib/subghz/protocols/megacode.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance * @param output Resulting text */ -void subghz_protocol_decoder_megacode_get_string(void* context, string_t output); +void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/nero_radio.c b/lib/subghz/protocols/nero_radio.c index b5a7e8c0e..d6925d485 100644 --- a/lib/subghz/protocols/nero_radio.c +++ b/lib/subghz/protocols/nero_radio.c @@ -370,7 +370,7 @@ bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat return ret; } -void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t output) { +void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderNeroRadio* instance = context; @@ -383,7 +383,7 @@ void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t outpu uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/nero_radio.h b/lib/subghz/protocols/nero_radio.h index f04dc2b3c..ef270342c 100644 --- a/lib/subghz/protocols/nero_radio.h +++ b/lib/subghz/protocols/nero_radio.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance * @param output Resulting text */ -void subghz_protocol_decoder_nero_radio_get_string(void* context, string_t output); +void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/nero_sketch.c b/lib/subghz/protocols/nero_sketch.c index 66ee569c2..8080bf9e4 100644 --- a/lib/subghz/protocols/nero_sketch.c +++ b/lib/subghz/protocols/nero_sketch.c @@ -355,7 +355,7 @@ bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperForma return ret; } -void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t output) { +void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderNeroSketch* instance = context; @@ -368,7 +368,7 @@ void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t outp uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/nero_sketch.h b/lib/subghz/protocols/nero_sketch.h index ab592b48e..4536e7043 100644 --- a/lib/subghz/protocols/nero_sketch.h +++ b/lib/subghz/protocols/nero_sketch.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperForma * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance * @param output Resulting text */ -void subghz_protocol_decoder_nero_sketch_get_string(void* context, string_t output); +void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c index f07e9efcc..06538db10 100644 --- a/lib/subghz/protocols/nice_flo.c +++ b/lib/subghz/protocols/nice_flo.c @@ -309,7 +309,7 @@ bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* return ret; } -void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output) { +void subghz_protocol_decoder_nice_flo_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderNiceFlo* instance = context; @@ -318,7 +318,7 @@ void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output) instance->generic.data, instance->generic.data_count_bit); uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" diff --git a/lib/subghz/protocols/nice_flo.h b/lib/subghz/protocols/nice_flo.h index 0873e81b9..dd374006b 100644 --- a/lib/subghz/protocols/nice_flo.h +++ b/lib/subghz/protocols/nice_flo.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance * @param output Resulting text */ -void subghz_protocol_decoder_nice_flo_get_string(void* context, string_t output); +void subghz_protocol_decoder_nice_flo_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index 1d370e85a..d567ddf2c 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -354,7 +354,7 @@ bool subghz_protocol_decoder_nice_flor_s_deserialize(void* context, FlipperForma return ret; } -void subghz_protocol_decoder_nice_flor_s_get_string(void* context, string_t output) { +void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderNiceFlorS* instance = context; @@ -363,12 +363,12 @@ void subghz_protocol_decoder_nice_flor_s_get_string(void* context, string_t outp uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" "Sn:%05lX\r\n" - "Cnt:%04X Btn:%02lX\r\n", + "Cnt:%04lX Btn:%02X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, code_found_hi, diff --git a/lib/subghz/protocols/nice_flor_s.h b/lib/subghz/protocols/nice_flor_s.h index 7d98876f6..286d03d44 100644 --- a/lib/subghz/protocols/nice_flor_s.h +++ b/lib/subghz/protocols/nice_flor_s.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_nice_flor_s_deserialize(void* context, FlipperForma * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance * @param output Resulting text */ -void subghz_protocol_decoder_nice_flor_s_get_string(void* context, string_t output); +void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/oregon2.c b/lib/subghz/protocols/oregon2.c index 84bb38be4..561df819f 100644 --- a/lib/subghz/protocols/oregon2.c +++ b/lib/subghz/protocols/oregon2.c @@ -5,7 +5,6 @@ #include "../blocks/math.h" #include #include -#include #define TAG "SubGhzProtocolOregon2" @@ -247,21 +246,21 @@ bool subghz_protocol_decoder_oregon2_deserialize(void* context, FlipperFormat* f // append string of the variable data static void - oregon2_var_data_append_string(uint16_t sensor_id, uint32_t var_data, string_t output) { + oregon2_var_data_append_string(uint16_t sensor_id, uint32_t var_data, FuriString* output) { uint32_t val; if(sensor_id == 0xEC40) { val = ((var_data >> 4) & 0xF) * 10 + ((var_data >> 8) & 0xF); - string_cat_printf( + furi_string_cat_printf( output, - "Temp: %s%d.%d C\r\n", + "Temp: %s%ld.%ld C\r\n", (var_data & 0xF) ? "-" : "+", val, (uint32_t)(var_data >> 12) & 0xF); } } -static void oregon2_append_check_sum(uint32_t fix_data, uint32_t var_data, string_t output) { +static void oregon2_append_check_sum(uint32_t fix_data, uint32_t var_data, FuriString* output) { uint8_t sum = fix_data & 0xF; uint8_t ref_sum = var_data & 0xFF; var_data >>= 8; @@ -275,19 +274,19 @@ static void oregon2_append_check_sum(uint32_t fix_data, uint32_t var_data, strin // swap calculated sum nibbles sum = (((sum >> 4) & 0xF) | (sum << 4)) & 0xFF; if(sum == ref_sum) - string_cat_printf(output, "Sum ok: 0x%hhX", ref_sum); + furi_string_cat_printf(output, "Sum ok: 0x%hhX", ref_sum); else - string_cat_printf(output, "Sum err: 0x%hhX vs 0x%hhX", ref_sum, sum); + furi_string_cat_printf(output, "Sum err: 0x%hhX vs 0x%hhX", ref_sum, sum); } -void subghz_protocol_decoder_oregon2_get_string(void* context, string_t output) { +void subghz_protocol_decoder_oregon2_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderOregon2* instance = context; uint16_t sensor_id = OREGON2_SENSOR_ID(instance->generic.data); - string_cat_printf( + furi_string_cat_printf( output, "%s\r\n" - "ID: 0x%04lX, ch: %d%s, rc: 0x%02lX\r\n", + "ID: 0x%04lX, ch: %ld%s, rc: 0x%02lX\r\n", instance->generic.protocol_name, (uint32_t)sensor_id, (uint32_t)(instance->generic.data >> 12) & 0xF, diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index d680b2e62..019c3ec25 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -320,16 +320,16 @@ bool subghz_protocol_decoder_phoenix_v2_deserialize(void* context, FlipperFormat return ret; } -void subghz_protocol_decoder_phoenix_v2_get_string(void* context, string_t output) { +void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderPhoenix_V2* instance = context; subghz_protocol_phoenix_v2_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%02lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Btn:%lX\r\n", + "Btn:%X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32) & 0xFFFFFFFF, diff --git a/lib/subghz/protocols/phoenix_v2.h b/lib/subghz/protocols/phoenix_v2.h index 38cadc1a2..b2f182796 100644 --- a/lib/subghz/protocols/phoenix_v2.h +++ b/lib/subghz/protocols/phoenix_v2.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_phoenix_v2_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance * @param output Resulting text */ -void subghz_protocol_decoder_phoenix_v2_get_string(void* context, string_t output); +void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/power_smart.c b/lib/subghz/protocols/power_smart.c index bd009d887..3ec35c74f 100644 --- a/lib/subghz/protocols/power_smart.c +++ b/lib/subghz/protocols/power_smart.c @@ -373,12 +373,12 @@ bool subghz_protocol_decoder_power_smart_deserialize(void* context, FlipperForma return ret; } -void subghz_protocol_decoder_power_smart_get_string(void* context, string_t output) { +void subghz_protocol_decoder_power_smart_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderPowerSmart* instance = context; subghz_protocol_power_smart_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" diff --git a/lib/subghz/protocols/power_smart.h b/lib/subghz/protocols/power_smart.h index f6e9571b1..21e5dcf4a 100644 --- a/lib/subghz/protocols/power_smart.h +++ b/lib/subghz/protocols/power_smart.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_power_smart_deserialize(void* context, FlipperForma * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance * @param output Resulting text */ -void subghz_protocol_decoder_power_smart_get_string(void* context, string_t output); +void subghz_protocol_decoder_power_smart_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index a5b8134d8..370f33fb0 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -351,20 +351,20 @@ bool subghz_protocol_decoder_princeton_deserialize(void* context, FlipperFormat* return res; } -void subghz_protocol_decoder_princeton_get_string(void* context, string_t output) { +void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderPrinceton* instance = context; subghz_protocol_princeton_check_remote_controller(&instance->generic); uint32_t data_rev = subghz_protocol_blocks_reverse_key( instance->generic.data, instance->generic.data_count_bit); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%08lX\r\n" "Yek:0x%08lX\r\n" "Sn:0x%05lX Btn:%01X\r\n" - "Te:%dus\r\n", + "Te:%ldus\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data & 0xFFFFFF), diff --git a/lib/subghz/protocols/princeton.h b/lib/subghz/protocols/princeton.h index 9c296c4a1..4e482f747 100644 --- a/lib/subghz/protocols/princeton.h +++ b/lib/subghz/protocols/princeton.h @@ -104,4 +104,4 @@ bool subghz_protocol_decoder_princeton_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance * @param output Resulting text */ -void subghz_protocol_decoder_princeton_get_string(void* context, string_t output); +void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/princeton_for_testing.c b/lib/subghz/protocols/princeton_for_testing.c index 43078d2e2..0987e0ad6 100644 --- a/lib/subghz/protocols/princeton_for_testing.c +++ b/lib/subghz/protocols/princeton_for_testing.c @@ -94,7 +94,7 @@ void subghz_encoder_princeton_for_testing_print_log(void* context) { ((float)instance->time_high / (instance->time_high + instance->time_low)) * 100; FURI_LOG_I( TAG "Encoder", - "Radio tx_time=%dus ON=%dus, OFF=%dus, DutyCycle=%d,%d%%", + "Radio tx_time=%ldus ON=%ldus, OFF=%ldus, DutyCycle=%ld,%ld%%", instance->time_high + instance->time_low, instance->time_high, instance->time_low, diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 0419a39a0..fd234502a 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -29,7 +29,7 @@ struct SubGhzProtocolDecoderRAW { Storage* storage; FlipperFormat* flipper_file; uint32_t file_is_open; - string_t file_name; + FuriString* file_name; size_t sample_write; bool last_level; }; @@ -38,7 +38,7 @@ struct SubGhzProtocolEncoderRAW { SubGhzProtocolEncoderBase base; bool is_running; - string_t file_name; + FuriString* file_name; SubGhzFileEncoderWorker* file_worker_encoder; }; @@ -90,8 +90,8 @@ bool subghz_protocol_raw_save_to_file_init( instance->storage = furi_record_open(RECORD_STORAGE); instance->flipper_file = flipper_format_file_alloc(instance->storage); - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); bool init = false; do { @@ -104,17 +104,18 @@ bool subghz_protocol_raw_save_to_file_init( break; } - string_set(instance->file_name, dev_name); + furi_string_set(instance->file_name, dev_name); // First remove subghz device file if it was saved - string_printf(temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); + furi_string_printf(temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); - if(!storage_simply_remove(instance->storage, string_get_cstr(temp_str))) { + if(!storage_simply_remove(instance->storage, furi_string_get_cstr(temp_str))) { break; } // Open file - if(!flipper_format_file_open_always(instance->flipper_file, string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Unable to open file for write: %s", temp_str); + if(!flipper_format_file_open_always( + instance->flipper_file, furi_string_get_cstr(temp_str))) { + FURI_LOG_E(TAG, "Unable to open file for write: %s", furi_string_get_cstr(temp_str)); break; } @@ -130,13 +131,13 @@ bool subghz_protocol_raw_save_to_file_init( break; } - subghz_block_generic_get_preset_name(string_get_cstr(preset->name), temp_str); + subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); if(!flipper_format_write_string_cstr( - instance->flipper_file, "Preset", string_get_cstr(temp_str))) { + instance->flipper_file, "Preset", furi_string_get_cstr(temp_str))) { FURI_LOG_E(TAG, "Unable to add Preset"); break; } - if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { + if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { if(!flipper_format_write_string_cstr( instance->flipper_file, "Custom_preset_module", "CC1101")) { FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); @@ -160,7 +161,7 @@ bool subghz_protocol_raw_save_to_file_init( init = true; } while(0); - string_clear(temp_str); + furi_string_free(temp_str); return init; } @@ -210,7 +211,7 @@ void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment) { instance->ind_write = 0; instance->last_level = false; instance->file_is_open = RAWFileIsOpenClose; - string_init(instance->file_name); + instance->file_name = furi_string_alloc(); return instance; } @@ -218,7 +219,7 @@ void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment) { void subghz_protocol_decoder_raw_free(void* context) { furi_assert(context); SubGhzProtocolDecoderRAW* instance = context; - string_clear(instance->file_name); + furi_string_free(instance->file_name); free(instance); } @@ -255,12 +256,12 @@ bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipp return true; } -void subghz_protocol_decoder_raw_get_string(void* context, string_t output) { +void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output) { furi_assert(context); //SubGhzProtocolDecoderRAW* instance = context; UNUSED(context); //ToDo no use - string_cat_printf(output, "RAW Date"); + furi_string_cat_printf(output, "RAW Date"); } void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) { @@ -268,7 +269,7 @@ void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) { SubGhzProtocolEncoderRAW* instance = malloc(sizeof(SubGhzProtocolEncoderRAW)); instance->base.protocol = &subghz_protocol_raw; - string_init(instance->file_name); + instance->file_name = furi_string_alloc(); instance->is_running = false; return instance; } @@ -286,7 +287,7 @@ void subghz_protocol_encoder_raw_free(void* context) { furi_assert(context); SubGhzProtocolEncoderRAW* instance = context; subghz_protocol_encoder_raw_stop(instance); - string_clear(instance->file_name); + furi_string_free(instance->file_name); free(instance); } @@ -305,7 +306,7 @@ static bool subghz_protocol_encoder_raw_worker_init(SubGhzProtocolEncoderRAW* in instance->file_worker_encoder = subghz_file_encoder_worker_alloc(); if(subghz_file_encoder_worker_start( - instance->file_worker_encoder, string_get_cstr(instance->file_name))) { + instance->file_worker_encoder, furi_string_get_cstr(instance->file_name))) { //the worker needs a file in order to open and read part of the file furi_delay_ms(100); instance->is_running = true; @@ -334,8 +335,8 @@ bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipp furi_assert(context); SubGhzProtocolEncoderRAW* instance = context; bool res = false; - string_t temp_str; - string_init(temp_str); + FuriString* temp_str; + temp_str = furi_string_alloc(); do { if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); @@ -346,11 +347,11 @@ bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipp FURI_LOG_E(TAG, "Missing File_name"); break; } - string_set(instance->file_name, temp_str); + furi_string_set(instance->file_name, temp_str); res = subghz_protocol_encoder_raw_worker_init(instance); } while(false); - string_clear(temp_str); + furi_string_free(temp_str); return res; } diff --git a/lib/subghz/protocols/raw.h b/lib/subghz/protocols/raw.h index b52a7d84e..be03dea27 100644 --- a/lib/subghz/protocols/raw.h +++ b/lib/subghz/protocols/raw.h @@ -82,7 +82,7 @@ bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipp * @param context Pointer to a SubGhzProtocolDecoderRAW instance * @param output Resulting text */ -void subghz_protocol_decoder_raw_get_string(void* context, string_t output); +void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output); /** * Allocate SubGhzProtocolEncoderRAW. diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index 1c044e9db..837dcf058 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -263,18 +263,18 @@ bool subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat return subghz_block_generic_deserialize(&instance->generic, flipper_format); } -void subghz_protocol_decoder_scher_khan_get_string(void* context, string_t output) { +void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderScherKhan* instance = context; subghz_protocol_scher_khan_check_remote_controller( &instance->generic, &instance->protocol_name); - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:0x%lX%08lX\r\n" - "Sn:%07lX Btn:%lX Cnt:%04X\r\n" + "Sn:%07lX Btn:%X Cnt:%04lX\r\n" "Pt: %s\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/scher_khan.h b/lib/subghz/protocols/scher_khan.h index 391ccc414..f0fe595b4 100644 --- a/lib/subghz/protocols/scher_khan.h +++ b/lib/subghz/protocols/scher_khan.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance * @param output Resulting text */ -void subghz_protocol_decoder_scher_khan_get_string(void* context, string_t output); +void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index 77a0c62a2..cfe6bdee5 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -555,7 +555,7 @@ bool subghz_protocol_secplus_v1_check_fixed(uint32_t fixed) { return true; } -void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t output) { +void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v1* instance = context; @@ -567,7 +567,7 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu uint8_t id1 = (fixed / 9) % 3; uint16_t pin = 0; - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" @@ -587,9 +587,9 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu pin = (fixed / 59049) % 19683; if(pin <= 9999) { - string_cat_printf(output, " pin:%d", pin); + furi_string_cat_printf(output, " pin:%d", pin); } else if(10000 <= pin && pin <= 11029) { - string_cat_printf(output, " pin:enter"); + furi_string_cat_printf(output, " pin:enter"); } int pin_suffix = 0; @@ -597,16 +597,16 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu pin_suffix = (fixed / 1162261467) % 3; if(pin_suffix == 1) { - string_cat_printf(output, " #\r\n"); + furi_string_cat_printf(output, " #\r\n"); } else if(pin_suffix == 2) { - string_cat_printf(output, " *\r\n"); + furi_string_cat_printf(output, " *\r\n"); } else { - string_cat_printf(output, "\r\n"); + furi_string_cat_printf(output, "\r\n"); } - string_cat_printf( + furi_string_cat_printf( output, "Sn:0x%08lX\r\n" - "Cnt:0x%03X\r\n" + "Cnt:0x%03lX\r\n" "Sw_id:0x%X\r\n", instance->generic.serial, instance->generic.cnt, @@ -615,17 +615,17 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t outpu //id = fixed / 27; instance->generic.serial = fixed / 27; if(instance->generic.btn == 1) { - string_cat_printf(output, " Btn:left\r\n"); + furi_string_cat_printf(output, " Btn:left\r\n"); } else if(instance->generic.btn == 0) { - string_cat_printf(output, " Btn:middle\r\n"); + furi_string_cat_printf(output, " Btn:middle\r\n"); } else if(instance->generic.btn == 2) { - string_cat_printf(output, " Btn:right\r\n"); + furi_string_cat_printf(output, " Btn:right\r\n"); } - string_cat_printf( + furi_string_cat_printf( output, "Sn:0x%08lX\r\n" - "Cnt:0x%03X\r\n" + "Cnt:0x%03lX\r\n" "Sw_id:0x%X\r\n", instance->generic.serial, instance->generic.cnt, diff --git a/lib/subghz/protocols/secplus_v1.h b/lib/subghz/protocols/secplus_v1.h index 8ae1c0cb2..ba1762f55 100644 --- a/lib/subghz/protocols/secplus_v1.h +++ b/lib/subghz/protocols/secplus_v1.h @@ -110,4 +110,4 @@ bool subghz_protocol_secplus_v1_check_fixed(uint32_t fixed); * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance * @param output Resulting text */ -void subghz_protocol_decoder_secplus_v1_get_string(void* context, string_t output); +void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index c242d0b4d..73bb7802b 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -810,18 +810,18 @@ bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat return res; } -void subghz_protocol_decoder_secplus_v2_get_string(void* context, string_t output) { +void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderSecPlus_v2* instance = context; subghz_protocol_secplus_v2_remote_controller(&instance->generic, instance->secplus_packet_1); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Pk1:0x%lX%08lX\r\n" "Pk2:0x%lX%08lX\r\n" "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%03X\r\n", + "Cnt:0x%03lX\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, diff --git a/lib/subghz/protocols/secplus_v2.h b/lib/subghz/protocols/secplus_v2.h index 9e9ae2a7d..007609fc1 100644 --- a/lib/subghz/protocols/secplus_v2.h +++ b/lib/subghz/protocols/secplus_v2.h @@ -122,4 +122,4 @@ bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance * @param output Resulting text */ -void subghz_protocol_decoder_secplus_v2_get_string(void* context, string_t output); +void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index 7a3b2186f..cf627ef37 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -426,18 +426,18 @@ bool subghz_protocol_decoder_somfy_keytis_deserialize(void* context, FlipperForm return res; } -void subghz_protocol_decoder_somfy_keytis_get_string(void* context, string_t output) { +void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderSomfyKeytis* instance = context; subghz_protocol_somfy_keytis_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "%lX%08lX%06lX\r\n" "Sn:0x%06lX \r\n" - "Cnt:0x%04X\r\n" + "Cnt:0x%04lX\r\n" "Btn:%s\r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/somfy_keytis.h b/lib/subghz/protocols/somfy_keytis.h index 29f96cd6a..af1df91d5 100644 --- a/lib/subghz/protocols/somfy_keytis.h +++ b/lib/subghz/protocols/somfy_keytis.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_somfy_keytis_deserialize(void* context, FlipperForm * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance * @param output Resulting text */ -void subghz_protocol_decoder_somfy_keytis_get_string(void* context, string_t output); +void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index b9aac5777..6e375bb38 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -363,18 +363,18 @@ bool subghz_protocol_decoder_somfy_telis_deserialize(void* context, FlipperForma return ret; } -void subghz_protocol_decoder_somfy_telis_get_string(void* context, string_t output) { +void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderSomfyTelis* instance = context; subghz_protocol_somfy_telis_check_remote_controller(&instance->generic); - string_cat_printf( + furi_string_cat_printf( output, "%s %db\r\n" "Key:0x%lX%08lX\r\n" "Sn:0x%06lX \r\n" - "Cnt:0x%04X\r\n" + "Cnt:0x%04lX\r\n" "Btn:%s\r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/somfy_telis.h b/lib/subghz/protocols/somfy_telis.h index ff5b45e23..b6e58e34c 100644 --- a/lib/subghz/protocols/somfy_telis.h +++ b/lib/subghz/protocols/somfy_telis.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_somfy_telis_deserialize(void* context, FlipperForma * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance * @param output Resulting text */ -void subghz_protocol_decoder_somfy_telis_get_string(void* context, string_t output); +void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index 757b56622..4b89bd2bf 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -2,7 +2,6 @@ #include "keeloq_common.h" #include "../subghz_keystore.h" -#include #include #include "../blocks/const.h" @@ -229,7 +228,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( //Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -240,7 +239,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -248,7 +247,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( // Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } // Check for mirrored man @@ -260,7 +259,7 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( } decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } //########################### @@ -270,13 +269,13 @@ static uint8_t subghz_protocol_star_line_check_remote_controller_selector( subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = string_get_cstr(manufacture_code->name); + *manufacture_name = furi_string_get_cstr(manufacture_code->name); return 1; } break; @@ -355,7 +354,7 @@ bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* return res; } -void subghz_protocol_decoder_star_line_get_string(void* context, string_t output) { +void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output) { furi_assert(context); SubGhzProtocolDecoderStarLine* instance = context; @@ -370,12 +369,12 @@ void subghz_protocol_decoder_star_line_get_string(void* context, string_t output uint32_t code_found_reverse_hi = code_found_reverse >> 32; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - string_cat_printf( + furi_string_cat_printf( output, "%s %dbit\r\n" "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04X\r\n" - "Hop:0x%08lX Btn:%02lX\r\n" + "Fix:0x%08lX Cnt:%04lX\r\n" + "Hop:0x%08lX Btn:%02X\r\n" "MF:%s\r\n" "Sn:0x%07lX \r\n", instance->generic.protocol_name, diff --git a/lib/subghz/protocols/star_line.h b/lib/subghz/protocols/star_line.h index e240954b1..74c994101 100644 --- a/lib/subghz/protocols/star_line.h +++ b/lib/subghz/protocols/star_line.h @@ -70,4 +70,4 @@ bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* * @param context Pointer to a SubGhzProtocolDecoderStarLine instance * @param output Resulting text */ -void subghz_protocol_decoder_star_line_get_string(void* context, string_t output); +void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output); diff --git a/lib/subghz/subghz_file_encoder_worker.c b/lib/subghz/subghz_file_encoder_worker.c index 8f65ea004..29834b412 100644 --- a/lib/subghz/subghz_file_encoder_worker.c +++ b/lib/subghz/subghz_file_encoder_worker.c @@ -1,5 +1,4 @@ #include "subghz_file_encoder_worker.h" -#include #include #include @@ -11,7 +10,7 @@ struct SubGhzFileEncoderWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; Storage* storage; FlipperFormat* flipper_format; @@ -19,8 +18,8 @@ struct SubGhzFileEncoderWorker { volatile bool worker_running; volatile bool worker_stoping; bool level; - string_t str_data; - string_t file_path; + FuriString* str_data; + FuriString* file_path; SubGhzFileEncoderWorkerCallbackEnd callback_end; void* context_end; @@ -48,7 +47,7 @@ void subghz_file_encoder_worker_add_level_duration( if(res) { instance->level = !instance->level; - xStreamBufferSend(instance->stream, &duration, sizeof(int32_t), 100); + furi_stream_buffer_send(instance->stream, &duration, sizeof(int32_t), 100); } else { FURI_LOG_E(TAG, "Invalid level in the stream"); } @@ -83,10 +82,7 @@ LevelDuration subghz_file_encoder_worker_get_level_duration(void* context) { furi_assert(context); SubGhzFileEncoderWorker* instance = context; int32_t duration; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - int ret = xStreamBufferReceiveFromISR( - instance->stream, &duration, sizeof(int32_t), &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + int ret = furi_stream_buffer_receive(instance->stream, &duration, sizeof(int32_t), 0); if(ret == sizeof(int32_t)) { LevelDuration level_duration = {.level = LEVEL_DURATION_RESET}; if(duration < 0) { @@ -117,9 +113,11 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { Stream* stream = flipper_format_get_raw_stream(instance->flipper_format); do { if(!flipper_format_file_open_existing( - instance->flipper_format, string_get_cstr(instance->file_path))) { + instance->flipper_format, furi_string_get_cstr(instance->file_path))) { FURI_LOG_E( - TAG, "Unable to open file for read: %s", string_get_cstr(instance->file_path)); + TAG, + "Unable to open file for read: %s", + furi_string_get_cstr(instance->file_path)); break; } if(!flipper_format_read_string(instance->flipper_format, "Protocol", instance->str_data)) { @@ -135,12 +133,12 @@ static int32_t subghz_file_encoder_worker_thread(void* context) { } while(0); while(res && instance->worker_running) { - size_t stream_free_byte = xStreamBufferSpacesAvailable(instance->stream); + size_t stream_free_byte = furi_stream_buffer_spaces_available(instance->stream); if((stream_free_byte / sizeof(int32_t)) >= SUBGHZ_FILE_ENCODER_LOAD) { if(stream_read_line(stream, instance->str_data)) { - string_strim(instance->str_data); + furi_string_trim(instance->str_data); if(!subghz_file_encoder_worker_data_parse( - instance, string_get_cstr(instance->str_data))) { + instance, furi_string_get_cstr(instance->str_data))) { //to stop DMA correctly subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); @@ -181,13 +179,13 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { furi_thread_set_stack_size(instance->thread, 2048); furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_file_encoder_worker_thread); - instance->stream = xStreamBufferCreate(sizeof(int32_t) * 2048, sizeof(int32_t)); + instance->stream = furi_stream_buffer_alloc(sizeof(int32_t) * 2048, sizeof(int32_t)); instance->storage = furi_record_open(RECORD_STORAGE); instance->flipper_format = flipper_format_file_alloc(instance->storage); - string_init(instance->str_data); - string_init(instance->file_path); + instance->str_data = furi_string_alloc(); + instance->file_path = furi_string_alloc(); instance->level = false; instance->worker_stoping = true; @@ -197,11 +195,11 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { void subghz_file_encoder_worker_free(SubGhzFileEncoderWorker* instance) { furi_assert(instance); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); - string_clear(instance->str_data); - string_clear(instance->file_path); + furi_string_free(instance->str_data); + furi_string_free(instance->file_path); flipper_format_free(instance->flipper_format); furi_record_close(RECORD_STORAGE); @@ -213,8 +211,8 @@ bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const c furi_assert(instance); furi_assert(!instance->worker_running); - xStreamBufferReset(instance->stream); - string_set(instance->file_path, file_path); + furi_stream_buffer_reset(instance->stream); + furi_string_set(instance->file_path, file_path); instance->worker_running = true; furi_thread_start(instance->thread); diff --git a/lib/subghz/subghz_keystore.c b/lib/subghz/subghz_keystore.c index 4d2eb0e50..1b4b3b716 100644 --- a/lib/subghz/subghz_keystore.c +++ b/lib/subghz/subghz_keystore.c @@ -43,7 +43,7 @@ void subghz_keystore_free(SubGhzKeystore* instance) { for M_EACH(manufacture_code, instance->data, SubGhzKeyArray_t) { - string_clear(manufacture_code->name); + furi_string_free(manufacture_code->name); manufacture_code->key = 0; } SubGhzKeyArray_clear(instance->data); @@ -57,7 +57,7 @@ static void subghz_keystore_add_key( uint64_t key, uint16_t type) { SubGhzKey* manufacture_code = SubGhzKeyArray_push_raw(instance->data); - string_init_set_str(manufacture_code->name, name); + manufacture_code->name = furi_string_alloc_set(name); manufacture_code->key = key; manufacture_code->type = type; } @@ -191,8 +191,8 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { uint32_t version; SubGhzKeystoreEncryption encryption; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); FURI_LOG_I(TAG, "Loading keystore %s", file_name); @@ -213,7 +213,7 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { break; } - if(strcmp(string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_TYPE) != 0 || version != SUBGHZ_KEYSTORE_FILE_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -238,7 +238,7 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { furi_record_close(RECORD_STORAGE); - string_clear(filetype); + furi_string_free(filetype); return result; } @@ -294,7 +294,7 @@ bool subghz_keystore_save(SubGhzKeystore* instance, const char* file_name, uint8 (uint32_t)(key->key >> 32), (uint32_t)key->key, key->type, - string_get_cstr(key->name)); + furi_string_get_cstr(key->name)); // Verify length and align furi_assert(len > 0); if(len % 16 != 0) { @@ -349,8 +349,8 @@ bool subghz_keystore_raw_encrypted_save( uint8_t* iv) { bool encrypted = false; uint32_t version; - string_t filetype; - string_init(filetype); + FuriString* filetype; + filetype = furi_string_alloc(); SubGhzKeystoreEncryption encryption; Storage* storage = furi_record_open(RECORD_STORAGE); @@ -373,7 +373,7 @@ bool subghz_keystore_raw_encrypted_save( break; } - if(strcmp(string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || version != SUBGHZ_KEYSTORE_FILE_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -392,7 +392,9 @@ bool subghz_keystore_raw_encrypted_save( break; } if(!flipper_format_write_header_cstr( - output_flipper_format, string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_VERSION)) { + output_flipper_format, + furi_string_get_cstr(filetype), + SUBGHZ_KEYSTORE_FILE_VERSION)) { FURI_LOG_E(TAG, "Unable to add header"); break; } @@ -488,8 +490,8 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* uint32_t version; SubGhzKeystoreEncryption encryption; - string_t str_temp; - string_init(str_temp); + FuriString* str_temp; + str_temp = furi_string_alloc(); Storage* storage = furi_record_open(RECORD_STORAGE); char* decrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); @@ -509,7 +511,7 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* break; } - if(strcmp(string_get_cstr(str_temp), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || + if(strcmp(furi_string_get_cstr(str_temp), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || version != SUBGHZ_KEYSTORE_FILE_VERSION) { FURI_LOG_E(TAG, "Type or version mismatch"); break; @@ -605,7 +607,7 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* free(decrypted_line); - string_clear(str_temp); + furi_string_free(str_temp); return result; } diff --git a/lib/subghz/subghz_keystore.h b/lib/subghz/subghz_keystore.h index 2b7880f07..06ae8adae 100644 --- a/lib/subghz/subghz_keystore.h +++ b/lib/subghz/subghz_keystore.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -9,7 +9,7 @@ extern "C" { #endif typedef struct { - string_t name; + FuriString* name; uint64_t key; uint16_t type; } SubGhzKey; diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c index 78a186931..37c0bfc5e 100644 --- a/lib/subghz/subghz_tx_rx_worker.c +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -1,6 +1,5 @@ #include "subghz_tx_rx_worker.h" -#include #include #define TAG "SubGhzTxRxWorker" @@ -13,8 +12,8 @@ struct SubGhzTxRxWorker { FuriThread* thread; - StreamBufferHandle_t stream_tx; - StreamBufferHandle_t stream_rx; + FuriStreamBuffer* stream_tx; + FuriStreamBuffer* stream_rx; volatile bool worker_running; volatile bool worker_stoping; @@ -30,9 +29,9 @@ struct SubGhzTxRxWorker { bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { furi_assert(instance); bool ret = false; - size_t stream_tx_free_byte = xStreamBufferSpacesAvailable(instance->stream_tx); + size_t stream_tx_free_byte = furi_stream_buffer_spaces_available(instance->stream_tx); if(size && (stream_tx_free_byte >= size)) { - if(xStreamBufferSend( + if(furi_stream_buffer_send( instance->stream_tx, data, size, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) == size) { ret = true; @@ -43,12 +42,12 @@ bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size_t subghz_tx_rx_worker_available(SubGhzTxRxWorker* instance) { furi_assert(instance); - return xStreamBufferBytesAvailable(instance->stream_rx); + return furi_stream_buffer_bytes_available(instance->stream_rx); } size_t subghz_tx_rx_worker_read(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { furi_assert(instance); - return xStreamBufferReceive(instance->stream_rx, data, size, 0); + return furi_stream_buffer_receive(instance->stream_rx, data, size, 0); } void subghz_tx_rx_worker_set_callback_have_read( @@ -148,11 +147,11 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { while(instance->worker_running) { //transmit - size_tx = xStreamBufferBytesAvailable(instance->stream_tx); + size_tx = furi_stream_buffer_bytes_available(instance->stream_tx); if(size_tx > 0 && !timeout_tx) { timeout_tx = 10; //20ms if(size_tx > SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE) { - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream_tx, &data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE, @@ -160,20 +159,20 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { subghz_tx_rx_worker_tx(instance, data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); } else { //todo checking that he managed to write all the data to the TX buffer - xStreamBufferReceive( + furi_stream_buffer_receive( instance->stream_tx, &data, size_tx, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); subghz_tx_rx_worker_tx(instance, data, size_tx); } } else { //recive if(subghz_tx_rx_worker_rx(instance, data, size_rx)) { - if(xStreamBufferSpacesAvailable(instance->stream_rx) >= size_rx[0]) { + if(furi_stream_buffer_spaces_available(instance->stream_rx) >= size_rx[0]) { if(instance->callback_have_read && - xStreamBufferBytesAvailable(instance->stream_rx) == 0) { + furi_stream_buffer_bytes_available(instance->stream_rx) == 0) { callback_rx = true; } //todo checking that he managed to write all the data to the RX buffer - xStreamBufferSend( + furi_stream_buffer_send( instance->stream_rx, &data, size_rx[0], @@ -208,9 +207,9 @@ SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_tx_rx_worker_thread); instance->stream_tx = - xStreamBufferCreate(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); instance->stream_rx = - xStreamBufferCreate(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); instance->status = SubGhzTxRxWorkerStatusIDLE; instance->worker_stoping = true; @@ -221,8 +220,8 @@ SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance) { furi_assert(instance); furi_assert(!instance->worker_running); - vStreamBufferDelete(instance->stream_tx); - vStreamBufferDelete(instance->stream_rx); + furi_stream_buffer_free(instance->stream_tx); + furi_stream_buffer_free(instance->stream_rx); furi_thread_free(instance->thread); free(instance); @@ -232,8 +231,8 @@ bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency) { furi_assert(instance); furi_assert(!instance->worker_running); bool res = false; - xStreamBufferReset(instance->stream_tx); - xStreamBufferReset(instance->stream_rx); + furi_stream_buffer_reset(instance->stream_tx); + furi_stream_buffer_reset(instance->stream_rx); instance->worker_running = true; diff --git a/lib/subghz/subghz_worker.c b/lib/subghz/subghz_worker.c index 58db8ea5d..61146c168 100644 --- a/lib/subghz/subghz_worker.c +++ b/lib/subghz/subghz_worker.c @@ -1,13 +1,12 @@ #include "subghz_worker.h" -#include #include #define TAG "SubGhzWorker" struct SubGhzWorker { FuriThread* thread; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; volatile bool running; volatile bool overrun; @@ -30,16 +29,14 @@ struct SubGhzWorker { void subghz_worker_rx_callback(bool level, uint32_t duration, void* context) { SubGhzWorker* instance = context; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; LevelDuration level_duration = level_duration_make(level, duration); if(instance->overrun) { instance->overrun = false; level_duration = level_duration_reset(); } - size_t ret = xStreamBufferSendFromISR( - instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken); + size_t ret = + furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); if(sizeof(LevelDuration) != ret) instance->overrun = true; - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /** Worker callback thread @@ -52,8 +49,8 @@ static int32_t subghz_worker_thread_callback(void* context) { LevelDuration level_duration; while(instance->running) { - int ret = - xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 10); + int ret = furi_stream_buffer_receive( + instance->stream, &level_duration, sizeof(LevelDuration), 10); if(ret == sizeof(LevelDuration)) { if(level_duration_is_reset(level_duration)) { FURI_LOG_E(TAG, "Overrun buffer"); @@ -97,7 +94,8 @@ SubGhzWorker* subghz_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_worker_thread_callback); - instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); + instance->stream = + furi_stream_buffer_alloc(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); //setting filter instance->filter_running = true; @@ -109,7 +107,7 @@ SubGhzWorker* subghz_worker_alloc() { void subghz_worker_free(SubGhzWorker* instance) { furi_assert(instance); - vStreamBufferDelete(instance->stream); + furi_stream_buffer_free(instance->stream); furi_thread_free(instance->thread); free(instance); diff --git a/lib/subghz/types.h b/lib/subghz/types.h index 32b70b651..dd9cefb8b 100644 --- a/lib/subghz/types.h +++ b/lib/subghz/types.h @@ -41,7 +41,7 @@ typedef bool (*SubGhzDeserialize)(void* context, FlipperFormat* flipper_format); typedef void (*SubGhzDecoderFeed)(void* decoder, bool level, uint32_t duration); typedef void (*SubGhzDecoderReset)(void* decoder); typedef uint8_t (*SubGhzGetHashData)(void* decoder); -typedef void (*SubGhzGetString)(void* decoder, string_t output); +typedef void (*SubGhzGetString)(void* decoder, FuriString* output); // Encoder specific typedef void (*SubGhzEncoderStop)(void* encoder); diff --git a/lib/toolbox/args.c b/lib/toolbox/args.c index 287ca7efc..aa790ad68 100644 --- a/lib/toolbox/args.c +++ b/lib/toolbox/args.c @@ -1,60 +1,60 @@ #include "args.h" #include "hex.h" -size_t args_get_first_word_length(string_t args) { - size_t ws = string_search_char(args, ' '); - if(ws == STRING_FAILURE) { - ws = string_size(args); +size_t args_get_first_word_length(FuriString* args) { + size_t ws = furi_string_search_char(args, ' '); + if(ws == FURI_STRING_FAILURE) { + ws = furi_string_size(args); } return ws; } -size_t args_length(string_t args) { - return string_size(args); +size_t args_length(FuriString* args) { + return furi_string_size(args); } -bool args_read_int_and_trim(string_t args, int* value) { +bool args_read_int_and_trim(FuriString* args, int* value) { size_t cmd_length = args_get_first_word_length(args); if(cmd_length == 0) { return false; } - if(sscanf(string_get_cstr(args), "%d", value) == 1) { - string_right(args, cmd_length); - string_strim(args); + if(sscanf(furi_string_get_cstr(args), "%d", value) == 1) { + furi_string_right(args, cmd_length); + furi_string_trim(args); return true; } return false; } -bool args_read_string_and_trim(string_t args, string_t word) { +bool args_read_string_and_trim(FuriString* args, FuriString* word) { size_t cmd_length = args_get_first_word_length(args); if(cmd_length == 0) { return false; } - string_set_n(word, args, 0, cmd_length); - string_right(args, cmd_length); - string_strim(args); + furi_string_set_n(word, args, 0, cmd_length); + furi_string_right(args, cmd_length); + furi_string_trim(args); return true; } -bool args_read_probably_quoted_string_and_trim(string_t args, string_t word) { - if(string_size(args) > 1 && string_get_char(args, 0) == '\"') { - size_t second_quote_pos = string_search_char(args, '\"', 1); +bool args_read_probably_quoted_string_and_trim(FuriString* args, FuriString* word) { + if(furi_string_size(args) > 1 && furi_string_get_char(args, 0) == '\"') { + size_t second_quote_pos = furi_string_search_char(args, '\"', 1); if(second_quote_pos == 0) { return false; } - string_set_n(word, args, 1, second_quote_pos - 1); - string_right(args, second_quote_pos + 1); - string_strim(args); + furi_string_set_n(word, args, 1, second_quote_pos - 1); + furi_string_right(args, second_quote_pos + 1); + furi_string_trim(args); return true; } else { return args_read_string_and_trim(args, word); @@ -76,9 +76,9 @@ bool args_char_to_hex(char hi_nibble, char low_nibble, uint8_t* byte) { return result; } -bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count) { +bool args_read_hex_bytes(FuriString* args, uint8_t* bytes, size_t bytes_count) { bool result = true; - const char* str_pointer = string_get_cstr(args); + const char* str_pointer = furi_string_get_cstr(args); if(args_get_first_word_length(args) == (bytes_count * 2)) { for(size_t i = 0; i < bytes_count; i++) { diff --git a/lib/toolbox/args.h b/lib/toolbox/args.h index dc72bdafa..556fd4a72 100644 --- a/lib/toolbox/args.h +++ b/lib/toolbox/args.h @@ -2,7 +2,7 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -15,7 +15,7 @@ extern "C" { * @return true - success * @return false - arguments string does not contain int */ -bool args_read_int_and_trim(string_t args, int* value); +bool args_read_int_and_trim(FuriString* args, int* value); /** * @brief Extract first argument from arguments string and trim arguments string @@ -25,7 +25,7 @@ bool args_read_int_and_trim(string_t args, int* value); * @return true - success * @return false - arguments string does not contain anything */ -bool args_read_string_and_trim(string_t args, string_t word); +bool args_read_string_and_trim(FuriString* args, FuriString* word); /** * @brief Extract the first quoted argument from the argument string and trim the argument string. If the argument is not quoted, calls args_read_string_and_trim. @@ -35,7 +35,7 @@ bool args_read_string_and_trim(string_t args, string_t word); * @return true - success * @return false - arguments string does not contain anything */ -bool args_read_probably_quoted_string_and_trim(string_t args, string_t word); +bool args_read_probably_quoted_string_and_trim(FuriString* args, FuriString* word); /** * @brief Convert hex ASCII values to byte array @@ -46,7 +46,7 @@ bool args_read_probably_quoted_string_and_trim(string_t args, string_t word); * @return true - success * @return false - arguments string does not contain enough values, or contain non-hex ASCII values */ -bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count); +bool args_read_hex_bytes(FuriString* args, uint8_t* bytes, size_t bytes_count); /************************************ HELPERS ***************************************/ @@ -56,7 +56,7 @@ bool args_read_hex_bytes(string_t args, uint8_t* bytes, size_t bytes_count); * @param args arguments string * @return size_t length of first word */ -size_t args_get_first_word_length(string_t args); +size_t args_get_first_word_length(FuriString* args); /** * @brief Get length of arguments string @@ -64,7 +64,7 @@ size_t args_get_first_word_length(string_t args); * @param args arguments string * @return size_t length of arguments string */ -size_t args_length(string_t args); +size_t args_length(FuriString* args); /** * @brief Convert ASCII hex values to byte diff --git a/lib/toolbox/buffer_stream.c b/lib/toolbox/buffer_stream.c index 66d210963..37b2514ef 100644 --- a/lib/toolbox/buffer_stream.c +++ b/lib/toolbox/buffer_stream.c @@ -1,5 +1,4 @@ #include "buffer_stream.h" -#include struct Buffer { volatile bool occupied; @@ -10,7 +9,7 @@ struct Buffer { struct BufferStream { size_t stream_overrun_count; - StreamBufferHandle_t stream; + FuriStreamBuffer* stream; size_t index; Buffer* buffers; @@ -54,7 +53,7 @@ BufferStream* buffer_stream_alloc(size_t buffer_size, size_t buffers_count) { buffer_stream->buffers[i].data = malloc(buffer_size); buffer_stream->buffers[i].max_data_size = buffer_size; } - buffer_stream->stream = xStreamBufferCreate( + buffer_stream->stream = furi_stream_buffer_alloc( sizeof(BufferStream*) * buffer_stream->max_buffers_count, sizeof(BufferStream*)); buffer_stream->stream_overrun_count = 0; buffer_stream->index = 0; @@ -66,7 +65,7 @@ void buffer_stream_free(BufferStream* buffer_stream) { for(size_t i = 0; i < buffer_stream->max_buffers_count; i++) { free(buffer_stream->buffers[i].data); } - vStreamBufferDelete(buffer_stream->stream); + furi_stream_buffer_free(buffer_stream->stream); free(buffer_stream->buffers); free(buffer_stream); } @@ -83,11 +82,7 @@ static inline int8_t buffer_stream_get_free_buffer(BufferStream* buffer_stream) return id; } -bool buffer_stream_send_from_isr( - BufferStream* buffer_stream, - const uint8_t* data, - size_t size, - BaseType_t* const task_woken) { +bool buffer_stream_send_from_isr(BufferStream* buffer_stream, const uint8_t* data, size_t size) { Buffer* buffer = &buffer_stream->buffers[buffer_stream->index]; bool result = true; @@ -96,7 +91,7 @@ bool buffer_stream_send_from_isr( // if buffer is full - send it buffer->occupied = true; // we always have space for buffer in stream - xStreamBufferSendFromISR(buffer_stream->stream, &buffer, sizeof(Buffer*), task_woken); + furi_stream_buffer_send(buffer_stream->stream, &buffer, sizeof(Buffer*), 0); // get new buffer from the pool int8_t index = buffer_stream_get_free_buffer(buffer_stream); @@ -119,7 +114,8 @@ bool buffer_stream_send_from_isr( Buffer* buffer_stream_receive(BufferStream* buffer_stream, TickType_t timeout) { Buffer* buffer; - size_t size = xStreamBufferReceive(buffer_stream->stream, &buffer, sizeof(Buffer*), timeout); + size_t size = + furi_stream_buffer_receive(buffer_stream->stream, &buffer, sizeof(Buffer*), timeout); if(size == sizeof(Buffer*)) { return buffer; @@ -134,9 +130,8 @@ size_t buffer_stream_get_overrun_count(BufferStream* buffer_stream) { void buffer_stream_reset(BufferStream* buffer_stream) { FURI_CRITICAL_ENTER(); - BaseType_t xReturn = xStreamBufferReset(buffer_stream->stream); - furi_assert(xReturn == pdPASS); - UNUSED(xReturn); + furi_stream_buffer_reset(buffer_stream->stream); + buffer_stream->stream_overrun_count = 0; for(size_t i = 0; i < buffer_stream->max_buffers_count; i++) { buffer_reset(&buffer_stream->buffers[i]); diff --git a/lib/toolbox/buffer_stream.h b/lib/toolbox/buffer_stream.h index d4c3cddf7..9db547753 100644 --- a/lib/toolbox/buffer_stream.h +++ b/lib/toolbox/buffer_stream.h @@ -59,14 +59,9 @@ void buffer_stream_free(BufferStream* buffer_stream); * @param buffer_stream * @param data * @param size - * @param task_woken * @return bool */ -bool buffer_stream_send_from_isr( - BufferStream* buffer_stream, - const uint8_t* data, - size_t size, - BaseType_t* const task_woken); +bool buffer_stream_send_from_isr(BufferStream* buffer_stream, const uint8_t* data, size_t size); /** * @brief Receive buffer from stream diff --git a/lib/toolbox/dir_walk.c b/lib/toolbox/dir_walk.c index 348bd5442..b5e2cb52b 100644 --- a/lib/toolbox/dir_walk.c +++ b/lib/toolbox/dir_walk.c @@ -5,7 +5,7 @@ LIST_DEF(DirIndexList, uint32_t); struct DirWalk { File* file; - string_t path; + FuriString* path; DirIndexList_t index_list; uint32_t current_index; bool recursive; @@ -15,7 +15,7 @@ struct DirWalk { DirWalk* dir_walk_alloc(Storage* storage) { DirWalk* dir_walk = malloc(sizeof(DirWalk)); - string_init(dir_walk->path); + dir_walk->path = furi_string_alloc(); dir_walk->file = storage_file_alloc(storage); DirIndexList_init(dir_walk->index_list); dir_walk->recursive = true; @@ -25,7 +25,7 @@ DirWalk* dir_walk_alloc(Storage* storage) { void dir_walk_free(DirWalk* dir_walk) { storage_file_free(dir_walk->file); - string_clear(dir_walk->path); + furi_string_free(dir_walk->path); DirIndexList_clear(dir_walk->index_list); free(dir_walk); } @@ -40,7 +40,7 @@ void dir_walk_set_filter_cb(DirWalk* dir_walk, DirWalkFilterCb cb, void* context } bool dir_walk_open(DirWalk* dir_walk, const char* path) { - string_set(dir_walk->path, path); + furi_string_set(dir_walk->path, path); dir_walk->current_index = 0; return storage_dir_open(dir_walk->file, path); } @@ -53,7 +53,8 @@ static bool dir_walk_filter(DirWalk* dir_walk, const char* name, FileInfo* filei } } -static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo) { +static DirWalkResult + dir_walk_iter(DirWalk* dir_walk, FuriString* return_path, FileInfo* fileinfo) { DirWalkResult result = DirWalkError; char* name = malloc(256); // FIXME: remove magic number FileInfo info; @@ -68,7 +69,8 @@ static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, File if(dir_walk_filter(dir_walk, name, &info)) { if(return_path != NULL) { - string_printf(return_path, "%s/%s", string_get_cstr(dir_walk->path), name); + furi_string_printf( + return_path, "%s/%s", furi_string_get_cstr(dir_walk->path), name); } if(fileinfo != NULL) { @@ -84,8 +86,8 @@ static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, File dir_walk->current_index = 0; storage_dir_close(dir_walk->file); - string_cat_printf(dir_walk->path, "/%s", name); - storage_dir_open(dir_walk->file, string_get_cstr(dir_walk->path)); + furi_string_cat_printf(dir_walk->path, "/%s", name); + storage_dir_open(dir_walk->file, furi_string_get_cstr(dir_walk->path)); } } else if(storage_file_get_error(dir_walk->file) == FSE_NOT_EXIST) { if(DirIndexList_size(dir_walk->index_list) == 0) { @@ -100,12 +102,12 @@ static DirWalkResult dir_walk_iter(DirWalk* dir_walk, string_t return_path, File storage_dir_close(dir_walk->file); - size_t last_char = string_search_rchar(dir_walk->path, '/'); - if(last_char != STRING_FAILURE) { - string_left(dir_walk->path, last_char); + size_t last_char = furi_string_search_rchar(dir_walk->path, '/'); + if(last_char != FURI_STRING_FAILURE) { + furi_string_left(dir_walk->path, last_char); } - storage_dir_open(dir_walk->file, string_get_cstr(dir_walk->path)); + storage_dir_open(dir_walk->file, furi_string_get_cstr(dir_walk->path)); // rewind while(true) { @@ -137,7 +139,7 @@ FS_Error dir_walk_get_error(DirWalk* dir_walk) { return storage_file_get_error(dir_walk->file); } -DirWalkResult dir_walk_read(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo) { +DirWalkResult dir_walk_read(DirWalk* dir_walk, FuriString* return_path, FileInfo* fileinfo) { return dir_walk_iter(dir_walk, return_path, fileinfo); } @@ -147,6 +149,6 @@ void dir_walk_close(DirWalk* dir_walk) { } DirIndexList_reset(dir_walk->index_list); - string_reset(dir_walk->path); + furi_string_reset(dir_walk->path); dir_walk->current_index = 0; } diff --git a/lib/toolbox/dir_walk.h b/lib/toolbox/dir_walk.h index fc6510420..535237fc6 100644 --- a/lib/toolbox/dir_walk.h +++ b/lib/toolbox/dir_walk.h @@ -66,7 +66,7 @@ FS_Error dir_walk_get_error(DirWalk* dir_walk); * @param fileinfo * @return DirWalkResult */ -DirWalkResult dir_walk_read(DirWalk* dir_walk, string_t return_path, FileInfo* fileinfo); +DirWalkResult dir_walk_read(DirWalk* dir_walk, FuriString* return_path, FileInfo* fileinfo); /** * Close directory diff --git a/lib/toolbox/m_cstr_dup.h b/lib/toolbox/m_cstr_dup.h index 2bc35c877..0555f72c6 100644 --- a/lib/toolbox/m_cstr_dup.h +++ b/lib/toolbox/m_cstr_dup.h @@ -13,5 +13,4 @@ HASH(m_core_cstr_hash), \ EQUAL(M_CSTR_EQUAL), \ CMP(strcmp), \ - TYPE(const char*), \ - OUT_STR(M_CSTR_OUT_STR)) + TYPE(const char*)) diff --git a/lib/toolbox/path.c b/lib/toolbox/path.c index 1262362ef..53e9fc092 100644 --- a/lib/toolbox/path.c +++ b/lib/toolbox/path.c @@ -1,86 +1,85 @@ #include "path.h" -#include "m-string.h" #include -void path_extract_filename_no_ext(const char* path, string_t filename) { - string_set(filename, path); +void path_extract_filename_no_ext(const char* path, FuriString* filename) { + furi_string_set(filename, path); - size_t start_position = string_search_rchar(filename, '/'); - size_t end_position = string_search_rchar(filename, '.'); + size_t start_position = furi_string_search_rchar(filename, '/'); + size_t end_position = furi_string_search_rchar(filename, '.'); - if(start_position == STRING_FAILURE) { + if(start_position == FURI_STRING_FAILURE) { start_position = 0; } else { start_position += 1; } - if(end_position == STRING_FAILURE) { - end_position = string_size(filename); + if(end_position == FURI_STRING_FAILURE) { + end_position = furi_string_size(filename); } - string_mid(filename, start_position, end_position - start_position); + furi_string_mid(filename, start_position, end_position - start_position); } -void path_extract_filename(string_t path, string_t name, bool trim_ext) { - size_t filename_start = string_search_rchar(path, '/'); +void path_extract_filename(FuriString* path, FuriString* name, bool trim_ext) { + size_t filename_start = furi_string_search_rchar(path, '/'); if(filename_start > 0) { filename_start++; - string_set_n(name, path, filename_start, string_size(path) - filename_start); + furi_string_set_n(name, path, filename_start, furi_string_size(path) - filename_start); } if(trim_ext) { - size_t dot = string_search_rchar(name, '.'); + size_t dot = furi_string_search_rchar(name, '.'); if(dot > 0) { - string_left(name, dot); + furi_string_left(name, dot); } } } -void path_extract_extension(string_t path, char* ext, size_t ext_len_max) { - size_t dot = string_search_rchar(path, '.'); - size_t filename_start = string_search_rchar(path, '/'); +void path_extract_extension(FuriString* path, char* ext, size_t ext_len_max) { + size_t dot = furi_string_search_rchar(path, '.'); + size_t filename_start = furi_string_search_rchar(path, '/'); if((dot > 0) && (filename_start < dot)) { - strlcpy(ext, &(string_get_cstr(path))[dot], ext_len_max); + strlcpy(ext, &(furi_string_get_cstr(path))[dot], ext_len_max); } } -static inline void path_cleanup(string_t path) { - string_strim(path); - while(string_end_with_str_p(path, "/")) { - string_left(path, string_size(path) - 1); +static inline void path_cleanup(FuriString* path) { + furi_string_trim(path); + while(furi_string_end_with(path, "/")) { + furi_string_left(path, furi_string_size(path) - 1); } } -void path_extract_basename(const char* path, string_t basename) { - string_set(basename, path); +void path_extract_basename(const char* path, FuriString* basename) { + furi_string_set(basename, path); path_cleanup(basename); - size_t pos = string_search_rchar(basename, '/'); - if(pos != STRING_FAILURE) { - string_right(basename, pos + 1); + size_t pos = furi_string_search_rchar(basename, '/'); + if(pos != FURI_STRING_FAILURE) { + furi_string_right(basename, pos + 1); } } -void path_extract_dirname(const char* path, string_t dirname) { - string_set(dirname, path); +void path_extract_dirname(const char* path, FuriString* dirname) { + furi_string_set(dirname, path); path_cleanup(dirname); - size_t pos = string_search_rchar(dirname, '/'); - if(pos != STRING_FAILURE) { - string_left(dirname, pos); + size_t pos = furi_string_search_rchar(dirname, '/'); + if(pos != FURI_STRING_FAILURE) { + furi_string_left(dirname, pos); } } -void path_append(string_t path, const char* suffix) { +void path_append(FuriString* path, const char* suffix) { path_cleanup(path); - string_t suffix_str; - string_init_set(suffix_str, suffix); - string_strim(suffix_str); - string_strim(suffix_str, "/"); - string_cat_printf(path, "/%s", string_get_cstr(suffix_str)); - string_clear(suffix_str); + FuriString* suffix_str; + suffix_str = furi_string_alloc_set(suffix); + furi_string_trim(suffix_str); + furi_string_trim(suffix_str, "/"); + furi_string_cat_printf(path, "/%s", furi_string_get_cstr(suffix_str)); + furi_string_free(suffix_str); } -void path_concat(const char* path, const char* suffix, string_t out_path) { - string_set(out_path, path); +void path_concat(const char* path, const char* suffix, FuriString* out_path) { + furi_string_set(out_path, path); path_append(out_path, suffix); } diff --git a/lib/toolbox/path.h b/lib/toolbox/path.h index d46b210f0..e6145b715 100644 --- a/lib/toolbox/path.h +++ b/lib/toolbox/path.h @@ -1,6 +1,5 @@ #pragma once - -#include +#include #ifdef __cplusplus extern "C" { @@ -12,7 +11,7 @@ extern "C" { * @param path path string * @param filename output filename string. Must be initialized before. */ -void path_extract_filename_no_ext(const char* path, string_t filename); +void path_extract_filename_no_ext(const char* path, FuriString* filename); /** * @brief Extract filename string from path. @@ -21,7 +20,7 @@ void path_extract_filename_no_ext(const char* path, string_t filename); * @param filename output filename string. Must be initialized before. * @param trim_ext true - get filename without extension */ -void path_extract_filename(string_t path, string_t filename, bool trim_ext); +void path_extract_filename(FuriString* path, FuriString* filename, bool trim_ext); /** * @brief Extract file extension from path. @@ -30,7 +29,7 @@ void path_extract_filename(string_t path, string_t filename, bool trim_ext); * @param ext output extension string * @param ext_len_max maximum extension string length */ -void path_extract_extension(string_t path, char* ext, size_t ext_len_max); +void path_extract_extension(FuriString* path, char* ext, size_t ext_len_max); /** * @brief Extract last path component @@ -38,7 +37,7 @@ void path_extract_extension(string_t path, char* ext, size_t ext_len_max); * @param path path string * @param filename output string. Must be initialized before. */ -void path_extract_basename(const char* path, string_t basename); +void path_extract_basename(const char* path, FuriString* basename); /** * @brief Extract path, except for last component @@ -46,7 +45,7 @@ void path_extract_basename(const char* path, string_t basename); * @param path path string * @param filename output string. Must be initialized before. */ -void path_extract_dirname(const char* path, string_t dirname); +void path_extract_dirname(const char* path, FuriString* dirname); /** * @brief Appends new component to path, adding path delimiter @@ -54,7 +53,7 @@ void path_extract_dirname(const char* path, string_t dirname); * @param path path string * @param suffix path part to apply */ -void path_append(string_t path, const char* suffix); +void path_append(FuriString* path, const char* suffix); /** * @brief Appends new component to path, adding path delimiter @@ -63,7 +62,7 @@ void path_append(string_t path, const char* suffix); * @param suffix second path part * @param out_path output string to combine parts into. Must be initialized */ -void path_concat(const char* path, const char* suffix, string_t out_path); +void path_concat(const char* path, const char* suffix, FuriString* out_path); /** * @brief Check that path contains only ascii characters diff --git a/lib/toolbox/protocols/protocol.h b/lib/toolbox/protocols/protocol.h index 56bb1b74c..5a8015b1e 100644 --- a/lib/toolbox/protocols/protocol.h +++ b/lib/toolbox/protocols/protocol.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include typedef void* (*ProtocolAlloc)(void); typedef void (*ProtocolFree)(void* protocol); @@ -15,7 +15,7 @@ typedef bool (*ProtocolDecoderFeed)(void* protocol, bool level, uint32_t duratio typedef bool (*ProtocolEncoderStart)(void* protocol); typedef LevelDuration (*ProtocolEncoderYield)(void* protocol); -typedef void (*ProtocolRenderData)(void* protocol, string_t result); +typedef void (*ProtocolRenderData)(void* protocol, FuriString* result); typedef bool (*ProtocolWriteData)(void* protocol, void* data); typedef struct { diff --git a/lib/toolbox/protocols/protocol_dict.c b/lib/toolbox/protocols/protocol_dict.c index 2a022cc40..136dc1372 100644 --- a/lib/toolbox/protocols/protocol_dict.c +++ b/lib/toolbox/protocols/protocol_dict.c @@ -185,7 +185,7 @@ LevelDuration protocol_dict_encoder_yield(ProtocolDict* dict, size_t protocol_in } } -void protocol_dict_render_data(ProtocolDict* dict, string_t result, size_t protocol_index) { +void protocol_dict_render_data(ProtocolDict* dict, FuriString* result, size_t protocol_index) { furi_assert(protocol_index < dict->count); ProtocolRenderData fn = dict->base[protocol_index]->render_data; @@ -194,7 +194,7 @@ void protocol_dict_render_data(ProtocolDict* dict, string_t result, size_t proto } } -void protocol_dict_render_brief_data(ProtocolDict* dict, string_t result, size_t protocol_index) { +void protocol_dict_render_brief_data(ProtocolDict* dict, FuriString* result, size_t protocol_index) { furi_assert(protocol_index < dict->count); ProtocolRenderData fn = dict->base[protocol_index]->render_brief_data; diff --git a/lib/toolbox/protocols/protocol_dict.h b/lib/toolbox/protocols/protocol_dict.h index 3037ddd5e..cd8503952 100644 --- a/lib/toolbox/protocols/protocol_dict.h +++ b/lib/toolbox/protocols/protocol_dict.h @@ -58,9 +58,9 @@ bool protocol_dict_encoder_start(ProtocolDict* dict, size_t protocol_index); LevelDuration protocol_dict_encoder_yield(ProtocolDict* dict, size_t protocol_index); -void protocol_dict_render_data(ProtocolDict* dict, string_t result, size_t protocol_index); +void protocol_dict_render_data(ProtocolDict* dict, FuriString* result, size_t protocol_index); -void protocol_dict_render_brief_data(ProtocolDict* dict, string_t result, size_t protocol_index); +void protocol_dict_render_brief_data(ProtocolDict* dict, FuriString* result, size_t protocol_index); uint32_t protocol_dict_get_validate_count(ProtocolDict* dict, size_t protocol_index); diff --git a/lib/toolbox/stream/file_stream.c b/lib/toolbox/stream/file_stream.c index f7363c6be..064912168 100644 --- a/lib/toolbox/stream/file_stream.c +++ b/lib/toolbox/stream/file_stream.c @@ -173,17 +173,20 @@ static bool file_stream_delete_and_insert( Stream* scratch_stream = file_stream_alloc(_stream->storage); // TODO: we need something like "storage_open_tmpfile and storage_close_tmpfile" - string_t scratch_name; - string_t tmp_name; - string_init(tmp_name); + FuriString* scratch_name; + FuriString* tmp_name; + tmp_name = furi_string_alloc(); storage_get_next_filename( _stream->storage, STORAGE_ANY_PATH_PREFIX, ".scratch", ".pad", tmp_name, 255); - string_init_printf(scratch_name, ANY_PATH("%s.pad"), string_get_cstr(tmp_name)); - string_clear(tmp_name); + scratch_name = furi_string_alloc_printf(ANY_PATH("%s.pad"), furi_string_get_cstr(tmp_name)); + furi_string_free(tmp_name); do { if(!file_stream_open( - scratch_stream, string_get_cstr(scratch_name), FSAM_READ_WRITE, FSOM_CREATE_NEW)) + scratch_stream, + furi_string_get_cstr(scratch_name), + FSAM_READ_WRITE, + FSOM_CREATE_NEW)) break; size_t current_position = stream_tell(stream); @@ -225,8 +228,8 @@ static bool file_stream_delete_and_insert( } while(false); stream_free(scratch_stream); - storage_common_remove(_stream->storage, string_get_cstr(scratch_name)); - string_clear(scratch_name); + storage_common_remove(_stream->storage, furi_string_get_cstr(scratch_name)); + furi_string_free(scratch_name); return result; } diff --git a/lib/toolbox/stream/stream.c b/lib/toolbox/stream/stream.c index 088996f02..86d35c959 100644 --- a/lib/toolbox/stream/stream.c +++ b/lib/toolbox/stream/stream.c @@ -67,8 +67,8 @@ static bool stream_write_struct(Stream* stream, const void* context) { return (stream_write(stream, write_data->data, write_data->size) == write_data->size); } -bool stream_read_line(Stream* stream, string_t str_result) { - string_reset(str_result); +bool stream_read_line(Stream* stream, FuriString* str_result) { + furi_string_reset(str_result); const uint8_t buffer_size = 32; uint8_t buffer[buffer_size]; @@ -84,13 +84,13 @@ bool stream_read_line(Stream* stream, string_t str_result) { error = true; break; } - string_push_back(str_result, buffer[i]); + furi_string_push_back(str_result, buffer[i]); result = true; break; } else if(buffer[i] == '\r') { // Ignore } else { - string_push_back(str_result, buffer[i]); + furi_string_push_back(str_result, buffer[i]); } } @@ -99,7 +99,7 @@ bool stream_read_line(Stream* stream, string_t str_result) { } } while(true); - return string_size(str_result) != 0; + return furi_string_size(str_result) != 0; } bool stream_rewind(Stream* stream) { @@ -112,9 +112,10 @@ size_t stream_write_char(Stream* stream, char c) { return stream_write(stream, (const uint8_t*)&c, 1); } -size_t stream_write_string(Stream* stream, string_t string) { +size_t stream_write_string(Stream* stream, FuriString* string) { furi_assert(stream); - return stream_write(stream, (const uint8_t*)string_get_cstr(string), string_size(string)); + return stream_write( + stream, (const uint8_t*)furi_string_get_cstr(string), furi_string_size(string)); } size_t stream_write_cstring(Stream* stream, const char* string) { @@ -134,10 +135,10 @@ size_t stream_write_format(Stream* stream, const char* format, ...) { size_t stream_write_vaformat(Stream* stream, const char* format, va_list args) { furi_assert(stream); - string_t data; - string_init_vprintf(data, format, args); + FuriString* data; + data = furi_string_alloc_vprintf(format, args); size_t size = stream_write_string(stream, data); - string_clear(data); + furi_string_free(data); return size; } @@ -153,7 +154,7 @@ bool stream_insert_char(Stream* stream, char c) { return stream_delete_and_insert_char(stream, 0, c); } -bool stream_insert_string(Stream* stream, string_t string) { +bool stream_insert_string(Stream* stream, FuriString* string) { furi_assert(stream); return stream_delete_and_insert_string(stream, 0, string); } @@ -184,10 +185,10 @@ bool stream_delete_and_insert_char(Stream* stream, size_t delete_size, char c) { return stream_delete_and_insert(stream, delete_size, stream_write_struct, &write_data); } -bool stream_delete_and_insert_string(Stream* stream, size_t delete_size, string_t string) { +bool stream_delete_and_insert_string(Stream* stream, size_t delete_size, FuriString* string) { furi_assert(stream); StreamWriteData write_data = { - .data = (uint8_t*)string_get_cstr(string), .size = string_size(string)}; + .data = (uint8_t*)furi_string_get_cstr(string), .size = furi_string_size(string)}; return stream_delete_and_insert(stream, delete_size, stream_write_struct, &write_data); } @@ -213,12 +214,12 @@ bool stream_delete_and_insert_vaformat( const char* format, va_list args) { furi_assert(stream); - string_t data; - string_init_vprintf(data, format, args); + FuriString* data; + data = furi_string_alloc_vprintf(format, args); StreamWriteData write_data = { - .data = (uint8_t*)string_get_cstr(data), .size = string_size(data)}; + .data = (uint8_t*)furi_string_get_cstr(data), .size = furi_string_size(data)}; bool result = stream_delete_and_insert(stream, delete_size, stream_write_struct, &write_data); - string_clear(data); + furi_string_free(data); return result; } diff --git a/lib/toolbox/stream/stream.h b/lib/toolbox/stream/stream.h index c10e9f5e5..fc3855102 100644 --- a/lib/toolbox/stream/stream.h +++ b/lib/toolbox/stream/stream.h @@ -2,7 +2,6 @@ #include #include #include -#include #include #ifdef __cplusplus @@ -105,7 +104,7 @@ bool stream_delete_and_insert( * @return true if line lenght is not zero * @return false otherwise */ -bool stream_read_line(Stream* stream, string_t str_result); +bool stream_read_line(Stream* stream, FuriString* str_result); /** * Moves the rw pointer to the start @@ -127,7 +126,7 @@ size_t stream_write_char(Stream* stream, char c); * @param string string value * @return size_t how many bytes was written */ -size_t stream_write_string(Stream* stream, string_t string); +size_t stream_write_string(Stream* stream, FuriString* string); /** * Write const char* to the stream @@ -144,7 +143,8 @@ size_t stream_write_cstring(Stream* stream, const char* string); * @param ... * @return size_t how many bytes was written */ -size_t stream_write_format(Stream* stream, const char* format, ...); +size_t stream_write_format(Stream* stream, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Write formatted string to the stream, va_list version @@ -182,7 +182,7 @@ bool stream_insert_char(Stream* stream, char c); * @return true if the operation was successful * @return false on error */ -bool stream_insert_string(Stream* stream, string_t string); +bool stream_insert_string(Stream* stream, FuriString* string); /** * Insert const char* to the stream @@ -201,7 +201,8 @@ bool stream_insert_cstring(Stream* stream, const char* string); * @return true if the operation was successful * @return false on error */ -bool stream_insert_format(Stream* stream, const char* format, ...); +bool stream_insert_format(Stream* stream, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 2, 3))); /** * Insert formatted string to the stream, va_list version @@ -231,7 +232,7 @@ bool stream_delete_and_insert_char(Stream* stream, size_t delete_size, char c); * @return true if the operation was successful * @return false on error */ -bool stream_delete_and_insert_string(Stream* stream, size_t delete_size, string_t string); +bool stream_delete_and_insert_string(Stream* stream, size_t delete_size, FuriString* string); /** * Delete N chars from the stream and insert const char* to the stream @@ -252,7 +253,8 @@ bool stream_delete_and_insert_cstring(Stream* stream, size_t delete_size, const * @return true if the operation was successful * @return false on error */ -bool stream_delete_and_insert_format(Stream* stream, size_t delete_size, const char* format, ...); +bool stream_delete_and_insert_format(Stream* stream, size_t delete_size, const char* format, ...) + _ATTRIBUTE((__format__(__printf__, 3, 4))); /** * Delete N chars from the stream and insert formatted string to the stream, va_list version diff --git a/lib/toolbox/stream/string_stream.c b/lib/toolbox/stream/string_stream.c index f3e1364d1..075f0b26f 100644 --- a/lib/toolbox/stream/string_stream.c +++ b/lib/toolbox/stream/string_stream.c @@ -5,7 +5,7 @@ typedef struct { Stream stream_base; - string_t string; + FuriString* string; size_t index; } StringStream; @@ -39,14 +39,14 @@ const StreamVTable string_stream_vtable = { Stream* string_stream_alloc() { StringStream* stream = malloc(sizeof(StringStream)); - string_init(stream->string); + stream->string = furi_string_alloc(); stream->index = 0; stream->stream_base.vtable = &string_stream_vtable; return (Stream*)stream; } static void string_stream_free(StringStream* stream) { - string_clear(stream->string); + furi_string_free(stream->string); free(stream); } @@ -56,7 +56,7 @@ static bool string_stream_eof(StringStream* stream) { static void string_stream_clean(StringStream* stream) { stream->index = 0; - string_reset(stream->string); + furi_string_reset(stream->string); } static bool string_stream_seek(StringStream* stream, int32_t offset, StreamOffset offset_type) { @@ -79,8 +79,8 @@ static bool string_stream_seek(StringStream* stream, int32_t offset, StreamOffse } break; case StreamOffsetFromEnd: - if(((int32_t)string_size(stream->string) + offset) >= 0) { - stream->index = string_size(stream->string) + offset; + if(((int32_t)furi_string_size(stream->string) + offset) >= 0) { + stream->index = furi_string_size(stream->string) + offset; } else { result = false; stream->index = 0; @@ -88,7 +88,7 @@ static bool string_stream_seek(StringStream* stream, int32_t offset, StreamOffse break; } - int32_t diff = (stream->index - string_size(stream->string)); + int32_t diff = (stream->index - furi_string_size(stream->string)); if(diff > 0) { stream->index -= diff; result = false; @@ -102,7 +102,7 @@ static size_t string_stream_tell(StringStream* stream) { } static size_t string_stream_size(StringStream* stream) { - return string_size(stream->string); + return furi_string_size(stream->string); } static size_t string_stream_write(StringStream* stream, const char* data, size_t size) { @@ -117,7 +117,7 @@ static size_t string_stream_write(StringStream* stream, const char* data, size_t static size_t string_stream_read(StringStream* stream, char* data, size_t size) { size_t write_index = 0; - const char* cstr = string_get_cstr(stream->string); + const char* cstr = furi_string_get_cstr(stream->string); if(!string_stream_eof(stream)) { while(true) { @@ -145,17 +145,17 @@ static bool string_stream_delete_and_insert( remain_size = MIN(delete_size, remain_size); if(remain_size != 0) { - string_replace_at(stream->string, stream->index, remain_size, ""); + furi_string_replace_at(stream->string, stream->index, remain_size, ""); } } if(write_callback) { - string_t right; - string_init_set(right, &string_get_cstr(stream->string)[stream->index]); - string_left(stream->string, string_stream_tell(stream)); + FuriString* right; + right = furi_string_alloc_set(&furi_string_get_cstr(stream->string)[stream->index]); + furi_string_left(stream->string, string_stream_tell(stream)); result &= write_callback((Stream*)stream, ctx); - string_cat(stream->string, right); - string_clear(right); + furi_string_cat(stream->string, right); + furi_string_free(right); } return result; @@ -169,9 +169,9 @@ static bool string_stream_delete_and_insert( */ static size_t string_stream_write_char(StringStream* stream, char c) { if(string_stream_eof(stream)) { - string_push_back(stream->string, c); + furi_string_push_back(stream->string, c); } else { - string_set_char(stream->string, stream->index, c); + furi_string_set_char(stream->string, stream->index, c); } stream->index++; diff --git a/lib/toolbox/stream/string_stream.h b/lib/toolbox/stream/string_stream.h index 6cccfa6cc..f882a246b 100644 --- a/lib/toolbox/stream/string_stream.h +++ b/lib/toolbox/stream/string_stream.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include "stream.h" #ifdef __cplusplus diff --git a/lib/toolbox/tar/tar_archive.c b/lib/toolbox/tar/tar_archive.c index f51d62317..e8b447291 100644 --- a/lib/toolbox/tar/tar_archive.c +++ b/lib/toolbox/tar/tar_archive.c @@ -168,7 +168,44 @@ typedef struct { Storage_name_converter converter; } TarArchiveDirectoryOpParams; +static bool archive_extract_current_file(TarArchive* archive, const char* dst_path) { + mtar_t* tar = &archive->tar; + File* out_file = storage_file_alloc(archive->storage); + uint8_t* readbuf = malloc(FILE_BLOCK_SIZE); + + bool success = true; + uint8_t n_tries = FILE_OPEN_NTRIES; + do { + while(n_tries-- > 0) { + if(storage_file_open(out_file, dst_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + break; + } + FURI_LOG_W(TAG, "Failed to open '%s', reties: %d", dst_path, n_tries); + storage_file_close(out_file); + furi_delay_ms(FILE_OPEN_RETRY_DELAY); + } + + if(!storage_file_is_open(out_file)) { + success = false; + break; + } + + while(!mtar_eof_data(tar)) { + int32_t readcnt = mtar_read_data(tar, readbuf, FILE_BLOCK_SIZE); + if(!readcnt || !storage_file_write(out_file, readbuf, readcnt)) { + success = false; + break; + } + } + } while(false); + storage_file_free(out_file); + free(readbuf); + + return success; +} + static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, void* param) { + UNUSED(tar); TarArchiveDirectoryOpParams* op_params = param; TarArchive* archive = op_params->archive; @@ -183,14 +220,14 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, return 0; } - string_t full_extracted_fname; + FuriString* full_extracted_fname; if(header->type == MTAR_TDIR) { - string_init(full_extracted_fname); + full_extracted_fname = furi_string_alloc(); path_concat(op_params->work_dir, header->name, full_extracted_fname); bool create_res = - storage_simply_mkdir(archive->storage, string_get_cstr(full_extracted_fname)); - string_clear(full_extracted_fname); + storage_simply_mkdir(archive->storage, furi_string_get_cstr(full_extracted_fname)); + furi_string_free(full_extracted_fname); return create_res ? 0 : -1; } @@ -199,58 +236,22 @@ static int archive_extract_foreach_cb(mtar_t* tar, const mtar_header_t* header, return 0; } - string_init(full_extracted_fname); + FURI_LOG_D(TAG, "Extracting %d bytes to '%s'", header->size, header->name); - string_t converted_fname; - string_init_set(converted_fname, header->name); + FuriString* converted_fname = furi_string_alloc_set(header->name); if(op_params->converter) { op_params->converter(converted_fname); } - path_concat(op_params->work_dir, string_get_cstr(converted_fname), full_extracted_fname); - string_clear(converted_fname); - FURI_LOG_D(TAG, "Extracting %d bytes to '%s'", header->size, header->name); - File* out_file = storage_file_alloc(archive->storage); - uint8_t* readbuf = malloc(FILE_BLOCK_SIZE); + full_extracted_fname = furi_string_alloc(); + path_concat(op_params->work_dir, furi_string_get_cstr(converted_fname), full_extracted_fname); - bool failed = false; - uint8_t n_tries = FILE_OPEN_NTRIES; - do { - while(n_tries-- > 0) { - if(storage_file_open( - out_file, - string_get_cstr(full_extracted_fname), - FSAM_WRITE, - FSOM_CREATE_ALWAYS)) { - break; - } - FURI_LOG_W( - TAG, - "Failed to open '%s', reties: %d", - string_get_cstr(full_extracted_fname), - n_tries); - storage_file_close(out_file); - furi_delay_ms(FILE_OPEN_RETRY_DELAY); - } + bool success = + archive_extract_current_file(archive, furi_string_get_cstr(full_extracted_fname)); - if(!storage_file_is_open(out_file)) { - failed = true; - break; - } - - while(!mtar_eof_data(tar)) { - int32_t readcnt = mtar_read_data(tar, readbuf, FILE_BLOCK_SIZE); - if(!readcnt || !storage_file_write(out_file, readbuf, readcnt)) { - failed = true; - break; - } - } - } while(false); - - storage_file_free(out_file); - free(readbuf); - string_clear(full_extracted_fname); - return failed ? -1 : 0; + furi_string_free(converted_fname); + furi_string_free(full_extracted_fname); + return success ? 0 : -1; } bool tar_archive_unpack_to( @@ -332,32 +333,32 @@ bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const ch break; } - string_t element_name, element_fs_abs_path; - string_init(element_name); - string_init(element_fs_abs_path); + FuriString* element_name = furi_string_alloc(); + FuriString* element_fs_abs_path = furi_string_alloc(); path_concat(fs_full_path, name, element_fs_abs_path); if(strlen(path_prefix)) { path_concat(path_prefix, name, element_name); } else { - string_init_set(element_name, name); + furi_string_set(element_name, name); } if(file_info.flags & FSF_DIRECTORY) { - success = tar_archive_dir_add_element(archive, string_get_cstr(element_name)) && - tar_archive_add_dir( - archive, - string_get_cstr(element_fs_abs_path), - string_get_cstr(element_name)); + success = + tar_archive_dir_add_element(archive, furi_string_get_cstr(element_name)) && + tar_archive_add_dir( + archive, + furi_string_get_cstr(element_fs_abs_path), + furi_string_get_cstr(element_name)); } else { success = tar_archive_add_file( archive, - string_get_cstr(element_fs_abs_path), - string_get_cstr(element_name), + furi_string_get_cstr(element_fs_abs_path), + furi_string_get_cstr(element_name), file_info.size); } - string_clear(element_name); - string_clear(element_fs_abs_path); + furi_string_free(element_name); + furi_string_free(element_fs_abs_path); if(!success) { break; @@ -369,3 +370,16 @@ bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const ch storage_file_free(directory); return success; } + +bool tar_archive_unpack_file( + TarArchive* archive, + const char* archive_fname, + const char* destination) { + furi_assert(archive); + furi_assert(archive_fname); + furi_assert(destination); + if(mtar_find(&archive->tar, archive_fname) != MTAR_ESUCCESS) { + return false; + } + return archive_extract_current_file(archive, destination); +} \ No newline at end of file diff --git a/lib/toolbox/tar/tar_archive.h b/lib/toolbox/tar/tar_archive.h index 88cb3dd4d..ba2f7749f 100644 --- a/lib/toolbox/tar/tar_archive.h +++ b/lib/toolbox/tar/tar_archive.h @@ -2,7 +2,6 @@ #include #include -#include #include #ifdef __cplusplus @@ -41,6 +40,11 @@ bool tar_archive_add_dir(TarArchive* archive, const char* fs_full_path, const ch int32_t tar_archive_get_entries_count(TarArchive* archive); +bool tar_archive_unpack_file( + TarArchive* archive, + const char* archive_fname, + const char* destination); + /* Optional per-entry callback on unpacking - return false to skip entry */ typedef bool (*tar_unpack_file_cb)(const char* name, bool is_directory, void* context); diff --git a/lib/update_util/lfs_backup.c b/lib/update_util/lfs_backup.c index 089f032d4..7786524ef 100644 --- a/lib/update_util/lfs_backup.c +++ b/lib/update_util/lfs_backup.c @@ -11,8 +11,8 @@ #define LFS_BACKUP_DEFAULT_LOCATION EXT_PATH(LFS_BACKUP_DEFAULT_FILENAME) -static void backup_name_converter(string_t filename) { - if(string_empty_p(filename) || (string_get_char(filename, 0) == '.')) { +static void backup_name_converter(FuriString* filename) { + if(furi_string_empty(filename) || (furi_string_get_char(filename, 0) == '.')) { return; } @@ -27,8 +27,8 @@ static void backup_name_converter(string_t filename) { }; for(size_t i = 0; i < COUNT_OF(names); i++) { - if(string_equal_str_p(filename, &names[i][1])) { - string_set_str(filename, names[i]); + if(furi_string_equal(filename, &names[i][1])) { + furi_string_set(filename, names[i]); return; } } diff --git a/lib/update_util/resources/manifest.c b/lib/update_util/resources/manifest.c new file mode 100644 index 000000000..8b6a1b33c --- /dev/null +++ b/lib/update_util/resources/manifest.c @@ -0,0 +1,115 @@ +#include "manifest.h" + +#include +#include + +struct ResourceManifestReader { + Storage* storage; + Stream* stream; + FuriString* linebuf; + ResourceManifestEntry entry; +}; + +ResourceManifestReader* resource_manifest_reader_alloc(Storage* storage) { + ResourceManifestReader* resource_manifest = + (ResourceManifestReader*)malloc(sizeof(ResourceManifestReader)); + resource_manifest->storage = storage; + resource_manifest->stream = buffered_file_stream_alloc(resource_manifest->storage); + memset(&resource_manifest->entry, 0, sizeof(ResourceManifestEntry)); + resource_manifest->entry.name = furi_string_alloc(); + resource_manifest->linebuf = furi_string_alloc(); + return resource_manifest; +} + +void resource_manifest_reader_free(ResourceManifestReader* resource_manifest) { + furi_assert(resource_manifest); + + furi_string_free(resource_manifest->linebuf); + furi_string_free(resource_manifest->entry.name); + buffered_file_stream_close(resource_manifest->stream); + stream_free(resource_manifest->stream); + free(resource_manifest); +} + +bool resource_manifest_reader_open(ResourceManifestReader* resource_manifest, const char* filename) { + furi_assert(resource_manifest); + + return buffered_file_stream_open( + resource_manifest->stream, filename, FSAM_READ, FSOM_OPEN_EXISTING); +} + +/* Read entries in format of + * F::: + * D: + */ +ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* resource_manifest) { + furi_assert(resource_manifest); + + furi_string_reset(resource_manifest->entry.name); + resource_manifest->entry.type = ResourceManifestEntryTypeUnknown; + resource_manifest->entry.size = 0; + memset(resource_manifest->entry.hash, 0, sizeof(resource_manifest->entry.hash)); + + do { + if(!stream_read_line(resource_manifest->stream, resource_manifest->linebuf)) { + return NULL; + } + + /* Trim end of line */ + furi_string_trim(resource_manifest->linebuf); + + char type_code = furi_string_get_char(resource_manifest->linebuf, 0); + switch(type_code) { + case 'F': + resource_manifest->entry.type = ResourceManifestEntryTypeFile; + break; + case 'D': + resource_manifest->entry.type = ResourceManifestEntryTypeDirectory; + break; + default: /* Skip other entries - version, timestamp, etc */ + continue; + }; + + if(resource_manifest->entry.type == ResourceManifestEntryTypeFile) { + /* Parse file entry + F::: */ + + /* Remove entry type code */ + furi_string_right(resource_manifest->linebuf, 2); + + if(furi_string_search_char(resource_manifest->linebuf, ':') != + sizeof(resource_manifest->entry.hash) * 2) { + /* Invalid hash */ + continue; + } + + /* Read hash */ + hex_chars_to_uint8( + furi_string_get_cstr(resource_manifest->linebuf), resource_manifest->entry.hash); + + /* Remove hash */ + furi_string_right( + resource_manifest->linebuf, sizeof(resource_manifest->entry.hash) * 2 + 1); + + resource_manifest->entry.size = atoi(furi_string_get_cstr(resource_manifest->linebuf)); + + /* Remove size */ + size_t offs = furi_string_search_char(resource_manifest->linebuf, ':'); + furi_string_right(resource_manifest->linebuf, offs + 1); + + furi_string_set(resource_manifest->entry.name, resource_manifest->linebuf); + } else if(resource_manifest->entry.type == ResourceManifestEntryTypeDirectory) { + /* Parse directory entry + D: */ + + /* Remove entry type code */ + furi_string_right(resource_manifest->linebuf, 2); + + furi_string_set(resource_manifest->entry.name, resource_manifest->linebuf); + } + + return &resource_manifest->entry; + } while(true); + + return NULL; +} diff --git a/lib/update_util/resources/manifest.h b/lib/update_util/resources/manifest.h new file mode 100644 index 000000000..8baa1613e --- /dev/null +++ b/lib/update_util/resources/manifest.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ResourceManifestEntryTypeUnknown = 0, + ResourceManifestEntryTypeDirectory, + ResourceManifestEntryTypeFile, +} ResourceManifestEntryType; + +typedef struct { + ResourceManifestEntryType type; + FuriString* name; + uint32_t size; + uint8_t hash[16]; +} ResourceManifestEntry; + +typedef struct ResourceManifestReader ResourceManifestReader; + +/** + * @brief Initialize resource manifest reader + * @param storage Storage API pointer + * @return allocated object + */ +ResourceManifestReader* resource_manifest_reader_alloc(Storage* storage); + +/** + * @brief Release resource manifest reader + * @param resource_manifest allocated object + */ +void resource_manifest_reader_free(ResourceManifestReader* resource_manifest); + +/** + * @brief Initialize resource manifest reader iteration + * @param resource_manifest allocated object + * @param filename manifest file name + * @return true if file opened + */ +bool resource_manifest_reader_open(ResourceManifestReader* resource_manifest, const char* filename); + +/** + * @brief Read next file/dir entry from manifest + * @param resource_manifest allocated object + * @return entry or NULL if end of file + */ +ResourceManifestEntry* resource_manifest_reader_next(ResourceManifestReader* resource_manifest); + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/lib/update_util/update_manifest.c b/lib/update_util/update_manifest.c index 1b205d9ce..795fdd5eb 100644 --- a/lib/update_util/update_manifest.c +++ b/lib/update_util/update_manifest.c @@ -21,12 +21,12 @@ UpdateManifest* update_manifest_alloc() { UpdateManifest* update_manifest = malloc(sizeof(UpdateManifest)); - string_init(update_manifest->version); - string_init(update_manifest->firmware_dfu_image); - string_init(update_manifest->radio_image); - string_init(update_manifest->staged_loader_file); - string_init(update_manifest->resource_bundle); - string_init(update_manifest->splash_file); + update_manifest->version = furi_string_alloc(); + update_manifest->firmware_dfu_image = furi_string_alloc(); + update_manifest->radio_image = furi_string_alloc(); + update_manifest->staged_loader_file = furi_string_alloc(); + update_manifest->resource_bundle = furi_string_alloc(); + update_manifest->splash_file = furi_string_alloc(); update_manifest->target = 0; update_manifest->manifest_version = 0; memset(update_manifest->ob_reference.bytes, 0, FURI_HAL_FLASH_OB_RAW_SIZE_BYTES); @@ -38,12 +38,12 @@ UpdateManifest* update_manifest_alloc() { void update_manifest_free(UpdateManifest* update_manifest) { furi_assert(update_manifest); - string_clear(update_manifest->version); - string_clear(update_manifest->firmware_dfu_image); - string_clear(update_manifest->radio_image); - string_clear(update_manifest->staged_loader_file); - string_clear(update_manifest->resource_bundle); - string_clear(update_manifest->splash_file); + furi_string_free(update_manifest->version); + furi_string_free(update_manifest->firmware_dfu_image); + furi_string_free(update_manifest->radio_image); + furi_string_free(update_manifest->staged_loader_file); + furi_string_free(update_manifest->resource_bundle); + furi_string_free(update_manifest->splash_file); free(update_manifest); } @@ -52,10 +52,10 @@ static bool furi_assert(update_manifest); furi_assert(flipper_file); - string_t filetype; + FuriString* filetype; // TODO: compare filetype? - string_init(filetype); + filetype = furi_string_alloc(); update_manifest->valid = flipper_format_read_header(flipper_file, filetype, &update_manifest->manifest_version) && flipper_format_read_string(flipper_file, MANIFEST_KEY_INFO, update_manifest->version) && @@ -68,7 +68,7 @@ static bool MANIFEST_KEY_LOADER_CRC, (uint8_t*)&update_manifest->staged_loader_crc, sizeof(uint32_t)); - string_clear(filetype); + furi_string_free(filetype); if(update_manifest->valid) { /* Optional fields - we can have dfu, radio, resources, or any combination */ @@ -114,9 +114,9 @@ static bool flipper_file, MANIFEST_KEY_SPLASH_FILE, update_manifest->splash_file); update_manifest->valid = - (!string_empty_p(update_manifest->firmware_dfu_image) || - !string_empty_p(update_manifest->radio_image) || - !string_empty_p(update_manifest->resource_bundle)); + (!furi_string_empty(update_manifest->firmware_dfu_image) || + !furi_string_empty(update_manifest->radio_image) || + !furi_string_empty(update_manifest->resource_bundle)); } return update_manifest->valid; diff --git a/lib/update_util/update_manifest.h b/lib/update_util/update_manifest.h index 8f3859471..c26e4f87b 100644 --- a/lib/update_util/update_manifest.h +++ b/lib/update_util/update_manifest.h @@ -6,7 +6,7 @@ extern "C" { #include #include -#include +#include #include /* Paths don't include /ext -- because at startup SD card is mounted as FS root */ @@ -28,20 +28,20 @@ _Static_assert(sizeof(UpdateManifestRadioVersion) == 6, "UpdateManifestRadioVers typedef struct { uint32_t manifest_version; - string_t version; + FuriString* version; uint32_t target; - string_t staged_loader_file; + FuriString* staged_loader_file; uint32_t staged_loader_crc; - string_t firmware_dfu_image; - string_t radio_image; + FuriString* firmware_dfu_image; + FuriString* radio_image; uint32_t radio_address; UpdateManifestRadioVersion radio_version; uint32_t radio_crc; - string_t resource_bundle; + FuriString* resource_bundle; FuriHalFlashRawOptionByteData ob_reference; FuriHalFlashRawOptionByteData ob_compare_mask; FuriHalFlashRawOptionByteData ob_write_mask; - string_t splash_file; + FuriString* splash_file; bool valid; } UpdateManifest; diff --git a/lib/update_util/update_operation.c b/lib/update_util/update_operation.c index 56f412a95..3a44605e0 100644 --- a/lib/update_util/update_operation.c +++ b/lib/update_util/update_operation.c @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -34,9 +33,9 @@ const char* update_operation_describe_preparation_result(const UpdatePrepareResu } } -static bool update_operation_get_current_package_path_rtc(Storage* storage, string_t out_path) { +static bool update_operation_get_current_package_path_rtc(Storage* storage, FuriString* out_path) { const uint32_t update_index = furi_hal_rtc_get_register(FuriHalRtcRegisterUpdateFolderFSIndex); - string_set_str(out_path, UPDATE_ROOT_DIR); + furi_string_set(out_path, UPDATE_ROOT_DIR); if(update_index == UPDATE_OPERATION_ROOT_DIR_PACKAGE_MAGIC) { return true; } @@ -63,7 +62,7 @@ static bool update_operation_get_current_package_path_rtc(Storage* storage, stri free(name_buffer); storage_file_free(dir); if(!found) { - string_reset(out_path); + furi_string_reset(out_path); } return found; @@ -72,8 +71,8 @@ static bool update_operation_get_current_package_path_rtc(Storage* storage, stri #define UPDATE_FILE_POINTER_FN EXT_PATH(UPDATE_MANIFEST_POINTER_FILE_NAME) #define UPDATE_MANIFEST_MAX_PATH_LEN 256u -bool update_operation_get_current_package_manifest_path(Storage* storage, string_t out_path) { - string_reset(out_path); +bool update_operation_get_current_package_manifest_path(Storage* storage, FuriString* out_path) { + furi_string_reset(out_path); if(storage_common_stat(storage, UPDATE_FILE_POINTER_FN, NULL) == FSE_OK) { char* manifest_name_buffer = malloc(UPDATE_MANIFEST_MAX_PATH_LEN); File* upd_file = NULL; @@ -91,23 +90,23 @@ bool update_operation_get_current_package_manifest_path(Storage* storage, string if(storage_common_stat(storage, manifest_name_buffer, NULL) != FSE_OK) { break; } - string_set_str(out_path, manifest_name_buffer); + furi_string_set(out_path, manifest_name_buffer); } while(0); free(manifest_name_buffer); storage_file_free(upd_file); } else { /* legacy, will be deprecated */ - string_t rtcpath; - string_init(rtcpath); + FuriString* rtcpath; + rtcpath = furi_string_alloc(); do { if(!update_operation_get_current_package_path_rtc(storage, rtcpath)) { break; } - path_concat(string_get_cstr(rtcpath), UPDATE_MANIFEST_DEFAULT_NAME, out_path); + path_concat(furi_string_get_cstr(rtcpath), UPDATE_MANIFEST_DEFAULT_NAME, out_path); } while(0); - string_clear(rtcpath); + furi_string_free(rtcpath); } - return !string_empty_p(out_path); + return !furi_string_empty(out_path); } static bool update_operation_persist_manifest_path(Storage* storage, const char* manifest_path) { @@ -141,8 +140,8 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { File* file = storage_file_alloc(storage); uint64_t free_int_space; - string_t stage_path; - string_init(stage_path); + FuriString* stage_path; + stage_path = furi_string_alloc(); do { if((storage_common_fs_info(storage, STORAGE_INT_PATH_PREFIX, NULL, &free_int_space) != FSE_OK) || @@ -171,9 +170,10 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { } path_extract_dirname(manifest_file_path, stage_path); - path_append(stage_path, string_get_cstr(manifest->staged_loader_file)); + path_append(stage_path, furi_string_get_cstr(manifest->staged_loader_file)); - if(!storage_file_open(file, string_get_cstr(stage_path), FSAM_READ, FSOM_OPEN_EXISTING)) { + if(!storage_file_open( + file, furi_string_get_cstr(stage_path), FSAM_READ, FSOM_OPEN_EXISTING)) { result = UpdatePrepareResultStageMissing; break; } @@ -193,7 +193,7 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePreUpdate); } while(false); - string_clear(stage_path); + furi_string_free(stage_path); storage_file_free(file); update_manifest_free(manifest); diff --git a/lib/update_util/update_operation.h b/lib/update_util/update_operation.h index 056520e11..65abf8e15 100644 --- a/lib/update_util/update_operation.h +++ b/lib/update_util/update_operation.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #ifdef __cplusplus @@ -19,7 +18,7 @@ extern "C" { * May be empty if update is in root update directory * @return bool if supplied path is valid and out_manifest_dir contains dir to apply */ -bool update_operation_get_package_dir_name(const char* full_path, string_t out_manifest_dir); +bool update_operation_get_package_dir_name(const char* full_path, FuriString* out_manifest_dir); /* When updating this enum, also update assets/protobuf/system.proto */ typedef enum { @@ -51,7 +50,7 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path); * @param out_path Path to manifest. Must be initialized * @return true if path was restored successfully */ -bool update_operation_get_current_package_manifest_path(Storage* storage, string_t out_path); +bool update_operation_get_current_package_manifest_path(Storage* storage, FuriString* out_path); /* * Checks if an update operation step is pending after reset diff --git a/scripts/assets.py b/scripts/assets.py index 1f36a135b..75bebcfb4 100755 --- a/scripts/assets.py +++ b/scripts/assets.py @@ -14,7 +14,7 @@ ICONS_TEMPLATE_H_HEADER = """#pragma once """ ICONS_TEMPLATE_H_ICON_NAME = "extern const Icon {name};\n" -ICONS_TEMPLATE_C_HEADER = """#include \"assets_icons.h\" +ICONS_TEMPLATE_C_HEADER = """#include "{assets_filename}.h" #include @@ -33,12 +33,26 @@ class Main(App): ) self.parser_icons.add_argument("input_directory", help="Source directory") self.parser_icons.add_argument("output_directory", help="Output directory") + self.parser_icons.add_argument( + "--filename", + help="Base filename for file with icon data", + required=False, + default="assets_icons", + ) + self.parser_icons.set_defaults(func=self.icons) self.parser_manifest = self.subparsers.add_parser( "manifest", help="Create directory Manifest" ) self.parser_manifest.add_argument("local_path", help="local_path") + self.parser_manifest.add_argument( + "--timestamp", + help="timestamp value to embed", + default=0, + type=int, + required=False, + ) self.parser_manifest.set_defaults(func=self.manifest) self.parser_copro = self.subparsers.add_parser( @@ -95,13 +109,15 @@ class Main(App): return extension in ICONS_SUPPORTED_FORMATS def icons(self): - self.logger.debug(f"Converting icons") + self.logger.debug("Converting icons") icons_c = open( - os.path.join(self.args.output_directory, "assets_icons.c"), + os.path.join(self.args.output_directory, f"{self.args.filename}.c"), "w", newline="\n", ) - icons_c.write(ICONS_TEMPLATE_C_HEADER) + icons_c.write( + ICONS_TEMPLATE_C_HEADER.format(assets_filename=self.args.filename) + ) icons = [] # Traverse icons tree, append image data to source file for dirpath, dirnames, filenames in os.walk(self.args.input_directory): @@ -111,7 +127,7 @@ class Main(App): if not filenames: continue if "frame_rate" in filenames: - self.logger.debug(f"Folder contatins animation") + self.logger.debug(f"Folder contains animation") icon_name = "A_" + os.path.split(dirpath)[1].replace("-", "_") width = height = None frame_count = 0 @@ -187,7 +203,7 @@ class Main(App): # Create Public Header self.logger.debug(f"Creating header") icons_h = open( - os.path.join(self.args.output_directory, "assets_icons.h"), + os.path.join(self.args.output_directory, f"{self.args.filename}.h"), "w", newline="\n", ) @@ -213,7 +229,7 @@ class Main(App): self.logger.info( f'Creating temporary Manifest for directory "{directory_path}"' ) - new_manifest = Manifest() + new_manifest = Manifest(self.args.timestamp) new_manifest.create(directory_path) self.logger.info(f"Comparing new manifest with existing") diff --git a/scripts/flipper/assets/manifest.py b/scripts/flipper/assets/manifest.py index 840761d72..a8f6855a4 100644 --- a/scripts/flipper/assets/manifest.py +++ b/scripts/flipper/assets/manifest.py @@ -106,11 +106,11 @@ addManifestRecord(ManifestRecordFile) class Manifest: - def __init__(self): + def __init__(self, timestamp_value=None): self.version = None self.records = [] self.records.append(ManifestRecordVersion(MANIFEST_VERSION)) - self.records.append(ManifestRecordTimestamp(timestamp())) + self.records.append(ManifestRecordTimestamp(timestamp_value or timestamp())) self.logger = logging.getLogger(self.__class__.__name__) def load(self, filename): diff --git a/scripts/lint.py b/scripts/lint.py index 30a5699a7..c178c8763 100755 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -54,6 +54,10 @@ class Main(App): output = [] for folder in folders: for dirpath, dirnames, filenames in os.walk(folder): + # Skipping 3rd-party code - usually resides in subfolder "lib" + if "lib" in dirnames: + dirnames.remove("lib") + for filename in filenames: ext = os.path.splitext(filename.lower())[1] if not ext in SOURCE_CODE_FILE_EXTENSIONS: diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index 2eeda2479..765af08f1 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -34,6 +34,14 @@ AddOption( help="List of applications to forcefully build as standalone .elf", ) +AddOption( + "--proxy-env", + action="store", + dest="proxy_env", + default="", + help="Comma-separated list of additional environment variables to pass to child SCons processes", +) + # Construction environment variables @@ -230,6 +238,7 @@ vars.Add( ("applications/system", False), ("applications/debug", False), ("applications/plugins", False), + ("applications/examples", False), ("applications_user", False), ], ) diff --git a/site_scons/environ.scons b/site_scons/environ.scons index c61f29616..3e0c6bea7 100644 --- a/site_scons/environ.scons +++ b/site_scons/environ.scons @@ -12,14 +12,20 @@ forward_os_env = { "PATH": os.environ["PATH"], } # Proxying CI environment to child processes & scripts -for env_value_name in ( +variables_to_forward = [ "WORKFLOW_BRANCH_OR_TAG", "DIST_SUFFIX", "HOME", "APPDATA", "PYTHONHOME", "PYTHONNOUSERSITE", -): + "TMP", + "TEMP", +] +if proxy_env := GetOption("proxy_env"): + variables_to_forward.extend(proxy_env.split(",")) + +for env_value_name in variables_to_forward: if environ_value := os.environ.get(env_value_name, None): forward_os_env[env_value_name] = environ_value diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons index 4cb5e35cf..c976fbbe5 100644 --- a/site_scons/extapps.scons +++ b/site_scons/extapps.scons @@ -1,10 +1,23 @@ +from SCons.Errors import UserError + + Import("ENV") from fbt.appmanifest import FlipperAppType appenv = ENV.Clone( - tools=[("fbt_extapps", {"EXT_APPS_WORK_DIR": ENV.subst("${BUILD_DIR}/.extapps")})] + tools=[ + ( + "fbt_extapps", + { + "EXT_APPS_WORK_DIR": ENV.subst( + "${BUILD_DIR}/.extapps", + ) + }, + ), + "fbt_assets", + ] ) appenv.Replace( @@ -83,15 +96,25 @@ if extra_app_list := GetOption("extra_ext_apps"): if appenv["FORCE"]: appenv.AlwaysBuild(extapps["compact"].values()) -Alias(appenv["FIRMWARE_BUILD_CFG"] + "_extapps", extapps["compact"].values()) + +# Deprecation stub +def legacy_app_build_stub(**kw): + raise UserError(f"Target name 'firmware_extapps' is deprecated, use 'faps' instead") + + +appenv.PhonyTarget("firmware_extapps", appenv.Action(legacy_app_build_stub, None)) + + +Alias("faps", extapps["compact"].values()) if appsrc := appenv.subst("$APPSRC"): - app_manifest, fap_file = appenv.GetExtAppFromPath(appsrc) + app_manifest, fap_file, app_validator = appenv.GetExtAppFromPath(appsrc) appenv.PhonyTarget( "launch_app", '${PYTHON3} scripts/runfap.py ${SOURCE} --fap_dst_dir "/ext/apps/${FAP_CATEGORY}"', source=fap_file, FAP_CATEGORY=app_manifest.fap_category, ) + appenv.Alias("launch_app", app_validator) Return("extapps") diff --git a/site_scons/fbt/appmanifest.py b/site_scons/fbt/appmanifest.py index a0ab5e7c6..de7c6b682 100644 --- a/site_scons/fbt/appmanifest.py +++ b/site_scons/fbt/appmanifest.py @@ -23,6 +23,22 @@ class FlipperAppType(Enum): @dataclass class FlipperApplication: + @dataclass + class ExternallyBuiltFile: + path: str + command: str + + @dataclass + class Library: + name: str + fap_include_paths: List[str] = field(default_factory=lambda: ["."]) + sources: List[str] = field(default_factory=lambda: ["*.c*"]) + cflags: List[str] = field(default_factory=list) + cdefines: List[str] = field(default_factory=list) + cincludes: List[str] = field(default_factory=list) + + PRIVATE_FIELD_PREFIX = "_" + appid: str apptype: FlipperAppType name: Optional[str] = "" @@ -38,13 +54,16 @@ class FlipperApplication: sdk_headers: List[str] = field(default_factory=list) # .fap-specific sources: List[str] = field(default_factory=lambda: ["*.c*"]) - fap_version: Tuple[int] = field(default_factory=lambda: (0, 0)) + fap_version: Tuple[int] = field(default_factory=lambda: (0, 1)) fap_icon: Optional[str] = None fap_libs: List[str] = field(default_factory=list) fap_category: str = "" fap_description: str = "" fap_author: str = "" fap_weburl: str = "" + fap_icon_assets: Optional[str] = None + fap_extbuild: List[ExternallyBuiltFile] = field(default_factory=list) + fap_private_libs: List[Library] = field(default_factory=list) # Internally used by fbt _appdir: Optional[object] = None _apppath: Optional[str] = None @@ -88,6 +107,12 @@ class AppManager: ), ) + def ExtFile(*args, **kw): + return FlipperApplication.ExternallyBuiltFile(*args, **kw) + + def Lib(*args, **kw): + return FlipperApplication.Library(*args, **kw) + try: with open(app_manifest_path, "rt") as manifest_file: exec(manifest_file.read()) diff --git a/site_scons/fbt/version.py b/site_scons/fbt/version.py index 1b1c166f2..e7fe2edaf 100644 --- a/site_scons/fbt/version.py +++ b/site_scons/fbt/version.py @@ -3,6 +3,11 @@ import datetime from functools import cache +@cache +def get_git_commit_unix_timestamp(): + return int(subprocess.check_output(["git", "show", "-s", "--format=%ct"])) + + @cache def get_fast_git_version_id(): try: diff --git a/site_scons/site_tools/fbt_assets.py b/site_scons/site_tools/fbt_assets.py index 877948471..f058d15f9 100644 --- a/site_scons/site_tools/fbt_assets.py +++ b/site_scons/site_tools/fbt_assets.py @@ -10,8 +10,8 @@ import subprocess def icons_emitter(target, source, env): target = [ - "compiled/assets_icons.c", - "compiled/assets_icons.h", + target[0].File(env.subst("${ICON_FILE_NAME}.c")), + target[0].File(env.subst("${ICON_FILE_NAME}.h")), ] source = env.GlobRecursive("*.*", env["ICON_SRC_DIR"]) return target, source @@ -99,17 +99,41 @@ def proto_ver_generator(target, source, env): file.write("\n".join(version_file_data)) +def CompileIcons(env, target_dir, source_dir, *, icon_bundle_name="assets_icons"): + # Gathering icons sources + icons_src = env.GlobRecursive("*.png", source_dir) + icons_src += env.GlobRecursive("frame_rate", source_dir) + + icons = env.IconBuilder( + target_dir, + ICON_SRC_DIR=source_dir, + ICON_FILE_NAME=icon_bundle_name, + ) + env.Depends(icons, icons_src) + return icons + + def generate(env): env.SetDefault( ASSETS_COMPILER="${ROOT_DIR.abspath}/scripts/assets.py", NANOPB_COMPILER="${ROOT_DIR.abspath}/lib/nanopb/generator/nanopb_generator.py", ) + env.AddMethod(CompileIcons) + + if not env["VERBOSE"]: + env.SetDefault( + ICONSCOMSTR="\tICONS\t${TARGET}", + PROTOCOMSTR="\tPROTO\t${SOURCE}", + DOLPHINCOMSTR="\tDOLPHIN\t${DOLPHIN_RES_TYPE}", + RESMANIFESTCOMSTR="\tMANIFEST\t${TARGET}", + PBVERCOMSTR="\tPBVER\t${TARGET}", + ) env.Append( BUILDERS={ "IconBuilder": Builder( action=Action( - '${PYTHON3} "${ASSETS_COMPILER}" icons ${ICON_SRC_DIR} ${TARGET.dir}', + '${PYTHON3} "${ASSETS_COMPILER}" icons ${ICON_SRC_DIR} ${TARGET.dir} --filename ${ICON_FILE_NAME}', "${ICONSCOMSTR}", ), emitter=icons_emitter, diff --git a/site_scons/site_tools/fbt_extapps.py b/site_scons/site_tools/fbt_extapps.py index 4b5845305..a1fa77140 100644 --- a/site_scons/site_tools/fbt_extapps.py +++ b/site_scons/site_tools/fbt_extapps.py @@ -6,47 +6,146 @@ import SCons.Warnings import os import pathlib from fbt.elfmanifest import assemble_manifest_data +from fbt.appmanifest import FlipperManifestException from fbt.sdk import SdkCache import itertools +from site_scons.fbt.appmanifest import FlipperApplication + def BuildAppElf(env, app): - work_dir = env.subst("$EXT_APPS_WORK_DIR") + ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR") + app_work_dir = os.path.join(ext_apps_work_dir, app.appid) + + env.VariantDir(app_work_dir, app._appdir, duplicate=False) + + app_env = env.Clone(FAP_SRC_DIR=app._appdir, FAP_WORK_DIR=app_work_dir) + + app_alias = f"fap_{app.appid}" + + # Deprecation stub + legacy_app_taget_name = f"{app_env['FIRMWARE_BUILD_CFG']}_{app.appid}" + + def legacy_app_build_stub(**kw): + raise UserError( + f"Target name '{legacy_app_taget_name}' is deprecated, use '{app_alias}' instead" + ) + + app_env.PhonyTarget(legacy_app_taget_name, Action(legacy_app_build_stub, None)) + + externally_built_files = [] + if app.fap_extbuild: + for external_file_def in app.fap_extbuild: + externally_built_files.append(external_file_def.path) + app_env.Alias(app_alias, external_file_def.path) + app_env.AlwaysBuild( + app_env.Command( + external_file_def.path, + None, + Action( + external_file_def.command, + "" if app_env["VERBOSE"] else "\tEXTCMD\t${TARGET}", + ), + ) + ) + + if app.fap_icon_assets: + app_env.CompileIcons( + app_env.Dir(app_work_dir), + app._appdir.Dir(app.fap_icon_assets), + icon_bundle_name=f"{app.appid}_icons", + ) + + private_libs = [] + + for lib_def in app.fap_private_libs: + lib_src_root_path = os.path.join(app_work_dir, "lib", lib_def.name) + app_env.AppendUnique( + CPPPATH=list( + app_env.Dir(lib_src_root_path).Dir(incpath).srcnode() + for incpath in lib_def.fap_include_paths + ), + ) + + lib_sources = list( + itertools.chain.from_iterable( + app_env.GlobRecursive(source_type, lib_src_root_path) + for source_type in lib_def.sources + ) + ) + if len(lib_sources) == 0: + raise UserError(f"No sources gathered for private library {lib_def}") + + private_lib_env = app_env.Clone() + private_lib_env.AppendUnique( + CCFLAGS=[ + *lib_def.cflags, + ], + CPPDEFINES=lib_def.cdefines, + CPPPATH=list( + os.path.join(app._appdir.path, cinclude) + for cinclude in lib_def.cincludes + ), + ) + + lib = private_lib_env.StaticLibrary( + os.path.join(app_work_dir, lib_def.name), + lib_sources, + ) + private_libs.append(lib) - app_alias = f"{env['FIRMWARE_BUILD_CFG']}_{app.appid}" - app_original_elf = os.path.join(work_dir, f"{app.appid}_d") app_sources = list( itertools.chain.from_iterable( - env.GlobRecursive(source_type, os.path.join(work_dir, app._appdir.relpath)) + app_env.GlobRecursive( + source_type, + app_work_dir, + exclude="lib", + ) for source_type in app.sources ) ) - app_elf_raw = env.Program( - app_original_elf, - app_sources, - APP_ENTRY=app.entry_point, - LIBS=env["LIBS"] + app.fap_libs, + + app_env.Append( + LIBS=[*app.fap_libs, *private_libs], + CPPPATH=env.Dir(app_work_dir), ) - app_elf_dump = env.ObjDump(app_elf_raw) - env.Alias(f"{app_alias}_list", app_elf_dump) + app_elf_raw = app_env.Program( + os.path.join(app_work_dir, f"{app.appid}_d"), + app_sources, + APP_ENTRY=app.entry_point, + ) - app_elf_augmented = env.EmbedAppMetadata( - os.path.join(env.subst("$PLUGIN_ELF_DIR"), app.appid), + app_env.Clean(app_elf_raw, [*externally_built_files, app_env.Dir(app_work_dir)]) + + app_elf_dump = app_env.ObjDump(app_elf_raw) + app_env.Alias(f"{app_alias}_list", app_elf_dump) + + app_elf_augmented = app_env.EmbedAppMetadata( + os.path.join(ext_apps_work_dir, app.appid), app_elf_raw, APP=app, ) - env.Depends(app_elf_augmented, [env["SDK_DEFINITION"], env.Value(app)]) - if app.fap_icon: - env.Depends( - app_elf_augmented, - env.File(f"{app._apppath}/{app.fap_icon}"), - ) - env.Alias(app_alias, app_elf_augmented) + manifest_vals = { + k: v + for k, v in vars(app).items() + if not k.startswith(FlipperApplication.PRIVATE_FIELD_PREFIX) + } - app_elf_import_validator = env.ValidateAppImports(app_elf_augmented) - env.AlwaysBuild(app_elf_import_validator) + app_env.Depends( + app_elf_augmented, + [app_env["SDK_DEFINITION"], app_env.Value(manifest_vals)], + ) + if app.fap_icon: + app_env.Depends( + app_elf_augmented, + app_env.File(f"{app._apppath}/{app.fap_icon}"), + ) + + app_elf_import_validator = app_env.ValidateAppImports(app_elf_augmented) + app_env.AlwaysBuild(app_elf_import_validator) + app_env.Alias(app_alias, app_elf_import_validator) return (app_elf_augmented, app_elf_raw, app_elf_import_validator) @@ -92,22 +191,32 @@ def GetExtAppFromPath(env, app_dir): appmgr = env["APPMGR"] app = None - for dir_part in reversed(pathlib.Path(app_dir).parts): - if app := appmgr.find_by_appdir(dir_part): - break + try: + # Maybe used passed an appid? + app = appmgr.get(app_dir) + except FlipperManifestException as _: + # Look up path components in known app dits + for dir_part in reversed(pathlib.Path(app_dir).parts): + if app := appmgr.find_by_appdir(dir_part): + break + if not app: raise UserError(f"Failed to resolve application for given APPSRC={app_dir}") app_elf = env["_extapps"]["compact"].get(app.appid, None) if not app_elf: - raise UserError(f"No external app found for {app.appid}") + raise UserError( + f"Application {app.appid} is not configured for building as external" + ) - return (app, app_elf[0]) + app_validator = env["_extapps"]["validators"].get(app.appid, None) + + return (app, app_elf[0], app_validator[0]) def generate(env, **kw): env.SetDefault(EXT_APPS_WORK_DIR=kw.get("EXT_APPS_WORK_DIR")) - env.VariantDir(env.subst("$EXT_APPS_WORK_DIR"), env.Dir("#"), duplicate=False) + # env.VariantDir(env.subst("$EXT_APPS_WORK_DIR"), env.Dir("#"), duplicate=False) env.AddMethod(BuildAppElf) env.AddMethod(GetExtAppFromPath) @@ -138,7 +247,7 @@ def generate(env, **kw): ), Action( validate_app_imports, - None, # "$APPCHECK_COMSTR", + "$APPCHECK_COMSTR", ), ], suffix=".impsyms",