Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mifare classic and icon/menu changes #13

Merged
merged 7 commits into from
May 18, 2022
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
32 changes: 16 additions & 16 deletions applications/applications.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,22 @@ const FlipperApplication FLIPPER_APPS[] = {
.flags = FlipperApplicationFlagDefault},
#endif

#ifdef APP_UNIVERSALRF
{.app = universal_rf_remote_app,
.name = "Universal SubGHz",
.stack_size = 2048,
.icon = &A_UniversalRemote_14,
.flags = FlipperApplicationFlagDefault},
#endif

#ifdef APP_JUKEBOX
{.app = jukebox_app,
.name = "Jukebox",
.stack_size = 2048,
.icon = &A_TouchTunes_14,
.flags = FlipperApplicationFlagDefault},
#endif

#ifdef APP_LF_RFID
{.app = lfrfid_app,
.name = "125 kHz RFID",
Expand Down Expand Up @@ -358,14 +374,6 @@ const FlipperApplication FLIPPER_PLUGINS[] = {
},
#endif

#ifdef APP_JUKEBOX
{.app = jukebox_app,
.name = "Jukebox",
.stack_size = 2048,
.icon = &A_UniversalRemote_14,
.flags = FlipperApplicationFlagDefault},
#endif

#ifdef APP_MUSIC_PLAYER
{.app = music_player_app,
.name = "Music Player",
Expand Down Expand Up @@ -394,14 +402,6 @@ const FlipperApplication FLIPPER_PLUGINS[] = {
{.app = tetris_game_app, .name = "Tetris Game", .stack_size = 1024, .icon = NULL},
#endif

#ifdef APP_UNIVERSALRF
{.app = universal_rf_remote_app,
.name = "Universal SubGHz",
.stack_size = 2048,
.icon = &A_UniversalRemote_14,
.flags = FlipperApplicationFlagDefault},
#endif

{.app = wav_player_app,
.name = "Wav Player",
.stack_size = 4096,
Expand Down
23 changes: 23 additions & 0 deletions applications/nfc/nfc_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <lib/nfc_protocols/mifare_ultralight.h>
#include <lib/nfc_protocols/mifare_classic.h>
#include <lib/nfc_protocols/mifare_desfire.h>
#include <lib/nfc_protocols/nfca.h>

#include "helpers/nfc_mf_classic_dict.h"

Expand Down Expand Up @@ -104,6 +105,8 @@ int32_t nfc_worker_task(void* context) {
nfc_worker_emulate_mifare_ul(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateReadMifareClassic) {
nfc_worker_mifare_classic_dict_attack(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateEmulateMifareClassic) {
nfc_worker_emulate_mifare_classic(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateReadMifareDesfire) {
nfc_worker_read_mifare_desfire(nfc_worker);
}
Expand Down Expand Up @@ -474,6 +477,26 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) {
stream_free(nfc_worker->dict_stream);
}

void nfc_worker_emulate_mifare_classic(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,
};
NfcaSignal* nfca_signal = nfca_signal_alloc();
tx_rx.nfca_signal = nfca_signal;

while(nfc_worker->state == NfcWorkerStateEmulateMifareClassic) {
if(furi_hal_nfc_listen(
nfc_data->uid, nfc_data->uid_len, nfc_data->atqa, nfc_data->sak, true, 4000)) {
mf_classic_emulator(&emulator, &tx_rx);
}
}

nfca_signal_free(nfca_signal);
}

void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) {
ReturnCode err;
uint8_t tx_buff[64] = {};
Expand Down
1 change: 1 addition & 0 deletions applications/nfc/nfc_worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ typedef enum {
NfcWorkerStateReadMifareUltralight,
NfcWorkerStateEmulateMifareUltralight,
NfcWorkerStateReadMifareClassic,
NfcWorkerStateEmulateMifareClassic,
NfcWorkerStateReadMifareDesfire,
// Transition
NfcWorkerStateStop,
Expand Down
1 change: 1 addition & 0 deletions applications/nfc/scenes/nfc_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ ADD_SCENE(nfc, restore_original, RestoreOriginal)
ADD_SCENE(nfc, debug, Debug)
ADD_SCENE(nfc, field, Field)
ADD_SCENE(nfc, read_mifare_classic, ReadMifareClassic)
ADD_SCENE(nfc, emulate_mifare_classic, EmulateMifareClassic)
ADD_SCENE(nfc, dict_not_found, DictNotFound)
64 changes: 64 additions & 0 deletions applications/nfc/scenes/nfc_scene_emulate_mifare_classic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "../nfc_i.h"
#include <dolphin/dolphin.h>

#define NFC_MF_CLASSIC_DATA_NOT_CHANGED (0UL)
#define NFC_MF_CLASSIC_DATA_CHANGED (1UL)

void nfc_emulate_mifare_classic_worker_callback(NfcWorkerEvent event, void* context) {
UNUSED(event);
Nfc* nfc = context;

scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_CLASSIC_DATA_CHANGED);
}

void nfc_scene_emulate_mifare_classic_on_enter(void* context) {
Nfc* nfc = context;
DOLPHIN_DEED(DolphinDeedNfcEmulate);

// Setup view
Popup* popup = nfc->popup;
if(strcmp(nfc->dev->dev_name, "")) {
nfc_text_store_set(nfc, "%s", nfc->dev->dev_name);
}
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
popup_set_header(popup, "Emulating\nMf Classic", 56, 31, AlignLeft, AlignTop);

// Setup and start worker
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
nfc_worker_start(
nfc->worker,
NfcWorkerStateEmulateMifareClassic,
&nfc->dev->dev_data,
nfc_emulate_mifare_classic_worker_callback,
nfc);
}

bool nfc_scene_emulate_mifare_classic_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;

if(event.type == SceneManagerEventTypeTick) {
notification_message(nfc->notifications, &sequence_blink_blue_10);
consumed = true;
} else if(event.type == SceneManagerEventTypeBack) {
// Stop worker
nfc_worker_stop(nfc->worker);
// Check if data changed and save in shadow file
if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmulateMifareUl) ==
NFC_MF_CLASSIC_DATA_CHANGED) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_CLASSIC_DATA_NOT_CHANGED);
nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name);
}
consumed = false;
}
return consumed;
}

