Ver Fonte

basic NFC support

rdefeo há 1 ano atrás
pai
commit
560e958536
12 ficheiros alterados com 132 adições e 51 exclusões
  1. 2 0
      actions/action.c
  2. 1 0
      actions/action_i.h
  3. 45 0
      actions/action_nfc.c
  4. 14 9
      actions/action_qpl.c
  5. 2 0
      item.c
  6. 1 0
      item.h
  7. 1 0
      quac.h
  8. 40 33
      quac_settings.c
  9. 1 0
      scenes/scene_items.c
  10. 23 9
      scenes/scene_settings.c
  11. 1 0
      views/action_menu.c
  12. 1 0
      views/action_menu.h

+ 2 - 0
actions/action.c

@@ -12,6 +12,8 @@ void action_tx(void* context, Item* item, FuriString* error) {
         action_ir_tx(context, item->path, error);
     } else if(!strcmp(item->ext, ".rfid")) {
         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, ".qpl")) {
         action_qpl_tx(context, item->path, error);
     } else {

+ 1 - 0
actions/action_i.h

@@ -8,4 +8,5 @@
 void action_subghz_tx(void* context, const FuriString* action_path, FuriString* error);
 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_qpl_tx(void* context, const FuriString* action_path, FuriString* error);

+ 45 - 0
actions/action_nfc.c

@@ -0,0 +1,45 @@
+// Methods for NFC transmission
+
+// nfc
+#include <furi.h>
+#include <furi_hal.h>
+#include <nfc/nfc.h>
+#include <nfc/nfc_device.h>
+#include <nfc/nfc_listener.h>
+
+#include "action_i.h"
+#include "quac.h"
+
+void action_nfc_tx(void* context, const FuriString* action_path, FuriString* error) {
+    App* app = context;
+
+    FURI_LOG_I(TAG, "NFC: Tx %s", furi_string_get_cstr(action_path));
+    Nfc* nfc = nfc_alloc();
+    NfcDevice* device = nfc_device_alloc();
+
+    if(nfc_device_load(device, furi_string_get_cstr(action_path))) {
+        NfcProtocol protocol = nfc_device_get_protocol(device);
+        FURI_LOG_I(TAG, "NFC: Protocol %s", nfc_device_get_protocol_name(protocol));
+        NfcListener* listener =
+            nfc_listener_alloc(nfc, protocol, nfc_device_get_data(device, protocol));
+        FURI_LOG_I(TAG, "NFC: Starting...");
+        nfc_listener_start(listener, NULL, NULL);
+
+        int16_t time_ms = app->settings.nfc_duration;
+        const int16_t interval_ms = 100;
+        while(time_ms > 0) {
+            furi_delay_ms(interval_ms);
+            time_ms -= interval_ms;
+        }
+
+        FURI_LOG_I(TAG, "NFC: Done");
+        nfc_listener_stop(listener);
+        nfc_listener_free(listener);
+    } else {
+        FURI_LOG_E(TAG, "NFC: Failed to load %s", furi_string_get_cstr(action_path));
+        ACTION_SET_ERROR("Failed to load %s", furi_string_get_cstr(action_path));
+    }
+    nfc_device_clear(device); // probably not needed?
+    nfc_free(nfc);
+    nfc_device_free(device);
+}

+ 14 - 9
actions/action_qpl.c

@@ -30,8 +30,9 @@
 void action_qpl_tx(void* context, const FuriString* action_path, FuriString* error) {
     App* app = context;
 
-    // Save the current RFID Duration, in case it is changed during playback
+    // Save the current RFID and NFC Durations, in case the are changed during playback
     uint32_t orig_rfid_duration = app->settings.rfid_duration;
+    uint32_t orig_nfc_duration = app->settings.nfc_duration;
 
     FuriString* buffer;
     buffer = furi_string_alloc();
@@ -83,13 +84,6 @@ void action_qpl_tx(void* context, const FuriString* action_path, FuriString* err
                     break;
                 }
 
-                // FURI_LOG_I(TAG, "Still checking for commands...");
-                // FURI_LOG_I(
-                //     TAG,
-                //     "args_temp: '%s', buffer: '%s'",
-                //     furi_string_get_cstr(args_tmp),
-                //     furi_string_get_cstr(buffer));
-
                 // First token wasn't "pause", so maybe args_tmp is a .rfid filename followed
                 // by a transmit duration in ms in buffer
                 // Note: Not using path_extract_extension since it expects to find slashes in the
@@ -101,13 +95,20 @@ void action_qpl_tx(void* context, const FuriString* action_path, FuriString* err
                 }
 
                 // FURI_LOG_I(TAG, " - Found extension of %s", ext);
-                uint32_t rfid_duration = 0;
+
                 if(!strcmp(ext, ".rfid")) {
+                    uint32_t rfid_duration = 0;
                     // FURI_LOG_I(TAG, "RFID file with duration");
                     if(sscanf(furi_string_get_cstr(buffer), "%lu", &rfid_duration) == 1) {
                         FURI_LOG_I(TAG, "RFID duration = %lu", rfid_duration);
                         app->settings.rfid_duration = rfid_duration;
                     }
+                } else if(!strcmp(ext, ".nfc")) {
+                    uint32_t nfc_duration = 0;
+                    if(sscanf(furi_string_get_cstr(buffer), "%lu", &nfc_duration) == 1) {
+                        FURI_LOG_I(TAG, "NFC duration = %lu", nfc_duration);
+                        app->settings.nfc_duration = nfc_duration;
+                    }
                 }
 
             } while(false);
@@ -140,6 +141,10 @@ void action_qpl_tx(void* context, const FuriString* action_path, FuriString* err
                 app->settings.rfid_duration = orig_rfid_duration;
             } else if(!strcmp(ext, ".ir")) {
                 action_ir_tx(context, buffer, error);
+            } else if(!strcmp(ext, ".nfc")) {
+                action_nfc_tx(context, buffer, error);
+                // Reset our default duration back - in case it was changed during playback
+                app->settings.nfc_duration = orig_nfc_duration;
             } else if(!strcmp(ext, ".qpl")) {
                 ACTION_SET_ERROR("Playlist: Can't call playlist from playlist");
             } else {

+ 2 - 0
item.c

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

+ 1 - 0
item.h

@@ -15,6 +15,7 @@ typedef enum {
     Item_SubGhz,
     Item_RFID,
     Item_IR,
+    Item_NFC,
     Item_Playlist,
     Item_Group,
     Item_Settings,

+ 1 - 0
quac.h

@@ -59,6 +59,7 @@ typedef struct App {
         bool show_icons; // Defaults to True
         bool show_headers; // Defaults to True
         uint32_t rfid_duration; // Defaults to 2500 ms
+        uint32_t nfc_duration; // Defaults to 1000 ms
         bool subghz_use_ext_antenna; // Defaults to False
         bool show_hidden; // Defaults to False
     } settings;

+ 40 - 33
quac_settings.c

@@ -7,10 +7,11 @@
 #define QUAC_SETTINGS_FILE_VERSION 1
 
 void quac_set_default_settings(App* app) {
-    app->settings.rfid_duration = 2500;
     app->settings.layout = QUAC_APP_LANDSCAPE;
     app->settings.show_icons = true;
     app->settings.show_headers = true;
+    app->settings.rfid_duration = 2500;
+    app->settings.nfc_duration = 1000;
     app->settings.subghz_use_ext_antenna = false;
     app->settings.show_hidden = false;
 }
@@ -21,11 +22,13 @@ void quac_load_settings(App* app) {
     temp_str = furi_string_alloc();
     uint32_t temp_data32 = 0;
 
+    // Initialize settings to the defaults
+    quac_set_default_settings(app);
+
     FURI_LOG_I(TAG, "SETTINGS: Reading: %s", QUAC_SETTINGS_PATH);
-    bool successful = false;
     do {
         if(!flipper_format_file_open_existing(fff_settings, QUAC_SETTINGS_PATH)) {
-            FURI_LOG_I(TAG, "SETTINGS: File not found, loading defaults");
+            FURI_LOG_I(TAG, "SETTINGS: File not found, using defaults");
             break;
         }
 
@@ -43,55 +46,54 @@ void quac_load_settings(App* app) {
 
         // Now read actual values we care about
         if(!flipper_format_read_string(fff_settings, "Layout", temp_str)) {
-            FURI_LOG_E(TAG, "SETTINGS: Missing Layout");
-            break;
-        }
-        if(!strcmp(furi_string_get_cstr(temp_str), "Landscape")) {
-            app->settings.layout = QUAC_APP_LANDSCAPE;
-        } else if(!strcmp(furi_string_get_cstr(temp_str), "Portrait")) {
-            app->settings.layout = QUAC_APP_PORTRAIT;
+            FURI_LOG_W(TAG, "SETTINGS: Missing Layout");
         } else {
-            FURI_LOG_E(TAG, "SETTINGS: Invalid Layout");
-            break;
+            if(!strcmp(furi_string_get_cstr(temp_str), "Landscape")) {
+                app->settings.layout = QUAC_APP_LANDSCAPE;
+            } else if(!strcmp(furi_string_get_cstr(temp_str), "Portrait")) {
+                app->settings.layout = QUAC_APP_PORTRAIT;
+            } else {
+                FURI_LOG_E(TAG, "SETTINGS: Invalid Layout");
+            }
         }
 
         if(!flipper_format_read_uint32(fff_settings, "Show Icons", &temp_data32, 1)) {
-            FURI_LOG_E(TAG, "SETTINGS: Missing 'Show Icons'");
-            break;
+            FURI_LOG_W(TAG, "SETTINGS: Missing 'Show Icons'");
+        } else {
+            app->settings.show_icons = (temp_data32 == 0) ? false : true;
         }
-        app->settings.show_icons = (temp_data32 == 0) ? false : true;
 
         if(!flipper_format_read_uint32(fff_settings, "Show Headers", &temp_data32, 1)) {
-            FURI_LOG_E(TAG, "SETTINGS: Missing 'Show Headers'");
-            break;
+            FURI_LOG_W(TAG, "SETTINGS: Missing 'Show Headers'");
+        } else {
+            app->settings.show_headers = (temp_data32 == 1) ? true : false;
         }
-        app->settings.show_headers = (temp_data32 == 1) ? true : false;
 
         if(!flipper_format_read_uint32(fff_settings, "RFID Duration", &temp_data32, 1)) {
-            FURI_LOG_E(TAG, "SETTINGS: Missing 'RFID Duration'");
-            break;
+            FURI_LOG_W(TAG, "SETTINGS: Missing 'RFID Duration'");
+        } else {
+            app->settings.rfid_duration = temp_data32;
+        }
+
+        if(!flipper_format_read_uint32(fff_settings, "NFC Duration", &temp_data32, 1)) {
+            FURI_LOG_W(TAG, "SETTINGS: Missing 'NFC Duration'");
+        } else {
+            app->settings.nfc_duration = temp_data32;
         }
-        app->settings.rfid_duration = temp_data32;
 
         if(!flipper_format_read_uint32(fff_settings, "SubGHz Ext Antenna", &temp_data32, 1)) {
-            FURI_LOG_E(TAG, "SETTINGS: Missing 'SubGHz Ext Antenna'");
-            break;
+            FURI_LOG_W(TAG, "SETTINGS: Missing 'SubGHz Ext Antenna'");
+        } else {
+            app->settings.subghz_use_ext_antenna = (temp_data32 == 1) ? true : false;
         }
-        app->settings.subghz_use_ext_antenna = (temp_data32 == 1) ? true : false;
 
         if(!flipper_format_read_uint32(fff_settings, "Show Hidden", &temp_data32, 1)) {
-            FURI_LOG_E(TAG, "SETTINGS: Missing 'Show Hidden'");
-            break;
+            FURI_LOG_W(TAG, "SETTINGS: Missing 'Show Hidden'");
+        } else {
+            app->settings.show_hidden = (temp_data32 == 1) ? true : false;
         }
-        app->settings.show_hidden = (temp_data32 == 1) ? true : false;
-
-        successful = true;
     } while(false);
 
-    if(!successful) {
-        quac_set_default_settings(app);
-    }
-
     furi_string_free(temp_str);
     flipper_format_free(fff_settings);
 }
@@ -137,6 +139,11 @@ void quac_save_settings(App* app) {
             FURI_LOG_E(TAG, "SETTINGS: Failed to write 'RFID Duration'");
             break;
         }
+        if(!flipper_format_write_uint32(
+               fff_settings, "NFC Duration", &app->settings.nfc_duration, 1)) {
+            FURI_LOG_E(TAG, "SETTINGS: Failed to write 'NFC Duration'");
+            break;
+        }
         temp_data32 = app->settings.subghz_use_ext_antenna ? 1 : 0;
         if(!flipper_format_write_uint32(fff_settings, "SubGHz Ext Antenna", &temp_data32, 1)) {
             FURI_LOG_E(TAG, "SETTINGS: Failed to write 'SubGHz Ext Antenna'");

+ 1 - 0
scenes/scene_items.c

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

+ 23 - 9
scenes/scene_settings.c

@@ -19,6 +19,7 @@ typedef enum {
     SceneSettingsIcons,
     SceneSettingsHeaders,
     SceneSettingsRFIDDuration,
+    SceneSettingsNFCDuration,
     SceneSettingsSubGHzExtAnt,
     SceneSettingsHidden,
     SceneSettingsAbout
@@ -30,8 +31,8 @@ static const uint32_t layout_value[2] = {QUAC_APP_PORTRAIT, QUAC_APP_LANDSCAPE};
 static const char* const show_offon_text[2] = {"OFF", "ON"};
 static const uint32_t show_offon_value[2] = {false, true};
 
-#define V_RFID_DURATION_COUNT 8
-static const char* const rfid_duration_text[V_RFID_DURATION_COUNT] = {
+#define V_DURATION_COUNT 8
+static const char* const duration_text[V_DURATION_COUNT] = {
     "500 ms",
     "1 sec",
     "1.5 sec",
@@ -41,7 +42,7 @@ static const char* const rfid_duration_text[V_RFID_DURATION_COUNT] = {
     "5 sec",
     "10 sec",
 };
-static const uint32_t rfid_duration_value[V_RFID_DURATION_COUNT] = {
+static const uint32_t duration_value[V_DURATION_COUNT] = {
     500,
     1000,
     1500,
@@ -79,8 +80,15 @@ static void scene_settings_show_headers_changed(VariableItem* item) {
 static void scene_settings_rfid_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, rfid_duration_text[index]);
-    app->settings.rfid_duration = rfid_duration_value[index];
+    variable_item_set_current_value_text(item, duration_text[index]);
+    app->settings.rfid_duration = duration_value[index];
+}
+
+static void scene_settings_nfc_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.nfc_duration = duration_value[index];
 }
 
 static void scene_settings_subghz_ext_changed(VariableItem* item) {
@@ -129,11 +137,17 @@ void scene_settings_on_enter(void* context) {
     variable_item_set_current_value_text(item, show_offon_text[value_index]);
 
     item = variable_item_list_add(
-        vil, "RFID Duration", V_RFID_DURATION_COUNT, scene_settings_rfid_duration_changed, app);
-    value_index = value_index_uint32(
-        app->settings.rfid_duration, rfid_duration_value, V_RFID_DURATION_COUNT);
+        vil, "RFID Duration", V_DURATION_COUNT, scene_settings_rfid_duration_changed, app);
+    value_index =
+        value_index_uint32(app->settings.rfid_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, "NFC Duration", V_DURATION_COUNT, scene_settings_nfc_duration_changed, app);
+    value_index = value_index_uint32(app->settings.nfc_duration, duration_value, V_DURATION_COUNT);
     variable_item_set_current_value_index(item, value_index);
-    variable_item_set_current_value_text(item, rfid_duration_text[value_index]);
+    variable_item_set_current_value_text(item, duration_text[value_index]);
 
     item =
         variable_item_list_add(vil, "SubGHz Ext Ant", 2, scene_settings_subghz_ext_changed, app);

+ 1 - 0
views/action_menu.c

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

+ 1 - 0
views/action_menu.h

@@ -21,6 +21,7 @@ typedef enum {
     ActionMenuItemTypeSubGHz,
     ActionMenuItemTypeRFID,
     ActionMenuItemTypeIR,
+    ActionMenuItemTypeNFC,
     ActionMenuItemTypePlaylist,
     ActionMenuItemTypeGroup,
     ActionMenuItemTypeSettings,