Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions applications/main/nfc/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ App(
"gui",
"dialogs",
],
# provides=["nfc_start"],
provides=["nfc_start"],
icon="A_NFC_14",
stack_size=5 * 1024,
order=30,
Expand Down Expand Up @@ -52,10 +52,10 @@ App(
requires=["nfc"],
)

# App(
# appid="nfc_start",
# apptype=FlipperAppType.STARTUP,
# entry_point="nfc_on_system_start",
# requires=["nfc"],
# order=30,
# )
App(
appid="nfc_start",
apptype=FlipperAppType.STARTUP,
entry_point="nfc_on_system_start",
requires=["nfc"],
order=30,
)
216 changes: 60 additions & 156 deletions applications/main/nfc/nfc_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
#include <lib/toolbox/args.h>
#include <lib/toolbox/hex.h>

#include <lib/nfc/deprecated/nfc_types.h>
#include <lib/nfc/deprecated/nfc_device_old.h>
#include <drivers/st25r3916.h>
#include <nfc/nfc.h>
#include <f_hal_nfc.h>
#include <f_hal_nfc_i.h>

#include <furi_hal_resources.h>
#include <signal_reader/parsers/iso15693/iso15693_parser.h>

#define FLAG_EVENT (1 << 10)

static void nfc_cli_print_usage() {
printf("Usage:\r\n");
Expand All @@ -19,155 +26,72 @@ static void nfc_cli_print_usage() {
}
}

static void nfc_cli_check(Cli* cli, FuriString* args) {
UNUSED(args);
UNUSED(cli);
}
static void f_hal_nfc_iso15693_listener_transparent_mode_enter(FuriHalSpiBusHandle* handle) {
st25r3916_direct_cmd(handle, ST25R3916_CMD_TRANSPARENT_MODE);

static void nfc_cli_detect(Cli* cli, FuriString* args) {
UNUSED(args);
// Check if nfc worker is not busy
if(furi_hal_nfc_is_busy()) {
printf("Nfc is busy\r\n");
return;
}

FuriHalNfcDevData dev_data = {};
bool cmd_exit = false;
furi_hal_nfc_exit_sleep();
printf("Detecting nfc...\r\nPress Ctrl+C to abort\r\n");
while(!cmd_exit) {
cmd_exit |= cli_cmd_interrupt_received(cli);
if(furi_hal_nfc_detect(&dev_data, 400)) {
printf("Found: %s ", nfc_get_dev_type(dev_data.type));
printf("UID length: %d, UID:", dev_data.uid_len);
for(size_t i = 0; i < dev_data.uid_len; i++) {
printf("%02X", dev_data.uid[i]);
}
printf("\r\n");
break;
}
furi_hal_nfc_sleep();
furi_delay_ms(50);
}
furi_hal_nfc_sleep();
furi_hal_spi_bus_handle_deinit(handle);
f_hal_nfc_deinit_gpio_isr();
}

static void nfc_cli_emulate(Cli* cli, FuriString* args) {
UNUSED(args);
// Check if nfc worker is not busy
if(furi_hal_nfc_is_busy()) {
printf("Nfc is busy\r\n");
return;
}
static void f_hal_nfc_iso15693_listener_transparent_mode_exit(FuriHalSpiBusHandle* handle) {
// Configure gpio back to SPI and exit transparent mode
f_hal_nfc_init_gpio_isr();
furi_hal_spi_bus_handle_init(handle);

furi_hal_nfc_exit_sleep();
printf("Emulating NFC-A Type: T2T UID: 36 9C E7 B1 0A C1 34 SAK: 00 ATQA: 00/44\r\n");
printf("Press Ctrl+C to abort\r\n");

FuriHalNfcDevData params = {
.uid = {0x36, 0x9C, 0xe7, 0xb1, 0x0A, 0xC1, 0x34},
.uid_len = 7,
.atqa = {0x44, 0x00},
.sak = 0x00,
.type = FuriHalNfcTypeA,
};

while(!cli_cmd_interrupt_received(cli)) {
if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 100)) {
printf("Reader detected\r\n");
furi_hal_nfc_sleep();
}
furi_delay_ms(50);
}
furi_hal_nfc_sleep();
st25r3916_direct_cmd(handle, ST25R3916_CMD_UNMASK_RECEIVE_DATA);
}

