Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
54f42e5
NFC: gen4 gtu detect in magic app
nullableVoidPtr Dec 27, 2022
e38fe37
NFC: more support for GTU card
nullableVoidPtr Jan 2, 2023
1774300
Merge branch 'dev' into gtu-magic
nullableVoidPtr Jan 2, 2023
2ae8279
NFC: Fix Gen1 in Magic
nullableVoidPtr Jan 2, 2023
10d6d1a
Merge branch 'dev' into gtu-magic
nullableVoidPtr Jan 9, 2023
1302146
Merge branch 'dev' into gtu-magic
nullableVoidPtr Jan 29, 2023
d47c94c
Allow double UIDs for MFClassic on GTU cards
nullableVoidPtr Jan 29, 2023
dc79046
NFC: Small magic app tweaks
nullableVoidPtr Feb 4, 2023
cccb3fa
Merge branch 'dev' into gtu-magic
nullableVoidPtr Feb 4, 2023
bec9358
nfc magic: notify card event on wiping
nullableVoidPtr Feb 6, 2023
64d96b4
WIP: [UNTESTED] merge from dev
nullableVoidPtr Mar 23, 2023
7fa5033
Merge branch 'dev' into gtu-magic
nullableVoidPtr Apr 12, 2023
c92bbea
Merge remote-tracking branch 'upstream/dev' into gtu-magic
nullableVoidPtr Apr 22, 2023
6f06758
Merge remote-tracking branch 'upstream/dev' into gtu-magic
nullableVoidPtr Apr 29, 2023
fa84573
nfc magic: fix power consumption
nullableVoidPtr May 7, 2023
773ac0b
nfc magic: disable i2c writing and fix wipe loop
nullableVoidPtr May 7, 2023
966829b
Merge branch 'dev' into gtu-magic
skotopes May 9, 2023
f13e160
NfcMagic: correct formatting in printf
skotopes May 9, 2023
92d46bd
NfcMagic: correct formatting in printf, proper version
skotopes May 9, 2023
87fe26a
Format sources
skotopes May 9, 2023
c3c6191
nfc_magic: rework card found notification and gen4 wiping
nullableVoidPtr May 15, 2023
0a01107
Merge remote-tracking branch 'upstream/dev' into gtu-magic
nullableVoidPtr May 15, 2023
94ecf4a
Merge branch 'dev' into gtu-magic
skotopes May 24, 2023
8030c40
Merge branch 'dev' into gtu-magic
skotopes May 25, 2023
5db6d62
Fix PVS warnings
skotopes May 25, 2023
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
175 changes: 175 additions & 0 deletions applications/external/nfc_magic/lib/magic/classic_gen1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include "classic_gen1.h"

#include <furi_hal_nfc.h>

#define TAG "Magic"

#define MAGIC_CMD_WUPA (0x40)
#define MAGIC_CMD_WIPE (0x41)
#define MAGIC_CMD_ACCESS (0x43)

#define MAGIC_MIFARE_READ_CMD (0x30)
#define MAGIC_MIFARE_WRITE_CMD (0xA0)

#define MAGIC_ACK (0x0A)

#define MAGIC_BUFFER_SIZE (32)

bool magic_gen1_wupa() {
bool magic_activated = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;

do {
// Start communication
tx_data[0] = MAGIC_CMD_WUPA;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
7,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;
magic_activated = true;
} while(false);

return magic_activated;
}

bool magic_gen1_data_access_cmd() {
bool write_cmd_success = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;

do {
tx_data[0] = MAGIC_CMD_ACCESS;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;

write_cmd_success = true;
} while(false);

return write_cmd_success;
}

bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data) {
furi_assert(data);

bool read_success = false;

uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;

do {
tx_data[0] = MAGIC_MIFARE_READ_CMD;
tx_data[1] = block_num;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
2 * 8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON,
furi_hal_nfc_ll_ms2fc(20));

if(ret != FuriHalNfcReturnOk) break;
if(rx_len != 16 * 8) break;
memcpy(data->value, rx_data, sizeof(data->value));
read_success = true;
} while(false);

return read_success;
}

bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data) {
furi_assert(data);

bool write_success = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;

do {
tx_data[0] = MAGIC_MIFARE_WRITE_CMD;
tx_data[1] = block_num;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
2 * 8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;

memcpy(tx_data, data->value, sizeof(data->value));
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
16 * 8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(20));
if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;

write_success = true;
} while(false);

return write_success;
}

bool magic_gen1_wipe() {
bool wipe_success = false;
uint8_t tx_data[MAGIC_BUFFER_SIZE] = {};
uint8_t rx_data[MAGIC_BUFFER_SIZE] = {};
uint16_t rx_len = 0;
FuriHalNfcReturn ret = 0;

do {
tx_data[0] = MAGIC_CMD_WIPE;
ret = furi_hal_nfc_ll_txrx_bits(
tx_data,
8,
rx_data,
sizeof(rx_data),
&rx_len,
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON |
FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP,
furi_hal_nfc_ll_ms2fc(2000));

if(ret != FuriHalNfcReturnIncompleteByte) break;
if(rx_len != 4) break;
if(rx_data[0] != MAGIC_ACK) break;

wipe_success = true;
} while(false);

return wipe_success;
}
13 changes: 13 additions & 0 deletions applications/external/nfc_magic/lib/magic/classic_gen1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <lib/nfc/protocols/mifare_classic.h>

bool magic_gen1_wupa();

bool magic_gen1_read_block(uint8_t block_num, MfClassicBlock* data);

bool magic_gen1_data_access_cmd();

bool magic_gen1_write_blk(uint8_t block_num, MfClassicBlock* data);

bool magic_gen1_wipe();
33 changes: 33 additions & 0 deletions applications/external/nfc_magic/lib/magic/common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "common.h"

#include <furi_hal_nfc.h>

#define REQA (0x26)
#define CL1_PREFIX (0x93)
#define SELECT (0x70)

#define MAGIC_BUFFER_SIZE (32)

bool magic_activate() {
FuriHalNfcReturn ret = 0;

// Setup nfc poller
furi_hal_nfc_exit_sleep();
furi_hal_nfc_ll_txrx_on();
furi_hal_nfc_ll_poll();
ret = furi_hal_nfc_ll_set_mode(
FuriHalNfcModePollNfca, FuriHalNfcBitrate106, FuriHalNfcBitrate106);
if(ret != FuriHalNfcReturnOk) return false;

furi_hal_nfc_ll_set_fdt_listen(FURI_HAL_NFC_LL_FDT_LISTEN_NFCA_POLLER);
furi_hal_nfc_ll_set_fdt_poll(FURI_HAL_NFC_LL_FDT_POLL_NFCA_POLLER);
furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc);
furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCA);

return true;
}

void magic_deactivate() {
furi_hal_nfc_ll_txrx_off();
furi_hal_nfc_sleep();
}
19 changes: 19 additions & 0 deletions applications/external/nfc_magic/lib/magic/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <stdint.h>
#include <stdbool.h>

typedef enum {
MagicTypeClassicGen1,
MagicTypeClassicDirectWrite,
MagicTypeClassicAPDU,
MagicTypeUltralightGen1,
MagicTypeUltralightDirectWrite,
MagicTypeUltralightC_Gen1,
MagicTypeUltralightC_DirectWrite,
MagicTypeGen4,
} MagicType;

bool magic_activate();

void magic_deactivate();
Loading