From 0cb784aadd344865bbf71a5320abbeb466fb0775 Mon Sep 17 00:00:00 2001 From: g3gg0 Date: Fri, 25 Nov 2022 12:08:36 +0100 Subject: [PATCH] undo NfcA changes which might have looked better, but brought no reliability improvement --- firmware/targets/f7/furi_hal/furi_hal_nfc.c | 74 +---------- .../targets/furi_hal_include/furi_hal_nfc.h | 7 -- lib/nfc/nfc_worker.c | 95 +------------- lib/nfc/nfc_worker.h | 1 + lib/nfc/nfc_worker_i.h | 1 - lib/nfc/protocols/nfca.c | 117 ++++++------------ lib/nfc/protocols/nfca.h | 7 +- 7 files changed, 49 insertions(+), 253 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index c1ce2ebbb..44505c7cd 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -368,7 +368,6 @@ void furi_hal_nfc_listen_start(FuriHalNfcDevData* nfc_data) { } void furi_hal_nfcv_listen_start() { - furi_hal_gpio_init(&gpio_nfc_irq_rfid_pull, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh); // Clear interrupts st25r3916ClearInterrupts(); @@ -536,8 +535,9 @@ static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_ // Send signal FURI_CRITICAL_ENTER(); nfca_signal_encode(tx_rx->nfca_signal, tx_rx->tx_data, tx_rx->tx_bits, tx_rx->tx_parity); - digital_sequence_send(tx_rx->nfca_signal->tx_signal); + digital_signal_send(tx_rx->nfca_signal->tx_signal, &gpio_spi_r_mosi); FURI_CRITICAL_EXIT(); + furi_hal_gpio_write(&gpio_spi_r_mosi, false); // Configure gpio back to SPI and exit transparent furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc); @@ -601,51 +601,6 @@ static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_ return ret; } -static bool furi_hal_nfc_fully_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { - furi_assert(tx_rx); - - bool received = false; - - tx_rx->rx_bits = 0; - - if(tx_rx->tx_bits) { - nfca_trans_rx_pause(&tx_rx->nfca_trans_state); - FURI_CRITICAL_ENTER(); - furi_hal_gpio_write(&gpio_spi_r_mosi, false); - nfca_signal_encode(tx_rx->nfca_signal, tx_rx->tx_data, tx_rx->tx_bits, tx_rx->tx_parity); - digital_sequence_send(tx_rx->nfca_signal->tx_signal); - furi_hal_gpio_write(&gpio_spi_r_mosi, false); - FURI_CRITICAL_EXIT(); - nfca_trans_rx_continue(&tx_rx->nfca_trans_state); - - if(tx_rx->sniff_tx) { - tx_rx->sniff_tx(tx_rx->tx_data, tx_rx->tx_bits, false, tx_rx->sniff_context); - } - } - - if(timeout_ms) { - tx_rx->nfca_trans_state.bits_received = 0; - received = nfca_trans_rx_loop(&tx_rx->nfca_trans_state, timeout_ms); - - if(received) { - if(tx_rx->nfca_trans_state.bits_received > 7) { - tx_rx->rx_bits = tx_rx->nfca_trans_state.bits_received/9 * 8; - memcpy(tx_rx->rx_data, tx_rx->nfca_trans_state.frame_data, tx_rx->nfca_trans_state.bits_received/9); - } else { - tx_rx->rx_bits = tx_rx->nfca_trans_state.bits_received; - tx_rx->rx_data[0] = tx_rx->nfca_trans_state.frame_data[0] & ~(0xFF << tx_rx->rx_bits); - } - - if(tx_rx->sniff_rx) { - tx_rx->sniff_rx(tx_rx->rx_data, tx_rx->rx_bits, false, tx_rx->sniff_context); - } - } - } - - return received; -} - - static uint32_t furi_hal_nfc_tx_rx_get_flag(FuriHalNfcTxRxType type) { uint32_t flags = 0; @@ -719,26 +674,6 @@ uint16_t furi_hal_nfc_bitstream_to_data_and_parity( return curr_byte * 8; } -static uint8_t furi_hal_nfc_gen_parity(uint8_t value) { - value ^= (value >> 4); - value ^= (value >> 2); - value ^= (value >> 1); - - return (value ^ 1) & 1; -} - -void furi_hal_nfc_gen_bitstream(FuriHalNfcTxRxContext* tx_rx, uint8_t *buffer, size_t len) { - for(size_t pos = 0; pos < len; pos++) { - uint32_t parity_bit_num = pos % 8; - uint8_t bit = furi_hal_nfc_gen_parity(buffer[pos]); - - tx_rx->tx_data[pos] = buffer[pos]; - tx_rx->tx_parity[pos / 8] &= ~(1 << (7 - parity_bit_num)); - tx_rx->tx_parity[pos / 8] |= bit << (7 - parity_bit_num); - } - tx_rx->tx_bits = len * 8; -} - bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { furi_assert(tx_rx); @@ -749,11 +684,6 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { uint8_t* temp_rx_buff = NULL; uint16_t* temp_rx_bits = NULL; - /* send and receive data using transparent mode */ - if(tx_rx->tx_rx_type == FuriHalNfcTxRxFullyTransparent) { - return furi_hal_nfc_fully_transparent_tx_rx(tx_rx, timeout_ms); - } - /* send data using transparent mode and receive data in standard mode */ if(tx_rx->tx_rx_type == FuriHalNfcTxRxTransparent) { return furi_hal_nfc_transparent_tx_rx(tx_rx, timeout_ms); } diff --git a/firmware/targets/furi_hal_include/furi_hal_nfc.h b/firmware/targets/furi_hal_include/furi_hal_nfc.h index a43b76cf0..1363a1572 100644 --- a/firmware/targets/furi_hal_include/furi_hal_nfc.h +++ b/firmware/targets/furi_hal_include/furi_hal_nfc.h @@ -14,7 +14,6 @@ extern "C" { #endif #include #include -#include #define FURI_HAL_NFC_UID_MAX_LEN 10 #define FURI_HAL_NFC_DATA_BUFF_SIZE (512) @@ -47,7 +46,6 @@ typedef enum { FuriHalNfcTxRxTypeRaw, FuriHalNfcTxRxTypeRxRaw, FuriHalNfcTxRxTransparent, - FuriHalNfcTxRxFullyTransparent } FuriHalNfcTxRxType; typedef bool (*FuriHalNfcEmulateCallback)( @@ -93,8 +91,6 @@ typedef struct { uint16_t rx_bits; FuriHalNfcTxRxType tx_rx_type; NfcaSignal* nfca_signal; - NfcaTransRxState nfca_trans_state; - bool nfca_trans_initialized; FuriHalNfcTxRxSniffCallback sniff_tx; FuriHalNfcTxRxSniffCallback sniff_rx; @@ -429,9 +425,6 @@ FuriHalNfcReturn furi_hal_nfc_ll_txrx_bits( void furi_hal_nfc_ll_poll(); - -void furi_hal_nfc_gen_bitstream(FuriHalNfcTxRxContext* tx_rx, uint8_t *buffer, size_t len); - #ifdef __cplusplus } #endif diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 03d8862d0..818d54968 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -6,7 +6,6 @@ #define TAG "NfcWorker" - /***************************** NFC Worker API *******************************/ NfcWorker* nfc_worker_alloc() { @@ -94,8 +93,6 @@ int32_t nfc_worker_task(void* context) { nfc_worker_read(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateUidEmulate) { nfc_worker_emulate_uid(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateNfcVEmulate) { - nfc_worker_emulate_nfcv(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateEmulateApdu) { nfc_worker_emulate_apdu(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateMfUltralightEmulate) { @@ -112,6 +109,8 @@ int32_t nfc_worker_task(void* context) { nfc_worker_mf_classic_dict_attack(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateAnalyzeReader) { nfc_worker_analyze_reader(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateNfcVEmulate) { + nfc_worker_emulate_nfcv(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateNfcVUnlock) { nfc_worker_nfcv_unlock(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateNfcVUnlockAndSave) { @@ -894,98 +893,8 @@ void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker) { } nfca_signal_free(nfca_signal); -} - -/* software-defined variant of MFC emulation, seems to also struggle with frame errors etc */ -void nfc_worker_emulate_mf_classic_trans(NfcWorker* nfc_worker) { - FuriHalNfcTxRxContext tx_rx = {}; - FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; - MfClassicEmulator emulator = { - .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4), - .data = nfc_worker->dev_data->mf_classic_data, - .data_changed = false, - }; - NfcaSignal* nfca_signal = nfca_signal_alloc(); - tx_rx.nfca_signal = nfca_signal; - - rfal_platform_spi_acquire(); - - furi_hal_nfc_listen_start(nfc_data); - nfca_trans_rx_init(&tx_rx.nfca_trans_state); - - /* we are usingthe fully transparent ISO14443-A mode */ - tx_rx.tx_rx_type = FuriHalNfcTxRxFullyTransparent; - - /* prepare some answers to save time */ - uint8_t tx_buffer_aticoll[32]; - memcpy(tx_buffer_aticoll, &nfc_data->uid, 4); - nfca_append_crc16(tx_buffer_aticoll, 4); - - uint8_t tx_buffer_ack[8]; - tx_buffer_ack[0] = nfc_data->sak; - nfca_append_crc16(tx_buffer_ack, 1); - - while(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { - tx_rx.tx_bits = 0; - tx_rx.rx_bits = 0; - if(furi_hal_nfc_tx_rx(&tx_rx, 300)) { - if(tx_rx.rx_bits == 7) { - switch(tx_rx.rx_data[0]) { - /* MAGIC WUPC1 */ - case 0x40: - continue; - - /* WUPA */ - case 0x52: - furi_hal_nfc_gen_bitstream(&tx_rx, nfc_data->atqa, 2); - furi_hal_nfc_tx_rx(&tx_rx, 0); - continue; - } - } - - if(tx_rx.rx_bits >= 16) { - switch(tx_rx.rx_data[0]) { - /* SELECT */ - case 0x93: - switch(tx_rx.rx_data[1]) { - /* ANTICOLL */ - case 0x20: - furi_hal_nfc_gen_bitstream(&tx_rx, tx_buffer_aticoll, 6); - furi_hal_nfc_tx_rx(&tx_rx, 0); - continue; - - /* SELECT UID */ - case 0x70: - furi_hal_nfc_gen_bitstream(&tx_rx, tx_buffer_ack, 3); - furi_hal_nfc_tx_rx(&tx_rx, 0); - continue; - } - break; - - /* HALS */ - case 0x50: - continue; - } - } - - mf_classic_emulator(&emulator, &tx_rx); - } - } - - if(emulator.data_changed) { - nfc_worker->dev_data->mf_classic_data = emulator.data; - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - emulator.data_changed = false; - } - - nfca_trans_rx_deinit(&tx_rx.nfca_trans_state); rfal_platform_spi_release(); - - - nfca_signal_free(nfca_signal); } void nfc_worker_write_mf_classic(NfcWorker* nfc_worker) { diff --git a/lib/nfc/nfc_worker.h b/lib/nfc/nfc_worker.h index 6e8ef854d..121d8b2bd 100644 --- a/lib/nfc/nfc_worker.h +++ b/lib/nfc/nfc_worker.h @@ -93,3 +93,4 @@ void nfc_worker_start( void nfc_worker_stop(NfcWorker* nfc_worker); void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker); void nfc_worker_emulate_nfcv(NfcWorker* nfc_worker); + diff --git a/lib/nfc/nfc_worker_i.h b/lib/nfc/nfc_worker_i.h index ef1983e81..67fdcdc3d 100644 --- a/lib/nfc/nfc_worker_i.h +++ b/lib/nfc/nfc_worker_i.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/lib/nfc/protocols/nfca.c b/lib/nfc/protocols/nfca.c index 328db012b..c401f8cc5 100644 --- a/lib/nfc/protocols/nfca.c +++ b/lib/nfc/protocols/nfca.c @@ -2,27 +2,19 @@ #include #include #include -#include -#include #define NFCA_CMD_RATS (0xE0U) #define NFCA_CRC_INIT (0x6363) -#define NFCA_F_SIG (13560000.0) /* [Hz] NFC frequency */ -#define NFCA_F_SUB (NFCA_F_SIG/16) /* [Hz] NFC subcarrier frequency fs/16 (847500 Hz) */ -#define T_SUB (1000000000000.0f / NFCA_F_SUB) /* [ps] subcarrier period = 1/NFCA_F_SUB (1.18 µs) */ -#define T_SUB_PHASE (T_SUB/2) /* [ps] a single subcarrier phase (590 µs) */ +#define NFCA_F_SIG (13560000.0) +#define T_SIG 7374 //73.746ns*100 +#define T_SIG_x8 58992 //T_SIG*8 +#define T_SIG_x8_x8 471936 //T_SIG*8*8 +#define T_SIG_x8_x9 530928 //T_SIG*8*9 #define NFCA_SIGNAL_MAX_EDGES (1350) -#define SEQ_SOF 0 -#define SEQ_BIT0 1 -#define SEQ_BIT1 2 -#define SEQ_EOF 3 -#define SEQ_IDLE 4 - - typedef struct { uint8_t cmd; uint8_t param; @@ -71,69 +63,46 @@ bool nfca_emulation_handler( return sleep; } +static void nfca_add_bit(DigitalSignal* signal, bool bit) { + if(bit) { + signal->start_level = true; + for(size_t i = 0; i < 7; i++) { + signal->edge_timings[i] = T_SIG_x8; + } + signal->edge_timings[7] = T_SIG_x8_x9; + signal->edge_cnt = 8; + } else { + signal->start_level = false; + signal->edge_timings[0] = T_SIG_x8_x8; + for(size_t i = 1; i < 9; i++) { + signal->edge_timings[i] = T_SIG_x8; + } + signal->edge_cnt = 9; + } +} + static void nfca_add_byte(NfcaSignal* nfca_signal, uint8_t byte, bool parity) { for(uint8_t i = 0; i < 8; i++) { if(byte & (1 << i)) { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT1); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->one); } else { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT0); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero); } } if(parity) { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT1); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->one); } else { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT0); - } -} - -static void nfca_add_modulation(DigitalSignal* signal, size_t phases) { - for(size_t i = 0; i < phases; i++) { - signal->edge_timings[signal->edge_cnt++] = DIGITAL_SIGNAL_PS(T_SUB_PHASE); - } -} - -static void nfca_add_silence(DigitalSignal* signal, size_t phases) { - bool end_level = signal->start_level ^ ((signal->edge_cnt % 2) == 0); - - if((signal->edge_cnt == 0) || end_level) { - signal->edge_timings[signal->edge_cnt++] = DIGITAL_SIGNAL_PS(phases * T_SUB_PHASE); - } else { - signal->edge_timings[signal->edge_cnt - 1] += DIGITAL_SIGNAL_PS(phases * T_SUB_PHASE); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero); } } NfcaSignal* nfca_signal_alloc() { NfcaSignal* nfca_signal = malloc(sizeof(NfcaSignal)); - - /* ISO14443-2 defines 3 sequences for type A communication */ - nfca_signal->seq_d = digital_signal_alloc(10); - nfca_signal->seq_e = digital_signal_alloc(10); - nfca_signal->seq_f = digital_signal_alloc(10); - - /* SEQ D has the first half modulated, used as SOF */ - nfca_signal->seq_d->start_level = true; - nfca_add_modulation(nfca_signal->seq_d, 8); - nfca_add_silence(nfca_signal->seq_d, 8); - - /* SEQ E has the second half modulated */ - nfca_signal->seq_e->start_level = false; - nfca_add_silence(nfca_signal->seq_e, 8); - nfca_add_modulation(nfca_signal->seq_e, 8); - - /* SEQ F is just no modulation, used as EOF */ - nfca_signal->seq_f->start_level = false; - nfca_add_silence(nfca_signal->seq_f, 16); - - nfca_signal->tx_signal = digital_sequence_alloc(NFCA_SIGNAL_MAX_EDGES, &gpio_spi_r_mosi); - - /* we are dealing with shorter sequences, enable bake-before-sending */ - //nfca_signal->tx_signal->bake = true; - - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_SOF, nfca_signal->seq_d); - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_BIT0, nfca_signal->seq_e); - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_BIT1, nfca_signal->seq_d); - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_EOF, nfca_signal->seq_f); - digital_sequence_set_signal(nfca_signal->tx_signal, SEQ_IDLE, nfca_signal->seq_f); + nfca_signal->one = digital_signal_alloc(10); + nfca_signal->zero = digital_signal_alloc(10); + nfca_add_bit(nfca_signal->one, true); + nfca_add_bit(nfca_signal->zero, false); + nfca_signal->tx_signal = digital_signal_alloc(NFCA_SIGNAL_MAX_EDGES); return nfca_signal; } @@ -141,10 +110,9 @@ NfcaSignal* nfca_signal_alloc() { void nfca_signal_free(NfcaSignal* nfca_signal) { furi_assert(nfca_signal); - digital_signal_free(nfca_signal->seq_d); - digital_signal_free(nfca_signal->seq_e); - digital_signal_free(nfca_signal->seq_f); - digital_sequence_free(nfca_signal->tx_signal); + digital_signal_free(nfca_signal->one); + digital_signal_free(nfca_signal->zero); + digital_signal_free(nfca_signal->tx_signal); free(nfca_signal); } @@ -153,18 +121,17 @@ void nfca_signal_encode(NfcaSignal* nfca_signal, uint8_t* data, uint16_t bits, u furi_assert(data); furi_assert(parity); - digital_sequence_clear(nfca_signal->tx_signal); - - /* add some idle bit times before SOF in case the GPIO was active */ - digital_sequence_add(nfca_signal->tx_signal, SEQ_IDLE); - digital_sequence_add(nfca_signal->tx_signal, SEQ_SOF); + nfca_signal->tx_signal->edge_cnt = 0; + nfca_signal->tx_signal->start_level = true; + // Start of frame + digital_signal_append(nfca_signal->tx_signal, nfca_signal->one); if(bits < 8) { for(size_t i = 0; i < bits; i++) { if(FURI_BIT(data[0], i)) { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT1); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->one); } else { - digital_sequence_add(nfca_signal->tx_signal, SEQ_BIT0); + digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero); } } } else { @@ -172,6 +139,4 @@ void nfca_signal_encode(NfcaSignal* nfca_signal, uint8_t* data, uint16_t bits, u nfca_add_byte(nfca_signal, data[i], parity[i / 8] & (1 << (7 - (i & 0x07)))); } } - - digital_sequence_add(nfca_signal->tx_signal, SEQ_EOF); } diff --git a/lib/nfc/protocols/nfca.h b/lib/nfc/protocols/nfca.h index 82fb3e334..498ef2843 100644 --- a/lib/nfc/protocols/nfca.h +++ b/lib/nfc/protocols/nfca.h @@ -6,10 +6,9 @@ #include typedef struct { - DigitalSignal* seq_d; /* sequence D, modulation with subcarrier during first half */ - DigitalSignal* seq_e; /* sequence E, modulation with subcarrier during second half */ - DigitalSignal* seq_f; /* sequence F, no modulation at all */ - DigitalSequence* tx_signal; + DigitalSignal* one; + DigitalSignal* zero; + DigitalSignal* tx_signal; } NfcaSignal; uint16_t nfca_get_crc16(uint8_t* buff, uint16_t len);