Skip to content

Commit

Permalink
Refactor response decoder
Browse files Browse the repository at this point in the history
Read transactions history
  • Loading branch information
wosk committed Jan 28, 2024
1 parent 39055ff commit 4b786fb
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 178 deletions.
50 changes: 50 additions & 0 deletions applications/main/nfc/helpers/protocol_support/emv/emv_render.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,56 @@ void nfc_render_emv_application(const EmvApplication* apl, FuriString* str) {
furi_string_cat_printf(str, "\n");
}

void nfc_render_emv_transactions(const EmvApplication* apl, FuriString* str) {
const uint8_t len = apl->active_tr;
if(!len) {
return;
}
furi_string_cat_printf(str, "Transactions:\n");
for(int i = 0; i < len; i++) {
if(!apl->trans[i].amount) continue;
uint8_t* a = (uint8_t*)&apl->trans[i].amount;
furi_string_cat_printf(str, "%d: ", apl->trans[i].atc);
bool top = true;
for(int x = 0; x < 6; x++) {
if(x == 5) {
furi_string_cat_printf(str, ".%02X", a[x]);
break;
}
if(a[x]) {
if(top) {
furi_string_cat_printf(str, "%X", a[x]);
top = false;
} else {
furi_string_cat_printf(str, "%02X", a[x]);
}
}
}
// TODO to string
furi_string_cat_printf(str, " %x\n", apl->trans[i].currency);

// TODO to string
if(apl->trans[i].country)
furi_string_cat_printf(str, "country: %x\n", apl->trans[i].country);

if(apl->trans[i].time)
furi_string_cat_printf(
str,
"%02lx:%02lx:%02lx ",
apl->trans[i].time & 0xff,
(apl->trans[i].time >> 8) & 0xff,
apl->trans[i].time >> 16);
if(apl->trans[i].date)
furi_string_cat_printf(
str,
"%02lx/%02lx/%02lx\n",
apl->trans[i].date >> 16,
(apl->trans[i].date >> 8) & 0xff,
apl->trans[i].date & 0xff);
}
}

void nfc_render_emv_extra(const EmvData* data, FuriString* str) {
nfc_render_emv_application(&data->emv_application, str);
//nfc_render_emv_transactions(&data->emv_application, str);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ void nfc_render_emv_expired(const EmvApplication* apl, FuriString* str);
void nfc_render_emv_country(const EmvApplication* apl, FuriString* str);

void nfc_render_emv_currency(const EmvApplication* apl, FuriString* str);

void nfc_render_emv_transactions(const EmvApplication* data, FuriString* str);
22 changes: 22 additions & 0 deletions lib/nfc/protocols/emv/emv.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ extern "C" {
#define EMV_TAG_CARD_NAME 0x50
#define EMV_TAG_FCI 0xBF0C
#define EMV_TAG_LOG_ENTRY 0x9F4D
#define EMV_TAG_LOG_FMT 0x9F4F

#define EMV_TAG_ATC 0x9F36
#define EMV_TAG_LOG_AMOUNT 0x9F02
#define EMV_TAG_LOG_COUNTRY 0x9F1A
#define EMV_TAG_LOG_CURRENCY 0x5F2A
#define EMV_TAG_LOG_DATE 0x9A
#define EMV_TAG_LOG_TIME 0x9F21

#define EMV_TAG_TRACK_1_EQUIV 0x56
#define EMV_TAG_TRACK_2_EQUIV 0x57
#define EMV_TAG_PAN 0x5A
Expand All @@ -39,9 +48,22 @@ typedef struct {
uint8_t data[MAX_APDU_LEN];
} APDU;

typedef struct {
uint16_t atc;
uint64_t amount;
uint16_t country;
uint16_t currency;
uint32_t date;
uint32_t time;
} Transaction;

typedef struct {
uint8_t log_sfi;
uint8_t log_records;
uint8_t log_fmt[50];
uint8_t log_fmt_len;
uint8_t active_tr;
Transaction trans[16];
uint8_t priority;
uint8_t aid[16];
uint8_t aid_len;
Expand Down
21 changes: 19 additions & 2 deletions lib/nfc/protocols/emv/emv_poller.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,14 @@ static NfcCommand emv_poller_handler_get_processing_options(EmvPoller* instance)
}

static NfcCommand emv_poller_handler_read_files(EmvPoller* instance) {
instance->error = emv_poller_read_files(instance);
instance->error = emv_poller_read_afl(instance);

if(instance->error == EmvErrorNone) {
FURI_LOG_D(TAG, "Read files success");
instance->state = EmvPollerStateReadSuccess;
if(instance->data->emv_application.log_sfi)
instance->state = EmvPollerStateReadLogs;
else
instance->state = EmvPollerStateReadSuccess;
} else {
FURI_LOG_E(TAG, "Failed to read files");
instance->state = EmvPollerStateReadFailed;
Expand All @@ -124,6 +127,19 @@ static NfcCommand emv_poller_handler_read_files(EmvPoller* instance) {
return NfcCommandContinue;
}

static NfcCommand emv_poller_handler_read_logs(EmvPoller* instance) {
instance->error = emv_poller_read_log_entry(instance);

if(instance->error == EmvErrorNone) {
FURI_LOG_D(TAG, "Log entries had been read");
} else {
FURI_LOG_D(TAG, "No log entry");
}

instance->state = EmvPollerStateReadSuccess;
return NfcCommandContinue;
}

static NfcCommand emv_poller_handler_read_fail(EmvPoller* instance) {
FURI_LOG_D(TAG, "Read failed");
iso14443_4a_poller_halt(instance->iso14443_4a_poller);
Expand All @@ -147,6 +163,7 @@ static const EmvPollerReadHandler emv_poller_read_handler[EmvPollerStateNum] = {
[EmvPollerStateSelectApplication] = emv_poller_handler_select_application,
[EmvPollerStateGetProcessingOptions] = emv_poller_handler_get_processing_options,
[EmvPollerStateReadFiles] = emv_poller_handler_read_files,
[EmvPollerStateReadLogs] = emv_poller_handler_read_logs,
[EmvPollerStateReadFailed] = emv_poller_handler_read_fail,
[EmvPollerStateReadSuccess] = emv_poller_handler_read_success,
};
Expand Down
4 changes: 3 additions & 1 deletion lib/nfc/protocols/emv/emv_poller.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ EmvError emv_poller_get_processing_options(EmvPoller* instance);

EmvError emv_poller_read_sfi_record(EmvPoller* instance, uint8_t sfi, uint8_t record_num);

EmvError emv_poller_read_files(EmvPoller* instance);
EmvError emv_poller_read_afl(EmvPoller* instance);

EmvError emv_poller_read_log_entry(EmvPoller* instance);

#ifdef __cplusplus
}
Expand Down
Loading

0 comments on commit 4b786fb

Please sign in to comment.