diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index a249f85e..e59896e3 100755 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -3,19 +3,19 @@ bool nfc_custom_event_callback(void* context, uint32_t event) { furi_assert(context); - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; return scene_manager_handle_custom_event(nfc->scene_manager, event); } bool nfc_back_event_callback(void* context) { furi_assert(context); - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; return scene_manager_handle_back_event(nfc->scene_manager); } void nfc_tick_event_callback(void* context) { furi_assert(context); - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; scene_manager_handle_tick_event(nfc->scene_manager); } diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c index 98024e7d..52c971ef 100755 --- a/applications/nfc/nfc_cli.c +++ b/applications/nfc/nfc_cli.c @@ -16,40 +16,35 @@ static void nfc_cli_print_usage() { } } -void nfc_cli_detect(Cli* cli, string_t args) { +static void nfc_cli_detect(Cli* cli, string_t args) { // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { printf("Nfc is busy\r\n"); return; } - rfalNfcDevice* dev_list; - uint8_t dev_cnt = 0; + + FuriHalNfcDevData dev_data = {}; bool cmd_exit = false; furi_hal_nfc_exit_sleep(); printf("Detecting nfc...\r\nPress Ctrl+C to abort\r\n"); while(!cmd_exit) { cmd_exit |= cli_cmd_interrupt_received(cli); - cmd_exit |= furi_hal_nfc_detect(&dev_list, &dev_cnt, 400, true); - if(dev_cnt > 0) { - printf("Found %d devices\r\n", dev_cnt); - for(uint8_t i = 0; i < dev_cnt; i++) { - printf("%d found: %s ", i + 1, nfc_get_rfal_type(dev_list[i].type)); - if(dev_list[i].type == RFAL_NFC_LISTEN_TYPE_NFCA) { - printf("type: %s, ", nfc_get_nfca_type(dev_list[i].dev.nfca.type)); - } - printf("UID length: %d, UID:", dev_list[i].nfcidLen); - for(uint8_t j = 0; j < dev_list[i].nfcidLen; j++) { - printf("%02X", dev_list[i].nfcid[j]); - } - printf("\r\n"); + if(furi_hal_nfc_detect(&dev_data, 400)) { + printf("found: %s ", nfc_get_dev_type(dev_data.type)); + printf("UID length: %d, UID:", dev_data.uid_len); + for(size_t i = 0; i < dev_data.uid_len; i++) { + printf("%02X", dev_data.uid[i]); } + printf("\r\n"); + break; } + furi_hal_nfc_sleep(); osDelay(50); } - furi_hal_nfc_deactivate(); + furi_hal_nfc_sleep(); } -void nfc_cli_emulate(Cli* cli, string_t args) { +static void nfc_cli_emulate(Cli* cli, string_t args) { // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { printf("Nfc is busy\r\n"); @@ -60,26 +55,25 @@ void nfc_cli_emulate(Cli* cli, string_t args) { printf("Emulating NFC-A Type: T2T UID: 36 9C E7 B1 0A C1 34 SAK: 00 ATQA: 00/44\r\n"); printf("Press Ctrl+C to abort\r\n"); - NfcDeviceCommonData params = { + FuriHalNfcDevData params = { .uid = {0x36, 0x9C, 0xe7, 0xb1, 0x0A, 0xC1, 0x34}, .uid_len = 7, .atqa = {0x44, 0x00}, .sak = 0x00, - .device = NfcDeviceNfca, - .protocol = NfcDeviceProtocolMifareUl, + .type = FuriHalNfcTypeA, }; while(!cli_cmd_interrupt_received(cli)) { if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 100)) { printf("Reader detected\r\n"); - furi_hal_nfc_deactivate(); + furi_hal_nfc_sleep(); } osDelay(50); } - furi_hal_nfc_deactivate(); + furi_hal_nfc_sleep(); } -void nfc_cli_field(Cli* cli, string_t args) { +static void nfc_cli_field(Cli* cli, string_t args) { // Check if nfc worker is not busy if(furi_hal_nfc_is_busy()) { printf("Nfc is busy\r\n"); @@ -97,7 +91,7 @@ void nfc_cli_field(Cli* cli, string_t args) { } furi_hal_nfc_field_off(); - furi_hal_nfc_deactivate(); + furi_hal_nfc_sleep(); } static void nfc_cli(Cli* cli, string_t args, void* context) { diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index 954a48cd..c3e6bdd4 100644 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -41,31 +41,31 @@ static void nfc_device_prepare_format_string(NfcDevice* dev, string_t format_str static bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_string) { if(string_start_with_str_p(format_string, "UID")) { dev->format = NfcDeviceSaveFormatUid; - dev->dev_data.nfc_data.protocol = NfcDeviceProtocolUnknown; + dev->dev_data.protocol = NfcDeviceProtocolUnknown; return true; } if(string_start_with_str_p(format_string, "Bank card")) { dev->format = NfcDeviceSaveFormatBankCard; - dev->dev_data.nfc_data.protocol = NfcDeviceProtocolEMV; + dev->dev_data.protocol = NfcDeviceProtocolEMV; return true; } // Check Mifare Ultralight types for(MfUltralightType type = MfUltralightTypeUnknown; type < MfUltralightTypeNum; type++) { - if(string_start_with_str_p(format_string, nfc_mf_ul_type(type, true))) { + if(string_equal_str_p(format_string, nfc_mf_ul_type(type, true))) { dev->format = NfcDeviceSaveFormatMifareUl; - dev->dev_data.nfc_data.protocol = NfcDeviceProtocolMifareUl; + dev->dev_data.protocol = NfcDeviceProtocolMifareUl; dev->dev_data.mf_ul_data.type = type; return true; } } if(string_start_with_str_p(format_string, "Mifare Classic")) { dev->format = NfcDeviceSaveFormatMifareClassic; - dev->dev_data.nfc_data.protocol = NfcDeviceProtocolMifareClassic; + dev->dev_data.protocol = NfcDeviceProtocolMifareClassic; return true; } if(string_start_with_str_p(format_string, "Mifare DESFire")) { dev->format = NfcDeviceSaveFormatMifareDesfire; - dev->dev_data.nfc_data.protocol = NfcDeviceProtocolMifareDesfire; + dev->dev_data.protocol = NfcDeviceProtocolMifareDesfire; return true; } return false; @@ -73,7 +73,7 @@ static bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_strin static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { bool saved = false; - MifareUlData* data = &dev->dev_data.mf_ul_data; + MfUltralightData* data = &dev->dev_data.mf_ul_data; string_t temp_str; string_init(temp_str); @@ -122,7 +122,7 @@ static bool nfc_device_save_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; - MifareUlData* data = &dev->dev_data.mf_ul_data; + MfUltralightData* data = &dev->dev_data.mf_ul_data; string_t temp_str; string_init(temp_str); @@ -548,7 +548,7 @@ bool nfc_device_load_mifare_df_data(FlipperFormat* file, NfcDevice* dev) { static bool nfc_device_save_bank_card_data(FlipperFormat* file, NfcDevice* dev) { bool saved = false; - NfcEmvData* data = &dev->dev_data.emv_data; + EmvData* data = &dev->dev_data.emv_data; uint32_t data_temp = 0; do { @@ -577,8 +577,8 @@ static bool nfc_device_save_bank_card_data(FlipperFormat* file, NfcDevice* dev) bool nfc_device_load_bank_card_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; - NfcEmvData* data = &dev->dev_data.emv_data; - memset(data, 0, sizeof(NfcEmvData)); + EmvData* data = &dev->dev_data.emv_data; + memset(data, 0, sizeof(EmvData)); uint32_t data_cnt = 0; string_t temp_str; string_init(temp_str); @@ -700,7 +700,7 @@ static bool nfc_device_save_file( bool saved = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); - NfcDeviceCommonData* data = &dev->dev_data.nfc_data; + FuriHalNfcDevData* data = &dev->dev_data.nfc_data; string_t temp_str; string_init(temp_str); @@ -758,7 +758,7 @@ bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name) { static bool nfc_device_load_data(NfcDevice* dev, string_t path) { bool parsed = false; FlipperFormat* file = flipper_format_file_alloc(dev->storage); - NfcDeviceCommonData* data = &dev->dev_data.nfc_data; + FuriHalNfcDevData* data = &dev->dev_data.nfc_data; uint32_t data_cnt = 0; string_t temp_str; string_init(temp_str); @@ -789,6 +789,7 @@ static bool nfc_device_load_data(NfcDevice* dev, string_t path) { if(!nfc_device_parse_format_string(dev, temp_str)) break; // Read and parse UID, ATQA and SAK if(!flipper_format_get_value_count(file, "UID", &data_cnt)) break; + if(!(data_cnt == 4 || data_cnt == 7)) break; data->uid_len = data_cnt; if(!flipper_format_read_hex(file, "UID", data->uid, data->uid_len)) break; if(!flipper_format_read_hex(file, "ATQA", data->atqa, 2)) break; @@ -863,7 +864,7 @@ bool nfc_file_select(NfcDevice* dev) { } void nfc_device_data_clear(NfcDeviceData* dev_data) { - if(dev_data->nfc_data.protocol == NfcDeviceProtocolMifareDesfire) { + if(dev_data->protocol == NfcDeviceProtocolMifareDesfire) { mf_df_clear(&dev_data->mf_df_data); } } diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h index 78b2fe4c..215f637f 100644 --- a/applications/nfc/nfc_device.h +++ b/applications/nfc/nfc_device.h @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include #include @@ -17,13 +19,6 @@ #define NFC_APP_EXTENSION ".nfc" #define NFC_APP_SHADOW_EXTENSION ".shd" -typedef enum { - NfcDeviceNfca, - NfcDeviceNfcb, - NfcDeviceNfcf, - NfcDeviceNfcv, -} NfcDeviceType; - typedef enum { NfcDeviceProtocolUnknown, NfcDeviceProtocolEMV, @@ -40,38 +35,18 @@ typedef enum { NfcDeviceSaveFormatMifareDesfire, } NfcDeviceSaveFormat; -typedef struct { - uint8_t uid_len; - uint8_t uid[10]; - uint8_t atqa[2]; - uint8_t sak; - NfcDeviceType device; - NfcProtocol protocol; -} NfcDeviceCommonData; - -typedef struct { - char name[32]; - uint8_t aid[16]; - uint16_t aid_len; - uint8_t number[10]; - uint8_t number_len; - uint8_t exp_mon; - uint8_t exp_year; - uint16_t country_code; - uint16_t currency_code; -} NfcEmvData; - typedef struct { uint8_t data[NFC_READER_DATA_MAX_SIZE]; uint16_t size; } NfcReaderRequestData; typedef struct { - NfcDeviceCommonData nfc_data; + FuriHalNfcDevData nfc_data; + NfcProtocol protocol; NfcReaderRequestData reader_data; union { - NfcEmvData emv_data; - MifareUlData mf_ul_data; + EmvData emv_data; + MfUltralightData mf_ul_data; MfClassicData mf_classic_data; MifareDesfireData mf_df_data; }; diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index 34b9b906..51ea82e6 100755 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -40,7 +40,7 @@ struct Nfc { NotificationApp* notifications; SceneManager* scene_manager; NfcDevice* dev; - NfcDeviceCommonData dev_edit_data; + FuriHalNfcDevData dev_edit_data; char text_store[NFC_TEXT_STORE_SIZE + 1]; string_t text_box_store; diff --git a/applications/nfc/nfc_types.c b/applications/nfc/nfc_types.c index 6cd42445..1b67284c 100644 --- a/applications/nfc/nfc_types.c +++ b/applications/nfc/nfc_types.c @@ -1,48 +1,14 @@ #include "nfc_types.h" -const char* nfc_get_rfal_type(rfalNfcDevType type) { - if(type == RFAL_NFC_LISTEN_TYPE_NFCA) { +const char* nfc_get_dev_type(FuriHalNfcType type) { + if(type == FuriHalNfcTypeA) { return "NFC-A"; - } else if(type == RFAL_NFC_LISTEN_TYPE_NFCB) { + } else if(type == FuriHalNfcTypeB) { return "NFC-B"; - } else if(type == RFAL_NFC_LISTEN_TYPE_NFCF) { + } else if(type == FuriHalNfcTypeF) { return "NFC-F"; - } else if(type == RFAL_NFC_LISTEN_TYPE_NFCV) { + } else if(type == FuriHalNfcTypeV) { return "NFC-V"; - } else if(type == RFAL_NFC_LISTEN_TYPE_ST25TB) { - return "NFC-ST25TB"; - } else if(type == RFAL_NFC_LISTEN_TYPE_AP2P) { - return "NFC-AP2P"; - } else { - return "Unknown"; - } -} - -const char* nfc_get_dev_type(NfcDeviceType type) { - if(type == NfcDeviceNfca) { - return "NFC-A"; - } else if(type == NfcDeviceNfcb) { - return "NFC-B"; - } else if(type == NfcDeviceNfcf) { - return "NFC-F"; - } else if(type == NfcDeviceNfcv) { - return "NFC-V"; - } else { - return "Unknown"; - } -} - -const char* nfc_get_nfca_type(rfalNfcaListenDeviceType type) { - if(type == RFAL_NFCA_T1T) { - return "T1T"; - } else if(type == RFAL_NFCA_T2T) { - return "T2T"; - } else if(type == RFAL_NFCA_T4T) { - return "T4T"; - } else if(type == RFAL_NFCA_NFCDEP) { - return "NFCDEP"; - } else if(type == RFAL_NFCA_T4T_NFCDEP) { - return "T4T_NFCDEP"; } else { return "Unknown"; } diff --git a/applications/nfc/nfc_types.h b/applications/nfc/nfc_types.h index 267934d6..fb53ce7c 100644 --- a/applications/nfc/nfc_types.h +++ b/applications/nfc/nfc_types.h @@ -1,16 +1,8 @@ #pragma once -#include "st_errno.h" -#include "rfal_nfc.h" +#include "nfc_device.h" -#include -#include "nfc_worker.h" - -const char* nfc_get_rfal_type(rfalNfcDevType type); - -const char* nfc_get_dev_type(NfcDeviceType type); - -const char* nfc_get_nfca_type(rfalNfcaListenDeviceType type); +const char* nfc_get_dev_type(FuriHalNfcType type); const char* nfc_guess_protocol(NfcProtocol protocol); diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index a925a8d7..13248394 100644 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -2,7 +2,8 @@ #include #include -#include +#include +#include #include #include #include @@ -94,22 +95,20 @@ int32_t nfc_worker_task(void* context) { nfc_worker_emulate(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateReadEMVApp) { nfc_worker_read_emv_app(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateReadEMV) { + } else if(nfc_worker->state == NfcWorkerStateReadEMVData) { nfc_worker_read_emv(nfc_worker); } else if(nfc_worker->state == NfcWorkerStateEmulateApdu) { nfc_worker_emulate_apdu(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateReadMifareUl) { - nfc_worker_read_mifare_ul(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateEmulateMifareUl) { + } else if(nfc_worker->state == NfcWorkerStateReadMifareUltralight) { + nfc_worker_read_mifare_ultralight(nfc_worker); + } else if(nfc_worker->state == NfcWorkerStateEmulateMifareUltralight) { 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 == NfcWorkerStateReadMifareDesfire) { nfc_worker_read_mifare_desfire(nfc_worker); - } else if(nfc_worker->state == NfcWorkerStateField) { - nfc_worker_field(nfc_worker); } - furi_hal_nfc_deactivate(); + furi_hal_nfc_sleep(); nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); furi_hal_power_insomnia_exit(); @@ -117,579 +116,225 @@ int32_t nfc_worker_task(void* context) { } void nfc_worker_detect(NfcWorker* nfc_worker) { - rfalNfcDevice* dev_list; - rfalNfcDevice* dev; - uint8_t dev_cnt; nfc_device_data_clear(nfc_worker->dev_data); - NfcDeviceCommonData* result = &nfc_worker->dev_data->nfc_data; + NfcDeviceData* dev_data = nfc_worker->dev_data; + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; while(nfc_worker->state == NfcWorkerStateDetect) { - if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) { + if(furi_hal_nfc_detect(nfc_data, 1000)) { // Process first found device - dev = &dev_list[0]; - result->uid_len = dev->nfcidLen; - memcpy(result->uid, dev->nfcid, dev->nfcidLen); - if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCA) { - result->device = NfcDeviceNfca; - result->atqa[0] = dev->dev.nfca.sensRes.anticollisionInfo; - result->atqa[1] = dev->dev.nfca.sensRes.platformInfo; - result->sak = dev->dev.nfca.selRes.sak; - if(mf_ul_check_card_type( - dev->dev.nfca.sensRes.anticollisionInfo, - dev->dev.nfca.sensRes.platformInfo, - dev->dev.nfca.selRes.sak)) { - result->protocol = NfcDeviceProtocolMifareUl; + if(nfc_data->type == FuriHalNfcTypeA) { + if(mf_ul_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { + dev_data->protocol = NfcDeviceProtocolMifareUl; } else if(mf_classic_check_card_type( - dev->dev.nfca.sensRes.anticollisionInfo, - dev->dev.nfca.sensRes.platformInfo, - dev->dev.nfca.selRes.sak)) { - result->protocol = NfcDeviceProtocolMifareClassic; + nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { + dev_data->protocol = NfcDeviceProtocolMifareClassic; } else if(mf_df_check_card_type( - dev->dev.nfca.sensRes.anticollisionInfo, - dev->dev.nfca.sensRes.platformInfo, - dev->dev.nfca.selRes.sak)) { - result->protocol = NfcDeviceProtocolMifareDesfire; - } else if(dev->rfInterface == RFAL_NFC_INTERFACE_ISODEP) { - result->protocol = NfcDeviceProtocolEMV; + nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { + dev_data->protocol = NfcDeviceProtocolMifareDesfire; + } else if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { + dev_data->protocol = NfcDeviceProtocolEMV; } else { - result->protocol = NfcDeviceProtocolUnknown; + dev_data->protocol = NfcDeviceProtocolUnknown; } - } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCB) { - result->device = NfcDeviceNfcb; - } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCF) { - result->device = NfcDeviceNfcf; - } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCV) { - result->device = NfcDeviceNfcv; } + // Notify caller and exit if(nfc_worker->callback) { nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); } break; } + furi_hal_nfc_sleep(); osDelay(100); } } -bool nfc_worker_emulate_uid_callback( - uint8_t* buff_rx, - uint16_t buff_rx_len, - uint8_t* buff_tx, - uint16_t* buff_tx_len, - uint32_t* data_type, - void* context) { - furi_assert(context); - NfcWorker* nfc_worker = context; - NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data; - reader_data->size = buff_rx_len / 8; - if(reader_data->size > 0) { - memcpy(reader_data->data, buff_rx, reader_data->size); - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - } - return true; -} - void nfc_worker_emulate(NfcWorker* nfc_worker) { - NfcDeviceCommonData* data = &nfc_worker->dev_data->nfc_data; + FuriHalNfcTxRxContext tx_rx = {}; + FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data; + NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data; + while(nfc_worker->state == NfcWorkerStateEmulate) { - furi_hal_nfc_emulate_nfca( - data->uid, - data->uid_len, - data->atqa, - data->sak, - nfc_worker_emulate_uid_callback, - nfc_worker, - 1000); + if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, true, 100)) { + if(furi_hal_nfc_tx_rx(&tx_rx, 100)) { + reader_data->size = tx_rx.rx_bits / 8; + if(reader_data->size > 0) { + memcpy(reader_data->data, tx_rx.rx_data, reader_data->size); + if(nfc_worker->callback) { + nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); + } + } + } else { + FURI_LOG_E(TAG, "Failed to get reader commands"); + } + } } } void nfc_worker_read_emv_app(NfcWorker* nfc_worker) { - ReturnCode err; - rfalNfcDevice* dev_list; + FuriHalNfcTxRxContext tx_rx = {}; EmvApplication emv_app = {}; - uint8_t dev_cnt = 0; - uint8_t tx_buff[255] = {}; - uint16_t tx_len = 0; - uint8_t* rx_buff; - uint16_t* rx_len; NfcDeviceData* result = nfc_worker->dev_data; + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; nfc_device_data_clear(result); while(nfc_worker->state == NfcWorkerStateReadEMVApp) { - memset(&emv_app, 0, sizeof(emv_app)); - if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { + if(furi_hal_nfc_detect(nfc_data, 1000)) { // Card was found. Check that it supports EMV - if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) { - result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; - result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo; - result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo; - result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak; - memcpy( - result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len); - result->nfc_data.protocol = NfcDeviceProtocolEMV; - - FURI_LOG_D(TAG, "Send select PPSE command"); - tx_len = emv_prepare_select_ppse(tx_buff); - err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); - if(err != ERR_NONE) { - FURI_LOG_D(TAG, "Error during selection PPSE request: %d", err); - furi_hal_nfc_deactivate(); - continue; - } - FURI_LOG_D(TAG, "Select PPSE response received. Start parsing response"); - if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) { - FURI_LOG_D(TAG, "Select PPSE responce parced"); + if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { + result->protocol = NfcDeviceProtocolEMV; + if(emv_search_application(&tx_rx, &emv_app)) { // Notify caller and exit result->emv_data.aid_len = emv_app.aid_len; memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len); if(nfc_worker->callback) { nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); } - break; - } else { - FURI_LOG_D(TAG, "Can't find pay application"); - furi_hal_nfc_deactivate(); - continue; } } else { - // Can't find EMV card FURI_LOG_W(TAG, "Card doesn't support EMV"); - furi_hal_nfc_deactivate(); } } else { - // Can't find EMV card FURI_LOG_D(TAG, "Can't find any cards"); - furi_hal_nfc_deactivate(); } + furi_hal_nfc_sleep(); osDelay(20); } } void nfc_worker_read_emv(NfcWorker* nfc_worker) { - ReturnCode err; - rfalNfcDevice* dev_list; + FuriHalNfcTxRxContext tx_rx = {}; EmvApplication emv_app = {}; - uint8_t dev_cnt = 0; - uint8_t tx_buff[255] = {}; - uint16_t tx_len = 0; - uint8_t* rx_buff; - uint16_t* rx_len; NfcDeviceData* result = nfc_worker->dev_data; + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; nfc_device_data_clear(result); - while(nfc_worker->state == NfcWorkerStateReadEMV) { - memset(&emv_app, 0, sizeof(emv_app)); - if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { + while(nfc_worker->state == NfcWorkerStateReadEMVData) { + if(furi_hal_nfc_detect(nfc_data, 1000)) { // Card was found. Check that it supports EMV - if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) { - result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; - result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo; - result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo; - result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak; - memcpy( - result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len); - result->nfc_data.protocol = NfcDeviceProtocolEMV; - - FURI_LOG_D(TAG, "Send select PPSE command"); - tx_len = emv_prepare_select_ppse(tx_buff); - err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); - if(err != ERR_NONE) { - FURI_LOG_D(TAG, "Error during selection PPSE request: %d", err); - furi_hal_nfc_deactivate(); - continue; - } - FURI_LOG_D(TAG, "Select PPSE response received. Start parsing response"); - if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) { - FURI_LOG_D(TAG, "Select PPSE responce parced"); + if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { + result->protocol = NfcDeviceProtocolEMV; + if(emv_read_bank_card(&tx_rx, &emv_app)) { + result->emv_data.number_len = emv_app.card_number_len; + memcpy( + result->emv_data.number, emv_app.card_number, result->emv_data.number_len); result->emv_data.aid_len = emv_app.aid_len; memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len); - } else { - FURI_LOG_D(TAG, "Can't find pay application"); - furi_hal_nfc_deactivate(); - continue; + if(emv_app.name_found) { + memcpy(result->emv_data.name, emv_app.name, sizeof(emv_app.name)); + } + if(emv_app.exp_month) { + result->emv_data.exp_mon = emv_app.exp_month; + result->emv_data.exp_year = emv_app.exp_year; + } + if(emv_app.country_code) { + result->emv_data.country_code = emv_app.country_code; + } + if(emv_app.currency_code) { + result->emv_data.currency_code = emv_app.currency_code; + } + // Notify caller and exit + if(nfc_worker->callback) { + nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); + } + break; } - FURI_LOG_D(TAG, "Starting application ..."); - tx_len = emv_prepare_select_app(tx_buff, &emv_app); - err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); - if(err != ERR_NONE) { - FURI_LOG_D(TAG, "Error during application selection request: %d", err); - furi_hal_nfc_deactivate(); - continue; - } - FURI_LOG_D(TAG, "Select application response received. Start parsing response"); - if(emv_decode_select_app_response(rx_buff, *rx_len, &emv_app)) { - FURI_LOG_D(TAG, "Card name: %s", emv_app.name); - memcpy(result->emv_data.name, emv_app.name, sizeof(emv_app.name)); - } else if(emv_app.pdol.size > 0) { - FURI_LOG_D(TAG, "Can't find card name, but PDOL is present."); - } else { - FURI_LOG_D(TAG, "Can't find card name or PDOL"); - furi_hal_nfc_deactivate(); - continue; - } - FURI_LOG_D(TAG, "Starting Get Processing Options command ..."); - tx_len = emv_prepare_get_proc_opt(tx_buff, &emv_app); - err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); - if(err != ERR_NONE) { - FURI_LOG_D(TAG, "Error during Get Processing Options command: %d", err); - furi_hal_nfc_deactivate(); - continue; - } - if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) { - FURI_LOG_D(TAG, "Card number parsed"); - result->emv_data.number_len = emv_app.card_number_len; - memcpy(result->emv_data.number, emv_app.card_number, emv_app.card_number_len); + } else { + FURI_LOG_W(TAG, "Card doesn't support EMV"); + } + } else { + FURI_LOG_D(TAG, "Can't find any cards"); + } + furi_hal_nfc_sleep(); + osDelay(20); + } +} + +void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { + FuriHalNfcTxRxContext tx_rx = {}; + FuriHalNfcDevData params = { + .uid = {0xCF, 0x72, 0xd4, 0x40}, + .uid_len = 4, + .atqa = {0x00, 0x04}, + .sak = 0x20, + .type = FuriHalNfcTypeA, + }; + + while(nfc_worker->state == NfcWorkerStateEmulateApdu) { + if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 300)) { + FURI_LOG_D(TAG, "POS terminal detected"); + if(emv_card_emulation(&tx_rx)) { + FURI_LOG_D(TAG, "EMV card emulated"); + } + } else { + FURI_LOG_D(TAG, "Can't find reader"); + } + furi_hal_nfc_sleep(); + osDelay(20); + } +} + +void nfc_worker_read_mifare_ultralight(NfcWorker* nfc_worker) { + FuriHalNfcTxRxContext tx_rx = {}; + MfUltralightReader reader = {}; + MfUltralightData data = {}; + NfcDeviceData* result = nfc_worker->dev_data; + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; + + while(nfc_worker->state == NfcWorkerStateReadMifareUltralight) { + if(furi_hal_nfc_detect(nfc_data, 300)) { + if(nfc_data->type == FuriHalNfcTypeA && + mf_ul_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { + FURI_LOG_D(TAG, "Found Mifare Ultralight tag. Start reading"); + if(mf_ul_read_card(&tx_rx, &reader, &data)) { + result->protocol = NfcDeviceProtocolMifareUl; + result->mf_ul_data = data; // Notify caller and exit if(nfc_worker->callback) { nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); } break; } else { - // Mastercard doesn't give PAN / card number as GPO response - // Iterate over all files found in application - bool pan_found = false; - for(uint8_t i = 0; (i < emv_app.afl.size) && !pan_found; i += 4) { - uint8_t sfi = emv_app.afl.data[i] >> 3; - uint8_t record_start = emv_app.afl.data[i + 1]; - uint8_t record_end = emv_app.afl.data[i + 2]; - - // Iterate over all records in file - for(uint8_t record = record_start; record <= record_end; ++record) { - tx_len = emv_prepare_read_sfi_record(tx_buff, sfi, record); - err = furi_hal_nfc_data_exchange( - tx_buff, tx_len, &rx_buff, &rx_len, false); - if(err != ERR_NONE) { - FURI_LOG_D( - TAG, - "Error reading application sfi %d, record %d", - sfi, - record); - } - if(emv_decode_read_sfi_record(rx_buff, *rx_len, &emv_app)) { - pan_found = true; - break; - } - } - } - if(pan_found) { - FURI_LOG_D(TAG, "Card PAN found"); - result->emv_data.number_len = emv_app.card_number_len; - memcpy( - result->emv_data.number, - emv_app.card_number, - result->emv_data.number_len); - if(emv_app.exp_month) { - result->emv_data.exp_mon = emv_app.exp_month; - result->emv_data.exp_year = emv_app.exp_year; - } - if(emv_app.country_code) { - result->emv_data.country_code = emv_app.country_code; - } - if(emv_app.currency_code) { - result->emv_data.currency_code = emv_app.currency_code; - } - // Notify caller and exit - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - break; - } else { - FURI_LOG_D(TAG, "Can't read card number"); - } - furi_hal_nfc_deactivate(); + FURI_LOG_D(TAG, "Failed reading Mifare Ultralight"); } } else { - // Can't find EMV card - FURI_LOG_W(TAG, "Card doesn't support EMV"); - furi_hal_nfc_deactivate(); - } - } else { - // Can't find EMV card - FURI_LOG_D(TAG, "Can't find any cards"); - furi_hal_nfc_deactivate(); - } - osDelay(20); - } -} - -void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { - ReturnCode err; - uint8_t tx_buff[255] = {}; - uint16_t tx_len = 0; - uint8_t* rx_buff; - uint16_t* rx_len; - NfcDeviceCommonData params = { - .uid = {0xCF, 0x72, 0xd4, 0x40}, - .uid_len = 4, - .atqa = {0x00, 0x04}, - .sak = 0x20, - .device = NfcDeviceNfca, - .protocol = NfcDeviceProtocolEMV, - }; - // Test RX data - const uint8_t debug_rx[] = { - 0xba, 0x0b, 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, - 0xca, 0xfe, 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, - 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, - 0x0b, 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, - 0xfe, 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, - 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, - 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, - 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, - 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, - 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, - 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, - 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, 0xba, - 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, 0xce, - 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, - 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, 0xba, 0x20, - 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, 0xce, 0x14, - 0x88, 0x00}; - // Test TX data - const uint8_t debug_tx[] = { - 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, - 0x10, 0x14, 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, - 0xbe, 0xef, 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, - 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x14, 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, - 0xef, 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, - 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, - 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, - 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, - 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, - 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xce, - 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, 0x78, - 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, 0x02, - 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xce, 0xee, - 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, 0x78, 0x9a, - 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, 0x02, 0x28, - 0x00, 0x00}; - - while(nfc_worker->state == NfcWorkerStateEmulateApdu) { - if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 300)) { - FURI_LOG_D(TAG, "POS terminal detected"); - // Read data from POS terminal - err = furi_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false); - if(err == ERR_NONE) { - FURI_LOG_D(TAG, "Received Select PPSE"); - } else { - FURI_LOG_D(TAG, "Error in 1st data exchange: select PPSE"); - furi_hal_nfc_deactivate(); - continue; - } - FURI_LOG_D(TAG, "Transive SELECT PPSE ANS"); - tx_len = emv_select_ppse_ans(tx_buff); - err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); - if(err == ERR_NONE) { - FURI_LOG_D(TAG, "Received Select APP"); - } else { - FURI_LOG_D(TAG, "Error in 2nd data exchange: select APP"); - furi_hal_nfc_deactivate(); - continue; - } - - FURI_LOG_D(TAG, "Transive SELECT APP ANS"); - tx_len = emv_select_app_ans(tx_buff); - err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); - if(err == ERR_NONE) { - FURI_LOG_D(TAG, "Received PDOL"); - } else { - FURI_LOG_D(TAG, "Error in 3rd data exchange: receive PDOL"); - furi_hal_nfc_deactivate(); - continue; - } - - FURI_LOG_D(TAG, "Transive PDOL ANS"); - tx_len = emv_get_proc_opt_ans(tx_buff); - err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); - if(err == ERR_NONE) { - FURI_LOG_D(TAG, "Transive PDOL ANS"); - } else { - FURI_LOG_D(TAG, "Error in 4rd data exchange: Transive PDOL ANS"); - furi_hal_nfc_deactivate(); - continue; - } - - if(*rx_len != sizeof(debug_rx) || memcmp(rx_buff, debug_rx, sizeof(debug_rx))) { - FURI_LOG_D(TAG, "Failed long message test"); - } else { - FURI_LOG_D(TAG, "Correct debug message received"); - tx_len = sizeof(debug_tx); - err = furi_hal_nfc_data_exchange( - (uint8_t*)debug_tx, tx_len, &rx_buff, &rx_len, false); - if(err == ERR_NONE) { - FURI_LOG_D(TAG, "Transive Debug message"); - } - } - furi_hal_nfc_deactivate(); - } else { - FURI_LOG_D(TAG, "Can't find reader"); - } - osDelay(20); - } -} - -void nfc_worker_read_mifare_ul(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; - MifareUlDevice mf_ul_read; - NfcDeviceData* result = nfc_worker->dev_data; - nfc_device_data_clear(result); - - while(nfc_worker->state == NfcWorkerStateReadMifareUl) { - furi_hal_nfc_deactivate(); - memset(&mf_ul_read, 0, sizeof(mf_ul_read)); - if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, 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_D(TAG, "Found Mifare Ultralight tag. Reading tag version"); - tx_len = mf_ul_prepare_get_version(tx_buff); - err = furi_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_D( - TAG, - "Mifare Ultralight Type: %d, Pages: %d", - mf_ul_read.data.type, - mf_ul_read.pages_to_read); - FURI_LOG_D(TAG, "Reading signature ..."); - tx_len = mf_ul_prepare_read_signature(tx_buff); - if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { - FURI_LOG_D(TAG, "Failed reading signature"); - memset(mf_ul_read.data.signature, 0, sizeof(mf_ul_read.data.signature)); - } else { - mf_ul_parse_read_signature_response(rx_buff, &mf_ul_read); - } - } else if(err == ERR_TIMEOUT) { - FURI_LOG_D( - TAG, - "Card doesn't respond to GET VERSION command. Setting default read parameters"); - err = ERR_NONE; - mf_ul_set_default_version(&mf_ul_read); - // Reinit device - furi_hal_nfc_deactivate(); - if(!furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) { - FURI_LOG_D(TAG, "Lost connection. Restarting search"); - continue; - } - } else { - FURI_LOG_D( - TAG, "Error getting Mifare Ultralight version. Error code: %d", err); - continue; - } - - if(mf_ul_read.support_fast_read) { - FURI_LOG_D(TAG, "Reading pages ..."); - tx_len = mf_ul_prepare_fast_read(tx_buff, 0x00, mf_ul_read.pages_to_read - 1); - if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { - FURI_LOG_D(TAG, "Failed reading pages"); - continue; - } else { - mf_ul_parse_fast_read_response( - rx_buff, 0x00, mf_ul_read.pages_to_read - 1, &mf_ul_read); - } - - FURI_LOG_D(TAG, "Reading 3 counters ..."); - for(uint8_t i = 0; i < 3; i++) { - tx_len = mf_ul_prepare_read_cnt(tx_buff, i); - if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { - FURI_LOG_W(TAG, "Failed reading Counter %d", i); - mf_ul_read.data.counter[i] = 0; - } else { - mf_ul_parse_read_cnt_response(rx_buff, i, &mf_ul_read); - } - } - - FURI_LOG_D(TAG, "Checking tearing flags ..."); - for(uint8_t i = 0; i < 3; i++) { - tx_len = mf_ul_prepare_check_tearing(tx_buff, i); - if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { - FURI_LOG_D(TAG, "Error checking tearing flag %d", i); - mf_ul_read.data.tearing[i] = MF_UL_TEARING_FLAG_DEFAULT; - } else { - mf_ul_parse_check_tearing_response(rx_buff, i, &mf_ul_read); - } - } - } 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) { - FURI_LOG_D(TAG, "Reading pages %d - %d ...", page, page + 3); - tx_len = mf_ul_prepare_read(tx_buff, page); - if(furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false)) { - FURI_LOG_D(TAG, "Read pages %d - %d failed", page, page + 3); - continue; - } else { - mf_ul_parse_read_response(rx_buff, page, &mf_ul_read); - } - } - } - - // Fill result data - result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; - result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo; - result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo; - result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak; - result->nfc_data.protocol = NfcDeviceProtocolMifareUl; - memcpy( - result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len); - result->mf_ul_data = mf_ul_read.data; - - // Notify caller and exit - if(nfc_worker->callback) { - nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); - } - break; - } else { - FURI_LOG_W(TAG, "Tag does not support Mifare Ultralight"); + FURI_LOG_W(TAG, "Tag is not Mifare Ultralight"); } } else { FURI_LOG_D(TAG, "Can't find any tags"); } + furi_hal_nfc_sleep(); osDelay(100); } } void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) { - NfcDeviceCommonData* nfc_common = &nfc_worker->dev_data->nfc_data; - MifareUlDevice mf_ul_emulate; - mf_ul_prepare_emulation(&mf_ul_emulate, &nfc_worker->dev_data->mf_ul_data); - while(nfc_worker->state == NfcWorkerStateEmulateMifareUl) { + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; + MfUltralightEmulator emulator = {}; + mf_ul_prepare_emulation(&emulator, &nfc_worker->dev_data->mf_ul_data); + while(nfc_worker->state == NfcWorkerStateEmulateMifareUltralight) { furi_hal_nfc_emulate_nfca( - nfc_common->uid, - nfc_common->uid_len, - nfc_common->atqa, - nfc_common->sak, + nfc_data->uid, + nfc_data->uid_len, + nfc_data->atqa, + nfc_data->sak, mf_ul_prepare_emulation_response, - &mf_ul_emulate, + &emulator, 5000); // Check if data was modified - if(mf_ul_emulate.data_changed) { - nfc_worker->dev_data->mf_ul_data = mf_ul_emulate.data; + if(emulator.data_changed) { + nfc_worker->dev_data->mf_ul_data = emulator.data; if(nfc_worker->callback) { nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context); } - mf_ul_emulate.data_changed = false; + emulator.data_changed = false; } } } void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { furi_assert(nfc_worker->callback); - rfalNfcDevice* dev_list; - rfalNfcDevice* dev; - NfcDeviceCommonData* nfc_common; - uint8_t dev_cnt = 0; FuriHalNfcTxRxContext tx_rx_ctx = {}; MfClassicAuthContext auth_ctx = {}; MfClassicReader reader = {}; @@ -697,6 +342,7 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { uint16_t curr_sector = 0; uint8_t total_sectors = 0; NfcWorkerEvent event; + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; // Open dictionary nfc_worker->dict_stream = file_stream_alloc(nfc_worker->storage); @@ -710,14 +356,13 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { // Detect Mifare Classic card while(nfc_worker->state == NfcWorkerStateReadMifareClassic) { - if(furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) { - dev = &dev_list[0]; + if(furi_hal_nfc_detect(nfc_data, 300)) { if(mf_classic_get_type( - dev->nfcid, - dev->nfcidLen, - dev->dev.nfca.sensRes.anticollisionInfo, - dev->dev.nfca.sensRes.platformInfo, - dev->dev.nfca.selRes.sak, + nfc_data->uid, + nfc_data->uid_len, + nfc_data->atqa[0], + nfc_data->atqa[1], + nfc_data->sak, &reader)) { total_sectors = mf_classic_get_total_sectors_num(&reader); if(reader.type == MfClassicType1k) { @@ -745,7 +390,7 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { mf_classic_auth_init_context(&auth_ctx, reader.cuid, curr_sector); bool sector_key_found = false; while(nfc_mf_classic_dict_get_next_key(nfc_worker->dict_stream, &curr_key)) { - furi_hal_nfc_deactivate(); + furi_hal_nfc_sleep(); if(furi_hal_nfc_activate_nfca(300, &reader.cuid)) { if(!card_found_notified) { if(reader.type == MfClassicType1k) { @@ -817,15 +462,8 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { uint8_t sectors_read = mf_classic_read_card(&tx_rx_ctx, &reader, &nfc_worker->dev_data->mf_classic_data); if(sectors_read) { - dev = &dev_list[0]; - nfc_common = &nfc_worker->dev_data->nfc_data; - nfc_common->uid_len = dev->dev.nfca.nfcId1Len; - nfc_common->atqa[0] = dev->dev.nfca.sensRes.anticollisionInfo; - nfc_common->atqa[1] = dev->dev.nfca.sensRes.platformInfo; - nfc_common->sak = dev->dev.nfca.selRes.sak; - nfc_common->protocol = NfcDeviceProtocolMifareClassic; - memcpy(nfc_common->uid, dev->dev.nfca.nfcId1, nfc_common->uid_len); event = NfcWorkerEventSuccess; + nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic; FURI_LOG_I(TAG, "Successfully read %d sectors", sectors_read); } else { event = NfcWorkerEventFail; @@ -838,42 +476,8 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { stream_free(nfc_worker->dict_stream); } -ReturnCode nfc_exchange_full( - uint8_t* tx_buff, - uint16_t tx_len, - uint8_t* rx_buff, - uint16_t rx_cap, - uint16_t* rx_len) { - ReturnCode err; - uint8_t* part_buff; - uint16_t* part_len; - - err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &part_buff, &part_len, false); - if(*part_len > rx_cap) { - return ERR_OVERRUN; - } - memcpy(rx_buff, part_buff, *part_len); - *rx_len = *part_len; - while(err == ERR_NONE && rx_buff[0] == 0xAF) { - err = furi_hal_nfc_data_exchange(rx_buff, 1, &part_buff, &part_len, false); - if(*part_len > rx_cap - *rx_len) { - return ERR_OVERRUN; - } - if(*part_len == 0) { - return ERR_PROTO; - } - memcpy(rx_buff + *rx_len, part_buff + 1, *part_len - 1); - *rx_buff = *part_buff; - *rx_len += *part_len - 1; - } - - return err; -} - void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { ReturnCode err; - rfalNfcDevice* dev_list; - uint8_t dev_cnt = 0; uint8_t tx_buff[64] = {}; uint16_t tx_len = 0; uint8_t rx_buff[512] = {}; @@ -881,19 +485,17 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { NfcDeviceData* result = nfc_worker->dev_data; nfc_device_data_clear(result); MifareDesfireData* data = &result->mf_df_data; + FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; while(nfc_worker->state == NfcWorkerStateReadMifareDesfire) { - furi_hal_nfc_deactivate(); - if(!furi_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) { + furi_hal_nfc_sleep(); + if(!furi_hal_nfc_detect(nfc_data, 300)) { osDelay(100); continue; } memset(data, 0, sizeof(MifareDesfireData)); - if(dev_list[0].type != RFAL_NFC_LISTEN_TYPE_NFCA || - !mf_df_check_card_type( - dev_list[0].dev.nfca.sensRes.anticollisionInfo, - dev_list[0].dev.nfca.sensRes.platformInfo, - dev_list[0].dev.nfca.selRes.sak)) { + if(nfc_data->type != FuriHalNfcTypeA || + !mf_df_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) { FURI_LOG_D(TAG, "Tag is not DESFire"); osDelay(100); continue; @@ -901,18 +503,11 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { FURI_LOG_D(TAG, "Found DESFire tag"); - // Fill non-DESFire result data - result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; - result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo; - result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo; - result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak; - result->nfc_data.device = NfcDeviceNfca; - result->nfc_data.protocol = NfcDeviceProtocolMifareDesfire; - memcpy(result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len); + result->protocol = NfcDeviceProtocolMifareDesfire; // Get DESFire version tx_len = mf_df_prepare_get_version(tx_buff); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_W(TAG, "Bad exchange getting version, err: %d", err); continue; @@ -923,7 +518,7 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { } tx_len = mf_df_prepare_get_free_memory(tx_buff); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err == ERR_NONE) { data->free_memory = malloc(sizeof(MifareDesfireFreeMemory)); memset(data->free_memory, 0, sizeof(MifareDesfireFreeMemory)); @@ -935,7 +530,7 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { } tx_len = mf_df_prepare_get_key_settings(tx_buff); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_D(TAG, "Bad exchange getting key settings, err: %d", err); } else { @@ -951,7 +546,8 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { &data->master_key_settings->key_version_head; for(uint8_t key_id = 0; key_id < data->master_key_settings->max_keys; key_id++) { tx_len = mf_df_prepare_get_key_version(tx_buff, key_id); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = + furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_W(TAG, "Bad exchange getting key version, err: %d", err); continue; @@ -970,7 +566,7 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { } tx_len = mf_df_prepare_get_application_ids(tx_buff); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_W(TAG, "Bad exchange getting application IDs, err: %d", err); } else { @@ -981,13 +577,13 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { for(MifareDesfireApplication* app = data->app_head; app; app = app->next) { tx_len = mf_df_prepare_select_application(tx_buff, app->id); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(!mf_df_parse_select_application_response(rx_buff, rx_len)) { FURI_LOG_W(TAG, "Bad exchange selecting application, err: %d", err); continue; } tx_len = mf_df_prepare_get_key_settings(tx_buff); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_W(TAG, "Bad exchange getting key settings, err: %d", err); } else { @@ -1002,7 +598,8 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { MifareDesfireKeyVersion** key_version_head = &app->key_settings->key_version_head; for(uint8_t key_id = 0; key_id < app->key_settings->max_keys; key_id++) { tx_len = mf_df_prepare_get_key_version(tx_buff, key_id); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = furi_hal_nfc_exchange_full( + tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_W(TAG, "Bad exchange getting key version, err: %d", err); continue; @@ -1021,7 +618,7 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { } tx_len = mf_df_prepare_get_file_ids(tx_buff); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_W(TAG, "Bad exchange getting file IDs, err: %d", err); } else { @@ -1032,7 +629,8 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { for(MifareDesfireFile* file = app->file_head; file; file = file->next) { tx_len = mf_df_prepare_get_file_settings(tx_buff, file->id); - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = + furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_W(TAG, "Bad exchange getting file settings, err: %d", err); continue; @@ -1054,7 +652,8 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { tx_len = mf_df_prepare_read_records(tx_buff, file->id, 0, 0); break; } - err = nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); + err = + furi_hal_nfc_exchange_full(tx_buff, tx_len, rx_buff, sizeof(rx_buff), &rx_len); if(err != ERR_NONE) { FURI_LOG_W(TAG, "Bad exchange reading file %d, err: %d", file->id, err); continue; @@ -1073,11 +672,3 @@ void nfc_worker_read_mifare_desfire(NfcWorker* nfc_worker) { break; } } - -void nfc_worker_field(NfcWorker* nfc_worker) { - furi_hal_nfc_field_on(); - while(nfc_worker->state == NfcWorkerStateField) { - osDelay(50); - } - furi_hal_nfc_field_off(); -} diff --git a/applications/nfc/nfc_worker.h b/applications/nfc/nfc_worker.h index a0a5ae83..1933a79b 100755 --- a/applications/nfc/nfc_worker.h +++ b/applications/nfc/nfc_worker.h @@ -13,11 +13,11 @@ typedef enum { NfcWorkerStateDetect, NfcWorkerStateEmulate, NfcWorkerStateReadEMVApp, - NfcWorkerStateReadEMV, + NfcWorkerStateReadEMVData, NfcWorkerStateEmulateApdu, NfcWorkerStateField, - NfcWorkerStateReadMifareUl, - NfcWorkerStateEmulateMifareUl, + NfcWorkerStateReadMifareUltralight, + NfcWorkerStateEmulateMifareUltralight, NfcWorkerStateReadMifareClassic, NfcWorkerStateReadMifareDesfire, // Transition diff --git a/applications/nfc/nfc_worker_i.h b/applications/nfc/nfc_worker_i.h index bba983fc..a6f937f7 100755 --- a/applications/nfc/nfc_worker_i.h +++ b/applications/nfc/nfc_worker_i.h @@ -4,19 +4,8 @@ #include "nfc_worker.h" #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - struct NfcWorker { FuriThread* thread; Storage* storage; @@ -44,9 +33,7 @@ void nfc_worker_detect(NfcWorker* nfc_worker); void nfc_worker_emulate(NfcWorker* nfc_worker); -void nfc_worker_field(NfcWorker* nfc_worker); - -void nfc_worker_read_mifare_ul(NfcWorker* nfc_worker); +void nfc_worker_read_mifare_ultralight(NfcWorker* nfc_worker); void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker); diff --git a/applications/nfc/scenes/nfc_scene_card_menu.c b/applications/nfc/scenes/nfc_scene_card_menu.c index 03497958..b7862409 100755 --- a/applications/nfc/scenes/nfc_scene_card_menu.c +++ b/applications/nfc/scenes/nfc_scene_card_menu.c @@ -17,7 +17,7 @@ void nfc_scene_card_menu_on_enter(void* context) { Nfc* nfc = context; Submenu* submenu = nfc->submenu; - if(nfc->dev->dev_data.nfc_data.protocol > NfcDeviceProtocolUnknown) { + if(nfc->dev->dev_data.protocol > NfcDeviceProtocolUnknown) { submenu_add_item( submenu, "Run Compatible App", @@ -49,13 +49,13 @@ bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) { if(event.event == SubmenuIndexRunApp) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexRunApp); - if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolMifareUl) { + if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareUl) { scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareUl); - } else if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolMifareDesfire) { + } else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareDesfire) { scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareDesfire); - } else if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolEMV) { + } else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolEMV) { scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvApp); - } else if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolMifareClassic) { + } else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareClassic) { scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareClassic); } consumed = true; diff --git a/applications/nfc/scenes/nfc_scene_config.h b/applications/nfc/scenes/nfc_scene_config.h index c66725b9..6b5d5d10 100755 --- a/applications/nfc/scenes/nfc_scene_config.h +++ b/applications/nfc/scenes/nfc_scene_config.h @@ -2,7 +2,6 @@ ADD_SCENE(nfc, start, Start) ADD_SCENE(nfc, read_card, ReadCard) ADD_SCENE(nfc, read_card_success, ReadCardSuccess) ADD_SCENE(nfc, card_menu, CardMenu) -ADD_SCENE(nfc, not_implemented, NotImplemented) ADD_SCENE(nfc, emulate_uid, EmulateUid) ADD_SCENE(nfc, save_name, SaveName) ADD_SCENE(nfc, save_success, SaveSuccess) diff --git a/applications/nfc/scenes/nfc_scene_debug.c b/applications/nfc/scenes/nfc_scene_debug.c index a8f1e686..ed079c2e 100644 --- a/applications/nfc/scenes/nfc_scene_debug.c +++ b/applications/nfc/scenes/nfc_scene_debug.c @@ -6,13 +6,13 @@ enum SubmenuDebugIndex { }; void nfc_scene_debug_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } void nfc_scene_debug_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; Submenu* submenu = nfc->submenu; submenu_add_item( @@ -28,7 +28,7 @@ void nfc_scene_debug_on_enter(void* context) { } bool nfc_scene_debug_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -48,7 +48,7 @@ bool nfc_scene_debug_on_event(void* context, SceneManagerEvent event) { } void nfc_scene_debug_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; submenu_reset(nfc->submenu); } diff --git a/applications/nfc/scenes/nfc_scene_delete.c b/applications/nfc/scenes/nfc_scene_delete.c index 2661d166..29328743 100755 --- a/applications/nfc/scenes/nfc_scene_delete.c +++ b/applications/nfc/scenes/nfc_scene_delete.c @@ -1,29 +1,28 @@ #include "../nfc_i.h" void nfc_scene_delete_widget_callback(GuiButtonType result, InputType type, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; if(type == InputTypeShort) { view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } } void nfc_scene_delete_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup Custom Widget view - char delete_str[64]; - snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", nfc->dev->dev_name); - widget_add_text_box_element(nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str); + char temp_str[64]; + snprintf(temp_str, sizeof(temp_str), "\e#Delete %s?\e#", nfc->dev->dev_name); + widget_add_text_box_element(nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, temp_str); widget_add_button_element( nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_delete_widget_callback, nfc); widget_add_button_element( nfc->widget, GuiButtonTypeRight, "Delete", nfc_scene_delete_widget_callback, nfc); - char uid_str[32]; - NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; + FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; if(data->uid_len == 4) { snprintf( - uid_str, - sizeof(uid_str), + temp_str, + sizeof(temp_str), "UID: %02X %02X %02X %02X", data->uid[0], data->uid[1], @@ -31,8 +30,8 @@ void nfc_scene_delete_on_enter(void* context) { data->uid[3]); } else if(data->uid_len == 7) { snprintf( - uid_str, - sizeof(uid_str), + temp_str, + sizeof(temp_str), "UID: %02X %02X %02X %02X %02X %02X %02X", data->uid[0], data->uid[1], @@ -42,12 +41,13 @@ void nfc_scene_delete_on_enter(void* context) { data->uid[5], data->uid[6]); } - widget_add_string_element(nfc->widget, 64, 23, AlignCenter, AlignTop, FontSecondary, uid_str); + widget_add_string_element(nfc->widget, 64, 23, AlignCenter, AlignTop, FontSecondary, temp_str); const char* protocol_name = NULL; - if(data->protocol == NfcDeviceProtocolEMV) { - protocol_name = nfc_guess_protocol(data->protocol); - } else if(data->protocol == NfcDeviceProtocolMifareUl) { + NfcProtocol protocol = nfc->dev->dev_data.protocol; + if(protocol == NfcDeviceProtocolEMV) { + protocol_name = nfc_guess_protocol(protocol); + } else if(protocol == NfcDeviceProtocolMifareUl) { protocol_name = nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, false); } if(protocol_name) { @@ -56,18 +56,17 @@ void nfc_scene_delete_on_enter(void* context) { } // TODO change dinamically widget_add_string_element(nfc->widget, 118, 33, AlignRight, AlignTop, FontSecondary, "NFC-A"); - char sak_str[16]; - snprintf(sak_str, sizeof(sak_str), "SAK: %02X", data->sak); - widget_add_string_element(nfc->widget, 10, 43, AlignLeft, AlignTop, FontSecondary, sak_str); - char atqa_str[16]; - snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]); - widget_add_string_element(nfc->widget, 118, 43, AlignRight, AlignTop, FontSecondary, atqa_str); + snprintf(temp_str, sizeof(temp_str), "SAK: %02X", data->sak); + widget_add_string_element(nfc->widget, 10, 43, AlignLeft, AlignTop, FontSecondary, temp_str); + snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]); + widget_add_string_element(nfc->widget, 118, 43, AlignRight, AlignTop, FontSecondary, temp_str); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == GuiButtonTypeLeft) { @@ -79,14 +78,14 @@ bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) { scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneStart); } - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_delete_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; widget_reset(nfc->widget); } diff --git a/applications/nfc/scenes/nfc_scene_delete_success.c b/applications/nfc/scenes/nfc_scene_delete_success.c index 1392fa9e..a52c40d8 100755 --- a/applications/nfc/scenes/nfc_scene_delete_success.c +++ b/applications/nfc/scenes/nfc_scene_delete_success.c @@ -1,12 +1,12 @@ #include "../nfc_i.h" void nfc_scene_delete_success_popup_callback(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); } void nfc_scene_delete_success_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup view Popup* popup = nfc->popup; @@ -20,27 +20,21 @@ void nfc_scene_delete_success_on_enter(void* context) { } bool nfc_scene_delete_success_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventViewExit) { - return scene_manager_search_and_switch_to_previous_scene( + consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneStart); } } - return false; + return consumed; } void nfc_scene_delete_success_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clear view - Popup* popup = nfc->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - popup_set_callback(popup, NULL); - popup_set_context(popup, NULL); - popup_set_timeout(popup, 0); - popup_disable_timeout(popup); -} + popup_reset(nfc->popup); +} \ No newline at end of file diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c index d408e555..78e56c09 100644 --- a/applications/nfc/scenes/nfc_scene_device_info.c +++ b/applications/nfc/scenes/nfc_scene_device_info.c @@ -43,12 +43,12 @@ void nfc_scene_device_info_on_enter(void* context) { widget_add_button_element( nfc->widget, GuiButtonTypeRight, "Data", nfc_scene_device_info_widget_callback, nfc); } - char uid_str[32]; - NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; + char temp_str[32]; + FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; if(data->uid_len == 4) { snprintf( - uid_str, - sizeof(uid_str), + temp_str, + sizeof(temp_str), "UID: %02X %02X %02X %02X", data->uid[0], data->uid[1], @@ -56,8 +56,8 @@ void nfc_scene_device_info_on_enter(void* context) { data->uid[3]); } else if(data->uid_len == 7) { snprintf( - uid_str, - sizeof(uid_str), + temp_str, + sizeof(temp_str), "UID: %02X %02X %02X %02X %02X %02X %02X", data->uid[0], data->uid[1], @@ -67,15 +67,15 @@ void nfc_scene_device_info_on_enter(void* context) { data->uid[5], data->uid[6]); } - widget_add_string_element(nfc->widget, 64, 21, AlignCenter, AlignTop, FontSecondary, uid_str); + widget_add_string_element(nfc->widget, 64, 21, AlignCenter, AlignTop, FontSecondary, temp_str); const char* protocol_name = NULL; - if(data->protocol == NfcDeviceProtocolEMV || - data->protocol == NfcDeviceProtocolMifareDesfire) { - protocol_name = nfc_guess_protocol(data->protocol); - } else if(data->protocol == NfcDeviceProtocolMifareUl) { + NfcProtocol protocol = nfc->dev->dev_data.protocol; + if(protocol == NfcDeviceProtocolEMV || protocol == NfcDeviceProtocolMifareDesfire) { + protocol_name = nfc_guess_protocol(protocol); + } else if(protocol == NfcDeviceProtocolMifareUl) { protocol_name = nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, false); - } else if(data->protocol == NfcDeviceProtocolMifareClassic) { + } else if(protocol == NfcDeviceProtocolMifareClassic) { protocol_name = nfc_mf_classic_type(nfc->dev->dev_data.mf_classic_data.type); } if(protocol_name) { @@ -84,12 +84,10 @@ void nfc_scene_device_info_on_enter(void* context) { } // TODO change dinamically widget_add_string_element(nfc->widget, 118, 32, AlignRight, AlignTop, FontSecondary, "NFC-A"); - char sak_str[16]; - snprintf(sak_str, sizeof(sak_str), "SAK: %02X", data->sak); - widget_add_string_element(nfc->widget, 10, 42, AlignLeft, AlignTop, FontSecondary, sak_str); - char atqa_str[16]; - snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]); - widget_add_string_element(nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, atqa_str); + snprintf(temp_str, sizeof(temp_str), "SAK: %02X", data->sak); + widget_add_string_element(nfc->widget, 10, 42, AlignLeft, AlignTop, FontSecondary, temp_str); + snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]); + widget_add_string_element(nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, temp_str); // Setup Data View if(nfc->dev->format == NfcDeviceSaveFormatUid) { @@ -99,7 +97,7 @@ void nfc_scene_device_info_on_enter(void* context) { dialog_ex_set_context(dialog_ex, nfc); dialog_ex_set_result_callback(dialog_ex, nfc_scene_device_info_dialog_callback); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { - MifareUlData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; + MfUltralightData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; TextBox* text_box = nfc->text_box; text_box_set_font(text_box, TextBoxFontHex); for(uint16_t i = 0; i < mf_ul_data->data_size; i += 2) { @@ -130,7 +128,7 @@ void nfc_scene_device_info_on_enter(void* context) { widget_add_string_element( nfc->widget, 64, 17, AlignCenter, AlignBottom, FontSecondary, nfc->text_store); } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { - NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data; + EmvData* emv_data = &nfc->dev->dev_data.emv_data; BankCard* bank_card = nfc->bank_card; bank_card_set_name(bank_card, emv_data->name); bank_card_set_number(bank_card, emv_data->number, emv_data->number_len); @@ -212,21 +210,16 @@ bool nfc_scene_device_info_on_event(void* context, SceneManagerEvent event) { } void nfc_scene_device_info_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; - // Clear Custom Widget + // Clear views widget_reset(nfc->widget); - if(nfc->dev->format == NfcDeviceSaveFormatUid) { - // Clear Dialog - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_reset(dialog_ex); + dialog_ex_reset(nfc->dialog_ex); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { - // Clear TextBox text_box_reset(nfc->text_box); string_reset(nfc->text_box_store); } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { - // Clear Bank Card bank_card_clear(nfc->bank_card); } } diff --git a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c index 1a87ea58..4f9626e9 100644 --- a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c +++ b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c @@ -1,36 +1,34 @@ #include "../nfc_i.h" void nfc_scene_emulate_apdu_sequence_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup view Popup* popup = nfc->popup; - popup_set_header(popup, "Run APDU reader", 64, 31, AlignCenter, AlignTop); // Setup and start worker - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); nfc_worker_start(nfc->worker, NfcWorkerStateEmulateApdu, &nfc->dev->dev_data, NULL, nfc); } bool nfc_scene_emulate_apdu_sequence_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeTick) { notification_message(nfc->notifications, &sequence_blink_blue_10); - return true; + consumed = true; } - return false; + + return consumed; } void nfc_scene_emulate_apdu_sequence_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Stop worker nfc_worker_stop(nfc->worker); - // Clear view - Popup* popup = nfc->popup; - popup_reset(popup); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c index 68225f33..871ca636 100755 --- a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c +++ b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c @@ -5,13 +5,14 @@ #define NFC_MF_UL_DATA_CHANGED (1UL) void nfc_emulate_mifare_ul_worker_callback(NfcWorkerEvent event, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + scene_manager_set_scene_state( nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_UL_DATA_CHANGED); } void nfc_scene_emulate_mifare_ul_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcEmulate); // Setup view @@ -26,14 +27,14 @@ void nfc_scene_emulate_mifare_ul_on_enter(void* context) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); nfc_worker_start( nfc->worker, - NfcWorkerStateEmulateMifareUl, + NfcWorkerStateEmulateMifareUltralight, &nfc->dev->dev_data, nfc_emulate_mifare_ul_worker_callback, nfc); } bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeTick) { @@ -55,11 +56,8 @@ bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event } void nfc_scene_emulate_mifare_ul_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clear view - Popup* popup = nfc->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_emulate_uid.c b/applications/nfc/scenes/nfc_scene_emulate_uid.c index 027a325d..3eeb5706 100755 --- a/applications/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/nfc/scenes/nfc_scene_emulate_uid.c @@ -1,6 +1,8 @@ #include "../nfc_i.h" #include +#define NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX (200) + enum { NfcSceneEmulateUidStateWidget, NfcSceneEmulateUidStateTextBox, @@ -28,7 +30,7 @@ void nfc_emulate_uid_textbox_callback(void* context) { // Add widget with device name or inform that data received static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { - NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; + FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; widget_reset(widget); string_t info_str; @@ -95,13 +97,15 @@ bool nfc_scene_emulate_uid_on_event(void* context, SceneManagerEvent event) { nfc_scene_emulate_uid_widget_config(nfc, true); } // Update TextBox data - string_cat_printf(nfc->text_box_store, "R:"); - for(uint16_t i = 0; i < reader_data->size; i++) { - string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]); + if(string_size(nfc->text_box_store) < NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX) { + string_cat_printf(nfc->text_box_store, "R:"); + for(uint16_t i = 0; i < reader_data->size; i++) { + string_cat_printf(nfc->text_box_store, " %02X", reader_data->data[i]); + } + string_push_back(nfc->text_box_store, '\n'); + text_box_set_text(nfc->text_box, string_get_cstr(nfc->text_box_store)); } - string_push_back(nfc->text_box_store, '\n'); memset(reader_data, 0, sizeof(NfcReaderRequestData)); - text_box_set_text(nfc->text_box, string_get_cstr(nfc->text_box_store)); consumed = true; } else if(event.event == GuiButtonTypeCenter && state == NfcSceneEmulateUidStateWidget) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); diff --git a/applications/nfc/scenes/nfc_scene_field.c b/applications/nfc/scenes/nfc_scene_field.c index 36670387..31cf74b8 100644 --- a/applications/nfc/scenes/nfc_scene_field.c +++ b/applications/nfc/scenes/nfc_scene_field.c @@ -1,7 +1,7 @@ #include "../nfc_i.h" void nfc_scene_field_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; furi_hal_nfc_field_on(); @@ -23,12 +23,9 @@ bool nfc_scene_field_on_event(void* context, SceneManagerEvent event) { } void nfc_scene_field_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; - - notification_internal_message(nfc->notifications, &sequence_reset_blue); - - Popup* popup = nfc->popup; - popup_reset(popup); + Nfc* nfc = context; furi_hal_nfc_field_off(); + notification_internal_message(nfc->notifications, &sequence_reset_blue); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_file_select.c b/applications/nfc/scenes/nfc_scene_file_select.c index 010e807e..a8126456 100755 --- a/applications/nfc/scenes/nfc_scene_file_select.c +++ b/applications/nfc/scenes/nfc_scene_file_select.c @@ -1,7 +1,7 @@ #include "../nfc_i.h" void nfc_scene_file_select_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Process file_select return if(nfc_file_select(nfc->dev)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu); diff --git a/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c b/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c index e68d46d1..0974c062 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c +++ b/applications/nfc/scenes/nfc_scene_mifare_desfire_app.c @@ -18,13 +18,13 @@ MifareDesfireApplication* nfc_scene_mifare_desfire_app_get_app(Nfc* nfc) { } void nfc_scene_mifare_desfire_app_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } void nfc_scene_mifare_desfire_app_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; Submenu* submenu = nfc->submenu; MifareDesfireApplication* app = nfc_scene_mifare_desfire_app_get_app(nfc); if(!app) { @@ -73,7 +73,8 @@ void nfc_scene_mifare_desfire_app_on_enter(void* context) { } bool nfc_scene_mifare_desfire_app_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireApp); if(event.type == SceneManagerEventTypeCustom) { @@ -96,24 +97,24 @@ bool nfc_scene_mifare_desfire_app_on_event(void* context, SceneManagerEvent even text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMifareDesfireApp, state | 1); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); - return true; + consumed = true; } else if(event.type == SceneManagerEventTypeBack) { if(state & 1) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); scene_manager_set_scene_state( nfc->scene_manager, NfcSceneMifareDesfireApp, state & ~1); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_mifare_desfire_app_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + // Clear views text_box_reset(nfc->text_box); string_reset(nfc->text_box_store); - submenu_reset(nfc->submenu); } diff --git a/applications/nfc/scenes/nfc_scene_mifare_desfire_data.c b/applications/nfc/scenes/nfc_scene_mifare_desfire_data.c index c34d7af1..3eb23fc2 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_desfire_data.c +++ b/applications/nfc/scenes/nfc_scene_mifare_desfire_data.c @@ -19,7 +19,7 @@ void nfc_scene_mifare_desfire_data_submenu_callback(void* context, uint32_t inde } void nfc_scene_mifare_desfire_data_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; Submenu* submenu = nfc->submenu; uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireData); MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data; @@ -61,7 +61,8 @@ void nfc_scene_mifare_desfire_data_on_enter(void* context) { } bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMifareDesfireData); MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data; @@ -76,7 +77,7 @@ bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent eve nfc->scene_manager, NfcSceneMifareDesfireData, MifareDesfireDataStateItem + SubmenuIndexCardInfo); - return true; + consumed = true; } else { uint16_t index = event.event - SubmenuIndexDynamic; scene_manager_set_scene_state( @@ -84,25 +85,25 @@ bool nfc_scene_mifare_desfire_data_on_event(void* context, SceneManagerEvent eve scene_manager_set_scene_state( nfc->scene_manager, NfcSceneMifareDesfireApp, index << 1); scene_manager_next_scene(nfc->scene_manager, NfcSceneMifareDesfireApp); - return true; + consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { if(state >= MifareDesfireDataStateItem) { view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); scene_manager_set_scene_state( nfc->scene_manager, NfcSceneMifareDesfireData, MifareDesfireDataStateMenu); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_mifare_desfire_data_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + // Clear views text_box_reset(nfc->text_box); string_reset(nfc->text_box_store); - submenu_reset(nfc->submenu); } diff --git a/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c b/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c index 9aa68a43..f6171c8b 100644 --- a/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c +++ b/applications/nfc/scenes/nfc_scene_mifare_desfire_menu.c @@ -5,13 +5,13 @@ enum SubmenuIndex { }; void nfc_scene_mifare_desfire_menu_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } void nfc_scene_mifare_desfire_menu_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; Submenu* submenu = nfc->submenu; submenu_add_item( @@ -24,7 +24,8 @@ void nfc_scene_mifare_desfire_menu_on_enter(void* context) { } bool nfc_scene_mifare_desfire_menu_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSave) { @@ -34,15 +35,16 @@ bool nfc_scene_mifare_desfire_menu_on_event(void* context, SceneManagerEvent eve // Clear device name nfc_device_set_name(nfc->dev, ""); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_mifare_desfire_menu_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + // Clear view submenu_reset(nfc->submenu); } diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c index 0e2aaf99..0099f1a0 100755 --- a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c +++ b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c @@ -6,13 +6,13 @@ enum SubmenuIndex { }; void nfc_scene_mifare_ul_menu_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } void nfc_scene_mifare_ul_menu_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; Submenu* submenu = nfc->submenu; submenu_add_item( @@ -26,7 +26,8 @@ void nfc_scene_mifare_ul_menu_on_enter(void* context) { } bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSave) { @@ -36,23 +37,24 @@ bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) { // Clear device name nfc_device_set_name(nfc->dev, ""); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); - return true; + consumed = true; } else if(event.event == SubmenuIndexEmulate) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexEmulate); scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); - return true; + consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { - return scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneStart); + consumed = + scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart); } - return false; + return consumed; } void nfc_scene_mifare_ul_menu_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + // Clear view submenu_reset(nfc->submenu); } diff --git a/applications/nfc/scenes/nfc_scene_not_implemented.c b/applications/nfc/scenes/nfc_scene_not_implemented.c deleted file mode 100644 index 3167f9c0..00000000 --- a/applications/nfc/scenes/nfc_scene_not_implemented.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../nfc_i.h" - -void nfc_scene_not_implemented_dialog_callback(DialogExResult result, void* context) { - Nfc* nfc = (Nfc*)context; - - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); -} - -void nfc_scene_not_implemented_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; - - // TODO Set data from worker - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_set_left_button_text(dialog_ex, "Back"); - dialog_ex_set_header(dialog_ex, "Not implemented", 60, 24, AlignCenter, AlignCenter); - dialog_ex_set_context(dialog_ex, nfc); - dialog_ex_set_result_callback(dialog_ex, nfc_scene_not_implemented_dialog_callback); - - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); -} - -bool nfc_scene_not_implemented_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == DialogExResultLeft) { - return scene_manager_previous_scene(nfc->scene_manager); - } - } - return false; -} - -void nfc_scene_not_implemented_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; - - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); -} diff --git a/applications/nfc/scenes/nfc_scene_read_card.c b/applications/nfc/scenes/nfc_scene_read_card.c index 72a6e4f2..4d151c08 100755 --- a/applications/nfc/scenes/nfc_scene_read_card.c +++ b/applications/nfc/scenes/nfc_scene_read_card.c @@ -2,12 +2,12 @@ #include void nfc_read_card_worker_callback(NfcWorkerEvent event, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } void nfc_scene_read_card_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcRead); // Setup view @@ -22,29 +22,26 @@ void nfc_scene_read_card_on_enter(void* context) { } bool nfc_scene_read_card_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventWorkerExit) { scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess); - return true; + consumed = true; } } else if(event.type == SceneManagerEventTypeTick) { notification_message(nfc->notifications, &sequence_blink_blue_10); - return true; + consumed = true; } - return false; + return consumed; } void nfc_scene_read_card_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Stop worker nfc_worker_stop(nfc->worker); - // Clear view - Popup* popup = nfc->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_read_card_success.c b/applications/nfc/scenes/nfc_scene_read_card_success.c index 260dccef..c0a865bc 100755 --- a/applications/nfc/scenes/nfc_scene_read_card_success.c +++ b/applications/nfc/scenes/nfc_scene_read_card_success.c @@ -7,13 +7,15 @@ void nfc_scene_read_card_success_widget_callback( void* context) { furi_assert(context); Nfc* nfc = context; + if(type == InputTypeShort) { view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } } void nfc_scene_read_card_success_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + string_t data_str; string_t uid_str; string_init(data_str); @@ -24,9 +26,9 @@ void nfc_scene_read_card_success_on_enter(void* context) { notification_message(nfc->notifications, &sequence_success); // Setup view - NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; + FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; Widget* widget = nfc->widget; - string_set_str(data_str, nfc_get_dev_type(data->device)); + string_set_str(data_str, nfc_get_dev_type(data->type)); string_set_str(uid_str, "UID:"); for(uint8_t i = 0; i < data->uid_len; i++) { string_cat_printf(uid_str, " %02X", data->uid[i]); @@ -34,7 +36,7 @@ void nfc_scene_read_card_success_on_enter(void* context) { widget_add_button_element( widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_card_success_widget_callback, nfc); - if(data->device == NfcDeviceNfca) { + if(data->type == FuriHalNfcTypeA) { widget_add_button_element( widget, GuiButtonTypeRight, "More", nfc_scene_read_card_success_widget_callback, nfc); widget_add_icon_element(widget, 8, 13, &I_Medium_chip_22x21); @@ -44,7 +46,7 @@ void nfc_scene_read_card_success_on_enter(void* context) { string_printf( data_str, "%s\nATQA: %02X%02X SAK: %02X", - nfc_guess_protocol(data->protocol), + nfc_guess_protocol(nfc->dev->dev_data.protocol), data->atqa[0], data->atqa[1], data->sak); @@ -66,14 +68,14 @@ void nfc_scene_read_card_success_on_enter(void* context) { } bool nfc_scene_read_card_success_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; - NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; + Nfc* nfc = context; + FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == GuiButtonTypeLeft) { consumed = scene_manager_previous_scene(nfc->scene_manager); - } else if(data->device == NfcDeviceNfca && event.event == GuiButtonTypeRight) { + } else if(data->type == FuriHalNfcTypeA && event.event == GuiButtonTypeRight) { // Clear device name nfc_device_set_name(nfc->dev, ""); scene_manager_next_scene(nfc->scene_manager, NfcSceneCardMenu); @@ -84,6 +86,8 @@ bool nfc_scene_read_card_success_on_event(void* context, SceneManagerEvent event } void nfc_scene_read_card_success_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + + // Clear view widget_reset(nfc->widget); } diff --git a/applications/nfc/scenes/nfc_scene_read_emv_app.c b/applications/nfc/scenes/nfc_scene_read_emv_app.c index a2f0a325..f0192cb9 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_app.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_app.c @@ -2,12 +2,12 @@ #include void nfc_read_emv_app_worker_callback(NfcWorkerEvent event, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } void nfc_scene_read_emv_app_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcRead); // Setup view @@ -26,31 +26,30 @@ void nfc_scene_read_emv_app_on_enter(void* context) { } bool nfc_scene_read_emv_app_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventWorkerExit) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneReadEmvAppSuccess, NFC_SEND_NOTIFICATION_TRUE); scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvAppSuccess); - return true; + consumed = true; } } else if(event.type == SceneManagerEventTypeTick) { notification_message(nfc->notifications, &sequence_blink_blue_10); - return true; + consumed = true; } - return false; + + return consumed; } void nfc_scene_read_emv_app_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Stop worker nfc_worker_stop(nfc->worker); // Clear view - Popup* popup = nfc->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_read_emv_app_success.c b/applications/nfc/scenes/nfc_scene_read_emv_app_success.c index 057dd59e..b9bc5ba4 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_app_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_app_success.c @@ -2,27 +2,38 @@ #include "../helpers/nfc_emv_parser.h" #include -#define NFC_SCENE_READ_SUCCESS_SHIFT " " - -void nfc_scene_read_emv_app_success_dialog_callback(DialogExResult result, void* context) { - Nfc* nfc = (Nfc*)context; - - view_dispatcher_send_custom_event(nfc->view_dispatcher, result); +void nfc_scene_read_emv_app_widget_callback(GuiButtonType result, InputType type, void* context) { + Nfc* nfc = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); + } } void nfc_scene_read_emv_app_success_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcReadSuccess); // Setup view - NfcDeviceCommonData* nfc_data = &nfc->dev->dev_data.nfc_data; - NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data; - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_set_left_button_text(dialog_ex, "Retry"); - dialog_ex_set_right_button_text(dialog_ex, "Run app"); - dialog_ex_set_header(dialog_ex, "Found EMV App", 36, 8, AlignLeft, AlignCenter); - dialog_ex_set_icon(dialog_ex, 8, 13, &I_Medium_chip_22x21); - // Display UID and AID + FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data; + EmvData* emv_data = &nfc->dev->dev_data.emv_data; + Widget* widget = nfc->widget; + widget_add_button_element( + widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_emv_app_widget_callback, nfc); + widget_add_button_element( + widget, GuiButtonTypeRight, "Run app", nfc_scene_read_emv_app_widget_callback, nfc); + widget_add_string_element(widget, 36, 5, AlignLeft, AlignTop, FontPrimary, "Found EMV App"); + widget_add_icon_element(widget, 8, 5, &I_Medium_chip_22x21); + // Display UID + string_t temp_str; + string_init_printf(temp_str, "UID:"); + for(size_t i = 0; i < nfc_data->uid_len; i++) { + string_cat_printf(temp_str, " %02X", nfc_data->uid[i]); + } + widget_add_string_element( + widget, 36, 18, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); + string_reset(temp_str); + // Display application + string_printf(temp_str, "App: "); string_t aid; string_init(aid); bool aid_found = @@ -32,19 +43,11 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) { string_cat_printf(aid, "%02X", emv_data->aid[i]); } } - nfc_text_store_set( - nfc, - NFC_SCENE_READ_SUCCESS_SHIFT "UID: %02X %02X %02X %02X \n" NFC_SCENE_READ_SUCCESS_SHIFT - "Application:\n%s", - nfc_data->uid[0], - nfc_data->uid[1], - nfc_data->uid[2], - nfc_data->uid[3], - string_get_cstr(aid)); + string_cat(temp_str, aid); + widget_add_string_element( + widget, 7, 29, AlignLeft, AlignTop, FontSecondary, string_get_cstr(temp_str)); + string_clear(temp_str); string_clear(aid); - dialog_ex_set_text(dialog_ex, nfc->text_store, 8, 16, AlignLeft, AlignTop); - dialog_ex_set_context(dialog_ex, nfc); - dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_emv_app_success_dialog_callback); // Send notification if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadEmvAppSuccess) == @@ -54,32 +57,27 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) { nfc->scene_manager, NfcSceneReadEmvAppSuccess, NFC_SEND_NOTIFICATION_FALSE); } - view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } bool nfc_scene_read_emv_app_success_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == DialogExResultLeft) { - return scene_manager_previous_scene(nfc->scene_manager); - } else if(event.event == DialogExResultRight) { + if(event.event == GuiButtonTypeLeft) { + consumed = scene_manager_previous_scene(nfc->scene_manager); + } else if(event.event == GuiButtonTypeRight) { scene_manager_next_scene(nfc->scene_manager, NfcSceneRunEmvAppConfirm); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_read_emv_app_success_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_icon(dialog_ex, 0, 0, NULL); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_right_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); + // Clear views + widget_reset(nfc->widget); } diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data.c b/applications/nfc/scenes/nfc_scene_read_emv_data.c index 37442c33..b72c873e 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data.c @@ -2,12 +2,12 @@ #include void nfc_read_emv_data_worker_callback(NfcWorkerEvent event, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } void nfc_scene_read_emv_data_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcRead); // Setup view @@ -21,38 +21,35 @@ void nfc_scene_read_emv_data_on_enter(void* context) { // Start worker nfc_worker_start( nfc->worker, - NfcWorkerStateReadEMV, + NfcWorkerStateReadEMVData, &nfc->dev->dev_data, nfc_read_emv_data_worker_callback, nfc); } bool nfc_scene_read_emv_data_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventWorkerExit) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneReadEmvDataSuccess, NFC_SEND_NOTIFICATION_TRUE); scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvDataSuccess); - return true; + consumed = true; } } else if(event.type == SceneManagerEventTypeTick) { notification_message(nfc->notifications, &sequence_blink_blue_10); - return true; + consumed = true; } - return false; + return consumed; } void nfc_scene_read_emv_data_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Stop worker nfc_worker_stop(nfc->worker); - // Clear view - Popup* popup = nfc->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c index 78078d05..275e9b86 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c @@ -6,16 +6,16 @@ void nfc_scene_read_emv_data_success_widget_callback( GuiButtonType result, InputType type, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; if(type == InputTypeShort) { view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } } void nfc_scene_read_emv_data_success_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; - NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data; - NfcDeviceCommonData* nfc_data = &nfc->dev->dev_data.nfc_data; + Nfc* nfc = context; + EmvData* emv_data = &nfc->dev->dev_data.emv_data; + FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data; DOLPHIN_DEED(DolphinDeedNfcReadSuccess); // Setup Custom Widget view @@ -78,25 +78,23 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { string_clear(disp_currency); } string_clear(currency_name); + char temp_str[32]; // Add ATQA - char atqa_str[16]; - snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", nfc_data->atqa[0], nfc_data->atqa[1]); - widget_add_string_element(nfc->widget, 121, 32, AlignRight, AlignTop, FontSecondary, atqa_str); + snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", nfc_data->atqa[0], nfc_data->atqa[1]); + widget_add_string_element(nfc->widget, 121, 32, AlignRight, AlignTop, FontSecondary, temp_str); // Add UID - char uid_str[32]; snprintf( - uid_str, - sizeof(uid_str), + temp_str, + sizeof(temp_str), "UID: %02X %02X %02X %02X", nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3]); - widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, uid_str); + widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, temp_str); // Add SAK - char sak_str[16]; - snprintf(sak_str, sizeof(sak_str), "SAK: %02X", nfc_data->sak); - widget_add_string_element(nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, sak_str); + snprintf(temp_str, sizeof(temp_str), "SAK: %02X", nfc_data->sak); + widget_add_string_element(nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, temp_str); // Add expiration date if(emv_data->exp_mon) { char exp_str[16]; @@ -117,28 +115,30 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { } bool nfc_scene_read_emv_data_success_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == GuiButtonTypeLeft) { - return scene_manager_search_and_switch_to_previous_scene( + consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneReadEmvAppSuccess); } else if(event.event == GuiButtonTypeRight) { // Clear device name nfc_device_set_name(nfc->dev, ""); nfc->dev->format = NfcDeviceSaveFormatBankCard; scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); - return true; + consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { - return scene_manager_search_and_switch_to_previous_scene( + consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneReadEmvAppSuccess); } - return false; + return consumed; } void nfc_scene_read_emv_data_success_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + // Clear view widget_reset(nfc->widget); } diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c b/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c index 1a0b3524..ebd7289b 100644 --- a/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c +++ b/applications/nfc/scenes/nfc_scene_read_mifare_desfire.c @@ -2,12 +2,12 @@ #include void nfc_read_mifare_desfire_worker_callback(NfcWorkerEvent event, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventWorkerExit); } void nfc_scene_read_mifare_desfire_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcRead); // Setup view @@ -26,31 +26,28 @@ void nfc_scene_read_mifare_desfire_on_enter(void* context) { } bool nfc_scene_read_mifare_desfire_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventWorkerExit) { notification_message(nfc->notifications, &sequence_success); scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareDesfireSuccess); - return true; + consumed = true; } } else if(event.type == SceneManagerEventTypeTick) { notification_message(nfc->notifications, &sequence_blink_blue_10); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); - return true; + consumed = true; } - return false; + return consumed; } void nfc_scene_read_mifare_desfire_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Stop worker nfc_worker_stop(nfc->worker); - // Clear view - Popup* popup = nfc->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_desfire_success.c b/applications/nfc/scenes/nfc_scene_read_mifare_desfire_success.c index 995869bf..17f62e41 100644 --- a/applications/nfc/scenes/nfc_scene_read_mifare_desfire_success.c +++ b/applications/nfc/scenes/nfc_scene_read_mifare_desfire_success.c @@ -9,13 +9,13 @@ enum { }; void nfc_scene_read_mifare_desfire_success_dialog_callback(DialogExResult result, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } void nfc_scene_read_mifare_desfire_success_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data; DialogEx* dialog_ex = nfc->dialog_ex; @@ -67,9 +67,9 @@ void nfc_scene_read_mifare_desfire_success_on_enter(void* context) { bool nfc_scene_read_mifare_desfire_success_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; + bool consumed = false; uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadMifareDesfireSuccess); - bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(state == ReadMifareDesfireSuccessStateShowUID && event.event == DialogExResultLeft) { @@ -98,9 +98,8 @@ bool nfc_scene_read_mifare_desfire_success_on_event(void* context, SceneManagerE } void nfc_scene_read_mifare_desfire_success_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clean dialog - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_reset(dialog_ex); + dialog_ex_reset(nfc->dialog_ex); } diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c index ce6d160e..8903e2c4 100755 --- a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c @@ -19,7 +19,7 @@ void nfc_scene_read_mifare_ul_on_enter(void* context) { // Start worker nfc_worker_start( nfc->worker, - NfcWorkerStateReadMifareUl, + NfcWorkerStateReadMifareUltralight, &nfc->dev->dev_data, nfc_read_mifare_ul_worker_callback, nfc); @@ -43,6 +43,7 @@ bool nfc_scene_read_mifare_ul_on_event(void* context, SceneManagerEvent event) { void nfc_scene_read_mifare_ul_on_exit(void* context) { Nfc* nfc = context; + // Stop worker nfc_worker_stop(nfc->worker); // Clear view diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c index 603ad54a..5bcf1589 100755 --- a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c @@ -9,21 +9,21 @@ enum { }; void nfc_scene_read_mifare_ul_success_dialog_callback(DialogExResult result, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } void nfc_scene_read_mifare_ul_success_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcReadSuccess); // Send notification notification_message(nfc->notifications, &sequence_success); // Setup dialog view - NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; - MifareUlData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; + FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; + MfUltralightData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; DialogEx* dialog_ex = nfc->dialog_ex; dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_right_button_text(dialog_ex, "More"); @@ -69,9 +69,9 @@ void nfc_scene_read_mifare_ul_success_on_enter(void* context) { bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = context; + bool consumed = false; uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadMifareUlSuccess); - bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(state == ReadMifareUlStateShowUID && event.event == DialogExResultLeft) { @@ -99,14 +99,10 @@ bool nfc_scene_read_mifare_ul_success_on_event(void* context, SceneManagerEvent } void nfc_scene_read_mifare_ul_success_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; - // Clean dialog - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_reset(dialog_ex); - - // Clean TextBox - TextBox* text_box = nfc->text_box; - text_box_reset(text_box); + // Clean views + dialog_ex_reset(nfc->dialog_ex); + text_box_reset(nfc->text_box); string_reset(nfc->text_box_store); } diff --git a/applications/nfc/scenes/nfc_scene_restore_original.c b/applications/nfc/scenes/nfc_scene_restore_original.c index 8ddac366..40b59b9e 100644 --- a/applications/nfc/scenes/nfc_scene_restore_original.c +++ b/applications/nfc/scenes/nfc_scene_restore_original.c @@ -1,12 +1,12 @@ #include "../nfc_i.h" void nfc_scene_restore_original_popup_callback(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); } void nfc_scene_restore_original_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup view Popup* popup = nfc->popup; @@ -20,7 +20,7 @@ void nfc_scene_restore_original_on_enter(void* context) { } bool nfc_scene_restore_original_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -32,15 +32,8 @@ bool nfc_scene_restore_original_on_event(void* context, SceneManagerEvent event) } void nfc_scene_restore_original_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clear view - Popup* popup = nfc->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - popup_set_callback(popup, NULL); - popup_set_context(popup, NULL); - popup_set_timeout(popup, 0); - popup_disable_timeout(popup); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c b/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c index d9948d4e..5ee9f442 100755 --- a/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c +++ b/applications/nfc/scenes/nfc_scene_run_emv_app_confirm.c @@ -1,15 +1,13 @@ #include "../nfc_i.h" -#define NFC_SCENE_READ_SUCCESS_SHIFT " " - void nfc_scene_run_emv_app_confirm_dialog_callback(DialogExResult result, void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } void nfc_scene_run_emv_app_confirm_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DialogEx* dialog_ex = nfc->dialog_ex; dialog_ex_set_left_button_text(dialog_ex, "Back"); @@ -29,28 +27,23 @@ void nfc_scene_run_emv_app_confirm_on_enter(void* context) { } bool nfc_scene_run_emv_app_confirm_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == DialogExResultLeft) { - return scene_manager_previous_scene(nfc->scene_manager); + consumed = scene_manager_previous_scene(nfc->scene_manager); } else if(event.event == DialogExResultRight) { scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvData); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_run_emv_app_confirm_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; - DialogEx* dialog_ex = nfc->dialog_ex; - dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); - dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); - dialog_ex_set_icon(dialog_ex, 0, 0, NULL); - dialog_ex_set_left_button_text(dialog_ex, NULL); - dialog_ex_set_right_button_text(dialog_ex, NULL); - dialog_ex_set_result_callback(dialog_ex, NULL); - dialog_ex_set_context(dialog_ex, NULL); + // Clean view + dialog_ex_reset(nfc->dialog_ex); } diff --git a/applications/nfc/scenes/nfc_scene_save_name.c b/applications/nfc/scenes/nfc_scene_save_name.c index aa05c8a6..e95c97eb 100755 --- a/applications/nfc/scenes/nfc_scene_save_name.c +++ b/applications/nfc/scenes/nfc_scene_save_name.c @@ -3,13 +3,13 @@ #include void nfc_scene_save_name_text_input_callback(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventTextInputDone); } void nfc_scene_save_name_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup view TextInput* text_input = nfc->text_input; @@ -37,7 +37,8 @@ void nfc_scene_save_name_on_enter(void* context) { } bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventTextInputDone) { @@ -50,18 +51,18 @@ bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) { strlcpy(nfc->dev->dev_name, nfc->text_store, strlen(nfc->text_store) + 1); if(nfc_device_save(nfc->dev, nfc->text_store)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess); - return true; + consumed = true; } else { - return scene_manager_search_and_switch_to_previous_scene( + consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneStart); } } } - return false; + return consumed; } void nfc_scene_save_name_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clear view void* validator_context = text_input_get_validator_callback_context(nfc->text_input); diff --git a/applications/nfc/scenes/nfc_scene_save_success.c b/applications/nfc/scenes/nfc_scene_save_success.c index b1a84003..985897a6 100644 --- a/applications/nfc/scenes/nfc_scene_save_success.c +++ b/applications/nfc/scenes/nfc_scene_save_success.c @@ -2,12 +2,12 @@ #include void nfc_scene_save_success_popup_callback(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit); } void nfc_scene_save_success_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcSave); // Setup view @@ -22,7 +22,7 @@ void nfc_scene_save_success_on_enter(void* context) { } bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -47,15 +47,8 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { } void nfc_scene_save_success_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clear view - Popup* popup = nfc->popup; - popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); - popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 0, NULL); - popup_set_callback(popup, NULL); - popup_set_context(popup, NULL); - popup_set_timeout(popup, 0); - popup_disable_timeout(popup); + popup_reset(nfc->popup); } diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c index 14eb4ca2..e0489c15 100644 --- a/applications/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/nfc/scenes/nfc_scene_saved_menu.c @@ -9,13 +9,13 @@ enum SubmenuIndex { }; void nfc_scene_saved_menu_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } void nfc_scene_saved_menu_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; Submenu* submenu = nfc->submenu; if(nfc->dev->format == NfcDeviceSaveFormatUid || @@ -56,7 +56,7 @@ void nfc_scene_saved_menu_on_enter(void* context) { } bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -92,7 +92,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { } void nfc_scene_saved_menu_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; submenu_reset(nfc->submenu); } diff --git a/applications/nfc/scenes/nfc_scene_set_atqa.c b/applications/nfc/scenes/nfc_scene_set_atqa.c index 85a70fe8..f2100aa1 100755 --- a/applications/nfc/scenes/nfc_scene_set_atqa.c +++ b/applications/nfc/scenes/nfc_scene_set_atqa.c @@ -1,13 +1,13 @@ #include "../nfc_i.h" void nfc_scene_set_atqa_byte_input_callback(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone); } void nfc_scene_set_atqa_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup view ByteInput* byte_input = nfc->byte_input; @@ -23,19 +23,20 @@ void nfc_scene_set_atqa_on_enter(void* context) { } bool nfc_scene_set_atqa_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventByteInputDone) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_set_atqa_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clear view byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0); diff --git a/applications/nfc/scenes/nfc_scene_set_sak.c b/applications/nfc/scenes/nfc_scene_set_sak.c index 11cfcf46..3c88f350 100755 --- a/applications/nfc/scenes/nfc_scene_set_sak.c +++ b/applications/nfc/scenes/nfc_scene_set_sak.c @@ -1,13 +1,13 @@ #include "../nfc_i.h" void nfc_scene_set_sak_byte_input_callback(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone); } void nfc_scene_set_sak_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup view ByteInput* byte_input = nfc->byte_input; @@ -23,19 +23,20 @@ void nfc_scene_set_sak_on_enter(void* context) { } bool nfc_scene_set_sak_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventByteInputDone) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSetAtqua); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_set_sak_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clear view byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0); diff --git a/applications/nfc/scenes/nfc_scene_set_type.c b/applications/nfc/scenes/nfc_scene_set_type.c index 0e6624bd..0dbb4f7e 100755 --- a/applications/nfc/scenes/nfc_scene_set_type.c +++ b/applications/nfc/scenes/nfc_scene_set_type.c @@ -6,13 +6,13 @@ enum SubmenuIndex { }; void nfc_scene_set_type_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } void nfc_scene_set_type_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; Submenu* submenu = nfc->submenu; // Clear device name nfc_device_set_name(nfc->dev, ""); @@ -24,26 +24,27 @@ void nfc_scene_set_type_on_enter(void* context) { } bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexNFCA7) { nfc->dev->dev_data.nfc_data.uid_len = 7; nfc->dev->format = NfcDeviceSaveFormatUid; scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak); - return true; + consumed = true; } else if(event.event == SubmenuIndexNFCA4) { nfc->dev->dev_data.nfc_data.uid_len = 4; nfc->dev->format = NfcDeviceSaveFormatUid; scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_set_type_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; submenu_reset(nfc->submenu); } diff --git a/applications/nfc/scenes/nfc_scene_set_uid.c b/applications/nfc/scenes/nfc_scene_set_uid.c index c5950129..6fe807ce 100755 --- a/applications/nfc/scenes/nfc_scene_set_uid.c +++ b/applications/nfc/scenes/nfc_scene_set_uid.c @@ -2,13 +2,13 @@ #include void nfc_scene_set_uid_byte_input_callback(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone); } void nfc_scene_set_uid_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup view ByteInput* byte_input = nfc->byte_input; @@ -26,19 +26,20 @@ void nfc_scene_set_uid_on_enter(void* context) { bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) { Nfc* nfc = (Nfc*)context; + bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventByteInputDone) { DOLPHIN_DEED(DolphinDeedNfcAdd); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); - return true; + consumed = true; } } - return false; + return consumed; } void nfc_scene_set_uid_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Clear view byte_input_set_result_callback(nfc->byte_input, NULL, NULL, NULL, NULL, 0); diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c index 2be7775b..d64aa76e 100644 --- a/applications/nfc/scenes/nfc_scene_start.c +++ b/applications/nfc/scenes/nfc_scene_start.c @@ -9,13 +9,13 @@ enum SubmenuIndex { }; void nfc_scene_start_submenu_callback(void* context, uint32_t index) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, index); } void nfc_scene_start_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; Submenu* submenu = nfc->submenu; submenu_add_item( @@ -43,7 +43,7 @@ void nfc_scene_start_on_enter(void* context) { } bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -70,7 +70,7 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) { } void nfc_scene_start_on_exit(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; submenu_reset(nfc->submenu); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index b29c5026..1d2c02d9 100755 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -48,13 +48,12 @@ void furi_hal_nfc_exit_sleep() { rfalLowPowerModeStop(); } -bool furi_hal_nfc_detect( - rfalNfcDevice** dev_list, - uint8_t* dev_cnt, - uint32_t timeout, - bool deactivate) { - furi_assert(dev_list); - furi_assert(dev_cnt); +bool furi_hal_nfc_detect(FuriHalNfcDevData* nfc_data, uint32_t timeout) { + furi_assert(nfc_data); + + rfalNfcDevice* dev_list = NULL; + uint8_t dev_cnt = 0; + bool detected = false; rfalLowPowerModeStop(); rfalNfcState state = rfalNfcGetState(); @@ -77,9 +76,13 @@ bool furi_hal_nfc_detect( uint32_t start = DWT->CYCCNT; rfalNfcDiscover(¶ms); - while(state != RFAL_NFC_STATE_ACTIVATED) { + while(true) { rfalNfcWorker(); state = rfalNfcGetState(); + if(state == RFAL_NFC_STATE_ACTIVATED) { + detected = true; + break; + } FURI_LOG_T(TAG, "Current state %d", state); if(state == RFAL_NFC_STATE_POLL_ACTIVATION) { start = DWT->CYCCNT; @@ -91,16 +94,42 @@ bool furi_hal_nfc_detect( if(DWT->CYCCNT - start > timeout * clocks_in_ms) { rfalNfcDeactivate(true); FURI_LOG_T(TAG, "Timeout"); - return false; + break; } osThreadYield(); } - rfalNfcGetDevicesFound(dev_list, dev_cnt); - if(deactivate) { - rfalNfcDeactivate(false); - rfalLowPowerModeStart(); + rfalNfcGetDevicesFound(&dev_list, &dev_cnt); + if(detected) { + if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCA) { + nfc_data->type = FuriHalNfcTypeA; + nfc_data->atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo; + nfc_data->atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo; + nfc_data->sak = dev_list[0].dev.nfca.selRes.sak; + uint8_t* cuid_start = dev_list[0].nfcid; + if(dev_list[0].nfcidLen == 7) { + cuid_start = &dev_list[0].nfcid[3]; + } + nfc_data->cuid = (cuid_start[0] << 24) | (cuid_start[1] << 16) | (cuid_start[2] << 8) | + (cuid_start[3]); + } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCB) { + nfc_data->type = FuriHalNfcTypeB; + } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCF) { + nfc_data->type = FuriHalNfcTypeF; + } else if(dev_list[0].type == RFAL_NFC_LISTEN_TYPE_NFCV) { + nfc_data->type = FuriHalNfcTypeV; + } + if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_RF) { + nfc_data->interface = FuriHalNfcInterfaceRf; + } else if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_ISODEP) { + nfc_data->interface = FuriHalNfcInterfaceIsoDep; + } else if(dev_list[0].rfInterface == RFAL_NFC_INTERFACE_NFCDEP) { + nfc_data->interface = FuriHalNfcInterfaceNfcDep; + } + nfc_data->uid_len = dev_list[0].nfcidLen; + memcpy(nfc_data->uid, dev_list[0].nfcid, nfc_data->uid_len); } - return true; + + return detected; } bool furi_hal_nfc_activate_nfca(uint32_t timeout, uint32_t* cuid) { @@ -326,12 +355,6 @@ bool furi_hal_nfc_emulate_nfca( return true; } -bool furi_hal_nfc_get_first_frame(uint8_t** rx_buff, uint16_t** rx_len) { - ReturnCode ret = - rfalNfcDataExchangeStart(NULL, 0, rx_buff, rx_len, 0, RFAL_TXRX_FLAGS_DEFAULT); - return ret == ERR_NONE; -} - ReturnCode furi_hal_nfc_data_exchange( uint8_t* tx_buff, uint16_t tx_len, @@ -370,6 +393,22 @@ ReturnCode furi_hal_nfc_data_exchange( return ret; } +static uint32_t furi_hal_nfc_tx_rx_get_flag(FuriHalNfcTxRxType type) { + uint32_t flags = 0; + + if(type == FuriHalNfcTxRxTypeRxNoCrc) { + flags = RFAL_TXRX_FLAGS_CRC_RX_KEEP; + } else if(type == FuriHalNfcTxRxTypeRxKeepPar) { + flags = RFAL_TXRX_FLAGS_CRC_TX_MANUAL | RFAL_TXRX_FLAGS_CRC_RX_KEEP | + RFAL_TXRX_FLAGS_PAR_RX_KEEP; + } 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; + } + + return flags; +} + static uint16_t furi_hal_nfc_data_and_parity_to_bitstream( uint8_t* data, uint16_t len, @@ -420,8 +459,8 @@ uint16_t furi_hal_nfc_bitstream_to_data_and_parity( return curr_byte; } -bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx_ctx) { - furi_assert(tx_rx_ctx); +bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { + furi_assert(tx_rx); ReturnCode ret; rfalNfcState state = RFAL_NFC_STATE_ACTIVATED; @@ -431,26 +470,18 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx_ctx) { uint16_t* temp_rx_bits = NULL; // Prepare data for FIFO if necessary - if(tx_rx_ctx->tx_rx_type == FURI_HAL_NFC_TXRX_RAW) { + uint32_t flags = furi_hal_nfc_tx_rx_get_flag(tx_rx->tx_rx_type); + if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw) { temp_tx_bits = furi_hal_nfc_data_and_parity_to_bitstream( - tx_rx_ctx->tx_data, tx_rx_ctx->tx_bits / 8, tx_rx_ctx->tx_parity, temp_tx_buff); + tx_rx->tx_data, tx_rx->tx_bits / 8, tx_rx->tx_parity, temp_tx_buff); ret = rfalNfcDataExchangeCustomStart( - temp_tx_buff, - temp_tx_bits, - &temp_rx_buff, - &temp_rx_bits, - RFAL_FWT_NONE, - tx_rx_ctx->tx_rx_type); + temp_tx_buff, temp_tx_bits, &temp_rx_buff, &temp_rx_bits, RFAL_FWT_NONE, flags); } else { ret = rfalNfcDataExchangeCustomStart( - tx_rx_ctx->tx_data, - tx_rx_ctx->tx_bits, - &temp_rx_buff, - &temp_rx_bits, - RFAL_FWT_NONE, - tx_rx_ctx->tx_rx_type); + tx_rx->tx_data, tx_rx->tx_bits, &temp_rx_buff, &temp_rx_bits, RFAL_FWT_NONE, flags); } if(ret != ERR_NONE) { + FURI_LOG_E(TAG, "Failed to start data exchange"); return false; } uint32_t start = DWT->CYCCNT; @@ -459,28 +490,64 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx_ctx) { state = rfalNfcGetState(); ret = rfalNfcDataExchangeGetStatus(); if(ret == ERR_BUSY) { - if(DWT->CYCCNT - start > 4 * clocks_in_ms) { + if(DWT->CYCCNT - start > timeout_ms * clocks_in_ms) { + FURI_LOG_D(TAG, "Timeout during data exchange"); return false; } continue; } else { start = DWT->CYCCNT; } - taskYIELD(); + osThreadYield(); } - if(tx_rx_ctx->tx_rx_type == FURI_HAL_NFC_TXRX_RAW) { - tx_rx_ctx->rx_bits = - 8 * furi_hal_nfc_bitstream_to_data_and_parity( - temp_rx_buff, *temp_rx_bits, tx_rx_ctx->rx_data, tx_rx_ctx->rx_parity); + if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw) { + 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 { - memcpy(tx_rx_ctx->rx_data, temp_rx_buff, *temp_rx_bits / 8); + memcpy(tx_rx->rx_data, temp_rx_buff, MIN(*temp_rx_bits / 8, FURI_HAL_NFC_DATA_BUFF_SIZE)); + tx_rx->rx_bits = *temp_rx_bits; } return true; } -void furi_hal_nfc_deactivate() { +ReturnCode furi_hal_nfc_exchange_full( + uint8_t* tx_buff, + uint16_t tx_len, + uint8_t* rx_buff, + uint16_t rx_cap, + uint16_t* rx_len) { + ReturnCode err; + uint8_t* part_buff; + uint16_t* part_len_bits; + uint16_t part_len_bytes; + + err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &part_buff, &part_len_bits, false); + part_len_bytes = *part_len_bits / 8; + if(part_len_bytes > rx_cap) { + return ERR_OVERRUN; + } + memcpy(rx_buff, part_buff, part_len_bytes); + *rx_len = part_len_bytes; + while(err == ERR_NONE && rx_buff[0] == 0xAF) { + err = furi_hal_nfc_data_exchange(rx_buff, 1, &part_buff, &part_len_bits, false); + part_len_bytes = *part_len_bits / 8; + if(part_len_bytes > rx_cap - *rx_len) { + return ERR_OVERRUN; + } + if(part_len_bytes == 0) { + return ERR_PROTO; + } + memcpy(rx_buff + *rx_len, part_buff + 1, part_len_bytes - 1); + *rx_buff = *part_buff; + *rx_len += part_len_bytes - 1; + } + + return err; +} + +void furi_hal_nfc_sleep() { rfalNfcDeactivate(false); rfalLowPowerModeStart(); } diff --git a/firmware/targets/furi_hal_include/furi_hal_nfc.h b/firmware/targets/furi_hal_include/furi_hal_nfc.h index edccab76..20a46900 100755 --- a/firmware/targets/furi_hal_include/furi_hal_nfc.h +++ b/firmware/targets/furi_hal_include/furi_hal_nfc.h @@ -15,32 +15,31 @@ extern "C" { #endif #define FURI_HAL_NFC_UID_MAX_LEN 10 -#define FURI_HAL_NFC_DATA_BUFF_SIZE (64) +#define FURI_HAL_NFC_DATA_BUFF_SIZE (256) #define FURI_HAL_NFC_PARITY_BUFF_SIZE (FURI_HAL_NFC_DATA_BUFF_SIZE / 8) #define FURI_HAL_NFC_TXRX_DEFAULT \ ((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_AUTO | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_REMV | \ - (uint32_t)RFAL_TXRX_FLAGS_NFCIP1_OFF | (uint32_t)RFAL_TXRX_FLAGS_AGC_ON | \ - (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO | \ - (uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO) + (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO) #define FURI_HAL_NFC_TX_DEFAULT_RX_NO_CRC \ ((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_AUTO | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \ - (uint32_t)RFAL_TXRX_FLAGS_NFCIP1_OFF | (uint32_t)RFAL_TXRX_FLAGS_AGC_ON | \ - (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO | \ - (uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO) + (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO) #define FURI_HAL_NFC_TXRX_WITH_PAR \ ((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \ - (uint32_t)RFAL_TXRX_FLAGS_NFCIP1_OFF | (uint32_t)RFAL_TXRX_FLAGS_AGC_ON | \ - (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO | \ - (uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO) + (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO) #define FURI_HAL_NFC_TXRX_RAW \ ((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \ - (uint32_t)RFAL_TXRX_FLAGS_NFCIP1_OFF | (uint32_t)RFAL_TXRX_FLAGS_AGC_ON | \ - (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE | \ - (uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO) + (uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE) + +typedef enum { + FuriHalNfcTxRxTypeDefault, + FuriHalNfcTxRxTypeRxNoCrc, + FuriHalNfcTxRxTypeRxKeepPar, + FuriHalNfcTxRxTypeRaw, +} FuriHalNfcTxRxType; typedef bool (*FuriHalNfcEmulateCallback)( uint8_t* buff_rx, @@ -50,6 +49,29 @@ typedef bool (*FuriHalNfcEmulateCallback)( uint32_t* flags, void* context); +typedef enum { + FuriHalNfcTypeA, + FuriHalNfcTypeB, + FuriHalNfcTypeF, + FuriHalNfcTypeV, +} FuriHalNfcType; + +typedef enum { + FuriHalNfcInterfaceRf, + FuriHalNfcInterfaceIsoDep, + FuriHalNfcInterfaceNfcDep, +} FuriHalNfcInterface; + +typedef struct { + FuriHalNfcType type; + FuriHalNfcInterface interface; + uint8_t uid_len; + uint8_t uid[10]; + uint32_t cuid; + uint8_t atqa[2]; + uint8_t sak; +} FuriHalNfcDevData; + typedef struct { uint8_t tx_data[FURI_HAL_NFC_DATA_BUFF_SIZE]; uint8_t tx_parity[FURI_HAL_NFC_PARITY_BUFF_SIZE]; @@ -57,7 +79,7 @@ typedef struct { uint8_t rx_data[FURI_HAL_NFC_DATA_BUFF_SIZE]; uint8_t rx_parity[FURI_HAL_NFC_PARITY_BUFF_SIZE]; uint16_t rx_bits; - uint32_t tx_rx_type; + FuriHalNfcTxRxType tx_rx_type; } FuriHalNfcTxRxContext; /** Init nfc @@ -95,11 +117,7 @@ void furi_hal_nfc_exit_sleep(); * * @return true on success */ -bool furi_hal_nfc_detect( - rfalNfcDevice** dev_list, - uint8_t* dev_cnt, - uint32_t timeout, - bool deactivate); +bool furi_hal_nfc_detect(FuriHalNfcDevData* nfc_data, uint32_t timeout); /** Activate NFC-A tag * @@ -138,15 +156,6 @@ bool furi_hal_nfc_emulate_nfca( void* context, uint32_t timeout); -/** Get first command from reader after activation in emulation mode - * - * @param rx_buff pointer to receive buffer - * @param rx_len receive buffer length - * - * @return true on success - */ -bool furi_hal_nfc_get_first_frame(uint8_t** rx_buff, uint16_t** rx_len); - /** NFC data exchange * * @param tx_buff transmit buffer @@ -170,11 +179,28 @@ ReturnCode furi_hal_nfc_data_exchange( * * @return true on success */ -bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx_ctx); +bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms); + +/** NFC data full exhange + * + * @param tx_buff transmit buffer + * @param tx_len transmit buffer length + * @param rx_buff receive buffer + * @param rx_cap receive buffer capacity + * @param rx_len receive buffer length + * + * @return ST ReturnCode + */ +ReturnCode furi_hal_nfc_exchange_full( + uint8_t* tx_buff, + uint16_t tx_len, + uint8_t* rx_buff, + uint16_t rx_cap, + uint16_t* rx_len); /** NFC deactivate and start sleep */ -void furi_hal_nfc_deactivate(); +void furi_hal_nfc_sleep(); void furi_hal_nfc_stop(); diff --git a/lib/ST25RFAL002/source/rfal_isoDep.c b/lib/ST25RFAL002/source/rfal_isoDep.c index 4f0cff58..77e67521 100644 --- a/lib/ST25RFAL002/source/rfal_isoDep.c +++ b/lib/ST25RFAL002/source/rfal_isoDep.c @@ -3015,7 +3015,7 @@ ReturnCode rfalIsoDepGetApduTransceiveStatus(void) { } /* Update output param rxLen */ - *gIsoDep.APDUParam.rxLen = gIsoDep.APDURxPos; + *gIsoDep.APDUParam.rxLen = gIsoDep.APDURxPos * 8; /* Wait for following I-Block or APDU TxRx has finished */ return ((ret == ERR_AGAIN) ? ERR_BUSY : ERR_NONE); diff --git a/lib/ST25RFAL002/source/rfal_nfc.c b/lib/ST25RFAL002/source/rfal_nfc.c index a4a6094d..9040b7f9 100755 --- a/lib/ST25RFAL002/source/rfal_nfc.c +++ b/lib/ST25RFAL002/source/rfal_nfc.c @@ -725,9 +725,14 @@ ReturnCode rfalNfcDataExchangeCustomStart( { /*******************************************************************************/ case RFAL_NFC_INTERFACE_RF: - ctx.rxBuf = gNfcDev.rxBuf.rfBuf, ctx.rxBufLen = sizeof(gNfcDev.rxBuf.rfBuf), - ctx.rxRcvdLen = &gNfcDev.rxLen, ctx.txBuf = txData, ctx.txBufLen = txDataLen, - ctx.flags = flags, ctx.fwt = fwt, *rxData = (uint8_t*)gNfcDev.rxBuf.rfBuf; + ctx.rxBuf = gNfcDev.rxBuf.rfBuf; + ctx.rxBufLen = 8 * sizeof(gNfcDev.rxBuf.rfBuf); + ctx.rxRcvdLen = &gNfcDev.rxLen; + ctx.txBuf = txData; + ctx.txBufLen = txDataLen; + ctx.flags = flags; + ctx.fwt = fwt; + *rxData = (uint8_t*)gNfcDev.rxBuf.rfBuf; *rvdLen = (uint16_t*)&gNfcDev.rxLen; err = rfalStartTransceive(&ctx); break; @@ -736,13 +741,14 @@ ReturnCode rfalNfcDataExchangeCustomStart( /*******************************************************************************/ case RFAL_NFC_INTERFACE_ISODEP: { rfalIsoDepApduTxRxParam isoDepTxRx; + uint16_t tx_bytes = txDataLen / 8; - if(txDataLen > sizeof(gNfcDev.txBuf.isoDepBuf.apdu)) { + if(tx_bytes > sizeof(gNfcDev.txBuf.isoDepBuf.apdu)) { return ERR_NOMEM; } - if(txDataLen > 0U) { - ST_MEMCPY((uint8_t*)gNfcDev.txBuf.isoDepBuf.apdu, txData, txDataLen); + if(tx_bytes > 0U) { + ST_MEMCPY((uint8_t*)gNfcDev.txBuf.isoDepBuf.apdu, txData, tx_bytes); } isoDepTxRx.DID = RFAL_ISODEP_NO_DID; @@ -751,7 +757,7 @@ ReturnCode rfalNfcDataExchangeCustomStart( isoDepTxRx.dFWT = gNfcDev.activeDev->proto.isoDep.info.dFWT; isoDepTxRx.FWT = gNfcDev.activeDev->proto.isoDep.info.FWT; isoDepTxRx.txBuf = &gNfcDev.txBuf.isoDepBuf; - isoDepTxRx.txBufLen = txDataLen; + isoDepTxRx.txBufLen = tx_bytes; isoDepTxRx.rxBuf = &gNfcDev.rxBuf.isoDepBuf; isoDepTxRx.rxLen = &gNfcDev.rxLen; isoDepTxRx.tmpBuf = &gNfcDev.tmpBuf.isoDepBuf; diff --git a/lib/nfc_protocols/emv_decoder.c b/lib/nfc_protocols/emv.c similarity index 55% rename from lib/nfc_protocols/emv_decoder.c rename to lib/nfc_protocols/emv.c index e63a6e96..6756981b 100644 --- a/lib/nfc_protocols/emv_decoder.c +++ b/lib/nfc_protocols/emv.c @@ -1,4 +1,8 @@ -#include "emv_decoder.h" +#include "emv.h" + +#include + +#define TAG "Emv" const PDOLValue pdol_term_info = {0x9F59, {0xC8, 0x80, 0x00}}; // Terminal transaction information const PDOLValue pdol_term_type = {0x9F5A, {0x00}}; // Terminal transaction type @@ -69,19 +73,6 @@ static bool emv_decode_search_tag_u16_r(uint16_t tag, uint8_t* buff, uint16_t* i return false; } -uint16_t emv_prepare_select_ppse(uint8_t* dest) { - const uint8_t emv_select_ppse[] = { - 0x00, 0xA4, // SELECT ppse - 0x04, 0x00, // P1:By name, P2: empty - 0x0e, // Lc: Data length - 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, // Data string: - 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, // 2PAY.SYS.DDF01 (PPSE) - 0x00 // Le - }; - memcpy(dest, emv_select_ppse, sizeof(emv_select_ppse)); - return sizeof(emv_select_ppse); -} - bool emv_decode_ppse_response(uint8_t* buff, uint16_t len, EmvApplication* app) { uint16_t i = 0; bool app_aid_found = false; @@ -89,7 +80,7 @@ bool emv_decode_ppse_response(uint8_t* buff, uint16_t len, EmvApplication* app) while(i < len) { if(buff[i] == EMV_TAG_APP_TEMPLATE) { uint8_t app_len = buff[++i]; - for(uint16_t j = i; j < i + app_len; j++) { + for(uint16_t j = i; j < MIN(i + app_len, len - 1); j++) { if(buff[j] == EMV_TAG_AID) { app_aid_found = true; app->aid_len = buff[j + 1]; @@ -105,7 +96,59 @@ bool emv_decode_ppse_response(uint8_t* buff, uint16_t len, EmvApplication* app) return app_aid_found; } -uint16_t emv_prepare_select_app(uint8_t* dest, EmvApplication* app) { +bool emv_select_ppse(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { + bool app_aid_found = false; + const uint8_t emv_select_ppse_cmd[] = { + 0x00, 0xA4, // SELECT ppse + 0x04, 0x00, // P1:By name, P2: empty + 0x0e, // Lc: Data length + 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, // Data string: + 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, // 2PAY.SYS.DDF01 (PPSE) + 0x00 // Le + }; + + memcpy(tx_rx->tx_data, emv_select_ppse_cmd, sizeof(emv_select_ppse_cmd)); + tx_rx->tx_bits = sizeof(emv_select_ppse_cmd) * 8; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + + FURI_LOG_D(TAG, "Send select PPSE"); + if(furi_hal_nfc_tx_rx(tx_rx, 300)) { + if(emv_decode_ppse_response(tx_rx->rx_data, tx_rx->rx_bits / 8, app)) { + app_aid_found = true; + } else { + FURI_LOG_E(TAG, "Failed to parse application"); + } + } else { + FURI_LOG_E(TAG, "Failed select PPSE"); + } + + return app_aid_found; +} + +static bool emv_decode_select_app_response(uint8_t* buff, uint16_t len, EmvApplication* app) { + uint16_t i = 0; + bool decode_success = false; + + while(i < len) { + if(buff[i] == EMV_TAG_CARD_NAME) { + uint8_t name_len = buff[i + 1]; + emv_parse_TLV((uint8_t*)app->name, buff, &i); + app->name[name_len] = '\0'; + app->name_found = true; + decode_success = true; + } else if(((buff[i] << 8) | buff[i + 1]) == EMV_TAG_PDOL) { + i++; + app->pdol.size = emv_parse_TLV(app->pdol.data, buff, &i); + decode_success = true; + } + i++; + } + + return decode_success; +} + +bool emv_select_app(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { + bool select_app_success = false; const uint8_t emv_select_header[] = { 0x00, 0xA4, // SELECT application @@ -113,33 +156,29 @@ uint16_t emv_prepare_select_app(uint8_t* dest, EmvApplication* app) { 0x00 // P1:By name, P2:First or only occurence }; uint16_t size = sizeof(emv_select_header); + // Copy header - memcpy(dest, emv_select_header, size); + memcpy(tx_rx->tx_data, emv_select_header, size); // Copy AID - dest[size++] = app->aid_len; - memcpy(&dest[size], app->aid, app->aid_len); + tx_rx->tx_data[size++] = app->aid_len; + memcpy(&tx_rx->tx_data[size], app->aid, app->aid_len); size += app->aid_len; - dest[size++] = 0; - return size; -} + tx_rx->tx_data[size++] = 0x00; + tx_rx->tx_bits = size * 8; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; -bool emv_decode_select_app_response(uint8_t* buff, uint16_t len, EmvApplication* app) { - uint16_t i = 0; - bool found_name = false; - - while(i < len) { - if(buff[i] == EMV_TAG_CARD_NAME) { - uint8_t name_len = buff[i + 1]; - emv_parse_TLV((uint8_t*)app->name, buff, &i); - app->name[name_len] = '\0'; - found_name = true; - } else if(((buff[i] << 8) | buff[i + 1]) == EMV_TAG_PDOL) { - i++; - app->pdol.size = emv_parse_TLV(app->pdol.data, buff, &i); + FURI_LOG_D(TAG, "Start application"); + if(furi_hal_nfc_tx_rx(tx_rx, 300)) { + if(emv_decode_select_app_response(tx_rx->rx_data, tx_rx->rx_bits / 8, app)) { + select_app_success = true; + } else { + FURI_LOG_E(TAG, "Failed to read PAN or PDOL"); } - i++; + } else { + FURI_LOG_E(TAG, "Failed to start application"); } - return found_name; + + return select_app_success; } static uint16_t emv_prepare_pdol(APDU* dest, APDU* src) { @@ -175,53 +214,56 @@ static uint16_t emv_prepare_pdol(APDU* dest, APDU* src) { return dest->size; } -uint16_t emv_prepare_get_proc_opt(uint8_t* dest, EmvApplication* app) { - // Get processing option header - const uint8_t emv_gpo_header[] = {0x80, 0xA8, 0x00, 0x00}; - uint16_t size = sizeof(emv_gpo_header); - // Copy header - memcpy(dest, emv_gpo_header, size); - APDU pdol_data = {0, {0}}; - // Prepare and copy pdol parameters - emv_prepare_pdol(&pdol_data, &app->pdol); - dest[size++] = 0x02 + pdol_data.size; - dest[size++] = 0x83; - dest[size++] = pdol_data.size; - memcpy(dest + size, pdol_data.data, pdol_data.size); - size += pdol_data.size; - dest[size++] = 0; - return size; -} +static bool emv_decode_get_proc_opt(uint8_t* buff, uint16_t len, EmvApplication* app) { + bool card_num_read = false; -bool emv_decode_get_proc_opt(uint8_t* buff, uint16_t len, EmvApplication* app) { for(uint16_t i = 0; i < len; i++) { if(buff[i] == EMV_TAG_CARD_NUM) { app->card_number_len = 8; memcpy(app->card_number, &buff[i + 2], app->card_number_len); - return true; + card_num_read = true; } else if(buff[i] == EMV_TAG_AFL) { app->afl.size = emv_parse_TLV(app->afl.data, buff, &i); } } - return false; + + return card_num_read; } -uint16_t emv_prepare_read_sfi_record(uint8_t* dest, uint8_t sfi, uint8_t record_num) { - const uint8_t sfi_param = (sfi << 3) | (1 << 2); - const uint8_t emv_sfi_header[] = { - 0x00, - 0xB2, // READ RECORD - record_num, - sfi_param, // P1:record_number and P2:SFI - 0x00 // Le - }; - uint16_t size = sizeof(emv_sfi_header); - memcpy(dest, emv_sfi_header, size); - return size; +static bool emv_get_processing_options(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { + bool card_num_read = false; + const uint8_t emv_gpo_header[] = {0x80, 0xA8, 0x00, 0x00}; + uint16_t size = sizeof(emv_gpo_header); + + // Copy header + memcpy(tx_rx->tx_data, emv_gpo_header, size); + APDU pdol_data = {0, {0}}; + // Prepare and copy pdol parameters + emv_prepare_pdol(&pdol_data, &app->pdol); + tx_rx->tx_data[size++] = 0x02 + pdol_data.size; + tx_rx->tx_data[size++] = 0x83; + tx_rx->tx_data[size++] = pdol_data.size; + memcpy(tx_rx->tx_data + size, pdol_data.data, pdol_data.size); + size += pdol_data.size; + tx_rx->tx_data[size++] = 0; + tx_rx->tx_bits = size * 8; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + + FURI_LOG_D(TAG, "Get proccessing options"); + if(furi_hal_nfc_tx_rx(tx_rx, 300)) { + if(emv_decode_get_proc_opt(tx_rx->rx_data, tx_rx->rx_bits / 8, app)) { + card_num_read = true; + } + } else { + FURI_LOG_E(TAG, "Failed to get processing options"); + } + + return card_num_read; } -bool emv_decode_read_sfi_record(uint8_t* buff, uint16_t len, EmvApplication* app) { +static bool emv_decode_read_sfi_record(uint8_t* buff, uint16_t len, EmvApplication* app) { bool pan_parsed = false; + for(uint16_t i = 0; i < len; i++) { if(buff[i] == EMV_TAG_PAN) { if(buff[i + 1] == 8 || buff[i + 1] == 10) { @@ -240,20 +282,118 @@ bool emv_decode_read_sfi_record(uint8_t* buff, uint16_t len, EmvApplication* app i += 2; } } + return pan_parsed; } -uint16_t emv_select_ppse_ans(uint8_t* buff) { - memcpy(buff, select_ppse_ans, sizeof(select_ppse_ans)); - return sizeof(select_ppse_ans); +static bool emv_read_sfi_record( + FuriHalNfcTxRxContext* tx_rx, + EmvApplication* app, + uint8_t sfi, + uint8_t record_num) { + bool card_num_read = false; + uint8_t sfi_param = (sfi << 3) | (1 << 2); + uint8_t emv_sfi_header[] = { + 0x00, + 0xB2, // READ RECORD + record_num, // P1:record_number + sfi_param, // P2:SFI + 0x00 // Le + }; + + memcpy(tx_rx->tx_data, emv_sfi_header, sizeof(emv_sfi_header)); + tx_rx->tx_bits = sizeof(emv_sfi_header) * 8; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + + if(furi_hal_nfc_tx_rx(tx_rx, 300)) { + if(emv_decode_read_sfi_record(tx_rx->rx_data, tx_rx->rx_bits / 8, app)) { + card_num_read = true; + } + } else { + FURI_LOG_E(TAG, "Failed to read SFI record %d", record_num); + } + + return card_num_read; } -uint16_t emv_select_app_ans(uint8_t* buff) { - memcpy(buff, select_app_ans, sizeof(select_app_ans)); - return sizeof(select_app_ans); +static bool emv_read_files(FuriHalNfcTxRxContext* tx_rx, EmvApplication* app) { + bool card_num_read = false; + + if(app->afl.size == 0) { + return false; + } + + FURI_LOG_D(TAG, "Search PAN in SFI"); + // Iterate through all files + for(size_t i = 0; i < app->afl.size; i += 4) { + uint8_t sfi = app->afl.data[i] >> 3; + uint8_t record_start = app->afl.data[i + 1]; + uint8_t record_end = app->afl.data[i + 2]; + // Iterate through all records in file + for(uint8_t record = record_start; record <= record_end; ++record) { + card_num_read |= emv_read_sfi_record(tx_rx, app, sfi, record); + } + } + + return card_num_read; } -uint16_t emv_get_proc_opt_ans(uint8_t* buff) { - memcpy(buff, pdol_ans, sizeof(pdol_ans)); - return sizeof(pdol_ans); +bool emv_search_application(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app) { + furi_assert(tx_rx); + furi_assert(emv_app); + memset(emv_app, 0, sizeof(EmvApplication)); + + return emv_select_ppse(tx_rx, emv_app); +} + +bool emv_read_bank_card(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app) { + furi_assert(tx_rx); + furi_assert(emv_app); + bool card_num_read = false; + memset(emv_app, 0, sizeof(EmvApplication)); + + do { + if(!emv_select_ppse(tx_rx, emv_app)) break; + if(!emv_select_app(tx_rx, emv_app)) break; + if(emv_get_processing_options(tx_rx, emv_app)) { + card_num_read = true; + } else { + card_num_read = emv_read_files(tx_rx, emv_app); + } + } while(false); + + return card_num_read; +} + +bool emv_card_emulation(FuriHalNfcTxRxContext* tx_rx) { + furi_assert(tx_rx); + bool emulation_complete = false; + memset(tx_rx, 0, sizeof(FuriHalNfcTxRxContext)); + + do { + FURI_LOG_D(TAG, "Read select PPSE command"); + if(!furi_hal_nfc_tx_rx(tx_rx, 300)) break; + + memcpy(tx_rx->tx_data, select_ppse_ans, sizeof(select_ppse_ans)); + tx_rx->tx_bits = sizeof(select_ppse_ans) * 8; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + FURI_LOG_D(TAG, "Send select PPSE answer and read select App command"); + if(!furi_hal_nfc_tx_rx(tx_rx, 300)) break; + + memcpy(tx_rx->tx_data, select_app_ans, sizeof(select_app_ans)); + tx_rx->tx_bits = sizeof(select_app_ans) * 8; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + FURI_LOG_D(TAG, "Send select App answer and read get PDOL command"); + if(!furi_hal_nfc_tx_rx(tx_rx, 300)) break; + + memcpy(tx_rx->tx_data, pdol_ans, sizeof(pdol_ans)); + tx_rx->tx_bits = sizeof(pdol_ans) * 8; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + FURI_LOG_D(TAG, "Send get PDOL answer"); + if(!furi_hal_nfc_tx_rx(tx_rx, 300)) break; + + emulation_complete = true; + } while(false); + + return emulation_complete; } diff --git a/lib/nfc_protocols/emv.h b/lib/nfc_protocols/emv.h new file mode 100755 index 00000000..b5a0c574 --- /dev/null +++ b/lib/nfc_protocols/emv.h @@ -0,0 +1,87 @@ +#pragma once + +#include + +#define MAX_APDU_LEN 255 + +#define EMV_TAG_APP_TEMPLATE 0x61 +#define EMV_TAG_AID 0x4F +#define EMV_TAG_PRIORITY 0x87 +#define EMV_TAG_PDOL 0x9F38 +#define EMV_TAG_CARD_NAME 0x50 +#define EMV_TAG_FCI 0xBF0C +#define EMV_TAG_LOG_CTRL 0x9F4D +#define EMV_TAG_CARD_NUM 0x57 +#define EMV_TAG_PAN 0x5A +#define EMV_TAG_AFL 0x94 +#define EMV_TAG_EXP_DATE 0x5F24 +#define EMV_TAG_COUNTRY_CODE 0x5F28 +#define EMV_TAG_CURRENCY_CODE 0x9F42 +#define EMV_TAG_CARDHOLDER_NAME 0x5F20 + +typedef struct { + char name[32]; + uint8_t aid[16]; + uint16_t aid_len; + uint8_t number[10]; + uint8_t number_len; + uint8_t exp_mon; + uint8_t exp_year; + uint16_t country_code; + uint16_t currency_code; +} EmvData; + +typedef struct { + uint16_t tag; + uint8_t data[]; +} PDOLValue; + +typedef struct { + uint8_t size; + uint8_t data[MAX_APDU_LEN]; +} APDU; + +typedef struct { + uint8_t priority; + uint8_t aid[16]; + uint8_t aid_len; + char name[32]; + bool name_found; + uint8_t card_number[10]; + uint8_t card_number_len; + uint8_t exp_month; + uint8_t exp_year; + uint16_t country_code; + uint16_t currency_code; + APDU pdol; + APDU afl; +} EmvApplication; + +/** Read bank card data + * @note Search EMV Application, start it, try to read AID, PAN, card name, + * expiration date, currency and country codes + * + * @param tx_rx FuriHalNfcTxRxContext instance + * @param emv_app EmvApplication instance + * + * @return true on success + */ +bool emv_read_bank_card(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app); + +/** Search for EMV Application + * + * @param tx_rx FuriHalNfcTxRxContext instance + * @param emv_app EmvApplication instance + * + * @return true on success + */ +bool emv_search_application(FuriHalNfcTxRxContext* tx_rx, EmvApplication* emv_app); + +/** Emulate bank card + * @note Answer to application selection and PDOL + * + * @param tx_rx FuriHalNfcTxRxContext instance + * + * @return true on success + */ +bool emv_card_emulation(FuriHalNfcTxRxContext* tx_rx); diff --git a/lib/nfc_protocols/emv_decoder.h b/lib/nfc_protocols/emv_decoder.h deleted file mode 100755 index 7328ee79..00000000 --- a/lib/nfc_protocols/emv_decoder.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include -#include - -#define MAX_APDU_LEN 255 - -#define EMV_TAG_APP_TEMPLATE 0x61 -#define EMV_TAG_AID 0x4F -#define EMV_TAG_PRIORITY 0x87 -#define EMV_TAG_PDOL 0x9F38 -#define EMV_TAG_CARD_NAME 0x50 -#define EMV_TAG_FCI 0xBF0C -#define EMV_TAG_LOG_CTRL 0x9F4D -#define EMV_TAG_CARD_NUM 0x57 -#define EMV_TAG_PAN 0x5A -#define EMV_TAG_AFL 0x94 -#define EMV_TAG_EXP_DATE 0x5F24 -#define EMV_TAG_COUNTRY_CODE 0x5F28 -#define EMV_TAG_CURRENCY_CODE 0x9F42 -#define EMV_TAG_CARDHOLDER_NAME 0x5F20 - -typedef struct { - uint16_t tag; - uint8_t data[]; -} PDOLValue; - -extern const PDOLValue* const pdol_values[]; - -typedef struct { - uint8_t size; - uint8_t data[MAX_APDU_LEN]; -} APDU; - -typedef struct { - uint8_t priority; - uint8_t aid[16]; - uint8_t aid_len; - char name[32]; - uint8_t card_number[10]; - uint8_t card_number_len; - uint8_t exp_month; - uint8_t exp_year; - uint16_t country_code; - uint16_t currency_code; - APDU pdol; - APDU afl; -} EmvApplication; - -/* Terminal emulation */ -uint16_t emv_prepare_select_ppse(uint8_t* dest); -bool emv_decode_ppse_response(uint8_t* buff, uint16_t len, EmvApplication* app); - -uint16_t emv_prepare_select_app(uint8_t* dest, EmvApplication* app); -bool emv_decode_select_app_response(uint8_t* buff, uint16_t len, EmvApplication* app); - -uint16_t emv_prepare_get_proc_opt(uint8_t* dest, EmvApplication* app); -bool emv_decode_get_proc_opt(uint8_t* buff, uint16_t len, EmvApplication* app); - -uint16_t emv_prepare_read_sfi_record(uint8_t* dest, uint8_t sfi, uint8_t record_num); -bool emv_decode_read_sfi_record(uint8_t* buff, uint16_t len, EmvApplication* app); - -/* Card emulation */ -uint16_t emv_select_ppse_ans(uint8_t* buff); -uint16_t emv_select_app_ans(uint8_t* buff); -uint16_t emv_get_proc_opt_ans(uint8_t* buff); diff --git a/lib/nfc_protocols/mifare_classic.c b/lib/nfc_protocols/mifare_classic.c index 65408e78..eb5d3dda 100644 --- a/lib/nfc_protocols/mifare_classic.c +++ b/lib/nfc_protocols/mifare_classic.c @@ -116,17 +116,15 @@ static bool mf_classic_auth( tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_B_CMD; } tx_rx->tx_data[1] = block; - tx_rx->tx_rx_type = FURI_HAL_NFC_TX_DEFAULT_RX_NO_CRC; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRxNoCrc; tx_rx->tx_bits = 2 * 8; - if(!furi_hal_nfc_tx_rx(tx_rx)) break; + if(!furi_hal_nfc_tx_rx(tx_rx, 4)) break; uint32_t nt = (uint32_t)nfc_util_bytes2num(tx_rx->rx_data, 4); crypto1_init(crypto, key); crypto1_word(crypto, nt ^ cuid, 0); uint8_t nr[4] = {}; - // uint8_t parity = 0; nfc_util_num2bytes(prng_successor(DWT->CYCCNT, 32), 4, nr); - // uint8_t nr_ar[8] = {}; for(uint8_t i = 0; i < 4; i++) { tx_rx->tx_data[i] = crypto1_byte(crypto, nr[i], 0) ^ nr[i]; tx_rx->tx_parity[0] |= @@ -140,9 +138,9 @@ static bool mf_classic_auth( (((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nt & 0xff)) & 0x01) << (7 - i)); } - tx_rx->tx_rx_type = FURI_HAL_NFC_TXRX_RAW; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw; tx_rx->tx_bits = 8 * 8; - if(!furi_hal_nfc_tx_rx(tx_rx)) break; + if(!furi_hal_nfc_tx_rx(tx_rx, 4)) break; if(tx_rx->rx_bits == 32) { crypto1_word(crypto, 0, 0); auth_success = true; @@ -178,7 +176,7 @@ bool mf_classic_auth_attempt( } if(need_halt) { - furi_hal_nfc_deactivate(); + furi_hal_nfc_sleep(); furi_hal_nfc_activate_nfca(300, &auth_ctx->cuid); } @@ -220,9 +218,9 @@ bool mf_classic_read_block( ((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(plain_cmd[i])) & 0x01) << (7 - i); } tx_rx->tx_bits = 4 * 9; - tx_rx->tx_rx_type = FURI_HAL_NFC_TXRX_RAW; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw; - if(furi_hal_nfc_tx_rx(tx_rx)) { + if(furi_hal_nfc_tx_rx(tx_rx, 4)) { if(tx_rx->rx_bits == 8 * 18) { for(uint8_t i = 0; i < 18; i++) { block->value[i] = crypto1_byte(crypto, 0, 0) ^ tx_rx->rx_data[i]; @@ -248,7 +246,7 @@ bool mf_classic_read_sector( uint8_t first_block; bool sector_read = false; - furi_hal_nfc_deactivate(); + furi_hal_nfc_sleep(); do { // Activate card if(!furi_hal_nfc_activate_nfca(200, &cuid)) break; diff --git a/lib/nfc_protocols/mifare_common.c b/lib/nfc_protocols/mifare_common.c new file mode 100644 index 00000000..0be24b51 --- /dev/null +++ b/lib/nfc_protocols/mifare_common.c @@ -0,0 +1,17 @@ +#include "mifare_common.h" + +MifareType mifare_common_get_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { + MifareType type = MifareTypeUnknown; + + if((ATQA0 == 0x44) && (ATQA1 == 0x00) && (SAK == 0x00)) { + type = MifareTypeUltralight; + } else if( + ((ATQA0 == 0x44 || ATQA0 == 0x04) && (SAK == 0x08)) || + ((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18))) { + type = MifareTypeClassic; + } else if(ATQA0 == 0x44 && ATQA1 == 0x03 && SAK == 0x20) { + type = MifareTypeDesfire; + } + + return type; +} diff --git a/lib/nfc_protocols/mifare_common.h b/lib/nfc_protocols/mifare_common.h new file mode 100644 index 00000000..2b694d90 --- /dev/null +++ b/lib/nfc_protocols/mifare_common.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +typedef enum { + MifareTypeUnknown, + MifareTypeUltralight, + MifareTypeClassic, + MifareTypeDesfire, +} MifareType; + +MifareType mifare_common_get_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); diff --git a/lib/nfc_protocols/mifare_ultralight.c b/lib/nfc_protocols/mifare_ultralight.c index c9311124..c824c646 100644 --- a/lib/nfc_protocols/mifare_ultralight.c +++ b/lib/nfc_protocols/mifare_ultralight.c @@ -1,6 +1,7 @@ #include "mifare_ultralight.h" #include -#include + +#define TAG "MfUltralight" bool mf_ul_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { if((ATQA0 == 0x44) && (ATQA1 == 0x00) && (SAK == 0x00)) { @@ -9,187 +10,204 @@ bool mf_ul_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { return false; } -uint16_t mf_ul_prepare_get_version(uint8_t* dest) { - dest[0] = MF_UL_GET_VERSION_CMD; - return 1; +static void mf_ul_set_default_version(MfUltralightReader* reader, MfUltralightData* data) { + data->type = MfUltralightTypeUnknown; + reader->pages_to_read = 16; + reader->support_fast_read = false; } -void mf_ul_parse_get_version_response(uint8_t* buff, MifareUlDevice* mf_ul_read) { - MfUltralightVersion* version = (MfUltralightVersion*)buff; - memcpy(&mf_ul_read->data.version, version, sizeof(MfUltralightVersion)); - if(version->storage_size == 0x0B || version->storage_size == 0x00) { - mf_ul_read->data.type = MfUltralightTypeUL11; - mf_ul_read->pages_to_read = 20; - mf_ul_read->support_fast_read = true; - } else if(version->storage_size == 0x0E) { - mf_ul_read->data.type = MfUltralightTypeUL21; - mf_ul_read->pages_to_read = 41; - mf_ul_read->support_fast_read = true; - } else if(version->storage_size == 0x0F) { - mf_ul_read->data.type = MfUltralightTypeNTAG213; - mf_ul_read->pages_to_read = 45; - mf_ul_read->support_fast_read = false; - } else if(version->storage_size == 0x11) { - mf_ul_read->data.type = MfUltralightTypeNTAG215; - mf_ul_read->pages_to_read = 135; - mf_ul_read->support_fast_read = false; - } else if(version->storage_size == 0x13) { - mf_ul_read->data.type = MfUltralightTypeNTAG216; - mf_ul_read->pages_to_read = 231; - mf_ul_read->support_fast_read = false; +bool mf_ultralight_read_version( + FuriHalNfcTxRxContext* tx_rx, + MfUltralightReader* reader, + MfUltralightData* data) { + bool version_read = false; + + do { + FURI_LOG_D(TAG, "Reading version"); + tx_rx->tx_data[0] = MF_UL_GET_VERSION_CMD; + tx_rx->tx_bits = 8; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + if(!furi_hal_nfc_tx_rx(tx_rx, 4)) { + FURI_LOG_D(TAG, "Failed reading version"); + mf_ul_set_default_version(reader, data); + furi_hal_nfc_sleep(); + furi_hal_nfc_activate_nfca(300, NULL); + break; + } + MfUltralightVersion* version = (MfUltralightVersion*)tx_rx->rx_data; + data->version = *version; + if(version->storage_size == 0x0B || version->storage_size == 0x00) { + data->type = MfUltralightTypeUL11; + reader->pages_to_read = 20; + reader->support_fast_read = true; + } else if(version->storage_size == 0x0E) { + data->type = MfUltralightTypeUL21; + reader->pages_to_read = 41; + reader->support_fast_read = true; + } else if(version->storage_size == 0x0F) { + data->type = MfUltralightTypeNTAG213; + reader->pages_to_read = 45; + reader->support_fast_read = false; + } else if(version->storage_size == 0x11) { + data->type = MfUltralightTypeNTAG215; + reader->pages_to_read = 135; + reader->support_fast_read = false; + } else if(version->storage_size == 0x13) { + data->type = MfUltralightTypeNTAG216; + reader->pages_to_read = 231; + reader->support_fast_read = false; + } else { + mf_ul_set_default_version(reader, data); + break; + } + version_read = true; + } while(false); + + return version_read; +} + +bool mf_ultralight_read_pages( + FuriHalNfcTxRxContext* tx_rx, + MfUltralightReader* reader, + MfUltralightData* data) { + uint8_t pages_read_cnt = 0; + + for(size_t i = 0; i < reader->pages_to_read; i += 4) { + FURI_LOG_D(TAG, "Reading pages %d - %d", i, i + 3); + tx_rx->tx_data[0] = MF_UL_READ_CMD; + tx_rx->tx_data[1] = i; + tx_rx->tx_bits = 16; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + if(!furi_hal_nfc_tx_rx(tx_rx, 4)) { + FURI_LOG_D(TAG, "Failed to read pages %d - %d", i, i + 3); + break; + } + if(i + 4 <= reader->pages_to_read) { + pages_read_cnt = 4; + } else { + pages_read_cnt = reader->pages_to_read - reader->pages_read; + } + reader->pages_read += pages_read_cnt; + data->data_size = reader->pages_read * 4; + memcpy(&data->data[i * 4], tx_rx->rx_data, pages_read_cnt * 4); + } + + return reader->pages_read == reader->pages_to_read; +} + +bool mf_ultralight_fast_read_pages( + FuriHalNfcTxRxContext* tx_rx, + MfUltralightReader* reader, + MfUltralightData* data) { + FURI_LOG_D(TAG, "Reading pages 0 - %d", reader->pages_to_read); + tx_rx->tx_data[0] = MF_UL_FAST_READ_CMD; + tx_rx->tx_data[1] = 0; + tx_rx->tx_data[2] = reader->pages_to_read - 1; + tx_rx->tx_bits = 24; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + if(furi_hal_nfc_tx_rx(tx_rx, 20)) { + reader->pages_read = reader->pages_to_read; + data->data_size = reader->pages_read * 4; + memcpy(data->data, tx_rx->rx_data, data->data_size); } else { - mf_ul_set_default_version(mf_ul_read); - } -} - -void mf_ul_set_default_version(MifareUlDevice* mf_ul_read) { - mf_ul_read->data.type = MfUltralightTypeUnknown; - mf_ul_read->pages_to_read = 16; - mf_ul_read->support_fast_read = false; -} - -uint16_t mf_ul_prepare_read(uint8_t* dest, uint8_t start_page) { - dest[0] = MF_UL_READ_CMD; - dest[1] = start_page; - return 2; -} - -void mf_ul_parse_read_response(uint8_t* buff, uint16_t page_addr, MifareUlDevice* mf_ul_read) { - uint8_t pages_read = 4; - uint8_t page_read_count = mf_ul_read->pages_read + pages_read; - if(page_read_count > mf_ul_read->pages_to_read) { - pages_read -= page_read_count - mf_ul_read->pages_to_read; - } - mf_ul_read->pages_read += pages_read; - mf_ul_read->data.data_size = mf_ul_read->pages_read * 4; - memcpy(&mf_ul_read->data.data[page_addr * 4], buff, pages_read * 4); -} - -uint16_t mf_ul_prepare_fast_read(uint8_t* dest, uint8_t start_page, uint8_t end_page) { - dest[0] = MF_UL_FAST_READ_CMD; - dest[1] = start_page; - dest[2] = end_page; - return 3; -} - -void mf_ul_parse_fast_read_response( - uint8_t* buff, - uint8_t start_page, - uint8_t end_page, - MifareUlDevice* mf_ul_read) { - mf_ul_read->pages_read = end_page - start_page + 1; - mf_ul_read->data.data_size = mf_ul_read->pages_read * 4; - memcpy(mf_ul_read->data.data, buff, mf_ul_read->data.data_size); -} - -uint16_t mf_ul_prepare_read_signature(uint8_t* dest) { - dest[0] = MF_UL_READ_SIG; - dest[1] = 0; - return 2; -} - -void mf_ul_parse_read_signature_response(uint8_t* buff, MifareUlDevice* mf_ul_read) { - memcpy(mf_ul_read->data.signature, buff, sizeof(mf_ul_read->data.signature)); -} - -uint16_t mf_ul_prepare_read_cnt(uint8_t* dest, uint8_t cnt_index) { - if(cnt_index > 2) { - return 0; - } - dest[0] = MF_UL_READ_CNT; - dest[1] = cnt_index; - return 2; -} - -void mf_ul_parse_read_cnt_response(uint8_t* buff, uint8_t cnt_index, MifareUlDevice* mf_ul_read) { - // Reverse LSB sequence - if(cnt_index < 3) { - mf_ul_read->data.counter[cnt_index] = (buff[2] << 16) | (buff[1] << 8) | (buff[0]); - } -} - -uint16_t mf_ul_prepare_inc_cnt(uint8_t* dest, uint8_t cnt_index, uint32_t value) { - if(cnt_index > 2) { - return 0; - } - dest[0] = MF_UL_INC_CNT; - dest[1] = cnt_index; - dest[2] = (uint8_t)value; - dest[3] = (uint8_t)(value >> 8); - dest[4] = (uint8_t)(value >> 16); - dest[5] = 0; - return 6; -} - -uint16_t mf_ul_prepare_check_tearing(uint8_t* dest, uint8_t cnt_index) { - if(cnt_index > 2) { - return 0; - } - dest[0] = MF_UL_CHECK_TEARING; - dest[1] = cnt_index; - return 2; -} - -void mf_ul_parse_check_tearing_response( - uint8_t* buff, - uint8_t cnt_index, - MifareUlDevice* mf_ul_read) { - if(cnt_index < 2) { - mf_ul_read->data.tearing[cnt_index] = buff[0]; - } -} - -uint16_t mf_ul_prepare_write(uint8_t* dest, uint16_t page_addr, uint32_t data) { - if(page_addr < 2) { - return 0; - } - dest[0] = MF_UL_WRITE; - dest[1] = page_addr; - dest[2] = (uint8_t)(data >> 24); - dest[3] = (uint8_t)(data >> 16); - dest[4] = (uint8_t)(data >> 8); - dest[5] = (uint8_t)data; - return 6; -} - -void mf_ul_prepare_emulation(MifareUlDevice* mf_ul_emulate, MifareUlData* data) { - mf_ul_emulate->data = *data; - mf_ul_emulate->auth_data = NULL; - mf_ul_emulate->data_changed = false; - mf_ul_emulate->comp_write_cmd_started = false; - if(data->version.storage_size == 0) { - mf_ul_emulate->data.type = MfUltralightTypeUnknown; - mf_ul_emulate->support_fast_read = false; - } else if(data->version.storage_size == 0x0B) { - mf_ul_emulate->data.type = MfUltralightTypeUL11; - mf_ul_emulate->support_fast_read = true; - } else if(data->version.storage_size == 0x0E) { - mf_ul_emulate->data.type = MfUltralightTypeUL21; - mf_ul_emulate->support_fast_read = true; - } else if(data->version.storage_size == 0x0F) { - mf_ul_emulate->data.type = MfUltralightTypeNTAG213; - mf_ul_emulate->support_fast_read = true; - } else if(data->version.storage_size == 0x11) { - mf_ul_emulate->data.type = MfUltralightTypeNTAG215; - mf_ul_emulate->support_fast_read = true; - } else if(data->version.storage_size == 0x13) { - mf_ul_emulate->data.type = MfUltralightTypeNTAG216; - mf_ul_emulate->support_fast_read = true; + FURI_LOG_D(TAG, "Failed to read pages 0 - %d", reader->pages_to_read); } - if(mf_ul_emulate->data.type >= MfUltralightTypeNTAG213) { - uint16_t pwd_page = (data->data_size / 4) - 2; - mf_ul_emulate->auth_data = (MifareUlAuthData*)&data->data[pwd_page * 4]; - } + return reader->pages_read == reader->pages_to_read; } -void mf_ul_protect_auth_data_on_read_command( +bool mf_ultralight_read_signature(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data) { + bool signature_read = false; + + FURI_LOG_D(TAG, "Reading signature"); + tx_rx->tx_data[0] = MF_UL_READ_SIG; + tx_rx->tx_data[1] = 0; + tx_rx->tx_bits = 16; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + if(furi_hal_nfc_tx_rx(tx_rx, 7)) { + memcpy(data->signature, tx_rx->rx_data, sizeof(data->signature)); + signature_read = true; + } else { + FURI_LOG_D(TAG, "Failed redaing signature"); + } + + return signature_read; +} + +bool mf_ultralight_read_counters(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data) { + uint8_t counter_read = 0; + + FURI_LOG_D(TAG, "Reading counters"); + for(size_t i = 0; i < 3; i++) { + tx_rx->tx_data[0] = MF_UL_READ_CNT; + tx_rx->rx_data[1] = i; + tx_rx->tx_bits = 16; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + if(!furi_hal_nfc_tx_rx(tx_rx, 4)) { + FURI_LOG_D(TAG, "Failed to read %d counter", i); + break; + } + data->counter[i] = (tx_rx->rx_data[2] << 16) | (tx_rx->rx_data[1] << 8) | + tx_rx->rx_data[0]; + counter_read++; + } + + return counter_read == 2; +} + +bool mf_ultralight_read_tearing_flags(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data) { + uint8_t flag_read = 0; + + FURI_LOG_D(TAG, "Reading tearing flags"); + for(size_t i = 0; i < 3; i++) { + tx_rx->tx_data[0] = MF_UL_CHECK_TEARING; + tx_rx->rx_data[1] = i; + tx_rx->tx_bits = 16; + tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; + if(!furi_hal_nfc_tx_rx(tx_rx, 4)) { + FURI_LOG_D(TAG, "Failed to read %d tearing flag", i); + break; + } + data->tearing[i] = tx_rx->rx_data[0]; + flag_read++; + } + + return flag_read == 2; +} + +bool mf_ul_read_card( + FuriHalNfcTxRxContext* tx_rx, + MfUltralightReader* reader, + MfUltralightData* data) { + furi_assert(tx_rx); + furi_assert(reader); + furi_assert(data); + + bool card_read = false; + + // Read Mifare Ultralight version + if(mf_ultralight_read_version(tx_rx, reader, data)) { + // Read Signature + mf_ultralight_read_signature(tx_rx, data); + } + // Read data blocks + if(reader->support_fast_read) { + mf_ultralight_read_counters(tx_rx, data); + mf_ultralight_read_tearing_flags(tx_rx, data); + } + card_read = mf_ultralight_read_pages(tx_rx, reader, data); + + return card_read; +} + +// TODO rework +static void mf_ul_protect_auth_data_on_read_command( uint8_t* tx_buff, uint8_t start_page, uint8_t end_page, - MifareUlDevice* mf_ul_emulate) { - if(mf_ul_emulate->data.type >= MfUltralightTypeNTAG213) { - uint8_t pwd_page = (mf_ul_emulate->data.data_size / 4) - 2; + MfUltralightEmulator* emulator) { + if(emulator->data.type >= MfUltralightTypeNTAG213) { + uint8_t pwd_page = (emulator->data.data_size / 4) - 2; uint8_t pack_page = pwd_page + 1; if((start_page <= pwd_page) && (end_page >= pwd_page)) { memset(&tx_buff[(pwd_page - start_page) * 4], 0, 4); @@ -200,6 +218,31 @@ void mf_ul_protect_auth_data_on_read_command( } } +void mf_ul_prepare_emulation(MfUltralightEmulator* emulator, MfUltralightData* data) { + emulator->data = *data; + emulator->auth_data = NULL; + emulator->data_changed = false; + emulator->comp_write_cmd_started = false; + if(data->type == MfUltralightTypeUnknown) { + emulator->support_fast_read = false; + } else if(data->type == MfUltralightTypeUL11) { + emulator->support_fast_read = true; + } else if(data->type == MfUltralightTypeUL21) { + emulator->support_fast_read = true; + } else if(data->type == MfUltralightTypeNTAG213) { + emulator->support_fast_read = false; + } else if(data->type == MfUltralightTypeNTAG215) { + emulator->support_fast_read = false; + } else if(data->type == MfUltralightTypeNTAG216) { + emulator->support_fast_read = false; + } + + if(data->type >= MfUltralightTypeNTAG213) { + uint16_t pwd_page = (data->data_size / 4) - 2; + emulator->auth_data = (MfUltralightAuth*)&data->data[pwd_page * 4]; + } +} + bool mf_ul_prepare_emulation_response( uint8_t* buff_rx, uint16_t buff_rx_len, @@ -208,30 +251,30 @@ bool mf_ul_prepare_emulation_response( uint32_t* data_type, void* context) { furi_assert(context); - MifareUlDevice* mf_ul_emulate = context; + MfUltralightEmulator* emulator = context; uint8_t cmd = buff_rx[0]; - uint16_t page_num = mf_ul_emulate->data.data_size / 4; + uint16_t page_num = emulator->data.data_size / 4; uint16_t tx_bytes = 0; uint16_t tx_bits = 0; bool command_parsed = false; // Check composite commands - if(mf_ul_emulate->comp_write_cmd_started) { + if(emulator->comp_write_cmd_started) { // Compatibility write is the only one composit command if(buff_rx_len == 16) { - memcpy(&mf_ul_emulate->data.data[mf_ul_emulate->comp_write_page_addr * 4], buff_rx, 4); - mf_ul_emulate->data_changed = true; + memcpy(&emulator->data.data[emulator->comp_write_page_addr * 4], buff_rx, 4); + emulator->data_changed = true; // Send ACK message buff_tx[0] = 0x0A; tx_bits = 4; *data_type = FURI_HAL_NFC_TXRX_RAW; command_parsed = true; } - mf_ul_emulate->comp_write_cmd_started = false; + emulator->comp_write_cmd_started = false; } else if(cmd == MF_UL_GET_VERSION_CMD) { - if(mf_ul_emulate->data.type != MfUltralightTypeUnknown) { - tx_bytes = sizeof(mf_ul_emulate->data.version); - memcpy(buff_tx, &mf_ul_emulate->data.version, tx_bytes); + if(emulator->data.type != MfUltralightTypeUnknown) { + tx_bytes = sizeof(emulator->data.version); + memcpy(buff_tx, &emulator->data.version, tx_bytes); *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; } @@ -242,28 +285,24 @@ bool mf_ul_prepare_emulation_response( if(start_page + 4 > page_num) { // Handle roll-over mechanism uint8_t end_pages_num = page_num - start_page; - memcpy(buff_tx, &mf_ul_emulate->data.data[start_page * 4], end_pages_num * 4); - memcpy( - &buff_tx[end_pages_num * 4], - mf_ul_emulate->data.data, - (4 - end_pages_num) * 4); + memcpy(buff_tx, &emulator->data.data[start_page * 4], end_pages_num * 4); + memcpy(&buff_tx[end_pages_num * 4], emulator->data.data, (4 - end_pages_num) * 4); } else { - memcpy(buff_tx, &mf_ul_emulate->data.data[start_page * 4], tx_bytes); + memcpy(buff_tx, &emulator->data.data[start_page * 4], tx_bytes); } mf_ul_protect_auth_data_on_read_command( - buff_tx, start_page, (start_page + 4), mf_ul_emulate); + buff_tx, start_page, (start_page + 4), emulator); *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; } } else if(cmd == MF_UL_FAST_READ_CMD) { - if(mf_ul_emulate->support_fast_read) { + if(emulator->support_fast_read) { uint8_t start_page = buff_rx[1]; uint8_t end_page = buff_rx[2]; if((start_page < page_num) && (end_page < page_num) && (start_page < (end_page + 1))) { tx_bytes = ((end_page + 1) - start_page) * 4; - memcpy(buff_tx, &mf_ul_emulate->data.data[start_page * 4], tx_bytes); - mf_ul_protect_auth_data_on_read_command( - buff_tx, start_page, end_page, mf_ul_emulate); + memcpy(buff_tx, &emulator->data.data[start_page * 4], tx_bytes); + mf_ul_protect_auth_data_on_read_command(buff_tx, start_page, end_page, emulator); *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; } @@ -271,8 +310,8 @@ bool mf_ul_prepare_emulation_response( } else if(cmd == MF_UL_WRITE) { uint8_t write_page = buff_rx[1]; if((write_page > 1) && (write_page < page_num - 2)) { - memcpy(&mf_ul_emulate->data.data[write_page * 4], &buff_rx[2], 4); - mf_ul_emulate->data_changed = true; + memcpy(&emulator->data.data[write_page * 4], &buff_rx[2], 4); + emulator->data_changed = true; // ACK buff_tx[0] = 0x0A; tx_bits = 4; @@ -282,8 +321,8 @@ bool mf_ul_prepare_emulation_response( } else if(cmd == MF_UL_COMP_WRITE) { uint8_t write_page = buff_rx[1]; if((write_page > 1) && (write_page < page_num - 2)) { - mf_ul_emulate->comp_write_cmd_started = true; - mf_ul_emulate->comp_write_page_addr = write_page; + emulator->comp_write_cmd_started = true; + emulator->comp_write_page_addr = write_page; // ACK buff_tx[0] = 0x0A; tx_bits = 4; @@ -293,9 +332,9 @@ bool mf_ul_prepare_emulation_response( } else if(cmd == MF_UL_READ_CNT) { uint8_t cnt_num = buff_rx[1]; if(cnt_num < 3) { - buff_tx[0] = mf_ul_emulate->data.counter[cnt_num] >> 16; - buff_tx[1] = mf_ul_emulate->data.counter[cnt_num] >> 8; - buff_tx[2] = mf_ul_emulate->data.counter[cnt_num]; + buff_tx[0] = emulator->data.counter[cnt_num] >> 16; + buff_tx[1] = emulator->data.counter[cnt_num] >> 8; + buff_tx[2] = emulator->data.counter[cnt_num]; tx_bytes = 3; *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; @@ -303,9 +342,9 @@ bool mf_ul_prepare_emulation_response( } else if(cmd == MF_UL_INC_CNT) { uint8_t cnt_num = buff_rx[1]; uint32_t inc = (buff_rx[2] | (buff_rx[3] << 8) | (buff_rx[4] << 16)); - if((cnt_num < 3) && (mf_ul_emulate->data.counter[cnt_num] + inc < 0x00FFFFFF)) { - mf_ul_emulate->data.counter[cnt_num] += inc; - mf_ul_emulate->data_changed = true; + if((cnt_num < 3) && (emulator->data.counter[cnt_num] + inc < 0x00FFFFFF)) { + emulator->data.counter[cnt_num] += inc; + emulator->data_changed = true; // ACK buff_tx[0] = 0x0A; tx_bits = 4; @@ -313,14 +352,14 @@ bool mf_ul_prepare_emulation_response( command_parsed = true; } } else if(cmd == MF_UL_AUTH) { - if(mf_ul_emulate->data.type >= MfUltralightTypeNTAG213) { - if(memcmp(&buff_rx[1], mf_ul_emulate->auth_data->pwd, 4) == 0) { - buff_tx[0] = mf_ul_emulate->auth_data->pack.raw[0]; - buff_tx[1] = mf_ul_emulate->auth_data->pack.raw[1]; + if(emulator->data.type >= MfUltralightTypeNTAG213) { + if(memcmp(&buff_rx[1], emulator->auth_data->pwd, 4) == 0) { + buff_tx[0] = emulator->auth_data->pack.raw[0]; + buff_tx[1] = emulator->auth_data->pack.raw[1]; tx_bytes = 2; *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; - } else if(!mf_ul_emulate->auth_data->pack.value) { + } else if(!emulator->auth_data->pack.value) { buff_tx[0] = 0x80; buff_tx[1] = 0x80; tx_bytes = 2; @@ -331,15 +370,15 @@ bool mf_ul_prepare_emulation_response( } else if(cmd == MF_UL_READ_SIG) { // Check 2nd byte = 0x00 - RFU if(buff_rx[1] == 0x00) { - tx_bytes = sizeof(mf_ul_emulate->data.signature); - memcpy(buff_tx, mf_ul_emulate->data.signature, tx_bytes); + tx_bytes = sizeof(emulator->data.signature); + memcpy(buff_tx, emulator->data.signature, tx_bytes); *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; } } else if(cmd == MF_UL_CHECK_TEARING) { uint8_t cnt_num = buff_rx[1]; if(cnt_num < 3) { - buff_tx[0] = mf_ul_emulate->data.tearing[cnt_num]; + buff_tx[0] = emulator->data.tearing[cnt_num]; tx_bytes = 1; *data_type = FURI_HAL_NFC_TXRX_DEFAULT; command_parsed = true; diff --git a/lib/nfc_protocols/mifare_ultralight.h b/lib/nfc_protocols/mifare_ultralight.h index 84447c5d..b554b75b 100644 --- a/lib/nfc_protocols/mifare_ultralight.h +++ b/lib/nfc_protocols/mifare_ultralight.h @@ -1,8 +1,6 @@ #pragma once -#include -#include -#include +#include #define MF_UL_MAX_DUMP_SIZE 1024 @@ -62,7 +60,7 @@ typedef struct { uint8_t tearing[3]; uint16_t data_size; uint8_t data[MF_UL_MAX_DUMP_SIZE]; -} MifareUlData; +} MfUltralightData; typedef struct { uint8_t pwd[4]; @@ -70,52 +68,53 @@ typedef struct { uint8_t raw[2]; uint16_t value; } pack; -} MifareUlAuthData; +} MfUltralightAuth; typedef struct { uint8_t pages_to_read; uint8_t pages_read; bool support_fast_read; +} MfUltralightReader; + +typedef struct { + MfUltralightData data; + bool support_fast_read; bool data_changed; - MifareUlData data; - MifareUlAuthData* auth_data; bool comp_write_cmd_started; uint8_t comp_write_page_addr; -} MifareUlDevice; + MfUltralightAuth* auth_data; +} MfUltralightEmulator; bool mf_ul_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK); -uint16_t mf_ul_prepare_get_version(uint8_t* dest); -void mf_ul_parse_get_version_response(uint8_t* buff, MifareUlDevice* mf_ul_read); -void mf_ul_set_default_version(MifareUlDevice* mf_ul_read); +bool mf_ultralight_read_version( + FuriHalNfcTxRxContext* tx_rx, + MfUltralightReader* reader, + MfUltralightData* data); -uint16_t mf_ul_prepare_read_signature(uint8_t* dest); -void mf_ul_parse_read_signature_response(uint8_t* buff, MifareUlDevice* mf_ul_read); +bool mf_ultralight_read_pages( + FuriHalNfcTxRxContext* tx_rx, + MfUltralightReader* reader, + MfUltralightData* data); -uint16_t mf_ul_prepare_read_cnt(uint8_t* dest, uint8_t cnt_index); -void mf_ul_parse_read_cnt_response(uint8_t* buff, uint8_t cnt_index, MifareUlDevice* mf_ul_read); +bool mf_ultralight_fast_read_pages( + FuriHalNfcTxRxContext* tx_rx, + MfUltralightReader* reader, + MfUltralightData* data); -uint16_t mf_ul_prepare_inc_cnt(uint8_t* dest, uint8_t cnt_index, uint32_t value); +bool mf_ultralight_read_signature(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data); -uint16_t mf_ul_prepare_check_tearing(uint8_t* dest, uint8_t cnt_index); -void mf_ul_parse_check_tearing_response( - uint8_t* buff, - uint8_t cnt_index, - MifareUlDevice* mf_ul_read); +bool mf_ultralight_read_counters(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data); -uint16_t mf_ul_prepare_read(uint8_t* dest, uint8_t start_page); -void mf_ul_parse_read_response(uint8_t* buff, uint16_t page_addr, MifareUlDevice* mf_ul_read); +bool mf_ultralight_read_tearing_flags(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data); -uint16_t mf_ul_prepare_fast_read(uint8_t* dest, uint8_t start_page, uint8_t end_page); -void mf_ul_parse_fast_read_response( - uint8_t* buff, - uint8_t start_page, - uint8_t end_page, - MifareUlDevice* mf_ul_read); +bool mf_ul_read_card( + FuriHalNfcTxRxContext* tx_rx, + MfUltralightReader* reader, + MfUltralightData* data); -uint16_t mf_ul_prepare_write(uint8_t* dest, uint16_t page_addr, uint32_t data); +void mf_ul_prepare_emulation(MfUltralightEmulator* emulator, MfUltralightData* data); -void mf_ul_prepare_emulation(MifareUlDevice* mf_ul_emulate, MifareUlData* data); bool mf_ul_prepare_emulation_response( uint8_t* buff_rx, uint16_t buff_rx_len,