forked from flipperdevices/flipperzero-firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NFC magic cards support (flipperdevices#1966)
* nfc magic: introduce nfc app to work with magic cards * nfc: add nfc device functions to API * nfc magic: add bacis scenes * nfc magic: add wrong card and write confirm scenes * nfc magic: introduce magic lib * nfc magic: write magic lib * nfc magic: add write commands to magic lib * nfc magic: work on worker * furi_hal_nfc: add bits data exchage method to API * nfc magic: rework with new API * nfc magic: add check and wipe scenes * nfc magic: add icons, gui fixes * nfc: format python src Co-authored-by: あく <[email protected]>
- Loading branch information
Showing
35 changed files
with
1,693 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
App( | ||
appid="nfc_magic", | ||
name="Nfc Magic", | ||
apptype=FlipperAppType.EXTERNAL, | ||
entry_point="nfc_magic_app", | ||
requires=[ | ||
"storage", | ||
"gui", | ||
], | ||
stack_size=4 * 1024, | ||
order=30, | ||
fap_icon="../../../assets/icons/Archive/125_10px.png", | ||
fap_category="Tools", | ||
fap_private_libs=[ | ||
Lib( | ||
name="magic", | ||
), | ||
], | ||
fap_icon_assets="assets", | ||
) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
#include "magic.h" | ||
|
||
#include <furi_hal_nfc.h> | ||
|
||
#define TAG "Magic" | ||
|
||
#define MAGIC_CMD_WUPA (0x40) | ||
#define MAGIC_CMD_WIPE (0x41) | ||
#define MAGIC_CMD_READ (0x43) | ||
#define MAGIC_CMD_WRITE (0x43) | ||
|
||
#define MAGIC_MIFARE_READ_CMD (0x30) | ||
#define MAGIC_MIFARE_WRITE_CMD (0xA0) | ||
|
||
#define MAGIC_ACK (0x0A) | ||
|
||
#define MAGIC_BUFFER_SIZE (32) | ||
|
||
bool magic_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 { | ||
// 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) break; | ||
|
||
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); | ||
|
||
// 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); | ||
|
||
if(!magic_activated) { | ||
furi_hal_nfc_ll_txrx_off(); | ||
furi_hal_nfc_start_sleep(); | ||
} | ||
|
||
return magic_activated; | ||
} | ||
|
||
bool magic_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_WRITE; | ||
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); | ||
|
||
if(!write_cmd_success) { | ||
furi_hal_nfc_ll_txrx_off(); | ||
furi_hal_nfc_start_sleep(); | ||
} | ||
|
||
return write_cmd_success; | ||
} | ||
|
||
bool magic_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); | ||
|
||
if(!read_success) { | ||
furi_hal_nfc_ll_txrx_off(); | ||
furi_hal_nfc_start_sleep(); | ||
} | ||
|
||
return read_success; | ||
} | ||
|
||
bool magic_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); | ||
|
||
if(!write_success) { | ||
furi_hal_nfc_ll_txrx_off(); | ||
furi_hal_nfc_start_sleep(); | ||
} | ||
|
||
return write_success; | ||
} | ||
|
||
bool magic_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; | ||
} | ||
|
||
void magic_deactivate() { | ||
furi_hal_nfc_ll_txrx_off(); | ||
furi_hal_nfc_start_sleep(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#pragma once | ||
|
||
#include <lib/nfc/protocols/mifare_classic.h> | ||
|
||
bool magic_wupa(); | ||
|
||
bool magic_read_block(uint8_t block_num, MfClassicBlock* data); | ||
|
||
bool magic_data_access_cmd(); | ||
|
||
bool magic_write_blk(uint8_t block_num, MfClassicBlock* data); | ||
|
||
bool magic_wipe(); | ||
|
||
void magic_deactivate(); |
Oops, something went wrong.