static void nfc_cli_field(Cli* cli, FuriString* args) {
UNUSED(args);
// Check if nfc worker is not busy
if(furi_hal_nfc_is_busy()) {
printf("Nfc is busy\r\n");
return;
}

furi_hal_nfc_exit_sleep();
furi_hal_nfc_field_on();

printf("Field is on. Don't leave device in this mode for too long.\r\n");
printf("Press Ctrl+C to abort\r\n");
static void f_hal_nfc_iso15693_parser_callback(Iso15693ParserEvent event, void* context) {
furi_assert(context);

while(!cli_cmd_interrupt_received(cli)) {
furi_delay_ms(50);
if(event == Iso15693ParserEventDataReceived) {
FuriThreadId thread_id = context;
furi_thread_flags_set(thread_id, FLAG_EVENT);
}

furi_hal_nfc_field_off();
furi_hal_nfc_sleep();
}

static void nfc_cli_apdu(Cli* cli, FuriString* args) {
// TODO remove this test command
static void nfc_cli_check(Cli* cli, FuriString* args) {
UNUSED(args);
UNUSED(cli);
if(furi_hal_nfc_is_busy()) {
printf("Nfc is busy\r\n");
return;
FuriHalSpiBusHandle* handle = &furi_hal_spi_bus_handle_nfc;
uint8_t data[100] = {};
size_t bits = 0;

Nfc* nfc = nfc_alloc();
f_hal_nfc_low_power_mode_stop();
f_hal_nfc_set_mode(FHalNfcModeListener, FHalNfcTechIso15693);
f_hal_nfc_iso15693_listener_transparent_mode_enter(handle);
Iso15693Parser* instance = iso15693_parser_alloc(&gpio_spi_r_miso, 1024);

FuriThreadId thread_id = furi_thread_get_current_id();
furi_thread_set_current_priority(FuriThreadPriorityHighest);
iso15693_parser_start(instance, f_hal_nfc_iso15693_parser_callback, thread_id);

while(true) {
uint32_t flag = furi_thread_flags_wait(FLAG_EVENT, FuriFlagWaitAny, FuriWaitForever);
furi_thread_flags_clear(flag);

if(flag & FLAG_EVENT) {
if(iso15693_parser_run(instance)) {
iso15693_parser_get_data(instance, data, sizeof(data), &bits);
break;
}
}
}

furi_hal_nfc_exit_sleep();
FuriString* data = NULL;
data = furi_string_alloc();
FuriHalNfcTxRxContext tx_rx = {};
FuriHalNfcDevData dev_data = {};
uint8_t* req_buffer = NULL;
uint8_t* resp_buffer = NULL;
size_t apdu_size = 0;
size_t resp_size = 0;
for(size_t i = 0; i < bits / 8; i++) {
printf("%02X ", data[i]);
}
printf("\r\n");

do {
if(!args_read_string_and_trim(args, data)) {
printf(
"Use like `nfc apdu 00a404000e325041592e5359532e444446303100 00a4040008a0000003010102` \r\n");
break;
}
iso15693_parser_stop(instance);
f_hal_nfc_iso15693_listener_transparent_mode_exit(handle);

printf("detecting tag\r\n");
if(!furi_hal_nfc_detect(&dev_data, 300)) {
printf("Failed to detect tag\r\n");
break;
}
do {
apdu_size = furi_string_size(data) / 2;
req_buffer = malloc(apdu_size);
hex_chars_to_uint8(furi_string_get_cstr(data), req_buffer);

memcpy(tx_rx.tx_data, req_buffer, apdu_size);
tx_rx.tx_bits = apdu_size * 8;
tx_rx.tx_rx_type = FuriHalNfcTxRxTypeDefault;

printf("Sending APDU:%s to Tag\r\n", furi_string_get_cstr(data));
if(!furi_hal_nfc_tx_rx(&tx_rx, 300)) {
printf("Failed to tx_rx\r\n");
break;
}
resp_size = (tx_rx.rx_bits / 8) * 2;
if(!resp_size) {
printf("No response\r\n");
break;
}
resp_buffer = malloc(resp_size);
uint8_to_hex_chars(tx_rx.rx_data, resp_buffer, resp_size);
resp_buffer[resp_size] = 0;
printf("Response: %s\r\n", resp_buffer);
free(req_buffer);
free(resp_buffer);
req_buffer = NULL;
resp_buffer = NULL;
} while(args_read_string_and_trim(args, data));
} while(false);

free(req_buffer);
free(resp_buffer);
furi_string_free(data);
furi_hal_nfc_sleep();
iso15693_parser_free(instance);
f_hal_nfc_reset_mode();
f_hal_nfc_low_power_mode_start();
nfc_free(nfc);
}

static void nfc_cli(Cli* cli, FuriString* args, void* context) {
Expand All @@ -184,26 +108,6 @@ static void nfc_cli(Cli* cli, FuriString* args, void* context) {
nfc_cli_check(cli, args);
break;
}
if(furi_string_cmp_str(cmd, "detect") == 0) {
nfc_cli_detect(cli, args);
break;
}
if(furi_string_cmp_str(cmd, "emulate") == 0) {
nfc_cli_emulate(cli, args);
break;
}

if(furi_string_cmp_str(cmd, "apdu") == 0) {
nfc_cli_apdu(cli, args);
break;
}

if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
if(furi_string_cmp_str(cmd, "field") == 0) {
nfc_cli_field(cli, args);
break;
}
}

nfc_cli_print_usage();
} while(false);
Expand Down
3 changes: 2 additions & 1 deletion firmware/targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,36.1,,
Version,+,35.3,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
Expand Down Expand Up @@ -2677,6 +2677,7 @@ Function,+,signal_reader_free,void,SignalReader*
Function,+,signal_reader_set_polarity,void,"SignalReader*, SignalReaderPolarity"
Function,+,signal_reader_set_pull,void,"SignalReader*, GpioPull"
Function,+,signal_reader_set_sample_rate,void,"SignalReader*, SignalReaderTimeUnit, uint32_t"
Function,+,signal_reader_set_trigger,void,"SignalReader*, SignalReaderTrigger"
Function,+,signal_reader_start,void,"SignalReader*, SignalReaderCallback, void*"
Function,+,signal_reader_stop,void,SignalReader*
Function,+,simple_array_alloc,SimpleArray*,const SimpleArrayConfig*
Expand Down
4 changes: 1 addition & 3 deletions firmware/targets/f7/furi_hal/f_hal_nfc_iso15693.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ static FHalNfcEvent f_hal_nfc_iso15693_wait_event(uint32_t timeout_ms) {

if(flag & FHalNfcEventInternalTypeAbort) {
event = FHalNfcEventAbortRequest;
f_hal_nfc_iso15693_listener_transparent_mode_exit(handle);
break;
}
if(flag & FHalNfcEventInternalTypeTransparentDataReceived) {
Expand All @@ -372,9 +373,7 @@ static FHalNfcEvent f_hal_nfc_iso15693_wait_event(uint32_t timeout_ms) {
}
}
}

iso15693_parser_stop(f_hal_nfc_iso15693_listener->parser);
f_hal_nfc_iso15693_listener_transparent_mode_exit(handle);

return event;
}
Expand All @@ -386,7 +385,6 @@ static FHalNfcError f_hal_nfc_iso15693_listener_tx(
furi_assert(f_hal_nfc_iso15693_listener);

FHalNfcError error = FHalNfcErrorNone;
f_hal_nfc_iso15693_listener_transparent_mode_enter(handle);

error = f_hal_nfc_iso15693_listener_tx_transparent(tx_data, tx_bits / BITS_IN_BYTE);

Expand Down
Loading