|
@@ -90,7 +90,11 @@ int32_t nfc_worker_task(void* context) {
|
|
|
furi_hal_nfc_exit_sleep();
|
|
furi_hal_nfc_exit_sleep();
|
|
|
|
|
|
|
|
if(nfc_worker->state == NfcWorkerStateRead) {
|
|
if(nfc_worker->state == NfcWorkerStateRead) {
|
|
|
- nfc_worker_read(nfc_worker);
|
|
|
|
|
|
|
+ if(nfc_worker->dev_data->read_mode == NfcReadModeAuto) {
|
|
|
|
|
+ nfc_worker_read(nfc_worker);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ nfc_worker_read_type(nfc_worker);
|
|
|
|
|
+ }
|
|
|
} else if(nfc_worker->state == NfcWorkerStateUidEmulate) {
|
|
} else if(nfc_worker->state == NfcWorkerStateUidEmulate) {
|
|
|
nfc_worker_emulate_uid(nfc_worker);
|
|
nfc_worker_emulate_uid(nfc_worker);
|
|
|
} else if(nfc_worker->state == NfcWorkerStateEmulateApdu) {
|
|
} else if(nfc_worker->state == NfcWorkerStateEmulateApdu) {
|
|
@@ -394,6 +398,81 @@ void nfc_worker_read(NfcWorker* nfc_worker) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void nfc_worker_read_type(NfcWorker* nfc_worker) {
|
|
|
|
|
+ furi_assert(nfc_worker);
|
|
|
|
|
+ furi_assert(nfc_worker->callback);
|
|
|
|
|
+
|
|
|
|
|
+ NfcReadMode read_mode = nfc_worker->dev_data->read_mode;
|
|
|
|
|
+ nfc_device_data_clear(nfc_worker->dev_data);
|
|
|
|
|
+ NfcDeviceData* dev_data = nfc_worker->dev_data;
|
|
|
|
|
+ FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
|
|
|
|
|
+ FuriHalNfcTxRxContext tx_rx = {};
|
|
|
|
|
+ NfcWorkerEvent event = 0;
|
|
|
|
|
+ bool card_not_detected_notified = false;
|
|
|
|
|
+
|
|
|
|
|
+ while(nfc_worker->state == NfcWorkerStateRead) {
|
|
|
|
|
+ if(furi_hal_nfc_detect(nfc_data, 300)) {
|
|
|
|
|
+ FURI_LOG_D(TAG, "Card detected");
|
|
|
|
|
+ furi_hal_nfc_sleep();
|
|
|
|
|
+ // Process first found device
|
|
|
|
|
+ nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
|
|
|
|
|
+ card_not_detected_notified = false;
|
|
|
|
|
+ if(nfc_data->type == FuriHalNfcTypeA) {
|
|
|
|
|
+ if(read_mode == NfcReadModeMfClassic) {
|
|
|
|
|
+ nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic;
|
|
|
|
|
+ nfc_worker->dev_data->mf_classic_data.type = mf_classic_get_classic_type(
|
|
|
|
|
+ nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak);
|
|
|
|
|
+ if(nfc_worker_read_mf_classic(nfc_worker, &tx_rx)) {
|
|
|
|
|
+ FURI_LOG_D(TAG, "Card read");
|
|
|
|
|
+ dev_data->protocol = NfcDeviceProtocolMifareClassic;
|
|
|
|
|
+ event = NfcWorkerEventReadMfClassicDone;
|
|
|
|
|
+ break;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ FURI_LOG_D(TAG, "Card read failed");
|
|
|
|
|
+ dev_data->protocol = NfcDeviceProtocolMifareClassic;
|
|
|
|
|
+ event = NfcWorkerEventReadMfClassicDictAttackRequired;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if(read_mode == NfcReadModeMfUltralight) {
|
|
|
|
|
+ FURI_LOG_I(TAG, "Mifare Ultralight / NTAG");
|
|
|
|
|
+ nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl;
|
|
|
|
|
+ if(nfc_worker_read_mf_ultralight(nfc_worker, &tx_rx)) {
|
|
|
|
|
+ event = NfcWorkerEventReadMfUltralight;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if(read_mode == NfcReadModeMfDesfire) {
|
|
|
|
|
+ nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareDesfire;
|
|
|
|
|
+ if(nfc_worker_read_mf_desfire(nfc_worker, &tx_rx)) {
|
|
|
|
|
+ event = NfcWorkerEventReadMfDesfire;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if(read_mode == NfcReadModeEMV) {
|
|
|
|
|
+ nfc_worker->dev_data->protocol = NfcDeviceProtocolEMV;
|
|
|
|
|
+ if(nfc_worker_read_bank_card(nfc_worker, &tx_rx)) {
|
|
|
|
|
+ event = NfcWorkerEventReadBankCard;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if(read_mode == NfcReadModeNFCA) {
|
|
|
|
|
+ nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown;
|
|
|
|
|
+ event = NfcWorkerEventReadUidNfcA;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if(!card_not_detected_notified) {
|
|
|
|
|
+ nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context);
|
|
|
|
|
+ card_not_detected_notified = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ furi_hal_nfc_sleep();
|
|
|
|
|
+ furi_delay_ms(100);
|
|
|
|
|
+ }
|
|
|
|
|
+ // Notify caller and exit
|
|
|
|
|
+ if(event > NfcWorkerEventReserved) {
|
|
|
|
|
+ nfc_worker->callback(event, nfc_worker->context);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void nfc_worker_emulate_uid(NfcWorker* nfc_worker) {
|
|
void nfc_worker_emulate_uid(NfcWorker* nfc_worker) {
|
|
|
FuriHalNfcTxRxContext tx_rx = {};
|
|
FuriHalNfcTxRxContext tx_rx = {};
|
|
|
FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data;
|
|
FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data;
|