Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgornekich <n.gorbadey@gmail.com>2022-05-24 17:00:15 +0300
committerGitHub <noreply@github.com>2022-05-24 17:00:15 +0300
commitd31578508a95144cf5964878349a21aac642850d (patch)
tree6b206a5d43de87ef661933c6ce977dac7d800ccf /firmware
parent2017baac48939fc58344a2d60294a9d9e6513b64 (diff)
[FL-2245] Introduce Mifare Classic Emulation (#1242)
* digital signal: introduce digital signal * nfca: add nfca signal encoder * nfc: add mifare classic emulation scene * nfca: add classic emulation support to lib and hal * mifare classic: support basic read commands * nfc: add mifare classic menu scene * mifare classic: start parsing commands in emulation * mifare classic: add nested auth * nfc: fix errors * mifare classic: add encrypt function * nfc: fix mifare classic save * lib hex: add hex uint64_t ASCII parser * flipper format: add uint64 hex format support * nfc: add mifare classic key map * nfc: hide mifare classic keys on emulation * mifare classic: add NACK responce * nfc: add partial bytes support in transparent mode * nfc: mifare classic add shadow file support * digital signal: move arr buffer from BSS to heap * mifare classic: process access bits more careful * nfca: fix memory leack * nfc: format sources * mifare classic: cleun up Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'firmware')
-rwxr-xr-xfirmware/targets/f7/furi_hal/furi_hal_nfc.c89
-rwxr-xr-xfirmware/targets/furi_hal_include/furi_hal_nfc.h5
2 files changed, 92 insertions, 2 deletions
diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c
index 768a4bac..4391685e 100755
--- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c
@@ -1,9 +1,12 @@
#include "furi_hal_nfc.h"
#include <st25r3916.h>
+#include <st25r3916_irq.h>
#include <rfal_rf.h>
#include <furi.h>
#include <m-string.h>
-#include <lib/nfc_protocols/nfca.h>
+
+#include <lib/digital_signal/digital_signal.h>
+#include <furi_hal_delay.h>
#define TAG "FuriHalNfc"
@@ -394,6 +397,80 @@ ReturnCode furi_hal_nfc_data_exchange(
return ret;
}
+static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) {
+ furi_assert(tx_rx->nfca_signal);
+
+ platformDisableIrqCallback();
+
+ bool ret = false;
+
+ // Start transparent mode
+ st25r3916ExecuteCommand(ST25R3916_CMD_TRANSPARENT_MODE);
+ // Reconfigure gpio
+ furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
+ furi_hal_gpio_init(&gpio_spi_r_sck, GpioModeInput, GpioPullUp, GpioSpeedLow);
+ furi_hal_gpio_init(&gpio_spi_r_miso, GpioModeInput, GpioPullUp, GpioSpeedLow);
+ furi_hal_gpio_init(&gpio_nfc_cs, GpioModeInput, GpioPullUp, GpioSpeedLow);
+ furi_hal_gpio_init(&gpio_spi_r_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
+ furi_hal_gpio_write(&gpio_spi_r_mosi, false);
+
+ // Send signal
+ nfca_signal_encode(tx_rx->nfca_signal, tx_rx->tx_data, tx_rx->tx_bits, tx_rx->tx_parity);
+ digital_signal_send(tx_rx->nfca_signal->tx_signal, &gpio_spi_r_mosi);
+ 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);
+ st25r3916ExecuteCommand(ST25R3916_CMD_UNMASK_RECEIVE_DATA);
+
+ // Manually wait for interrupt
+ furi_hal_gpio_init(&gpio_rfid_pull, GpioModeInput, GpioPullDown, GpioSpeedVeryHigh);
+ st25r3916ClearAndEnableInterrupts(ST25R3916_IRQ_MASK_RXE);
+
+ uint32_t irq = 0;
+ uint8_t rxe = 0;
+ uint32_t start = DWT->CYCCNT;
+ while(true) {
+ if(furi_hal_gpio_read(&gpio_rfid_pull) == true) {
+ st25r3916ReadRegister(ST25R3916_REG_IRQ_MAIN, &rxe);
+ if(rxe & (1 << 4)) {
+ irq = 1;
+ break;
+ }
+ }
+ uint32_t timeout = DWT->CYCCNT - start;
+ if(timeout / furi_hal_delay_instructions_per_microsecond() > timeout_ms * 1000) {
+ FURI_LOG_D(TAG, "Interrupt waiting timeout");
+ break;
+ }
+ }
+ if(irq) {
+ uint8_t fifo_stat[2];
+ st25r3916ReadMultipleRegisters(
+ ST25R3916_REG_FIFO_STATUS1, fifo_stat, ST25R3916_FIFO_STATUS_LEN);
+ uint16_t len =
+ ((((uint16_t)fifo_stat[1] & ST25R3916_REG_FIFO_STATUS2_fifo_b_mask) >>
+ ST25R3916_REG_FIFO_STATUS2_fifo_b_shift)
+ << RFAL_BITS_IN_BYTE);
+ len |= (((uint16_t)fifo_stat[0]) & 0x00FFU);
+ uint8_t rx[100];
+ st25r3916ReadFifo(rx, len);
+
+ tx_rx->rx_bits = len * 8;
+ memcpy(tx_rx->rx_data, rx, len);
+
+ ret = true;
+ } else {
+ FURI_LOG_E(TAG, "Timeout error");
+ ret = false;
+ }
+
+ st25r3916ClearInterrupts();
+ platformEnableIrqCallback();
+
+ return ret;
+}
+
static uint32_t furi_hal_nfc_tx_rx_get_flag(FuriHalNfcTxRxType type) {
uint32_t flags = 0;
@@ -405,6 +482,9 @@ static uint32_t furi_hal_nfc_tx_rx_get_flag(FuriHalNfcTxRxType type) {
} else if(type == FuriHalNfcTxRxTypeRaw) {
flags = RFAL_TXRX_FLAGS_CRC_TX_MANUAL | RFAL_TXRX_FLAGS_CRC_RX_KEEP |
RFAL_TXRX_FLAGS_PAR_RX_KEEP | RFAL_TXRX_FLAGS_PAR_TX_NONE;
+ } else if(type == FuriHalNfcTxRxTypeRxRaw) {
+ flags = RFAL_TXRX_FLAGS_CRC_TX_MANUAL | RFAL_TXRX_FLAGS_CRC_RX_KEEP |
+ RFAL_TXRX_FLAGS_PAR_RX_KEEP | RFAL_TXRX_FLAGS_PAR_TX_NONE;
}
return flags;
@@ -470,6 +550,10 @@ 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;
+ if(tx_rx->tx_rx_type == FuriHalNfcTxRxTransparent) {
+ return furi_hal_nfc_transparent_tx_rx(tx_rx, timeout_ms);
+ }
+
// Prepare data for FIFO if necessary
uint32_t flags = furi_hal_nfc_tx_rx_get_flag(tx_rx->tx_rx_type);
if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw) {
@@ -502,7 +586,8 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) {
osDelay(1);
}
- if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw) {
+ if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw ||
+ tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRxRaw) {
tx_rx->rx_bits = 8 * furi_hal_nfc_bitstream_to_data_and_parity(
temp_rx_buff, *temp_rx_bits, tx_rx->rx_data, tx_rx->rx_parity);
} else {
diff --git a/firmware/targets/furi_hal_include/furi_hal_nfc.h b/firmware/targets/furi_hal_include/furi_hal_nfc.h
index 20a46900..860db80d 100755
--- a/firmware/targets/furi_hal_include/furi_hal_nfc.h
+++ b/firmware/targets/furi_hal_include/furi_hal_nfc.h
@@ -10,6 +10,8 @@
#include <stdbool.h>
#include <stdint.h>
+#include <lib/nfc_protocols/nfca.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -39,6 +41,8 @@ typedef enum {
FuriHalNfcTxRxTypeRxNoCrc,
FuriHalNfcTxRxTypeRxKeepPar,
FuriHalNfcTxRxTypeRaw,
+ FuriHalNfcTxRxTypeRxRaw,
+ FuriHalNfcTxRxTransparent,
} FuriHalNfcTxRxType;
typedef bool (*FuriHalNfcEmulateCallback)(
@@ -80,6 +84,7 @@ typedef struct {
uint8_t rx_parity[FURI_HAL_NFC_PARITY_BUFF_SIZE];
uint16_t rx_bits;
FuriHalNfcTxRxType tx_rx_type;
+ NfcaSignal* nfca_signal;
} FuriHalNfcTxRxContext;
/** Init nfc