Skip to content

Commit

Permalink
basic NFC support
Browse files Browse the repository at this point in the history
  • Loading branch information
rdefeo committed Apr 2, 2024
1 parent 09f7507 commit 560e958
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 51 deletions.
2 changes: 2 additions & 0 deletions actions/action.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions actions/action_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 45 additions & 0 deletions actions/action_nfc.c
Original file line number Diff line number Diff line change
@@ -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);
}
23 changes: 14 additions & 9 deletions actions/action_qpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions item.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions item.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ typedef enum {
Item_SubGhz,
Item_RFID,
Item_IR,
Item_NFC,
Item_Playlist,
Item_Group,
Item_Settings,
Expand Down
1 change: 1 addition & 0 deletions quac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
73 changes: 40 additions & 33 deletions quac_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand All @@ -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);
}
Expand Down Expand Up @@ -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'");
Expand Down
1 change: 1 addition & 0 deletions scenes/scene_items.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
32 changes: 23 additions & 9 deletions scenes/scene_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ typedef enum {
SceneSettingsIcons,
SceneSettingsHeaders,
SceneSettingsRFIDDuration,
SceneSettingsNFCDuration,
SceneSettingsSubGHzExtAnt,
SceneSettingsHidden,
SceneSettingsAbout
Expand All @@ -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",
Expand All @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions views/action_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions views/action_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef enum {
ActionMenuItemTypeSubGHz,
ActionMenuItemTypeRFID,
ActionMenuItemTypeIR,
ActionMenuItemTypeNFC,
ActionMenuItemTypePlaylist,
ActionMenuItemTypeGroup,
ActionMenuItemTypeSettings,
Expand Down

0 comments on commit 560e958

Please sign in to comment.