void nfc_scene_emulate_mifare_classic_on_exit(void* context) {
Nfc* nfc = context;

// Clear view
popup_reset(nfc->popup);
}
12 changes: 6 additions & 6 deletions applications/nfc/scenes/nfc_scene_saved_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@ void nfc_scene_saved_menu_on_enter(void* context) {
SubmenuIndexEmulate,
nfc_scene_saved_menu_submenu_callback,
nfc);
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
} else if(
nfc->dev->format == NfcDeviceSaveFormatMifareUl ||
nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
submenu_add_item(
submenu,
"Emulate Ultralight",
SubmenuIndexEmulate,
nfc_scene_saved_menu_submenu_callback,
nfc);
submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc);
}
submenu_add_item(
submenu, "Edit UID and Name", SubmenuIndexEdit, nfc_scene_saved_menu_submenu_callback, nfc);
Expand Down Expand Up @@ -64,6 +62,8 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
if(event.event == SubmenuIndexEmulate) {
if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl);
} else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareClassic);
} else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
}
Expand Down
89 changes: 87 additions & 2 deletions firmware/targets/f7/furi_hal/furi_hal_nfc.c
Original file line number Diff line number Diff line change
@@ -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"

Expand Down Expand Up @@ -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 / 8, 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;

Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 5 additions & 0 deletions firmware/targets/furi_hal_include/furi_hal_nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <stdbool.h>
#include <stdint.h>

#include <lib/nfc_protocols/nfca.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -39,6 +41,8 @@ typedef enum {
FuriHalNfcTxRxTypeRxNoCrc,
FuriHalNfcTxRxTypeRxKeepPar,
FuriHalNfcTxRxTypeRaw,
FuriHalNfcTxRxTypeRxRaw,
FuriHalNfcTxRxTransparent,
} FuriHalNfcTxRxType;

typedef bool (*FuriHalNfcEmulateCallback)(
Expand Down Expand Up @@ -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
Expand Down
Loading