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>2021-06-15 17:54:09 +0300
committerGitHub <noreply@github.com>2021-06-15 17:54:09 +0300
commita0fdc559c971a48a5ca58d0dc2ecdc1fce0be3fb (patch)
tree5626dbd6190f8fa79f81b81772f7b2f7139dd02b /applications/nfc/nfc_worker.c
parent0b14db4fb33d4466a02c0c85b01321bece5d6537 (diff)
[FL-662] Read Mifare Ultralight (#518)
* nfc: add read mifare ultralight to menu * emv_decoder: add pragma once * nfc: add mifare ultralight reader * nfc: add mifare ultralight read draw * nfc: add mifare ultralight type checker * nfc: rework menu callback * mifare ultralight: change type names Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'applications/nfc/nfc_worker.c')
-rwxr-xr-x[-rw-r--r--]applications/nfc/nfc_worker.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c
index 78825789..b2957608 100644..100755
--- a/applications/nfc/nfc_worker.c
+++ b/applications/nfc/nfc_worker.c
@@ -1,6 +1,7 @@
#include "nfc_worker_i.h"
#include <api-hal.h>
#include "nfc_protocols/emv_decoder.h"
+#include "nfc_protocols/mifare_ultralight.h"
#define NFC_WORKER_TAG "nfc worker"
@@ -71,6 +72,8 @@ void nfc_worker_task(void* context) {
nfc_worker_emulate(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateField) {
nfc_worker_field(nfc_worker);
+ } else if(nfc_worker->state == NfcWorkerStateReadMfUltralight) {
+ nfc_worker_read_mf_ultralight(nfc_worker);
}
api_hal_nfc_deactivate();
nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
@@ -306,6 +309,126 @@ void nfc_worker_poll(NfcWorker* nfc_worker) {
}
}
+void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) {
+ ReturnCode err;
+ rfalNfcDevice* dev_list;
+ uint8_t dev_cnt = 0;
+ uint8_t tx_buff[255] = {};
+ uint16_t tx_len = 0;
+ uint8_t* rx_buff;
+ uint16_t* rx_len;
+ MfUltralightRead mf_ul_read;
+
+ // Update screen before start searching
+ NfcMessage message = {.type = NfcMessageTypeMfUlNotFound};
+ while(nfc_worker->state == NfcWorkerStateReadMfUltralight) {
+ furi_check(
+ osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK);
+ api_hal_nfc_deactivate();
+ memset(&mf_ul_read, 0, sizeof(mf_ul_read));
+ if(api_hal_nfc_detect(&dev_list, &dev_cnt, 100, false)) {
+ if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA &&
+ mf_ul_check_card_type(
+ dev_list[0].dev.nfca.sensRes.anticollisionInfo,
+ dev_list[0].dev.nfca.sensRes.platformInfo,
+ dev_list[0].dev.nfca.selRes.sak)) {
+ // Get Mifare Ultralight version
+ FURI_LOG_I(
+ NFC_WORKER_TAG, "Found Mifare Ultralight tag. Trying to get tag version");
+ tx_len = mf_ul_prepare_get_version(tx_buff);
+ err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
+ if(err == ERR_NONE) {
+ mf_ul_parse_get_version_response(rx_buff, &mf_ul_read);
+ FURI_LOG_I(
+ NFC_WORKER_TAG,
+ "Mifare Ultralight Type: %d, Pages: %d",
+ mf_ul_read.type,
+ mf_ul_read.pages_to_read);
+ } else if(err == ERR_TIMEOUT) {
+ FURI_LOG_W(
+ NFC_WORKER_TAG,
+ "Card doesn't respond to GET VERSION command. Reinit card and set default read parameters");
+ err = ERR_NONE;
+ mf_ul_set_default_version(&mf_ul_read);
+ // Reinit device
+ api_hal_nfc_deactivate();
+ if(!api_hal_nfc_detect(&dev_list, &dev_cnt, 100, false)) {
+ FURI_LOG_E(NFC_WORKER_TAG, "Lost connection. Restarting search");
+ message.type = NfcMessageTypeMfUlNotFound;
+ continue;
+ }
+ } else {
+ FURI_LOG_E(
+ NFC_WORKER_TAG,
+ "Error getting Mifare Ultralight version. Error code: %d",
+ err);
+ message.type = NfcMessageTypeMfUlNotFound;
+ continue;
+ }
+
+ // Dump Mifare Ultralight card
+ FURI_LOG_I(NFC_WORKER_TAG, "Trying to read pages");
+ if(mf_ul_read.support_fast_read) {
+ // Read card with FAST_READ command
+ tx_len = mf_ul_prepare_fast_read(tx_buff, 0x00, mf_ul_read.pages_to_read - 1);
+ err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
+ if(err == ERR_NONE) {
+ FURI_LOG_I(
+ NFC_WORKER_TAG,
+ "Fast read pages %d - %d succeed",
+ 0,
+ mf_ul_read.pages_to_read - 1);
+ memcpy(mf_ul_read.dump, rx_buff, mf_ul_read.pages_to_read * 4);
+ mf_ul_read.pages_readed = mf_ul_read.pages_to_read;
+ } else {
+ FURI_LOG_E(NFC_WORKER_TAG, "Fast read failed");
+ message.type = NfcMessageTypeMfUlNotFound;
+ continue;
+ }
+ } else {
+ // READ card with READ command (4 pages at a time)
+ for(uint8_t page = 0; page < mf_ul_read.pages_to_read; page += 4) {
+ tx_len = mf_ul_prepare_read(tx_buff, page);
+ err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
+ if(err == ERR_NONE) {
+ FURI_LOG_I(
+ NFC_WORKER_TAG, "Read pages %d - %d succeed", page, page + 3);
+ memcpy(&mf_ul_read.dump[page * 4], rx_buff, 4 * 4);
+ mf_ul_read.pages_readed += 4;
+ } else {
+ FURI_LOG_W(
+ NFC_WORKER_TAG, "Read pages %d - %d failed", page, page + 3);
+ }
+ }
+ }
+
+ // Fill message for nfc application
+ message.type = NfcMessageTypeMfUlFound;
+ memcpy(
+ message.device.mf_ul_card.uid,
+ dev_list[0].dev.nfca.nfcId1,
+ sizeof(message.device.mf_ul_card.uid));
+ memcpy(message.device.mf_ul_card.man_block, mf_ul_read.dump, 4 * 3);
+ memcpy(message.device.mf_ul_card.otp, &mf_ul_read.dump[4 * 3], 4);
+ for(uint8_t i = 0; i < mf_ul_read.pages_readed * 4; i += 4) {
+ printf("Page %2d: ", i / 4);
+ for(uint8_t j = 0; j < 4; j++) {
+ printf("%02X ", mf_ul_read.dump[i + j]);
+ }
+ printf("\r\n");
+ }
+ } else {
+ message.type = NfcMessageTypeMfUlNotFound;
+ FURI_LOG_W(NFC_WORKER_TAG, "Tag does not support Mifare Ultralight");
+ }
+ } else {
+ message.type = NfcMessageTypeMfUlNotFound;
+ FURI_LOG_W(NFC_WORKER_TAG, "Can't find any tags");
+ }
+ osDelay(100);
+ }
+}
+
void nfc_worker_emulate(NfcWorker* nfc_worker) {
while(nfc_worker->state == NfcWorkerStateEmulate) {
if(api_hal_nfc_listen(100)) {