rdefeo 1 год назад
Родитель
Сommit
4b513e621c
13 измененных файлов с 110 добавлено и 6 удалено
  1. 17 0
      .clangd
  2. 2 0
      actions/action.c
  3. 1 0
      actions/action_i.h
  4. 48 0
      actions/action_ibutton.c
  5. BIN
      images/iButton_10px.png
  6. 2 0
      item.c
  7. 3 2
      item.h
  8. 8 4
      quac.h
  9. 12 0
      quac_settings.c
  10. 1 0
      scenes/scene_items.c
  11. 14 0
      scenes/scene_settings.c
  12. 1 0
      views/action_menu.c
  13. 1 0
      views/action_menu.h

+ 17 - 0
.clangd

@@ -0,0 +1,17 @@
+CompileFlags:
+    Add: 
+        - -Wno-unknown-warning-option
+        - -Wno-format
+    Remove: 
+        - -mword-relocations
+
+Diagnostics:
+    ClangTidy:
+        FastCheckFilter: None
+
+---
+
+If:
+    PathMatch: .*\.h
+Diagnostics:
+    UnusedIncludes: None

+ 2 - 0
actions/action.c

@@ -14,6 +14,8 @@ void action_tx(void* context, Item* item, FuriString* error) {
         action_rfid_tx(context, item->path, error);
     } else if(!strcmp(item->ext, ".nfc")) {
         action_nfc_tx(context, item->path, error);
+    } else if(!strcmp(item->ext, ".ibtn")) {
+        action_ibutton_tx(context, item->path, error);
     } else if(!strcmp(item->ext, ".qpl")) {
         action_qpl_tx(context, item->path, error);
     } else {

+ 1 - 0
actions/action_i.h

@@ -9,4 +9,5 @@ void action_subghz_tx(void* context, const FuriString* action_path, FuriString*
 void action_rfid_tx(void* context, const FuriString* action_path, FuriString* error);
 void action_ir_tx(void* context, const FuriString* action_path, FuriString* error);
 void action_nfc_tx(void* context, const FuriString* action_path, FuriString* error);
+void action_ibutton_tx(void* context, const FuriString* action_path, FuriString* error);
 void action_qpl_tx(void* context, const FuriString* action_path, FuriString* error);

+ 48 - 0
actions/action_ibutton.c

@@ -0,0 +1,48 @@
+// Methods for iButton transmission
+
+#include <furi.h>
+#include <furi_hal.h>
+
+#include <ibutton/ibutton_key.h>
+#include <ibutton/ibutton_worker.h>
+#include <ibutton/ibutton_protocols.h>
+
+#include "action_i.h"
+#include "quac.h"
+
+void action_ibutton_tx(void* context, const FuriString* action_path, FuriString* error) {
+    App* app = context;
+    const char* cpath = furi_string_get_cstr(action_path);
+
+    FURI_LOG_I(TAG, "iButton: Tx %s", cpath);
+
+    iButtonProtocols* protocols = ibutton_protocols_alloc();
+    iButtonKey* key = ibutton_key_alloc(ibutton_protocols_get_max_data_size(protocols));
+
+    const bool success = ibutton_protocols_load(protocols, key, cpath);
+    if(!success) {
+        FURI_LOG_E(TAG, "Error loading iButton file %s", cpath);
+        ACTION_SET_ERROR("Error loading %s", cpath);
+    } else {
+        FURI_LOG_I(TAG, "iButton: Starting...");
+        iButtonWorker* worker = ibutton_worker_alloc(protocols);
+        ibutton_worker_start_thread(worker);
+
+        ibutton_worker_emulate_start(worker, key);
+
+        int16_t time_ms = app->settings.ibutton_duration;
+        const int16_t interval_ms = 100;
+        while(time_ms > 0) {
+            furi_delay_ms(interval_ms);
+            time_ms -= interval_ms;
+        }
+
+        FURI_LOG_I(TAG, "iButton: Done");
+        ibutton_worker_stop(worker);
+        ibutton_worker_stop_thread(worker);
+        ibutton_worker_free(worker);
+    }
+
+    ibutton_key_free(key);
+    ibutton_protocols_free(protocols);
+}

BIN
images/iButton_10px.png


+ 2 - 0
item.c

@@ -163,6 +163,8 @@ ItemType item_get_item_type_from_extension(const char* ext) {
         type = Item_IR;
     } else if(!strcmp(ext, ".nfc")) {
         type = Item_NFC;
+    } else if(!strcmp(ext, ".ibtn")) {
+        type = Item_iButton;
     } else if(!strcmp(ext, ".qpl")) {
         type = Item_Playlist;
     }

+ 3 - 2
item.h

@@ -4,7 +4,7 @@
 
 // Max length of a filename, final path element only
 #define MAX_NAME_LEN 64
-#define MAX_EXT_LEN 6
+#define MAX_EXT_LEN  6
 
 /** Defines an individual item action or item group. Each object contains
  * the relevant file and type information needed to both render correctly
@@ -16,6 +16,7 @@ typedef enum {
     Item_RFID,
     Item_IR,
     Item_NFC,
+    Item_iButton,
     Item_Playlist,
     Item_Group,
     Item_Settings,
@@ -62,4 +63,4 @@ void item_prettify_name(FuriString* name);
 /** Return the ItemType enum for the given extension
  * @param   ext     File extension
 */
-ItemType item_get_item_type_from_extension(const char* ext);
+ItemType item_get_item_type_from_extension(const char* ext);

+ 8 - 4
quac.h

@@ -16,7 +16,7 @@
 #include "views/action_menu.h"
 #include "item.h"
 
-#define QUAC_NAME "Quac!"
+#define QUAC_NAME    "Quac!"
 #define QUAC_VERSION "v0.6.3"
 #define QUAC_ABOUT                                    \
     "Quick Action remote control\n" QUAC_VERSION "\n" \
@@ -25,9 +25,12 @@
 
 // Location of our actions and folders
 #define QUAC_SETTINGS_FILENAME ".quac.conf"
-#define QUAC_SETTINGS_PATH APP_DATA_PATH(QUAC_SETTINGS_FILENAME)
+#define QUAC_SETTINGS_PATH     APP_DATA_PATH(QUAC_SETTINGS_FILENAME)
 
-typedef enum { QUAC_APP_PORTRAIT, QUAC_APP_LANDSCAPE } QuacAppLayout;
+typedef enum {
+    QUAC_APP_PORTRAIT,
+    QUAC_APP_LANDSCAPE
+} QuacAppLayout;
 
 typedef struct App {
     SceneManager* scene_manager;
@@ -56,6 +59,7 @@ typedef struct App {
         bool show_headers; // Defaults to True
         uint32_t rfid_duration; // Defaults to 2500 ms
         uint32_t nfc_duration; // Defaults to 1000 ms
+        uint32_t ibutton_duration; // Defaults to 1000 ms
         uint32_t subghz_repeat; // Defaults to 10, just like the CLI
         bool subghz_use_ext_antenna; // Defaults to False
         bool ir_use_ext_module; // Defaults to False
@@ -65,4 +69,4 @@ typedef struct App {
 } App;
 
 App* app_alloc();
-void app_free(App* app);
+void app_free(App* app);

+ 12 - 0
quac_settings.c

@@ -12,6 +12,7 @@ void quac_set_default_settings(App* app) {
     app->settings.show_headers = true;
     app->settings.rfid_duration = 2500;
     app->settings.nfc_duration = 1000;
+    app->settings.ibutton_duration = 1000;
     app->settings.subghz_repeat = 10;
     app->settings.subghz_use_ext_antenna = false;
     app->settings.ir_use_ext_module = false;
@@ -83,6 +84,12 @@ void quac_load_settings(App* app) {
             app->settings.nfc_duration = temp_data32;
         }
 
+        if(!flipper_format_read_uint32(fff_settings, "iButton Duration", &temp_data32, 1)) {
+            FURI_LOG_W(TAG, "SETTINGS: Missing 'iButton Duration'");
+        } else {
+            app->settings.ibutton_duration = temp_data32;
+        }
+
         if(!flipper_format_read_uint32(fff_settings, "SubGHz Repeat", &temp_data32, 1)) {
             FURI_LOG_W(TAG, "SETTINGS: Missing 'SubGHz Repeat'");
         } else {
@@ -158,6 +165,11 @@ void quac_save_settings(App* app) {
             FURI_LOG_E(TAG, "SETTINGS: Failed to write 'NFC Duration'");
             break;
         }
+        if(!flipper_format_write_uint32(
+               fff_settings, "iButton Duration", &app->settings.ibutton_duration, 1)) {
+            FURI_LOG_E(TAG, "SETTINGS: Failed to write 'iButton Duration'");
+            break;
+        }
         if(!flipper_format_write_uint32(
                fff_settings, "SubGHz Repeat", &app->settings.subghz_repeat, 1)) {
             FURI_LOG_E(TAG, "SETTINGS: Failed to write 'SubGHz Repeat'");

+ 1 - 0
scenes/scene_items.c

@@ -19,6 +19,7 @@ static const ActionMenuItemType ItemToMenuItem[] = {
     [Item_RFID] = ActionMenuItemTypeRFID,
     [Item_IR] = ActionMenuItemTypeIR,
     [Item_NFC] = ActionMenuItemTypeNFC,
+    [Item_iButton] = ActionMenuItemTypeiButton,
     [Item_Playlist] = ActionMenuItemTypePlaylist,
     [Item_Group] = ActionMenuItemTypeGroup,
     [Item_Settings] = ActionMenuItemTypeSettings,

+ 14 - 0
scenes/scene_settings.c

@@ -99,6 +99,13 @@ static void scene_settings_nfc_duration_changed(VariableItem* item) {
     app->settings.nfc_duration = duration_value[index];
 }
 
+static void scene_settings_ibutton_duration_changed(VariableItem* item) {
+    App* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+    variable_item_set_current_value_text(item, duration_text[index]);
+    app->settings.ibutton_duration = duration_value[index];
+}
+
 static void scene_settings_subghz_repeat_changed(VariableItem* item) {
     App* app = variable_item_get_context(item);
     uint8_t index = variable_item_get_current_value_index(item);
@@ -171,6 +178,13 @@ void scene_settings_on_enter(void* context) {
     variable_item_set_current_value_index(item, value_index);
     variable_item_set_current_value_text(item, duration_text[value_index]);
 
+    item = variable_item_list_add(
+        vil, "iButton Duration", V_DURATION_COUNT, scene_settings_ibutton_duration_changed, app);
+    value_index =
+        value_index_uint32(app->settings.ibutton_duration, duration_value, V_DURATION_COUNT);
+    variable_item_set_current_value_index(item, value_index);
+    variable_item_set_current_value_text(item, duration_text[value_index]);
+
     item = variable_item_list_add(
         vil, "SubGHz Repeat", V_REPEAT_COUNT, scene_settings_subghz_repeat_changed, app);
     value_index = value_index_uint32(app->settings.subghz_repeat, repeat_value, V_REPEAT_COUNT);

+ 1 - 0
views/action_menu.c

@@ -25,6 +25,7 @@ static const Icon* ActionMenuIcons[] = {
     [ActionMenuItemTypeRFID] = &I_RFID_10px,
     [ActionMenuItemTypeIR] = &I_IR_10px,
     [ActionMenuItemTypeNFC] = &I_NFC_10px,
+    [ActionMenuItemTypeiButton] = &I_iButton_10px,
     [ActionMenuItemTypePlaylist] = &I_Playlist_10px,
     [ActionMenuItemTypeGroup] = &I_Directory_10px,
     [ActionMenuItemTypeSettings] = &I_Settings_10px,

+ 1 - 0
views/action_menu.h

@@ -22,6 +22,7 @@ typedef enum {
     ActionMenuItemTypeRFID,
     ActionMenuItemTypeIR,
     ActionMenuItemTypeNFC,
+    ActionMenuItemTypeiButton,
     ActionMenuItemTypePlaylist,
     ActionMenuItemTypeGroup,
     ActionMenuItemTypeSettings,