Kaynağa Gözat

Quac: Merge fixes and improvements

WillyJL 7 ay önce
ebeveyn
işleme
bbf43fd878

+ 1 - 0
quac/.github/FUNDING.yml

@@ -0,0 +1 @@
+buy_me_a_coffee: rdefeo

+ 1 - 1
quac/.github/workflows/build.yml

@@ -34,7 +34,7 @@ jobs:
         with:
           sdk-channel: ${{ matrix.sdk-channel }}
       - name: Upload app artifacts
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v4
         with:
           # See ufbt action docs for other output variables
           name: ${{ github.event.repository.name }}-${{ steps.build-app.outputs.suffix }}

+ 1 - 0
quac/.gitignore

@@ -1,6 +1,7 @@
 dist/*
 .vscode
 .clang-format
+.clangd
 .editorconfig
 .env
 .ufbt

+ 14 - 14
quac/actions/action.c

@@ -7,7 +7,7 @@
 
 void action_ql_resolve(
     void* context,
-    FuriString* action_path,
+    const FuriString* action_path,
     FuriString* new_path,
     FuriString* error) {
     UNUSED(error);
@@ -22,18 +22,19 @@ void action_ql_resolve(
         }
 
         furi_string_reset(new_path);
-
-        size_t ret = 0;
-        do {
-            uint8_t buffer[65] = {0};
-            ret = storage_file_read(file_link, buffer, sizeof(buffer) - 1);
-            for(size_t i = 0; i < ret; i++) {
-                furi_string_push_back(new_path, buffer[i]);
-            }
-        } while(ret > 0);
-
+        const size_t file_size = storage_file_size(file_link);
+        size_t bytes_read = 0;
+        while(bytes_read < file_size) {
+            char buffer[65] = {0};
+            const size_t chunk_size = MIN(file_size - bytes_read, sizeof(buffer) - 1);
+            size_t chunk_read = storage_file_read(file_link, buffer, chunk_size);
+            if(chunk_read != chunk_size) break;
+            bytes_read += chunk_read;
+            furi_string_cat_str(new_path, buffer);
+        }
         furi_string_trim(new_path);
-        if(!furi_string_size(new_path)) {
+
+        if(bytes_read != file_size) {
             ACTION_SET_ERROR(
                 "Quac Link: Error reading link file %s", furi_string_get_cstr(action_path));
             break;
@@ -52,8 +53,7 @@ void action_ql_resolve(
 void action_tx(void* context, Item* item, FuriString* error) {
     // FURI_LOG_I(TAG, "action_run: %s : %s", furi_string_get_cstr(item->name), item->ext);
 
-    FuriString* path = furi_string_alloc();
-    furi_string_set(path, item->path);
+    FuriString* path = furi_string_alloc_set(item->path);
     if(item->is_link) {
         // This is a Quac link, open the file and pull the real filename
         action_ql_resolve(context, item->path, path, error);

+ 16 - 23
quac/actions/action_subghz.c

@@ -87,9 +87,9 @@ void action_subghz_need_save_callback(void* context) {
 static void action_subghz_raw_end_callback(void* context) {
     FURI_LOG_I(TAG, "Stopping TX on RAW");
     furi_assert(context);
-    App* app = context;
+    FuriThread* thread = context;
 
-    app->raw_file_is_tx = false;
+    furi_thread_flags_set(furi_thread_get_id(thread), 0);
 }
 
 void action_subghz_tx(void* context, FuriString* action_path, FuriString* error) {
@@ -108,11 +108,10 @@ void action_subghz_tx(void* context, FuriString* action_path, FuriString* error)
 
     FuriString* preset_name = furi_string_alloc();
     FuriString* protocol_name = furi_string_alloc();
+    bool is_raw = false;
 
     subghz_custom_btns_reset();
 
-    app->raw_file_is_tx = false;
-
     FuriString* temp_str;
     temp_str = furi_string_alloc();
     uint32_t temp_data32;
@@ -197,6 +196,7 @@ void action_subghz_tx(void* context, FuriString* action_path, FuriString* error)
         if(!strcmp(furi_string_get_cstr(protocol_name), "RAW")) {
             subghz_protocol_raw_gen_fff_data(
                 fff_data, file_name, subghz_txrx_radio_device_get_name(txrx));
+            is_raw = true;
         } else {
             stream_copy_full(
                 flipper_format_get_raw_stream(fff_data_file),
@@ -218,35 +218,28 @@ void action_subghz_tx(void* context, FuriString* action_path, FuriString* error)
     flipper_format_file_close(fff_data_file);
     flipper_format_free(fff_data_file);
 
-    if(subghz_txrx_tx_start(txrx, subghz_txrx_get_fff_data(txrx)) != SubGhzTxRxStartTxStateOk) {
-        FURI_LOG_E(TAG, "Failed to start TX");
+    if(is_raw) {
+        subghz_txrx_set_raw_file_encoder_worker_callback_end(
+            txrx, action_subghz_raw_end_callback, furi_thread_get_current());
     }
 
-    bool skip_extra_stop = false;
-    FURI_LOG_D(TAG, "Checking if file is RAW...");
-    if(!strcmp(furi_string_get_cstr(protocol_name), "RAW")) {
-        subghz_txrx_set_raw_file_encoder_worker_callback_end(
-            txrx, action_subghz_raw_end_callback, app);
-        app->raw_file_is_tx = true;
-        skip_extra_stop = true;
+    if(subghz_txrx_tx_start(txrx, subghz_txrx_get_fff_data(txrx)) != SubGhzTxRxStartTxStateOk) {
+        FURI_LOG_E(TAG, "Failed to start TX");
     }
-    do {
-        furi_delay_ms(1);
-    } while(app->raw_file_is_tx);
 
-    if(!app->raw_file_is_tx && !skip_extra_stop) {
-        // TODO: Should this be based on a Setting?
-        furi_delay_ms(1500);
-        subghz_txrx_stop(txrx);
+    if(is_raw) {
+        // Wait for action_subghz_raw_end_callback() to notify us
+        furi_thread_flags_wait(0, FuriFlagWaitAll, FuriWaitForever);
     } else {
         // TODO: Should this be based on a Setting?
-        furi_delay_ms(50);
-        subghz_txrx_stop(txrx);
+        furi_delay_ms(1500);
     }
-    skip_extra_stop = false;
 
     FURI_LOG_I(TAG, "SUBGHZ: Action complete.");
 
+    // This will call need_save_callback, if necessary
+    subghz_txrx_stop(txrx);
+
     subghz_custom_btns_reset();
 
     subghz_txrx_free(txrx);

+ 0 - 1
quac/quac.h

@@ -49,7 +49,6 @@ typedef struct App {
     ItemsView* items_view;
     int depth;
     int selected_item;
-    bool raw_file_is_tx;
 
     FuriString* temp_str; // used for renames/etc
     char temp_cstr[MAX_NAME_LEN]; // used for renames/etc