diff options
author | gornekich <n.gorbadey@gmail.com> | 2021-08-20 22:56:43 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-20 22:56:43 +0300 |
commit | ecff31d228102234084c2c6a0c4d84e599eaf85a (patch) | |
tree | 752be3c30a5c6c8a3caf78d7c06bee950095f6a9 /applications/nfc | |
parent | b1bbf1730c5626bc84fb9794a96fe921a115f83c (diff) |
[FL-1643] NFC emv assets (#661)
* assets: add EMV AID table for NFC app
* file-worker: add searching for value by the key
* nfc: add emv parser helpers
* assets: add country and currency codes
* nfc: add country and currency code parsing
* emv_decoder: add country and currency code support
* nfc: add AID. currency and country display
* nfc: rework bank_card view
* nfc: add currency and country save
* assets: change emv chip asset
* nfc: change asset in bank card
* gui: add frame element to widget
* nfc: add bank card frame, add documentation
* rfal: fix long APDU command emulation
* nfc: fix typos
* Scripts ReadMe: assets delivery command
Co-authored-by: あく <alleteam@gmail.com>
Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
Diffstat (limited to 'applications/nfc')
-rwxr-xr-x | applications/nfc/helpers/nfc_emv_parser.c | 49 | ||||
-rwxr-xr-x | applications/nfc/helpers/nfc_emv_parser.h | 27 | ||||
-rwxr-xr-x | applications/nfc/nfc_device.c | 49 | ||||
-rw-r--r-- | applications/nfc/nfc_device.h | 3 | ||||
-rwxr-xr-x | applications/nfc/nfc_worker.c | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | applications/nfc/scenes/nfc_scene_device_info.c | 31 | ||||
-rwxr-xr-x | applications/nfc/scenes/nfc_scene_read_emv_app_success.c | 10 | ||||
-rw-r--r-- | applications/nfc/scenes/nfc_scene_read_emv_data.c | 2 | ||||
-rwxr-xr-x | applications/nfc/scenes/nfc_scene_read_emv_data_success.c | 40 | ||||
-rwxr-xr-x | applications/nfc/views/bank_card.c | 56 | ||||
-rw-r--r-- | applications/nfc/views/bank_card.h | 9 |
11 files changed, 243 insertions, 39 deletions
diff --git a/applications/nfc/helpers/nfc_emv_parser.c b/applications/nfc/helpers/nfc_emv_parser.c new file mode 100755 index 00000000..b84d35c3 --- /dev/null +++ b/applications/nfc/helpers/nfc_emv_parser.c @@ -0,0 +1,49 @@ +#include "nfc_emv_parser.h" + +#include <file-worker.h> + +static bool + nfc_emv_parser_get_value(const char* file_path, string_t key, char delimiter, string_t value) { + bool found = false; + FileWorker* file_worker = file_worker_alloc(true); + + if(file_worker_open(file_worker, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { + if(file_worker_get_value_from_key(file_worker, key, delimiter, value)) { + found = true; + } + } + + file_worker_close(file_worker); + file_worker_free(file_worker); + return found; +} + +bool nfc_emv_parser_get_aid_name(uint8_t* aid, uint8_t aid_len, string_t aid_name) { + bool result = false; + string_t key; + string_init(key); + for(uint8_t i = 0; i < aid_len; i++) { + string_cat_printf(key, "%02X", aid[i]); + } + result = nfc_emv_parser_get_value("/ext/nfc/emv/aid.nfc", key, ' ', aid_name); + string_clear(key); + return result; +} + +bool nfc_emv_parser_get_country_name(uint16_t country_code, string_t country_name) { + bool result = false; + string_t key; + string_init_printf(key, "%04X", country_code); + result = nfc_emv_parser_get_value("/ext/nfc/emv/country_code.nfc", key, ' ', country_name); + string_clear(key); + return result; +} + +bool nfc_emv_parser_get_currency_name(uint16_t currency_code, string_t currency_name) { + bool result = false; + string_t key; + string_init_printf(key, "%04X", currency_code); + result = nfc_emv_parser_get_value("/ext/nfc/emv/currency_code.nfc", key, ' ', currency_name); + string_clear(key); + return result; +} diff --git a/applications/nfc/helpers/nfc_emv_parser.h b/applications/nfc/helpers/nfc_emv_parser.h new file mode 100755 index 00000000..b81a06ee --- /dev/null +++ b/applications/nfc/helpers/nfc_emv_parser.h @@ -0,0 +1,27 @@ +#pragma once + +#include <stdint.h> +#include <stdbool.h> +#include <m-string.h> + +/** Get EMV application name by number + * @param aid - AID number array + * @param aid_len - AID length + * @param aid_name - string to keep AID name + * @return - true if AID found, false otherwies + */ +bool nfc_emv_parser_get_aid_name(uint8_t* aid, uint8_t aid_len, string_t aid_name); + +/** Get country name by country code + * @param country_code - ISO 3166 country code + * @param country_name - string to keep country name + * @return - true if country found, false otherwies + */ +bool nfc_emv_parser_get_country_name(uint16_t country_code, string_t country_name); + +/** Get currency name by currency code + * @param currency_code - ISO 3166 currency code + * @param currency_name - string to keep currency name + * @return - true if currency found, false otherwies + */ +bool nfc_emv_parser_get_currency_name(uint16_t currency_code, string_t currency_name); diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index bdb3d547..04a35a42 100755 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -10,7 +10,7 @@ static const char* nfc_app_folder = "/any/nfc"; static const char* nfc_app_extension = ".nfc"; static const char* nfc_app_shadow_extension = ".shd"; -static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len) { +static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len, uint8_t delim_len) { string_strim(str); uint8_t nibble_high = 0; uint8_t nibble_low = 0; @@ -20,7 +20,7 @@ static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len) { if(hex_char_to_hex_nibble(string_get_char(str, 0), &nibble_high) && hex_char_to_hex_nibble(string_get_char(str, 1), &nibble_low)) { buff[i] = (nibble_high << 4) | nibble_low; - string_right(str, 3); + string_right(str, delim_len + 2); } else { parsed = false; break; @@ -81,22 +81,22 @@ bool nfc_device_parse_uid_string(NfcDevice* dev, string_t uid_string) { do { // strlen("UID len: ") = 9 string_right(uid_string, 9); - if(!nfc_device_read_hex(uid_string, &uid_data->uid_len, 1)) { + if(!nfc_device_read_hex(uid_string, &uid_data->uid_len, 1, 1)) { break; } // strlen("UID: ") = 5 string_right(uid_string, 5); - if(!nfc_device_read_hex(uid_string, uid_data->uid, uid_data->uid_len)) { + if(!nfc_device_read_hex(uid_string, uid_data->uid, uid_data->uid_len, 1)) { break; } // strlen("ATQA: ") = 6 string_right(uid_string, 6); - if(!nfc_device_read_hex(uid_string, uid_data->atqa, 2)) { + if(!nfc_device_read_hex(uid_string, uid_data->atqa, 2, 1)) { break; } // strlen("SAK: ") = 5 string_right(uid_string, 5); - if(!nfc_device_read_hex(uid_string, &uid_data->sak, 1)) { + if(!nfc_device_read_hex(uid_string, &uid_data->sak, 1, 1)) { break; } parsed = true; @@ -149,13 +149,13 @@ bool nfc_device_parse_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string do { // strlen("Signature: ") = 11 string_right(mifare_ul_string, 11); - if(!nfc_device_read_hex(mifare_ul_string, data->signature, sizeof(data->signature))) { + if(!nfc_device_read_hex(mifare_ul_string, data->signature, sizeof(data->signature), 1)) { break; } // strlen("Version: ") = 9 string_right(mifare_ul_string, 9); if(!nfc_device_read_hex( - mifare_ul_string, (uint8_t*)&data->version, sizeof(data->version))) { + mifare_ul_string, (uint8_t*)&data->version, sizeof(data->version), 1)) { break; } string_strim(mifare_ul_string); @@ -184,7 +184,7 @@ bool nfc_device_parse_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string string_right(mifare_ul_string, ws + 1); // Read data for(uint16_t i = 0; i < data->data_size; i += 4) { - if(!nfc_device_read_hex(mifare_ul_string, &data->data[i], 4)) { + if(!nfc_device_read_hex(mifare_ul_string, &data->data[i], 4, 1)) { break; } } @@ -208,6 +208,12 @@ uint16_t nfc_device_prepare_bank_card_string(NfcDevice* dev, string_t bank_card_ string_cat_printf( bank_card_string, "\nExp date: %02X/%02X", data->exp_mon, data->exp_year); } + if(data->country_code) { + string_cat_printf(bank_card_string, "\nCountry code: %04X", data->country_code); + } + if(data->currency_code) { + string_cat_printf(bank_card_string, "\nCurrency code: %04X", data->currency_code); + } return string_size(bank_card_string); } @@ -215,6 +221,7 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string NfcEmvData* data = &dev->dev_data.emv_data; bool parsed = false; int res = 0; + uint8_t code[2] = {}; memset(data, 0, sizeof(NfcEmvData)); do { @@ -226,7 +233,7 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string string_right(bank_card_string, 9); size_t ws = string_search_char(bank_card_string, ':'); string_right(bank_card_string, ws + 1); - if(!nfc_device_read_hex(bank_card_string, data->aid, data->aid_len)) { + if(!nfc_device_read_hex(bank_card_string, data->aid, data->aid_len, 1)) { break; } res = sscanf(string_get_cstr(bank_card_string), "Name: %s\n", data->name); @@ -237,7 +244,7 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string string_right(bank_card_string, ws + 1); // strlen("Number: ") = 8 string_right(bank_card_string, 8); - if(!nfc_device_read_hex(bank_card_string, data->number, sizeof(data->number))) { + if(!nfc_device_read_hex(bank_card_string, data->number, sizeof(data->number), 1)) { break; } parsed = true; @@ -246,8 +253,24 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string if(ws != STRING_FAILURE) { // strlen("Exp date: ") = 10 string_right(bank_card_string, 10); - nfc_device_read_hex(bank_card_string, &data->exp_mon, 1); - nfc_device_read_hex(bank_card_string, &data->exp_year, 1); + nfc_device_read_hex(bank_card_string, &data->exp_mon, 1, 1); + nfc_device_read_hex(bank_card_string, &data->exp_year, 1, 1); + } + // Check country code presence + ws = string_search_str(bank_card_string, "Country code: "); + if(ws != STRING_FAILURE) { + // strlen("Country code: ") = 14 + string_right(bank_card_string, 14); + nfc_device_read_hex(bank_card_string, code, 2, 0); + data->country_code = code[0] << 8 | code[1]; + } + // Check currency code presence + ws = string_search_str(bank_card_string, "Currency code: "); + if(ws != STRING_FAILURE) { + // strlen("Currency code: ") = 15 + string_right(bank_card_string, 15); + nfc_device_read_hex(bank_card_string, code, 2, 0); + data->currency_code = code[0] << 8 | code[1]; } } while(0); diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h index 25f0e42f..c36b4828 100644 --- a/applications/nfc/nfc_device.h +++ b/applications/nfc/nfc_device.h @@ -43,7 +43,8 @@ typedef struct { uint8_t number[8]; uint8_t exp_mon; uint8_t exp_year; - char cardholder[32]; + uint16_t country_code; + uint16_t currency_code; } NfcEmvData; typedef struct { diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 9fd6dc64..0502a476 100755 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -328,6 +328,12 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { 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(nfc_worker->context); diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c index 6bd097d3..c944b0e5 100644..100755 --- a/applications/nfc/scenes/nfc_scene_device_info.c +++ b/applications/nfc/scenes/nfc_scene_device_info.c @@ -1,6 +1,6 @@ #include "../nfc_i.h" -#define NFC_SCENE_DEVICE_INFO_TEXTBOX_CUSTOM_EVENT (0UL) +#define NFC_SCENE_DEVICE_INFO_BACK_EVENT (0UL) enum { NfcSceneDeviceInfoUid, @@ -8,26 +8,27 @@ enum { }; void nfc_scene_device_info_widget_callback(GuiButtonType result, void* context) { - Nfc* nfc = (Nfc*)context; - + Nfc* nfc = context; view_dispatcher_send_custom_event(nfc->view_dispatcher, result); } void nfc_scene_device_info_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_device_info_text_box_callback(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); +} - view_dispatcher_send_custom_event( - nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_TEXTBOX_CUSTOM_EVENT); +void nfc_scene_device_info_bank_card_callback(GuiButtonType result, void* context) { + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); } void nfc_scene_device_info_on_enter(void* context) { - Nfc* nfc = (Nfc*)context; + Nfc* nfc = context; // Setup Custom Widget view widget_add_string_element( @@ -107,19 +108,23 @@ void nfc_scene_device_info_on_enter(void* context) { BankCard* bank_card = nfc->bank_card; bank_card_set_name(bank_card, emv_data->name); bank_card_set_number(bank_card, emv_data->number); - if(!strcmp(emv_data->name, "")) { - bank_card_set_cardholder_name(bank_card, emv_data->cardholder); - } + bank_card_set_back_callback(bank_card, nfc_scene_device_info_bank_card_callback, nfc); if(emv_data->exp_mon) { bank_card_set_exp_date(bank_card, emv_data->exp_mon, emv_data->exp_year); } + if(emv_data->country_code) { + bank_card_set_country_name(bank_card, emv_data->country_code); + } + if(emv_data->currency_code) { + bank_card_set_currency_name(bank_card, emv_data->currency_code); + } } scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); } const bool nfc_scene_device_info_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, NfcSceneDeviceInfo); 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 631b0456..0391cf25 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_app_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_app_success.c @@ -1,4 +1,5 @@ #include "../nfc_i.h" +#include "../helpers/nfc_emv_parser.h" #define NFC_SCENE_READ_SUCCESS_SHIFT " " @@ -21,9 +22,12 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) { dialog_ex_set_icon(dialog_ex, 8, 13, &I_Medium_chip_22x21); // Display UID and AID string_t aid; - string_init_printf(aid, "AID:"); - for(uint8_t i = 0; i < emv_data->aid_len; i++) { - string_cat_printf(aid, " %02X", emv_data->aid[i]); + string_init(aid); + bool aid_found = nfc_emv_parser_get_aid_name(emv_data->aid, emv_data->aid_len, aid); + if(!aid_found) { + for(uint8_t i = 0; i < emv_data->aid_len; i++) { + string_cat_printf(aid, " %02X", emv_data->aid[i]); + } } nfc_text_store_set( nfc, diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data.c b/applications/nfc/scenes/nfc_scene_read_emv_data.c index 38c5008e..0aeb6fe0 100644 --- a/applications/nfc/scenes/nfc_scene_read_emv_data.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data.c @@ -16,6 +16,8 @@ const void nfc_scene_read_emv_data_on_enter(void* context) { popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + // Clear emv data + memset(&nfc->dev.dev_data.emv_data, 0, sizeof(nfc->dev.dev_data.emv_data)); // Start worker nfc_worker_start( nfc->worker, 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 c6a9280c..bc73ff9a 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c @@ -1,4 +1,5 @@ #include "../nfc_i.h" +#include "../helpers/nfc_emv_parser.h" void nfc_scene_read_emv_data_success_widget_callback(GuiButtonType result, void* context) { Nfc* nfc = (Nfc*)context; @@ -15,6 +16,9 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { nfc_device_set_name(&nfc->dev, ""); // Setup Custom Widget view + // Add frame + widget_add_frame_element(nfc->widget, 0, 0, 128, 64, 6); + // Add buttons widget_add_button_element( nfc->widget, GuiButtonTypeLeft, @@ -27,8 +31,10 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { "Save", nfc_scene_read_emv_data_success_widget_callback, nfc); + // Add card name widget_add_string_element( nfc->widget, 64, 3, AlignCenter, AlignTop, FontSecondary, nfc->dev.dev_data.emv_data.name); + // Add cad number char pan_str[32]; snprintf( pan_str, @@ -43,9 +49,41 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { emv_data->number[6], emv_data->number[7]); widget_add_string_element(nfc->widget, 64, 13, AlignCenter, AlignTop, FontSecondary, pan_str); + // Parse country code + string_t country_name; + string_init(country_name); + if((emv_data->country_code) && + nfc_emv_parser_get_country_name(emv_data->country_code, country_name)) { + string_t disp_country; + string_init_printf(disp_country, "Reg:%s", country_name); + widget_add_string_element( + nfc->widget, 7, 23, AlignLeft, AlignTop, FontSecondary, string_get_cstr(disp_country)); + string_clear(disp_country); + } + string_clear(country_name); + // Parse currency code + string_t currency_name; + string_init(currency_name); + if((emv_data->currency_code) && + nfc_emv_parser_get_currency_name(emv_data->currency_code, currency_name)) { + string_t disp_currency; + string_init_printf(disp_currency, "Cur:%s", currency_name); + widget_add_string_element( + nfc->widget, + 121, + 23, + AlignRight, + AlignTop, + FontSecondary, + string_get_cstr(disp_currency)); + string_clear(disp_currency); + } + string_clear(currency_name); + // 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); + // Add UID char uid_str[32]; snprintf( uid_str, @@ -56,9 +94,11 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { nfc_data->uid[2], nfc_data->uid[3]); widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, uid_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); + // Add expiration date if(emv_data->exp_mon) { char exp_str[16]; snprintf( diff --git a/applications/nfc/views/bank_card.c b/applications/nfc/views/bank_card.c index f4354792..1be14ba7 100755 --- a/applications/nfc/views/bank_card.c +++ b/applications/nfc/views/bank_card.c @@ -1,5 +1,5 @@ #include "bank_card.h" -#include <gui/modules/widget.h> +#include "../helpers/nfc_emv_parser.h" #include <m-string.h> struct BankCard { @@ -43,10 +43,20 @@ void bank_card_set_number(BankCard* bank_card, uint8_t* number) { for(uint8_t i = 0; i < 8; i += 2) { string_cat_printf(num_str, "%02X%02X ", number[i], number[i + 1]); } + // Add number widget_add_string_element( - bank_card->widget, 25, 22, AlignLeft, AlignTop, FontSecondary, string_get_cstr(num_str)); - widget_add_icon_element(bank_card->widget, 6, 20, &I_EMV_Chip_14x11); + bank_card->widget, 64, 32, AlignCenter, AlignTop, FontSecondary, string_get_cstr(num_str)); string_clear(num_str); + // Add icon + widget_add_icon_element(bank_card->widget, 8, 15, &I_Detailed_chip_17x13); + // Add frame + widget_add_frame_element(bank_card->widget, 0, 0, 128, 64, 6); +} + +void bank_card_set_back_callback(BankCard* bank_card, ButtonCallback callback, void* context) { + furi_assert(bank_card); + furi_assert(callback); + widget_add_button_element(bank_card->widget, GuiButtonTypeLeft, "Back", callback, context); } void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year) { @@ -57,8 +67,42 @@ void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year) { bank_card->widget, 122, 54, AlignRight, AlignBottom, FontSecondary, exp_date_str); } -void bank_card_set_cardholder_name(BankCard* bank_card, char* name) { +void bank_card_set_country_name(BankCard* bank_card, uint16_t country_code) { furi_assert(bank_card); - furi_assert(name); - widget_add_string_element(bank_card->widget, 6, 37, AlignLeft, AlignTop, FontSecondary, name); + string_t country_name; + string_init(country_name); + if(nfc_emv_parser_get_country_name(country_code, country_name)) { + string_t disp_country; + string_init_printf(disp_country, "Reg:%s", country_name); + widget_add_string_element( + bank_card->widget, + 120, + 18, + AlignRight, + AlignTop, + FontSecondary, + string_get_cstr(disp_country)); + string_clear(disp_country); + } + string_clear(country_name); +} + +void bank_card_set_currency_name(BankCard* bank_card, uint16_t currency_code) { + furi_assert(bank_card); + string_t currency_name; + string_init(currency_name); + if(nfc_emv_parser_get_currency_name(currency_code, currency_name)) { + string_t disp_currency; + string_init_printf(disp_currency, "Cur:%s", currency_name); + widget_add_string_element( + bank_card->widget, + 31, + 18, + AlignLeft, + AlignTop, + FontSecondary, + string_get_cstr(disp_currency)); + string_clear(disp_currency); + } + string_clear(currency_name); } diff --git a/applications/nfc/views/bank_card.h b/applications/nfc/views/bank_card.h index f7252a80..e50309fa 100644 --- a/applications/nfc/views/bank_card.h +++ b/applications/nfc/views/bank_card.h @@ -1,11 +1,10 @@ #pragma once #include <stdint.h> #include <gui/view.h> +#include <gui/modules/widget.h> typedef struct BankCard BankCard; -typedef void (*BankCardBackCallback)(void); - BankCard* bank_card_alloc(); void bank_card_free(BankCard* bank_card); @@ -14,10 +13,14 @@ void bank_card_clear(BankCard* bank_card); View* bank_card_get_view(BankCard* bank_card); +void bank_card_set_back_callback(BankCard* bank_card, ButtonCallback callback, void* context); + void bank_card_set_name(BankCard* bank_card, char* name); void bank_card_set_number(BankCard* bank_card, uint8_t* number); void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year); -void bank_card_set_cardholder_name(BankCard* bank_card, char* name); +void bank_card_set_country_name(BankCard* bank_card, uint16_t country_code); + +void bank_card_set_currency_name(BankCard* bank_card, uint16_t currency_code); |