diff --git a/applications/nfc/helpers/nfc_emv_parser.c b/applications/nfc/helpers/nfc_emv_parser.c index b84d35c3..54c6c203 100755 --- a/applications/nfc/helpers/nfc_emv_parser.c +++ b/applications/nfc/helpers/nfc_emv_parser.c @@ -1,49 +1,80 @@ #include "nfc_emv_parser.h" +#include -#include +static const char* nfc_resources_header = "Flipper EMV resources"; +static const uint32_t nfc_resources_file_version = 1; -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); +static bool nfc_emv_parser_search_data( + Storage* storage, + const char* file_name, + string_t key, + string_t data) { + bool parsed = false; + FlipperFile* file = flipper_file_alloc(storage); + string_t temp_str; + string_init(temp_str); - 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; - } - } + do { + // Open file + if(!flipper_file_open_existing(file, file_name)) break; + // Read file header and version + uint32_t version = 0; + if(!flipper_file_read_header(file, temp_str, &version)) break; + if(string_cmp_str(temp_str, nfc_resources_header) || + (version != nfc_resources_file_version)) + break; + if(!flipper_file_read_string(file, string_get_cstr(key), data)) break; + parsed = true; + } while(false); - file_worker_close(file_worker); - file_worker_free(file_worker); - return found; + string_clear(temp_str); + flipper_file_free(file); + return parsed; } -bool nfc_emv_parser_get_aid_name(uint8_t* aid, uint8_t aid_len, string_t aid_name) { - bool result = false; +bool nfc_emv_parser_get_aid_name( + Storage* storage, + uint8_t* aid, + uint8_t aid_len, + string_t aid_name) { + furi_assert(storage); + bool parsed = 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); + if(nfc_emv_parser_search_data(storage, "/ext/nfc/emv/aid.nfc", key, aid_name)) { + parsed = true; + } string_clear(key); - return result; + return parsed; } -bool nfc_emv_parser_get_country_name(uint16_t country_code, string_t country_name) { - bool result = false; +bool nfc_emv_parser_get_country_name( + Storage* storage, + uint16_t country_code, + string_t country_name) { + bool parsed = 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); + if(nfc_emv_parser_search_data(storage, "/ext/nfc/emv/country_code.nfc", key, country_name)) { + parsed = true; + } string_clear(key); - return result; + return parsed; } -bool nfc_emv_parser_get_currency_name(uint16_t currency_code, string_t currency_name) { - bool result = false; +bool nfc_emv_parser_get_currency_name( + Storage* storage, + uint16_t currency_code, + string_t currency_name) { + bool parsed = 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); + if(nfc_emv_parser_search_data(storage, "/ext/nfc/emv/currency_code.nfc", key, currency_name)) { + parsed = true; + } string_clear(key); - return result; + return parsed; } diff --git a/applications/nfc/helpers/nfc_emv_parser.h b/applications/nfc/helpers/nfc_emv_parser.h index b81a06ee..5948ed34 100755 --- a/applications/nfc/helpers/nfc_emv_parser.h +++ b/applications/nfc/helpers/nfc_emv_parser.h @@ -3,25 +3,39 @@ #include #include #include +#include /** Get EMV application name by number + * @param storage Storage instance * @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); +bool nfc_emv_parser_get_aid_name( + Storage* storage, + uint8_t* aid, + uint8_t aid_len, + string_t aid_name); /** Get country name by country code + * @param storage Storage instance * @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); +bool nfc_emv_parser_get_country_name( + Storage* storage, + uint16_t country_code, + string_t country_name); /** Get currency name by currency code + * @param storage Storage instance * @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); +bool nfc_emv_parser_get_currency_name( + Storage* storage, + uint16_t currency_code, + string_t currency_name); diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index 8e5b7311..a29a6d19 100755 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -31,6 +31,9 @@ Nfc* nfc_alloc() { view_dispatcher_set_navigation_event_callback(nfc->view_dispatcher, nfc_back_event_callback); view_dispatcher_set_tick_event_callback(nfc->view_dispatcher, nfc_tick_event_callback, 100); + // Nfc device + nfc->dev = nfc_device_alloc(); + // Open GUI record nfc->gui = furi_record_open("gui"); view_dispatcher_attach_to_gui(nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); @@ -82,6 +85,9 @@ Nfc* nfc_alloc() { void nfc_free(Nfc* nfc) { furi_assert(nfc); + // Nfc device + nfc_device_free(nfc->dev); + // Submenu view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewMenu); submenu_free(nfc->submenu); @@ -154,8 +160,8 @@ int32_t nfc_app(void* p) { char* args = p; // Check argument and run corresponding scene - if((*args != '\0') && nfc_device_load(&nfc->dev, p)) { - if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { + if((*args != '\0') && nfc_device_load(nfc->dev, p)) { + if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c index 24fd8e40..17a261f2 100755 --- a/applications/nfc/nfc_device.c +++ b/applications/nfc/nfc_device.c @@ -1,45 +1,38 @@ -#include "nfc_device_i.h" +#include "nfc_device.h" -#include #include -#include - -#define NFC_DEVICE_MAX_DATA_LEN 14 +#include static const char* nfc_app_folder = "/any/nfc"; static const char* nfc_app_extension = ".nfc"; static const char* nfc_app_shadow_extension = ".shd"; +static const char* nfc_file_header = "Flipper NFC device"; +static const uint32_t nfc_file_version = 2; -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; - bool parsed = true; - - for(uint16_t i = 0; i < len; i++) { - 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, delim_len + 2); - } else { - parsed = false; - break; - } - } - return parsed; +NfcDevice* nfc_device_alloc() { + NfcDevice* nfc_dev = furi_alloc(sizeof(NfcDevice)); + nfc_dev->storage = furi_record_open("storage"); + nfc_dev->dialogs = furi_record_open("dialogs"); + return nfc_dev; } -uint16_t nfc_device_prepare_format_string(NfcDevice* dev, string_t format_string) { +void nfc_device_free(NfcDevice* nfc_dev) { + furi_assert(nfc_dev); + furi_record_close("storage"); + furi_record_close("dialogs"); + free(nfc_dev); +} + +void nfc_device_prepare_format_string(NfcDevice* dev, string_t format_string) { if(dev->format == NfcDeviceSaveFormatUid) { - string_set_str(format_string, "UID\n"); + string_set_str(format_string, "UID"); } else if(dev->format == NfcDeviceSaveFormatBankCard) { - string_set_str(format_string, "Bank card\n"); + string_set_str(format_string, "Bank card"); } else if(dev->format == NfcDeviceSaveFormatMifareUl) { - string_set_str(format_string, "Mifare Ultralight\n"); + string_set_str(format_string, "Mifare Ultralight"); } else { - string_set_str(format_string, "Unknown\n"); + string_set_str(format_string, "Unknown"); } - return string_size(format_string); } bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_string) { @@ -59,228 +52,166 @@ bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_string) { return false; } -uint16_t nfc_device_prepare_uid_string(NfcDevice* dev, string_t uid_string) { - NfcDeviceCommonData* uid_data = &dev->dev_data.nfc_data; - string_printf(uid_string, "UID len: %02X UID: ", dev->dev_data.nfc_data.uid_len); - for(uint8_t i = 0; i < uid_data->uid_len; i++) { - string_cat_printf(uid_string, "%02X ", uid_data->uid[i]); - } - string_cat_printf( - uid_string, - "ATQA: %02X %02X SAK: %02X\n", - uid_data->atqa[0], - uid_data->atqa[1], - uid_data->sak); - return string_size(uid_string); -} - -bool nfc_device_parse_uid_string(NfcDevice* dev, string_t uid_string) { - NfcDeviceCommonData* uid_data = &dev->dev_data.nfc_data; - bool parsed = false; - - do { - // strlen("UID len: ") = 9 - string_right(uid_string, 9); - 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, 1)) { - break; - } - // strlen("ATQA: ") = 6 - string_right(uid_string, 6); - 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, 1)) { - break; - } - parsed = true; - } while(0); - - return parsed; -} - -uint16_t nfc_device_prepare_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string) { +static bool nfc_device_save_mifare_ul_data(FlipperFile* file, NfcDevice* dev) { + bool saved = false; MifareUlData* data = &dev->dev_data.mf_ul_data; - string_printf(mifare_ul_string, "Signature:"); - for(uint8_t i = 0; i < sizeof(data->signature); i++) { - string_cat_printf(mifare_ul_string, " %02X", data->signature[i]); - } - string_cat_printf(mifare_ul_string, "\nVersion:"); - uint8_t* version = (uint8_t*)&data->version; - for(uint8_t i = 0; i < sizeof(data->version); i++) { - string_cat_printf(mifare_ul_string, " %02X", version[i]); - } - for(uint8_t i = 0; i < 3; i++) { - string_cat_printf( - mifare_ul_string, - "\nCounter %d: %lu Tearing flag %d: %02X", - i, - data->counter[i], - i, - data->tearing[i]); - } - string_cat_printf(mifare_ul_string, "\nData size: %d\n", data->data_size); - for(uint16_t i = 0; i < data->data_size; i += 4) { - string_cat_printf( - mifare_ul_string, - "%02X %02X %02X %02X\n", - data->data[i], - data->data[i + 1], - data->data[i + 2], - data->data[i + 3]); - } - return string_size(mifare_ul_string); -} - -bool nfc_device_parse_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string) { - MifareUlData* data = &dev->dev_data.mf_ul_data; - uint16_t tearing_tmp = 0; - uint16_t cnt_num = 0; - size_t ws = 0; - int res = 0; - bool parsed = false; + string_t temp_str; + string_init(temp_str); + // Save Mifare Ultralight specific data do { - // strlen("Signature: ") = 11 - string_right(mifare_ul_string, 11); - if(!nfc_device_read_hex(mifare_ul_string, data->signature, sizeof(data->signature), 1)) { + if(!flipper_file_write_comment_cstr(file, "Mifare Ultralight specific data")) break; + if(!flipper_file_write_hex(file, "Signature", data->signature, sizeof(data->signature))) 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), 1)) { + if(!flipper_file_write_hex( + file, "Mifare version", (uint8_t*)&data->version, sizeof(data->version))) break; - } - string_strim(mifare_ul_string); - // Read counters and tearing flags + // Write conters and tearing flags data + bool counters_saved = true; for(uint8_t i = 0; i < 3; i++) { - res = sscanf( - string_get_cstr(mifare_ul_string), - "Counter %hX: %lu Tearing flag %hX: %02hX", - &cnt_num, - &data->counter[i], - &cnt_num, - &tearing_tmp); - if(res != 4) { + string_printf(temp_str, "Counter %d", i); + if(!flipper_file_write_uint32(file, string_get_cstr(temp_str), &data->counter[i], 1)) { + counters_saved = false; + break; + } + string_printf(temp_str, "Tearing %d", i); + if(!flipper_file_write_hex(file, string_get_cstr(temp_str), &data->tearing[i], 1)) { + counters_saved = false; break; } - data->tearing[i] = tearing_tmp; - ws = string_search_char(mifare_ul_string, '\n'); - string_right(mifare_ul_string, ws + 1); } - // Read data size - res = sscanf(string_get_cstr(mifare_ul_string), "Data size: %hu", &data->data_size); - if(res != 1) { - break; - } - ws = string_search_char(mifare_ul_string, '\n'); - string_right(mifare_ul_string, ws + 1); - // Read data + if(!counters_saved) break; + // Write pages data + uint32_t pages_total = data->data_size / 4; + if(!flipper_file_write_uint32(file, "Pages total", &pages_total, 1)) break; + bool pages_saved = true; for(uint16_t i = 0; i < data->data_size; i += 4) { - if(!nfc_device_read_hex(mifare_ul_string, &data->data[i], 4, 1)) { + string_printf(temp_str, "Page %d", i / 4); + if(!flipper_file_write_hex(file, string_get_cstr(temp_str), &data->data[i], 4)) { + pages_saved = false; break; } } - parsed = true; - } while(0); + if(!pages_saved) break; + saved = true; + } while(false); + string_clear(temp_str); + return saved; +} + +bool nfc_device_load_mifare_ul_data(FlipperFile* file, NfcDevice* dev) { + bool parsed = false; + MifareUlData* data = &dev->dev_data.mf_ul_data; + string_t temp_str; + string_init(temp_str); + + do { + // Read signature + if(!flipper_file_read_hex(file, "Signature", data->signature, sizeof(data->signature))) + break; + // Read Mifare version + if(!flipper_file_read_hex( + file, "Mifare version", (uint8_t*)&data->version, sizeof(data->version))) + break; + // Read counters and tearing flags + bool counters_parsed = true; + for(uint8_t i = 0; i < 3; i++) { + string_printf(temp_str, "Counter %d", i); + if(!flipper_file_read_uint32(file, string_get_cstr(temp_str), &data->counter[i], 1)) { + counters_parsed = false; + break; + } + string_printf(temp_str, "Tearing %d", i); + if(!flipper_file_read_hex(file, string_get_cstr(temp_str), &data->tearing[i], 1)) { + counters_parsed = false; + break; + } + } + if(!counters_parsed) break; + // Read pages + uint32_t pages = 0; + if(!flipper_file_read_uint32(file, "Pages total", &pages, 1)) break; + data->data_size = pages * 4; + bool pages_parsed = true; + for(uint16_t i = 0; i < pages; i++) { + string_printf(temp_str, "Page %d", i); + if(!flipper_file_read_hex(file, string_get_cstr(temp_str), &data->data[i * 4], 4)) { + pages_parsed = false; + break; + } + } + if(!pages_parsed) break; + parsed = true; + } while(false); + + string_clear(temp_str); return parsed; } -uint16_t nfc_device_prepare_bank_card_string(NfcDevice* dev, string_t bank_card_string) { +static bool nfc_device_save_bank_card_data(FlipperFile* file, NfcDevice* dev) { + bool saved = false; NfcEmvData* data = &dev->dev_data.emv_data; - string_printf(bank_card_string, "AID len: %d, AID:", data->aid_len); - for(uint8_t i = 0; i < data->aid_len; i++) { - string_cat_printf(bank_card_string, " %02X", data->aid[i]); - } - string_cat_printf( - bank_card_string, "\nName: %s\nNumber len: %d\nNumber:", data->name, data->number_len); - for(uint8_t i = 0; i < data->number_len; i++) { - string_cat_printf(bank_card_string, " %02X", data->number[i]); - } - if(data->exp_mon) { - 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); -} - -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)); + uint32_t data_temp = 0; do { - res = sscanf(string_get_cstr(bank_card_string), "AID len: %hu", &data->aid_len); - if(res != 1) { - break; + // Write Bank card specific data + if(!flipper_file_write_comment_cstr(file, "Bank card specific data")) break; + if(!flipper_file_write_hex(file, "AID", data->aid, data->aid_len)) break; + if(!flipper_file_write_string_cstr(file, "Name", data->name)) break; + if(!flipper_file_write_hex(file, "Number", data->number, data->number_len)) break; + if(data->exp_mon) { + uint8_t exp_data[2] = {data->exp_mon, data->exp_year}; + if(!flipper_file_write_hex(file, "Exp data", exp_data, sizeof(exp_data))) break; } - // strlen("AID len: ") = 9 - 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, 1)) { - break; + if(data->country_code) { + data_temp = data->country_code; + if(!flipper_file_write_uint32(file, "Country code", &data_temp, 1)) break; } - res = sscanf(string_get_cstr(bank_card_string), "Name: %s\n", data->name); - if(res != 1) { - break; + if(data->currency_code) { + data_temp = data->currency_code; + if(!flipper_file_write_uint32(file, "Currency code", &data_temp, 1)) break; } - ws = string_search_char(bank_card_string, '\n'); - string_right(bank_card_string, ws + 1); - res = sscanf(string_get_cstr(bank_card_string), "Number len: %hhu", &data->number_len); - if(res != 1) { - break; - } - ws = string_search_char(bank_card_string, '\n'); - 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, data->number_len, 1)) { - break; - } - parsed = true; - // Check expiration date presence - ws = string_search_str(bank_card_string, "Exp date: "); - 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, 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); + saved = true; + } while(false); + return saved; +} + +bool nfc_device_load_bank_card_data(FlipperFile* file, NfcDevice* dev) { + bool parsed = false; + NfcEmvData* data = &dev->dev_data.emv_data; + memset(data, 0, sizeof(NfcEmvData)); + uint32_t data_cnt = 0; + string_t temp_str; + string_init(temp_str); + + do { + // Load essential data + if(!flipper_file_get_value_count(file, "AID", &data_cnt)) break; + data->aid_len = data_cnt; + if(!flipper_file_read_hex(file, "AID", data->aid, data->aid_len)) break; + if(!flipper_file_read_string(file, "Name", temp_str)) break; + strlcpy(data->name, string_get_cstr(temp_str), sizeof(data->name)); + if(!flipper_file_get_value_count(file, "Number", &data_cnt)) break; + data->number_len = data_cnt; + if(!flipper_file_read_hex(file, "Number", data->number, data->number_len)) break; + parsed = true; + // Load optional data + uint8_t exp_data[2] = {}; + if(flipper_file_read_hex(file, "Exp data", exp_data, 2)) { + data->exp_mon = exp_data[0]; + data->exp_year = exp_data[1]; + } + if(flipper_file_read_uint32(file, "Country code", &data_cnt, 1)) { + data->country_code = data_cnt; + } + if(flipper_file_read_uint32(file, "Currency code", &data_cnt, 1)) { + data->currency_code = data_cnt; + } + } while(false); + + string_clear(temp_str); return parsed; } @@ -297,58 +228,49 @@ static bool nfc_device_save_file( const char* extension) { furi_assert(dev); - FileWorker* file_worker = file_worker_alloc(false); - string_t dev_file_name; - string_init(dev_file_name); + bool saved = false; + FlipperFile* file = flipper_file_alloc(dev->storage); + NfcDeviceCommonData* data = &dev->dev_data.nfc_data; string_t temp_str; string_init(temp_str); - uint16_t string_len = 0; do { // Create nfc directory if necessary - if(!file_worker_mkdir(file_worker, nfc_app_folder)) { - break; - }; + if(!storage_simply_mkdir(dev->storage, nfc_app_folder)) break; // First remove nfc device file if it was saved - string_printf(dev_file_name, "%s/%s%s", folder, dev_name, extension); - if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) { - break; - }; + string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); // Open file - if(!file_worker_open( - file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + if(!flipper_file_open_always(file, string_get_cstr(temp_str))) break; + // Write header + if(!flipper_file_write_header_cstr(file, nfc_file_header, nfc_file_version)) break; + // Write nfc device type + if(!flipper_file_write_comment_cstr( + file, "Nfc device type can be UID, Mifare Ultralight, Bank card")) break; - } - // Prepare and write format name on 1st line - string_len = nfc_device_prepare_format_string(dev, temp_str); - if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) { + nfc_device_prepare_format_string(dev, temp_str); + if(!flipper_file_write_string(file, "Device type", temp_str)) break; + // Write UID, ATQA, SAK + if(!flipper_file_write_comment_cstr(file, "UID, ATQA and SAK are common for all formats")) break; - } - // Prepare and write UID data on 2nd line - string_len = nfc_device_prepare_uid_string(dev, temp_str); - if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) { - break; - } + if(!flipper_file_write_hex(file, "UID", data->uid, data->uid_len)) break; + if(!flipper_file_write_hex(file, "ATQA", data->atqa, 2)) break; + if(!flipper_file_write_hex(file, "SAK", &data->sak, 1)) break; // Save more data if necessary if(dev->format == NfcDeviceSaveFormatMifareUl) { - string_len = nfc_device_prepare_mifare_ul_string(dev, temp_str); - if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) { - break; - } + if(!nfc_device_save_mifare_ul_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatBankCard) { - string_len = nfc_device_prepare_bank_card_string(dev, temp_str); - if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) { - break; - } + if(!nfc_device_save_bank_card_data(file, dev)) break; } + saved = true; } while(0); + if(!saved) { + dialog_message_show_storage_error(dev->dialogs, "Can not save\nkey file"); + } string_clear(temp_str); - string_clear(dev_file_name); - file_worker_close(file_worker); - file_worker_free(file_worker); - - return true; + flipper_file_close(file); + flipper_file_free(file); + return saved; } bool nfc_device_save(NfcDevice* dev, const char* dev_name) { @@ -360,73 +282,64 @@ bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name) { return nfc_device_save_file(dev, dev_name, nfc_app_folder, nfc_app_shadow_extension); } -static bool nfc_device_load_data(FileWorker* file_worker, string_t path, NfcDevice* dev) { - string_t temp_string; - string_init(temp_string); +static bool nfc_device_load_data(NfcDevice* dev, string_t path) { bool parsed = false; + FlipperFile* file = flipper_file_alloc(dev->storage); + NfcDeviceCommonData* data = &dev->dev_data.nfc_data; + uint32_t data_cnt = 0; + string_t temp_str; + string_init(temp_str); + bool depricated_version = false; do { // Check existance of shadow file size_t ext_start = string_search_str(path, nfc_app_extension); - string_set_n(temp_string, path, 0, ext_start); - string_cat_printf(temp_string, "%s", nfc_app_shadow_extension); - if(!file_worker_is_file_exist( - file_worker, string_get_cstr(temp_string), &dev->shadow_file_exist)) { - break; - } + string_set_n(temp_str, path, 0, ext_start); + string_cat_printf(temp_str, "%s", nfc_app_shadow_extension); + dev->shadow_file_exist = + storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) == FSE_OK; // Open shadow file if it exists. If not - open original if(dev->shadow_file_exist) { - if(!file_worker_open( - file_worker, string_get_cstr(temp_string), FSAM_READ, FSOM_OPEN_EXISTING)) { - break; - } + if(!flipper_file_open_existing(file, string_get_cstr(temp_str))) break; } else { - if(!file_worker_open( - file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - break; - } + if(!flipper_file_open_existing(file, string_get_cstr(path))) break; } - - // Read and parse format from 1st line - if(!file_worker_read_until(file_worker, temp_string, '\n')) { - break; - } - if(!nfc_device_parse_format_string(dev, temp_string)) { - break; - } - // Read and parse UID data from 2nd line - if(!file_worker_read_until(file_worker, temp_string, '\n')) { - break; - } - if(!nfc_device_parse_uid_string(dev, temp_string)) { + // Read and verify file header + uint32_t version = 0; + if(!flipper_file_read_header(file, temp_str, &version)) break; + if(string_cmp_str(temp_str, nfc_file_header) || (version != nfc_file_version)) { + depricated_version = true; break; } + // Read Nfc device type + if(!flipper_file_read_string(file, "Device type", temp_str)) break; + if(!nfc_device_parse_format_string(dev, temp_str)) break; + // Read and parse UID, ATQA and SAK + if(!flipper_file_get_value_count(file, "UID", &data_cnt)) break; + data->uid_len = data_cnt; + if(!flipper_file_read_hex(file, "UID", data->uid, data->uid_len)) break; + if(!flipper_file_read_hex(file, "ATQA", data->atqa, 2)) break; + if(!flipper_file_read_hex(file, "SAK", &data->sak, 1)) break; // Parse other data if(dev->format == NfcDeviceSaveFormatMifareUl) { - // Read until EOF - if(!file_worker_read_until(file_worker, temp_string, 0x05)) { - break; - } - if(!nfc_device_parse_mifare_ul_string(dev, temp_string)) { - break; - } + if(!nfc_device_load_mifare_ul_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatBankCard) { - // Read until EOF - if(!file_worker_read_until(file_worker, temp_string, 0x05)) { - break; - } - if(!nfc_device_parse_bank_card_string(dev, temp_string)) { - break; - } + if(!nfc_device_load_bank_card_data(file, dev)) break; } parsed = true; - } while(0); + } while(false); if(!parsed) { - file_worker_show_error(file_worker, "Can not parse\nfile"); + if(depricated_version) { + dialog_message_show_storage_error(dev->dialogs, "File format depricated"); + } else { + dialog_message_show_storage_error(dev->dialogs, "Can not parse\nfile"); + } } - string_clear(temp_string); + string_clear(temp_str); + flipper_file_close(file); + flipper_file_free(file); return parsed; } @@ -434,19 +347,16 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path) { furi_assert(dev); furi_assert(file_path); - FileWorker* file_worker = file_worker_alloc(false); // Load device data string_t path; string_init_set_str(path, file_path); - bool dev_load = nfc_device_load_data(file_worker, path, dev); + bool dev_load = nfc_device_load_data(dev, path); if(dev_load) { // Set device name path_extract_filename_no_ext(file_path, path); nfc_device_set_name(dev, string_get_cstr(path)); } string_clear(path); - file_worker_close(file_worker); - file_worker_free(file_worker); return dev_load; } @@ -454,10 +364,9 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path) { bool nfc_file_select(NfcDevice* dev) { furi_assert(dev); - FileWorker* file_worker = file_worker_alloc(false); // Input events and views are managed by file_select - bool res = file_worker_file_select( - file_worker, + bool res = dialog_file_select_show( + dev->dialogs, nfc_app_folder, nfc_app_extension, dev->file_name, @@ -465,18 +374,14 @@ bool nfc_file_select(NfcDevice* dev) { dev->dev_name); if(res) { string_t dev_str; - // Get key file path string_init_printf(dev_str, "%s/%s%s", nfc_app_folder, dev->file_name, nfc_app_extension); - - res = nfc_device_load_data(file_worker, dev_str, dev); + res = nfc_device_load_data(dev, dev_str); if(res) { nfc_device_set_name(dev, dev->file_name); } string_clear(dev_str); } - file_worker_close(file_worker); - file_worker_free(file_worker); return res; } @@ -491,61 +396,48 @@ void nfc_device_clear(NfcDevice* dev) { bool nfc_device_delete(NfcDevice* dev) { furi_assert(dev); - bool result = true; - FileWorker* file_worker = file_worker_alloc(false); + bool deleted = false; string_t file_path; + string_init(file_path); do { // Delete original file string_init_printf(file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension); - if(!file_worker_remove(file_worker, string_get_cstr(file_path))) { - result = false; - break; - } + if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; // Delete shadow file if it exists if(dev->shadow_file_exist) { - string_clean(file_path); string_printf( file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension); - if(!file_worker_remove(file_worker, string_get_cstr(file_path))) { - result = false; - break; - } + if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break; } + deleted = true; } while(0); + if(!deleted) { + dialog_message_show_storage_error(dev->dialogs, "Can not remove file"); + } + string_clear(file_path); - file_worker_close(file_worker); - file_worker_free(file_worker); - return result; + return deleted; } bool nfc_device_restore(NfcDevice* dev) { furi_assert(dev); furi_assert(dev->shadow_file_exist); - bool result = true; - FileWorker* file_worker = file_worker_alloc(false); + bool restored = false; string_t path; do { string_init_printf( path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension); - if(!file_worker_remove(file_worker, string_get_cstr(path))) { - result = false; - break; - } + if(!storage_simply_remove(dev->storage, string_get_cstr(path))) break; dev->shadow_file_exist = false; - string_clean(path); string_printf(path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension); - if(!nfc_device_load_data(file_worker, path, dev)) { - result = false; - break; - } + if(!nfc_device_load_data(dev, path)) break; + restored = true; } while(0); string_clear(path); - file_worker_close(file_worker); - file_worker_free(file_worker); - return result; + return restored; } diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h index 50f435ca..888f0c2f 100644 --- a/applications/nfc/nfc_device.h +++ b/applications/nfc/nfc_device.h @@ -2,6 +2,8 @@ #include #include +#include +#include #include "mifare_ultralight.h" @@ -57,6 +59,8 @@ typedef struct { } NfcDeviceData; typedef struct { + Storage* storage; + DialogsApp* dialogs; NfcDeviceData dev_data; char dev_name[NFC_DEV_NAME_MAX_LEN + 1]; char file_name[NFC_FILE_NAME_MAX_LEN]; @@ -64,6 +68,10 @@ typedef struct { bool shadow_file_exist; } NfcDevice; +NfcDevice* nfc_device_alloc(); + +void nfc_device_free(NfcDevice* nfc_dev); + void nfc_device_set_name(NfcDevice* dev, const char* name); bool nfc_device_save(NfcDevice* dev, const char* dev_name); diff --git a/applications/nfc/nfc_device_i.h b/applications/nfc/nfc_device_i.h deleted file mode 100644 index 01309eb5..00000000 --- a/applications/nfc/nfc_device_i.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "nfc_device.h" -#include - -uint16_t nfc_device_prepare_format_string(NfcDevice* dev, string_t format_string); -bool nfc_device_parse_format_string(NfcDevice* dev, string_t format_string); - -uint16_t nfc_device_prepare_uid_string(NfcDevice* dev, string_t uid_string); -bool nfc_device_parse_uid_string(NfcDevice* dev, string_t uid_string); - -uint16_t nfc_device_prepare_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string); -bool nfc_device_parse_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string); - -uint16_t nfc_device_prepare_bank_card_string(NfcDevice* dev, string_t bank_card_string); -bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string); \ No newline at end of file diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index 379cc100..61a11ce8 100755 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -36,7 +36,7 @@ struct Nfc { Gui* gui; NotificationApp* notifications; SceneManager* scene_manager; - NfcDevice dev; + NfcDevice* dev; NfcDeviceCommonData dev_edit_data; char text_store[NFC_TEXT_STORE_SIZE + 1]; diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index e8312b88..c5702362 100755 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -248,6 +248,8 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { NFC_WORKER_TAG, "Select PPSE response received. Start parsing response"); if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) { FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced"); + result->emv_data.aid_len = emv_app.aid_len; + memcpy(result->emv_data.aid, emv_app.aid, emv_app.aid_len); } else { FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application"); furi_hal_nfc_deactivate(); diff --git a/applications/nfc/scenes/nfc_scene_card_menu.c b/applications/nfc/scenes/nfc_scene_card_menu.c index dbaefe4f..5724abdb 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 = (Nfc*)context; Submenu* submenu = nfc->submenu; - if(nfc->dev.dev_data.nfc_data.protocol > NfcDeviceProtocolUnknown) { + if(nfc->dev->dev_data.nfc_data.protocol > NfcDeviceProtocolUnknown) { submenu_add_item( submenu, "Run compatible app", @@ -48,9 +48,9 @@ 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.nfc_data.protocol == NfcDeviceProtocolMifareUl) { scene_manager_next_scene(nfc->scene_manager, NfcSceneReadMifareUl); - } else if(nfc->dev.dev_data.nfc_data.protocol == NfcDeviceProtocolEMV) { + } else if(nfc->dev->dev_data.nfc_data.protocol == NfcDeviceProtocolEMV) { scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvApp); } return true; @@ -66,7 +66,7 @@ bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) { return true; } else if(event.event == SubmenuIndexSave) { scene_manager_set_scene_state(nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexSave); - nfc->dev.format = NfcDeviceSaveFormatUid; + nfc->dev->format = NfcDeviceSaveFormatUid; scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); return true; } diff --git a/applications/nfc/scenes/nfc_scene_delete.c b/applications/nfc/scenes/nfc_scene_delete.c index 0ea1b214..498e6ecd 100755 --- a/applications/nfc/scenes/nfc_scene_delete.c +++ b/applications/nfc/scenes/nfc_scene_delete.c @@ -12,14 +12,14 @@ void nfc_scene_delete_on_enter(void* context) { // Setup Custom Widget view char delete_str[64]; - snprintf(delete_str, sizeof(delete_str), "\e#Delete %s\e#", nfc->dev.dev_name); + snprintf(delete_str, sizeof(delete_str), "\e#Delete %s\e#", nfc->dev->dev_name); widget_add_text_box_element(nfc->widget, 0, 0, 128, 24, AlignCenter, AlignCenter, delete_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; + NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; if(data->uid_len == 4) { snprintf( uid_str, @@ -73,7 +73,7 @@ bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) { if(event.event == GuiButtonTypeLeft) { return scene_manager_previous_scene(nfc->scene_manager); } else if(event.event == GuiButtonTypeRight) { - if(nfc_device_delete(&nfc->dev)) { + if(nfc_device_delete(nfc->dev)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneDeleteSuccess); } else { scene_manager_search_and_switch_to_previous_scene( diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c index 54196a32..d57327b7 100755 --- a/applications/nfc/scenes/nfc_scene_device_info.c +++ b/applications/nfc/scenes/nfc_scene_device_info.c @@ -1,4 +1,5 @@ #include "../nfc_i.h" +#include "../helpers/nfc_emv_parser.h" #define NFC_SCENE_DEVICE_INFO_BACK_EVENT (0UL) @@ -36,13 +37,13 @@ void nfc_scene_device_info_on_enter(void* context) { // Setup Custom Widget view widget_add_text_box_element( - nfc->widget, 0, 0, 128, 24, AlignCenter, AlignCenter, nfc->dev.dev_name); + nfc->widget, 0, 0, 128, 24, AlignCenter, AlignCenter, nfc->dev->dev_name); widget_add_button_element( nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_device_info_widget_callback, nfc); 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; + NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; if(data->uid_len == 4) { snprintf( uid_str, @@ -87,14 +88,14 @@ void nfc_scene_device_info_on_enter(void* context) { widget_add_string_element(nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, atqa_str); // Setup Data View - if(nfc->dev.format == NfcDeviceSaveFormatUid) { + if(nfc->dev->format == NfcDeviceSaveFormatUid) { DialogEx* dialog_ex = nfc->dialog_ex; dialog_ex_set_left_button_text(dialog_ex, "Back"); dialog_ex_set_text(dialog_ex, "No data", 64, 32, AlignCenter, AlignCenter); 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 = (MifareUlData*)&nfc->dev.dev_data.mf_ul_data; + } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { + MifareUlData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; TextBox* text_box = nfc->text_box; text_box_set_context(text_box, nfc); text_box_set_exit_callback(text_box, nfc_scene_device_info_text_box_callback); @@ -107,8 +108,8 @@ void nfc_scene_device_info_on_enter(void* context) { nfc->text_box_store, "%02X%02X ", mf_ul_data->data[i], mf_ul_data->data[i + 1]); } text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); - } else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) { - NfcEmvData* emv_data = &nfc->dev.dev_data.emv_data; + } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { + NfcEmvData* 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); @@ -116,12 +117,29 @@ void nfc_scene_device_info_on_enter(void* context) { if(emv_data->exp_mon) { bank_card_set_exp_date(bank_card, emv_data->exp_mon, emv_data->exp_year); } + string_t display_str; + string_init(display_str); if(emv_data->country_code) { - bank_card_set_country_name(bank_card, emv_data->country_code); + string_t country_name; + string_init(country_name); + if(nfc_emv_parser_get_country_name( + nfc->dev->storage, emv_data->country_code, country_name)) { + string_printf(display_str, "Reg:%s", string_get_cstr(country_name)); + bank_card_set_country_name(bank_card, string_get_cstr(display_str)); + } + string_clear(country_name); } if(emv_data->currency_code) { - bank_card_set_currency_name(bank_card, emv_data->currency_code); + string_t currency_name; + string_init(currency_name); + if(nfc_emv_parser_get_currency_name( + nfc->dev->storage, emv_data->country_code, currency_name)) { + string_printf(display_str, "Cur:%s", string_get_cstr(currency_name)); + bank_card_set_currency_name(bank_card, string_get_cstr(display_str)); + } + string_clear(currency_name); } + string_clear(display_str); } scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); @@ -136,17 +154,17 @@ bool nfc_scene_device_info_on_event(void* context, SceneManagerEvent event) { if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeLeft)) { consumed = scene_manager_previous_scene(nfc->scene_manager); } else if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeRight)) { - if(nfc->dev.format == NfcDeviceSaveFormatUid) { + if(nfc->dev->format == NfcDeviceSaveFormatUid) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); consumed = true; - } else if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { + } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); consumed = true; - } else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) { + } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewBankCard); @@ -168,7 +186,7 @@ void nfc_scene_device_info_on_exit(void* context) { // Clear Custom Widget widget_clear(nfc->widget); - if(nfc->dev.format == NfcDeviceSaveFormatUid) { + if(nfc->dev->format == NfcDeviceSaveFormatUid) { // Clear Dialog DialogEx* dialog_ex = nfc->dialog_ex; dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); @@ -179,11 +197,11 @@ void nfc_scene_device_info_on_exit(void* context) { dialog_ex_set_center_button_text(dialog_ex, NULL); dialog_ex_set_result_callback(dialog_ex, NULL); dialog_ex_set_context(dialog_ex, NULL); - } else if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { + } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { // Clear TextBox text_box_clean(nfc->text_box); string_clean(nfc->text_box_store); - } else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) { + } 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 b08660b3..c9e822e2 100644 --- a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c +++ b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c @@ -11,7 +11,7 @@ void nfc_scene_emulate_apdu_sequence_on_enter(void* context) { // 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); + nfc_worker_start(nfc->worker, NfcWorkerStateEmulateApdu, &nfc->dev->dev_data, NULL, nfc); } bool nfc_scene_emulate_apdu_sequence_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c index cba09437..bacdd347 100755 --- a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c +++ b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c @@ -14,8 +14,8 @@ void nfc_scene_emulate_mifare_ul_on_enter(void* context) { // Setup view Popup* popup = nfc->popup; - if(strcmp(nfc->dev.dev_name, "")) { - nfc_text_store_set(nfc, "%s", nfc->dev.dev_name); + if(strcmp(nfc->dev->dev_name, "")) { + nfc_text_store_set(nfc, "%s", nfc->dev->dev_name); } popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); popup_set_header(popup, "Emulating\nMf Ultralight", 56, 31, AlignLeft, AlignTop); @@ -25,7 +25,7 @@ void nfc_scene_emulate_mifare_ul_on_enter(void* context) { nfc_worker_start( nfc->worker, NfcWorkerStateEmulateMifareUl, - &nfc->dev.dev_data, + &nfc->dev->dev_data, nfc_emulate_mifare_ul_worker_callback, nfc); } @@ -45,7 +45,7 @@ bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event NFC_MF_UL_DATA_CHANGED) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_UL_DATA_NOT_CHANGED); - nfc_device_save_shadow(&nfc->dev, nfc->dev.dev_name); + nfc_device_save_shadow(nfc->dev, nfc->dev->dev_name); } consumed = false; } diff --git a/applications/nfc/scenes/nfc_scene_emulate_uid.c b/applications/nfc/scenes/nfc_scene_emulate_uid.c index ccd27de5..a8fff57b 100755 --- a/applications/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/nfc/scenes/nfc_scene_emulate_uid.c @@ -5,10 +5,10 @@ void nfc_scene_emulate_uid_on_enter(void* context) { // Setup view Popup* popup = nfc->popup; - NfcDeviceCommonData* data = &nfc->dev.dev_data.nfc_data; + NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_data; - if(strcmp(nfc->dev.dev_name, "")) { - nfc_text_store_set(nfc, "%s", nfc->dev.dev_name); + if(strcmp(nfc->dev->dev_name, "")) { + nfc_text_store_set(nfc, "%s", nfc->dev->dev_name); } else if(data->uid_len == 4) { nfc_text_store_set( nfc, "%02X %02X %02X %02X", data->uid[0], data->uid[1], data->uid[2], data->uid[3]); @@ -32,7 +32,7 @@ void nfc_scene_emulate_uid_on_enter(void* context) { // Setup and start worker view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - nfc_worker_start(nfc->worker, NfcWorkerStateEmulate, &nfc->dev.dev_data, NULL, nfc); + nfc_worker_start(nfc->worker, NfcWorkerStateEmulate, &nfc->dev->dev_data, NULL, nfc); } bool nfc_scene_emulate_uid_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/nfc/scenes/nfc_scene_file_select.c b/applications/nfc/scenes/nfc_scene_file_select.c index 67894fbf..010e807e 100755 --- a/applications/nfc/scenes/nfc_scene_file_select.c +++ b/applications/nfc/scenes/nfc_scene_file_select.c @@ -3,7 +3,7 @@ void nfc_scene_file_select_on_enter(void* context) { Nfc* nfc = (Nfc*)context; // Process file_select return - if(nfc_file_select(&nfc->dev)) { + if(nfc_file_select(nfc->dev)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu); } else { scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart); diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c index 236da374..344d4733 100755 --- a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c +++ b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c @@ -32,9 +32,9 @@ bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) { if(event.event == SubmenuIndexSave) { scene_manager_set_scene_state( nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexSave); - nfc->dev.format = NfcDeviceSaveFormatMifareUl; + nfc->dev->format = NfcDeviceSaveFormatMifareUl; // Clear device name - nfc_device_set_name(&nfc->dev, ""); + nfc_device_set_name(nfc->dev, ""); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); return true; } else if(event.event == SubmenuIndexEmulate) { diff --git a/applications/nfc/scenes/nfc_scene_read_card.c b/applications/nfc/scenes/nfc_scene_read_card.c index 8853858e..d01fa75d 100755 --- a/applications/nfc/scenes/nfc_scene_read_card.c +++ b/applications/nfc/scenes/nfc_scene_read_card.c @@ -18,7 +18,7 @@ void nfc_scene_read_card_on_enter(void* context) { // Start worker view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); nfc_worker_start( - nfc->worker, NfcWorkerStateDetect, &nfc->dev.dev_data, nfc_read_card_worker_callback, nfc); + nfc->worker, NfcWorkerStateDetect, &nfc->dev->dev_data, nfc_read_card_worker_callback, nfc); } bool nfc_scene_read_card_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/nfc/scenes/nfc_scene_read_card_success.c b/applications/nfc/scenes/nfc_scene_read_card_success.c index 5cac8258..c70bf1b2 100755 --- a/applications/nfc/scenes/nfc_scene_read_card_success.c +++ b/applications/nfc/scenes/nfc_scene_read_card_success.c @@ -15,7 +15,7 @@ void nfc_scene_read_card_success_on_enter(void* context) { notification_message(nfc->notifications, &sequence_success); // Setup view - NfcDeviceCommonData* data = (NfcDeviceCommonData*)&nfc->dev.dev_data.nfc_data; + NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_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"); @@ -68,7 +68,7 @@ bool nfc_scene_read_card_success_on_event(void* context, SceneManagerEvent event return scene_manager_previous_scene(nfc->scene_manager); } else if(event.event == DialogExResultRight) { // Clear device name - nfc_device_set_name(&nfc->dev, ""); + nfc_device_set_name(nfc->dev, ""); scene_manager_next_scene(nfc->scene_manager, NfcSceneCardMenu); return true; } diff --git a/applications/nfc/scenes/nfc_scene_read_emv_app.c b/applications/nfc/scenes/nfc_scene_read_emv_app.c index 63509ad8..665a121b 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_app.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_app.c @@ -20,7 +20,7 @@ void nfc_scene_read_emv_app_on_enter(void* context) { nfc_worker_start( nfc->worker, NfcWorkerStateReadEMVApp, - &nfc->dev.dev_data, + &nfc->dev->dev_data, nfc_read_emv_app_worker_callback, nfc); } 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 bea8d719..3fe62f3f 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_app_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_app_success.c @@ -13,8 +13,8 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) { Nfc* nfc = (Nfc*)context; // Setup view - NfcDeviceCommonData* nfc_data = &nfc->dev.dev_data.nfc_data; - NfcEmvData* emv_data = &nfc->dev.dev_data.emv_data; + 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"); @@ -23,7 +23,8 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) { // Display UID and AID string_t aid; string_init(aid); - bool aid_found = nfc_emv_parser_get_aid_name(emv_data->aid, emv_data->aid_len, aid); + bool aid_found = + nfc_emv_parser_get_aid_name(nfc->dev->storage, 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]); diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data.c b/applications/nfc/scenes/nfc_scene_read_emv_data.c index 953ac36f..4da1aaa7 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data.c @@ -17,12 +17,12 @@ void nfc_scene_read_emv_data_on_enter(void* context) { 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)); + memset(&nfc->dev->dev_data.emv_data, 0, sizeof(nfc->dev->dev_data.emv_data)); // Start worker nfc_worker_start( nfc->worker, NfcWorkerStateReadEMV, - &nfc->dev.dev_data, + &nfc->dev->dev_data, nfc_read_emv_data_worker_callback, nfc); } 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 92402c13..0867311f 100755 --- a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c +++ b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c @@ -13,8 +13,8 @@ void nfc_scene_read_emv_data_success_widget_callback( 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; + NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data; + NfcDeviceCommonData* nfc_data = &nfc->dev->dev_data.nfc_data; // Setup Custom Widget view // Add frame @@ -34,7 +34,7 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { nfc); // Add card name widget_add_string_element( - nfc->widget, 64, 3, AlignCenter, AlignTop, FontSecondary, nfc->dev.dev_data.emv_data.name); + nfc->widget, 64, 3, AlignCenter, AlignTop, FontSecondary, nfc->dev->dev_data.emv_data.name); // Add cad number string_t pan_str; string_init(pan_str); @@ -49,7 +49,7 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { 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)) { + nfc_emv_parser_get_country_name(nfc->dev->storage, emv_data->country_code, country_name)) { string_t disp_country; string_init_printf(disp_country, "Reg:%s", country_name); widget_add_string_element( @@ -61,7 +61,8 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { 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)) { + nfc_emv_parser_get_currency_name( + nfc->dev->storage, emv_data->currency_code, currency_name)) { string_t disp_currency; string_init_printf(disp_currency, "Cur:%s", currency_name); widget_add_string_element( @@ -122,8 +123,8 @@ bool nfc_scene_read_emv_data_success_on_event(void* context, SceneManagerEvent e nfc->scene_manager, NfcSceneReadEmvAppSuccess); } else if(event.event == GuiButtonTypeRight) { // Clear device name - nfc_device_set_name(&nfc->dev, ""); - nfc->dev.format = NfcDeviceSaveFormatBankCard; + nfc_device_set_name(nfc->dev, ""); + nfc->dev->format = NfcDeviceSaveFormatBankCard; scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); return true; } diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c index f4d4a6dc..a0bd057d 100755 --- a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c @@ -20,7 +20,7 @@ void nfc_scene_read_mifare_ul_on_enter(void* context) { nfc_worker_start( nfc->worker, NfcWorkerStateReadMifareUl, - &nfc->dev.dev_data, + &nfc->dev->dev_data, nfc_read_mifare_ul_worker_callback, nfc); } 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 55571666..b12b14a7 100755 --- a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c @@ -27,7 +27,7 @@ void nfc_scene_read_mifare_ul_success_on_enter(void* context) { notification_message(nfc->notifications, &sequence_success); // Setup dialog view - NfcDeviceCommonData* data = (NfcDeviceCommonData*)&nfc->dev.dev_data.nfc_data; + NfcDeviceCommonData* data = &nfc->dev->dev_data.nfc_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"); @@ -54,7 +54,7 @@ void nfc_scene_read_mifare_ul_success_on_enter(void* context) { dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_mifare_ul_success_dialog_callback); // Setup TextBox view - MifareUlData* mf_ul_data = (MifareUlData*)&nfc->dev.dev_data.mf_ul_data; + MifareUlData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data; TextBox* text_box = nfc->text_box; text_box_set_context(text_box, nfc); text_box_set_exit_callback(text_box, nfc_scene_read_mifare_ul_success_text_box_callback); diff --git a/applications/nfc/scenes/nfc_scene_save_name.c b/applications/nfc/scenes/nfc_scene_save_name.c index ca3afdac..44babcdd 100755 --- a/applications/nfc/scenes/nfc_scene_save_name.c +++ b/applications/nfc/scenes/nfc_scene_save_name.c @@ -15,11 +15,11 @@ void nfc_scene_save_name_on_enter(void* context) { // Setup view TextInput* text_input = nfc->text_input; bool dev_name_empty = false; - if(!strcmp(nfc->dev.dev_name, "")) { + if(!strcmp(nfc->dev->dev_name, "")) { set_random_name(nfc->text_store, sizeof(nfc->text_store)); dev_name_empty = true; } else { - nfc_text_store_set(nfc, nfc->dev.dev_name); + nfc_text_store_set(nfc, nfc->dev->dev_name); } text_input_set_header_text(text_input, "Name the card"); text_input_set_result_callback( @@ -37,14 +37,14 @@ bool nfc_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SCENE_SAVE_NAME_CUSTOM_EVENT) { - if(strcmp(nfc->dev.dev_name, "")) { - nfc_device_delete(&nfc->dev); + if(strcmp(nfc->dev->dev_name, "")) { + nfc_device_delete(nfc->dev); } if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetUid)) { - nfc->dev.dev_data.nfc_data = nfc->dev_edit_data; + nfc->dev->dev_data.nfc_data = nfc->dev_edit_data; } - strlcpy(nfc->dev.dev_name, nfc->text_store, strlen(nfc->text_store) + 1); - if(nfc_device_save(&nfc->dev, nfc->text_store)) { + 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; } else { diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c index a8e2ce7f..ea38ce3d 100755 --- a/applications/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/nfc/scenes/nfc_scene_saved_menu.c @@ -18,7 +18,7 @@ void nfc_scene_saved_menu_on_enter(void* context) { Nfc* nfc = (Nfc*)context; Submenu* submenu = nfc->submenu; - if(nfc->dev.format != NfcDeviceSaveFormatBankCard) { + if(nfc->dev->format != NfcDeviceSaveFormatBankCard) { submenu_add_item( submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc); } @@ -30,7 +30,7 @@ void nfc_scene_saved_menu_on_enter(void* context) { submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc); submenu_set_selected_item( nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSavedMenu)); - if(nfc->dev.shadow_file_exist) { + if(nfc->dev->shadow_file_exist) { submenu_add_item( submenu, "Restore original", @@ -49,7 +49,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, event.event); if(event.event == SubmenuIndexEmulate) { - if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { + if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); @@ -65,7 +65,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo); consumed = true; } else if(event.event == SubmenuIndexRestoreOriginal) { - if(!nfc_device_restore(&nfc->dev)) { + if(!nfc_device_restore(nfc->dev)) { scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneStart); } else { diff --git a/applications/nfc/scenes/nfc_scene_set_atqa.c b/applications/nfc/scenes/nfc_scene_set_atqa.c index 7936880c..1c682f18 100755 --- a/applications/nfc/scenes/nfc_scene_set_atqa.c +++ b/applications/nfc/scenes/nfc_scene_set_atqa.c @@ -19,7 +19,7 @@ void nfc_scene_set_atqa_on_enter(void* context) { nfc_scene_set_atqa_byte_input_callback, NULL, nfc, - nfc->dev.dev_data.nfc_data.atqa, + nfc->dev->dev_data.nfc_data.atqa, 2); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput); } diff --git a/applications/nfc/scenes/nfc_scene_set_sak.c b/applications/nfc/scenes/nfc_scene_set_sak.c index 5df999d0..edeb27a9 100755 --- a/applications/nfc/scenes/nfc_scene_set_sak.c +++ b/applications/nfc/scenes/nfc_scene_set_sak.c @@ -19,7 +19,7 @@ void nfc_scene_set_sak_on_enter(void* context) { nfc_scene_set_sak_byte_input_callback, NULL, nfc, - &nfc->dev.dev_data.nfc_data.sak, + &nfc->dev->dev_data.nfc_data.sak, 1); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput); } diff --git a/applications/nfc/scenes/nfc_scene_set_type.c b/applications/nfc/scenes/nfc_scene_set_type.c index badab0c0..66eafe83 100755 --- a/applications/nfc/scenes/nfc_scene_set_type.c +++ b/applications/nfc/scenes/nfc_scene_set_type.c @@ -15,7 +15,7 @@ void nfc_scene_set_type_on_enter(void* context) { Nfc* nfc = (Nfc*)context; Submenu* submenu = nfc->submenu; // Clear device name - nfc_device_set_name(&nfc->dev, ""); + nfc_device_set_name(nfc->dev, ""); submenu_add_item( submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc); submenu_add_item( @@ -28,13 +28,13 @@ bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexNFCA7) { - nfc->dev.dev_data.nfc_data.uid_len = 7; - nfc->dev.format = NfcDeviceSaveFormatUid; + nfc->dev->dev_data.nfc_data.uid_len = 7; + nfc->dev->format = NfcDeviceSaveFormatUid; scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak); return true; } else if(event.event == SubmenuIndexNFCA4) { - nfc->dev.dev_data.nfc_data.uid_len = 4; - nfc->dev.format = NfcDeviceSaveFormatUid; + nfc->dev->dev_data.nfc_data.uid_len = 4; + nfc->dev->format = NfcDeviceSaveFormatUid; scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak); return true; } diff --git a/applications/nfc/scenes/nfc_scene_set_uid.c b/applications/nfc/scenes/nfc_scene_set_uid.c index 7ecfbf32..5d179f77 100755 --- a/applications/nfc/scenes/nfc_scene_set_uid.c +++ b/applications/nfc/scenes/nfc_scene_set_uid.c @@ -14,7 +14,7 @@ void nfc_scene_set_uid_on_enter(void* context) { // Setup view ByteInput* byte_input = nfc->byte_input; byte_input_set_header_text(byte_input, "Enter uid in hex"); - nfc->dev_edit_data = nfc->dev.dev_data.nfc_data; + nfc->dev_edit_data = nfc->dev->dev_data.nfc_data; byte_input_set_result_callback( byte_input, nfc_scene_set_uid_byte_input_callback, diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c index cdf7dbe2..bfeb494b 100755 --- a/applications/nfc/scenes/nfc_scene_start.c +++ b/applications/nfc/scenes/nfc_scene_start.c @@ -34,7 +34,7 @@ void nfc_scene_start_on_enter(void* context) { submenu_set_selected_item( submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneStart)); - nfc_device_clear(&nfc->dev); + nfc_device_clear(nfc->dev); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } diff --git a/applications/nfc/views/bank_card.c b/applications/nfc/views/bank_card.c index 483491d6..07b4db58 100755 --- a/applications/nfc/views/bank_card.c +++ b/applications/nfc/views/bank_card.c @@ -67,42 +67,14 @@ 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_country_name(BankCard* bank_card, uint16_t country_code) { +void bank_card_set_country_name(BankCard* bank_card, const char* country_name) { furi_assert(bank_card); - 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); + widget_add_string_element( + bank_card->widget, 120, 18, AlignRight, AlignTop, FontSecondary, country_name); } -void bank_card_set_currency_name(BankCard* bank_card, uint16_t currency_code) { +void bank_card_set_currency_name(BankCard* bank_card, const char* currency_name) { 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); + widget_add_string_element( + bank_card->widget, 31, 18, AlignLeft, AlignTop, FontSecondary, currency_name); } diff --git a/applications/nfc/views/bank_card.h b/applications/nfc/views/bank_card.h index a4342856..628d9deb 100644 --- a/applications/nfc/views/bank_card.h +++ b/applications/nfc/views/bank_card.h @@ -21,6 +21,6 @@ void bank_card_set_number(BankCard* bank_card, uint8_t* number, uint8_t len); void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year); -void bank_card_set_country_name(BankCard* bank_card, uint16_t country_code); +void bank_card_set_country_name(BankCard* bank_card, const char* country_name); -void bank_card_set_currency_name(BankCard* bank_card, uint16_t currency_code); +void bank_card_set_currency_name(BankCard* bank_card, const char* currency_name); diff --git a/assets/resources/nfc/emv/aid.nfc b/assets/resources/nfc/emv/aid.nfc index 2655df56..43854f3d 100644 --- a/assets/resources/nfc/emv/aid.nfc +++ b/assets/resources/nfc/emv/aid.nfc @@ -1,148 +1,151 @@ -A00000000305076010 VISA ELO Credit -A0000000031010 VISA Debit/Credit (Classic) -A000000003101001 VISA Credit -A000000003101002 VISA Debit -A0000000032010 VISA Electron -A0000000032020 VISA -A0000000033010 VISA Interlink -A0000000034010 VISA Specific -A0000000035010 VISA Specific -A0000000036010 Domestic Visa Cash -A0000000036020 International Visa Cash -A0000000038002 VISA Auth EMV-CAP (DPA) -A0000000038010 VISA Plus -A0000000039010 VISA Loyalty -A000000003999910 VISA Proprietary ATM -A00000000401 MasterCard PayPass -A0000000041010 MasterCard Global -A00000000410101213 MasterCard Credit -A00000000410101215 MasterCard Credit -A0000000042010 MasterCard Specific -A0000000043010 MasterCard Specific -A0000000043060 Maestro (Debit) -A000000004306001 Maestro (Debit) -A0000000044010 MasterCard Specific -A0000000045010 MasterCard Specific -A0000000046000 Cirrus -A0000000048002 SecureCode EMV-CAP -A0000000049999 MasterCard PayPass -A0000000050001 Maestro UK -A0000000050002 Solo -A00000002401 Self Service -A000000025 American Express -A0000000250000 American Express -A00000002501 American Express -A000000025010402 American Express -A000000025010701 ExpressPay -A000000025010801 American Express -A0000000291010 Link / American Express -A0000000421010 Cartes Bancaire EMV Card -A0000000426010 Apple Pay -A00000006510 JCB -A0000000651010 JCB J Smart Credit -A00000006900 Moneo -A000000077010000021000000000003B Visa AEPN -A000000098 Debit Card -A0000000980848 Debit Card -A0000001211010 Dankort VISA GEM Vision -A0000001410001 PagoBANCOMAT -A0000001523010 Discover, Pulse D Pas -A0000001524010 Discover -A0000001544442 Banricompras Debito -A000000172950001 BAROC Taiwan -A0000002281010 SPAN (M/Chip) -A0000002282010 SPAN (VIS) -A0000002771010 INTERAC -A00000031510100528 Currence PuC -A0000003156020 Chipknip -A0000003591010028001 Girocard EAPS -A0000003710001 InterSwitch Verve Card -A0000004540010 Etranzact Genesis Card -A0000004540011 Etranzact Genesis Card 2 -A0000004766C GOOGLE_PAYMENT -A0000005241010 RuPay -A0000006723010 TROY chip credit card -A0000006723020 TROY chip debit card -A0000007705850 XTRAPOWER -B012345678 Maestro TEST -D27600002545500100 Girocard -D5780000021010 Bankaxept -F0000000030001 BRADESCO -A000000003000000 (VISA) Card Manager -A000000003534441 Schlumberger SD -A0000000035350 Security Domain -A000000003535041 Security Domain -A0000000040000 MasterCard Card Manager -A000000018434D Gemplus card manager -A000000018434D00 Gemplus Security Domain -A0000000960200 Proton WISD -A0000001510000 Global Platform SD -A00000015153504341534400 CASD_AID -A000000476A010 GSD_MANAGER_AID -A000000476A110 GSD_MANAGER_AID -315041592E5359532E4444463031 Visa PSE -325041592E5359532E4444463031 Visa PPSE -A0000000042203 MasterCard Specific -A0000000045555 APDULogger -A0000000090001FF44FF1289 Orange -A0000000101030 Maestro-CH -A00000001800 Gemplus -A0000000181001 gemplus util packages -A000000025010104 American Express -A00000002949034010100001 HSBC -A00000002949282010100000 Barclay -A00000005945430100 Girocard Electronic Cash -A0000000980840 Visa Common Debit -A0000001570010 AMEX -A0000001570020 MasterCard -A0000001570021 Maestro -A0000001570022 Maestro -A0000001570023 CASH -A0000001570030 VISA -A0000001570031 VISA -A0000001570040 JCB -A0000001570050 Postcard -A0000001570051 Postcard -A0000001570100 MCard -A0000001570104 MyOne -A000000157010C WIRCard -A000000157010D Power Card -A0000001574443 DINERS CLUB -A0000001574444 Supercard Plus -A00000022820101010 SPAN -A000000308000010000100 ID-ONE PIV BIO -A0000003241010 Discover Zip -A000000333010101 UnionPay Debit -A000000333010102 UnionPay Credit -A000000333010103 UnionPay Quasi Credit -A000000333010106 UnionPay Electronic Cash -A000000333010108 U.S. UnionPay Common Debit -A000000337102000 Classic -A000000337101001 Prepaye Online -A000000337102001 Prepaye Possibile Offiline -A000000337601001 Porte Monnaie Electronique -A0000006581010 MIR Credit -A0000006581011 MIR Credit -A0000006582010 MIR Debit -D040000001000002 Paylife Quick IEP -D040000002000002 RFU -D040000003000002 POS -D040000004000002 ATM -D04000000B000002 Retail -D04000000C000002 Bank_Data -D04000000D000002 Shopping -D040000013000001 DF_UNI_Kepler1 -D040000013000001 DF_Schüler1 -D040000013000002 DF_UNI_Kepler2 -D040000013000002 DF_Schüler2 -D040000014000001 DF_Mensa -D040000015000001 DF_UNI_Ausweis -D040000015000001 DF_Ausweis -D0400000190001 EMV ATM Maestro -D0400000190002 EMV POS Maestro -D0400000190003 EMV ATM MasterCard -D0400000190004 EMV POS MasterCard -D276000025 Girocard -D27600002547410100 Girocard ATM -D7560000010101 Reka Card -D7560000300101 M Budget \ No newline at end of file +Filetype: Flipper EMV resources +Version: 1 +# EMV Application ID code: Application ID name +A00000000305076010: VISA ELO Credit +A0000000031010: VISA Debit/Credit (Classic) +A000000003101001: VISA Credit +A000000003101002: VISA Debit +A0000000032010: VISA Electron +A0000000032020: VISA +A0000000033010: VISA Interlink +A0000000034010: VISA Specific +A0000000035010: VISA Specific +A0000000036010: Domestic Visa Cash +A0000000036020: International Visa Cash +A0000000038002: VISA Auth EMV-CAP (DPA) +A0000000038010: VISA Plus +A0000000039010: VISA Loyalty +A000000003999910: VISA Proprietary ATM +A00000000401: MasterCard PayPass +A0000000041010: MasterCard Global +A00000000410101213: MasterCard Credit +A00000000410101215: MasterCard Credit +A0000000042010: MasterCard Specific +A0000000043010: MasterCard Specific +A0000000043060: Maestro (Debit) +A000000004306001: Maestro (Debit) +A0000000044010: MasterCard Specific +A0000000045010: MasterCard Specific +A0000000046000: Cirrus +A0000000048002: SecureCode EMV-CAP +A0000000049999: MasterCard PayPass +A0000000050001: Maestro UK +A0000000050002: Solo +A00000002401: Self Service +A000000025: American Express +A0000000250000: American Express +A00000002501: American Express +A000000025010402: American Express +A000000025010701: ExpressPay +A000000025010801: American Express +A0000000291010: Link / American Express +A0000000421010: Cartes Bancaire EMV Card +A0000000426010: Apple Pay +A00000006510: JCB +A0000000651010: JCB J Smart Credit +A00000006900: Moneo +A000000077010000021000000000003B: Visa AEPN +A000000098: Debit Card +A0000000980848: Debit Card +A0000001211010: Dankort VISA GEM Vision +A0000001410001: PagoBANCOMAT +A0000001523010: Discover, Pulse D Pas +A0000001524010: Discover +A0000001544442: Banricompras Debito +A000000172950001: BAROC Taiwan +A0000002281010: SPAN (M/Chip) +A0000002282010: SPAN (VIS) +A0000002771010: INTERAC +A00000031510100528: Currence PuC +A0000003156020: Chipknip +A0000003591010028001: Girocard EAPS +A0000003710001: InterSwitch Verve Card +A0000004540010: Etranzact Genesis Card +A0000004540011: Etranzact Genesis Card 2 +A0000004766C: GOOGLE_PAYMENT +A0000005241010: RuPay +A0000006723010: TROY chip credit card +A0000006723020: TROY chip debit card +A0000007705850: XTRAPOWER +B012345678: Maestro TEST +D27600002545500100: Girocard +D5780000021010: Bankaxept +F0000000030001: BRADESCO +A000000003000000: (VISA) Card Manager +A000000003534441: Schlumberger SD +A0000000035350: Security Domain +A000000003535041: Security Domain +A0000000040000: MasterCard Card Manager +A000000018434D: Gemplus card manager +A000000018434D00: Gemplus Security Domain +A0000000960200: Proton WISD +A0000001510000: Global Platform SD +A00000015153504341534400: CASD_AID +A000000476A010: GSD_MANAGER_AID +A000000476A110: GSD_MANAGER_AID +315041592E5359532E4444463031: Visa PSE +325041592E5359532E4444463031: Visa PPSE +A0000000042203: MasterCard Specific +A0000000045555: APDULogger +A0000000090001FF44FF1289: Orange +A0000000101030: Maestro-CH +A00000001800: Gemplus +A0000000181001: gemplus util packages +A000000025010104: American Express +A00000002949034010100001: HSBC +A00000002949282010100000: Barclay +A00000005945430100: Girocard Electronic Cash +A0000000980840: Visa Common Debit +A0000001570010: AMEX +A0000001570020: MasterCard +A0000001570021: Maestro +A0000001570022: Maestro +A0000001570023: CASH +A0000001570030: VISA +A0000001570031: VISA +A0000001570040: JCB +A0000001570050: Postcard +A0000001570051: Postcard +A0000001570100: MCard +A0000001570104: MyOne +A000000157010C: WIRCard +A000000157010D: Power Card +A0000001574443: DINERS CLUB +A0000001574444: Supercard Plus +A00000022820101010: SPAN +A000000308000010000100: ID-ONE PIV BIO +A0000003241010: Discover Zip +A000000333010101: UnionPay Debit +A000000333010102: UnionPay Credit +A000000333010103: UnionPay Quasi Credit +A000000333010106: UnionPay Electronic Cash +A000000333010108: U.S. UnionPay Common Debit +A000000337102000: Classic +A000000337101001: Prepaye Online +A000000337102001: Prepaye Possibile Offiline +A000000337601001: Porte Monnaie Electronique +A0000006581010: MIR Credit +A0000006581011: MIR Credit +A0000006582010: MIR Debit +D040000001000002: Paylife Quick IEP +D040000002000002: RFU +D040000003000002: POS +D040000004000002: ATM +D04000000B000002: Retail +D04000000C000002: Bank_Data +D04000000D000002: Shopping +D040000013000001: DF_UNI_Kepler1 +D040000013000001: DF_Schüler1 +D040000013000002: DF_UNI_Kepler2 +D040000013000002: DF_Schüler2 +D040000014000001: DF_Mensa +D040000015000001: DF_UNI_Ausweis +D040000015000001: DF_Ausweis +D0400000190001: EMV ATM Maestro +D0400000190002: EMV POS Maestro +D0400000190003: EMV ATM MasterCard +D0400000190004: EMV POS MasterCard +D276000025: Girocard +D27600002547410100: Girocard ATM +D7560000010101: Reka Card +D7560000300101: M Budget \ No newline at end of file diff --git a/assets/resources/nfc/emv/country_code.nfc b/assets/resources/nfc/emv/country_code.nfc index e43c35f3..8b19ab83 100644 --- a/assets/resources/nfc/emv/country_code.nfc +++ b/assets/resources/nfc/emv/country_code.nfc @@ -1,249 +1,252 @@ -0004 AFG -0008 ALB -0010 ATA -0012 DZA -0016 ASM -0020 AND -0024 AGO -0028 ATG -0031 AZE -0032 ARG -0036 AUS -0040 AUT -0044 BHS -0048 BHR -0050 BGD -0051 ARM -0052 BRB -0056 BEL -0060 BMU -0064 BTN -0068 BOL -0070 BIH -0072 BWA -0074 BVT -0076 BRA -0084 BLZ -0086 IOT -0090 SLB -0092 VGB -0096 BRN -0100 BGR -0104 MMR -0108 BDI -0112 BLR -0116 KHM -0120 CMR -0124 CAN -0132 CPV -0136 CYM -0140 CAF -0144 LKA -0148 TCD -0152 CHL -0156 CHN -0158 TWN -0162 CXR -0166 CCK -0170 COL -0174 COM -0175 MYT -0178 COG -0180 COD -0184 COK -0188 CRI -0191 HRV -0192 CUB -0196 CYP -0203 CZE -0204 BEN -0208 DNK -0212 DMA -0214 DOM -0218 ECU -0222 SLV -0226 GNQ -0231 ETH -0232 ERI -0233 EST -0234 FRO -0238 FLK -0239 SGS -0242 FJI -0246 FIN -0248 ALA -0250 FRA -0254 GUF -0258 PYF -0260 ATF -0262 DJI -0266 GAB -0268 GEO -0270 GMB -0275 PSE -0276 DEU -0288 GHA -0292 GIB -0296 KIR -0300 GRC -0304 GRL -0308 GRD -0312 GLP -0316 GUM -0320 GTM -0324 GIN -0328 GUY -0332 HTI -0334 HMD -0336 VAT -0340 HND -0344 HKG -0348 HUN -0352 ISL -0356 IND -0360 IDN -0364 IRN -0368 IRQ -0372 IRL -0376 ISR -0380 ITA -0384 CIV -0388 JAM -0392 JPN -0398 KAZ -0400 JOR -0404 KEN -0408 PRK -0410 KOR -0414 KWT -0417 KGZ -0418 LAO -0422 LBN -0426 LSO -0428 LVA -0430 LBR -0434 LBY -0438 LIE -0440 LTU -0442 LUX -0446 MAC -0450 MDG -0454 MWI -0458 MYS -0462 MDV -0466 MLI -0470 MLT -0474 MTQ -0478 MRT -0480 MUS -0484 MEX -0492 MCO -0496 MNG -0498 MDA -0499 MNE -0500 MSR -0504 MAR -0508 MOZ -0512 OMN -0516 NAM -0520 NRU -0524 NPL -0528 NLD -0531 CUW -0533 ABW -0534 SXM -0535 BES -0540 NCL -0548 VUT -0554 NZL -0558 NIC -0562 NER -0566 NGA -0570 NIU -0574 NFK -0578 NOR -0580 MNP -0581 UMI -0583 FSM -0584 MHL -0585 PLW -0586 PAK -0591 PAN -0598 PNG -0600 PRY -0604 PER -0608 PHL -0612 PCN -0616 POL -0620 PRT -0624 GNB -0626 TLS -0630 PRI -0634 QAT -0638 REU -0642 ROU -0643 RUS -0646 RWA -0652 BLM -0654 SHN -0659 KNA -0660 AIA -0662 LCA -0663 MAF -0666 SPM -0670 VCT -0674 SMR -0678 STP -0682 SAU -0686 SEN -0688 SRB -0690 SYC -0694 SLE -0702 SGP -0703 SVK -0704 VNM -0705 SVN -0706 SOM -0710 ZAF -0716 ZWE -0724 ESP -0728 SSD -0729 SDN -0732 ESH -0740 SUR -0744 SJM -0748 SWZ -0752 SWE -0756 CHE -0760 SYR -0762 TJK -0764 THA -0768 TGO -0772 TKL -0776 TON -0780 TTO -0784 ARE -0788 TUN -0792 TUR -0795 TKM -0796 TCA -0798 TUV -0800 UGA -0804 UKR -0807 MKD -0818 EGY -0826 GBR -0831 GGY -0832 JEY -0833 IMN -0834 TZA -0840 USA -0850 VIR -0854 BFA -0858 URY -0860 UZB -0862 VEN -0876 WLF -0882 WSM -0887 YEM -0894 ZMB \ No newline at end of file +Filetype: Flipper EMV resources +Version: 1 +# EMV country code: country name +0004: AFG +0008: ALB +0010: ATA +0012: DZA +0016: ASM +0020: AND +0024: AGO +0028: ATG +0031: AZE +0032: ARG +0036: AUS +0040: AUT +0044: BHS +0048: BHR +0050: BGD +0051: ARM +0052: BRB +0056: BEL +0060: BMU +0064: BTN +0068: BOL +0070: BIH +0072: BWA +0074: BVT +0076: BRA +0084: BLZ +0086: IOT +0090: SLB +0092: VGB +0096: BRN +0100: BGR +0104: MMR +0108: BDI +0112: BLR +0116: KHM +0120: CMR +0124: CAN +0132: CPV +0136: CYM +0140: CAF +0144: LKA +0148: TCD +0152: CHL +0156: CHN +0158: TWN +0162: CXR +0166: CCK +0170: COL +0174: COM +0175: MYT +0178: COG +0180: COD +0184: COK +0188: CRI +0191: HRV +0192: CUB +0196: CYP +0203: CZE +0204: BEN +0208: DNK +0212: DMA +0214: DOM +0218: ECU +0222: SLV +0226: GNQ +0231: ETH +0232: ERI +0233: EST +0234: FRO +0238: FLK +0239: SGS +0242: FJI +0246: FIN +0248: ALA +0250: FRA +0254: GUF +0258: PYF +0260: ATF +0262: DJI +0266: GAB +0268: GEO +0270: GMB +0275: PSE +0276: DEU +0288: GHA +0292: GIB +0296: KIR +0300: GRC +0304: GRL +0308: GRD +0312: GLP +0316: GUM +0320: GTM +0324: GIN +0328: GUY +0332: HTI +0334: HMD +0336: VAT +0340: HND +0344: HKG +0348: HUN +0352: ISL +0356: IND +0360: IDN +0364: IRN +0368: IRQ +0372: IRL +0376: ISR +0380: ITA +0384: CIV +0388: JAM +0392: JPN +0398: KAZ +0400: JOR +0404: KEN +0408: PRK +0410: KOR +0414: KWT +0417: KGZ +0418: LAO +0422: LBN +0426: LSO +0428: LVA +0430: LBR +0434: LBY +0438: LIE +0440: LTU +0442: LUX +0446: MAC +0450: MDG +0454: MWI +0458: MYS +0462: MDV +0466: MLI +0470: MLT +0474: MTQ +0478: MRT +0480: MUS +0484: MEX +0492: MCO +0496: MNG +0498: MDA +0499: MNE +0500: MSR +0504: MAR +0508: MOZ +0512: OMN +0516: NAM +0520: NRU +0524: NPL +0528: NLD +0531: CUW +0533: ABW +0534: SXM +0535: BES +0540: NCL +0548: VUT +0554: NZL +0558: NIC +0562: NER +0566: NGA +0570: NIU +0574: NFK +0578: NOR +0580: MNP +0581: UMI +0583: FSM +0584: MHL +0585: PLW +0586: PAK +0591: PAN +0598: PNG +0600: PRY +0604: PER +0608: PHL +0612: PCN +0616: POL +0620: PRT +0624: GNB +0626: TLS +0630: PRI +0634: QAT +0638: REU +0642: ROU +0643: RUS +0646: RWA +0652: BLM +0654: SHN +0659: KNA +0660: AIA +0662: LCA +0663: MAF +0666: SPM +0670: VCT +0674: SMR +0678: STP +0682: SAU +0686: SEN +0688: SRB +0690: SYC +0694: SLE +0702: SGP +0703: SVK +0704: VNM +0705: SVN +0706: SOM +0710: ZAF +0716: ZWE +0724: ESP +0728: SSD +0729: SDN +0732: ESH +0740: SUR +0744: SJM +0748: SWZ +0752: SWE +0756: CHE +0760: SYR +0762: TJK +0764: THA +0768: TGO +0772: TKL +0776: TON +0780: TTO +0784: ARE +0788: TUN +0792: TUR +0795: TKM +0796: TCA +0798: TUV +0800: UGA +0804: UKR +0807: MKD +0818: EGY +0826: GBR +0831: GGY +0832: JEY +0833: IMN +0834: TZA +0840: USA +0850: VIR +0854: BFA +0858: URY +0860: UZB +0862: VEN +0876: WLF +0882: WSM +0887: YEM +0894: ZMB \ No newline at end of file diff --git a/assets/resources/nfc/emv/currency_code.nfc b/assets/resources/nfc/emv/currency_code.nfc index 4ee69181..31c575b3 100644 --- a/assets/resources/nfc/emv/currency_code.nfc +++ b/assets/resources/nfc/emv/currency_code.nfc @@ -1,168 +1,171 @@ -0997 USN -0994 XSU -0990 CLF -0986 BRL -0985 PLN -0984 BOV -0981 GEL -0980 UAH -0979 MXV -0978 EUR -0977 BAM -0976 CDF -0975 BGN -0973 AOA -0972 TJS -0971 AFN -0970 COU -0969 MGA -0968 SRD -0967 ZMW -0965 XUA -0960 XDR -0953 XPF -0952 XOF -0951 XCD -0950 XAF -0949 TRY -0948 CHW -0947 CHE -0946 RON -0944 AZN -0943 MZN -0941 RSD -0940 UYI -0938 SDG -0937 VEF -0936 GHS -0934 TMT -0933 BYN -0932 ZWL -0931 CUC -0930 STN -0929 MRU -0901 TWD -0886 YER -0882 WST -0860 UZS -0858 UYU -0840 USD -0834 TZS -0826 GBP -0818 EGP -0807 MKD -0800 UGX -0788 TND -0784 AED -0780 TTD -0776 TOP -0764 THB -0760 SYP -0756 CHF -0752 SEK -0748 SZL -0728 SSP -0710 ZAR -0706 SOS -0704 VND -0702 SGD -0694 SLL -0690 SCR -0682 SAR -0654 SHP -0646 RWF -0643 RUB -0634 QAR -0608 PHP -0604 PEN -0600 PYG -0598 PGK -0590 PAB -0586 PKR -0578 NOK -0566 NGN -0558 NIO -0554 NZD -0548 VUV -0533 AWG -0532 ANG -0524 NPR -0516 NAD -0512 OMR -0504 MAD -0498 MDL -0496 MNT -0484 MXN -0480 MUR -0462 MVR -0458 MYR -0454 MWK -0446 MOP -0434 LYD -0430 LRD -0426 LSL -0422 LBP -0418 LAK -0417 KGS -0414 KWD -0410 KRW -0408 KPW -0404 KES -0400 JOD -0398 KZT -0392 JPY -0388 JMD -0376 ILS -0368 IQD -0364 IRR -0360 IDR -0356 INR -0352 ISK -0348 HUF -0344 HKD -0340 HNL -0332 HTG -0328 GYD -0324 GNF -0320 GTQ -0292 GIP -0270 GMD -0262 DJF -0242 FJD -0238 FKP -0232 ERN -0230 ETB -0222 SVC -0214 DOP -0208 DKK -0203 CZK -0192 CUP -0191 HRK -0188 CRC -0174 KMF -0170 COP -0156 CNY -0152 CLP -0144 LKR -0136 KYD -0132 CVE -0124 CAD -0116 KHR -0108 BIF -0104 MMK -0096 BND -0090 SBD -0084 BZD -0072 BWP -0068 BOB -0064 BTN -0060 BMD -0052 BBD -0051 AMD -0050 BDT -0048 BHD -0044 BSD -0036 AUD -0032 ARS -0012 DZD -0008 ALL \ No newline at end of file +Filetype: Flipper EMV resources +Version: 1 +# EMV currency code: currency name +0997: USN +0994: XSU +0990: CLF +0986: BRL +0985: PLN +0984: BOV +0981: GEL +0980: UAH +0979: MXV +0978: EUR +0977: BAM +0976: CDF +0975: BGN +0973: AOA +0972: TJS +0971: AFN +0970: COU +0969: MGA +0968: SRD +0967: ZMW +0965: XUA +0960: XDR +0953: XPF +0952: XOF +0951: XCD +0950: XAF +0949: TRY +0948: CHW +0947: CHE +0946: RON +0944: AZN +0943: MZN +0941: RSD +0940: UYI +0938: SDG +0937: VEF +0936: GHS +0934: TMT +0933: BYN +0932: ZWL +0931: CUC +0930: STN +0929: MRU +0901: TWD +0886: YER +0882: WST +0860: UZS +0858: UYU +0840: USD +0834: TZS +0826: GBP +0818: EGP +0807: MKD +0800: UGX +0788: TND +0784: AED +0780: TTD +0776: TOP +0764: THB +0760: SYP +0756: CHF +0752: SEK +0748: SZL +0728: SSP +0710: ZAR +0706: SOS +0704: VND +0702: SGD +0694: SLL +0690: SCR +0682: SAR +0654: SHP +0646: RWF +0643: RUB +0634: QAR +0608: PHP +0604: PEN +0600: PYG +0598: PGK +0590: PAB +0586: PKR +0578: NOK +0566: NGN +0558: NIO +0554: NZD +0548: VUV +0533: AWG +0532: ANG +0524: NPR +0516: NAD +0512: OMR +0504: MAD +0498: MDL +0496: MNT +0484: MXN +0480: MUR +0462: MVR +0458: MYR +0454: MWK +0446: MOP +0434: LYD +0430: LRD +0426: LSL +0422: LBP +0418: LAK +0417: KGS +0414: KWD +0410: KRW +0408: KPW +0404: KES +0400: JOD +0398: KZT +0392: JPY +0388: JMD +0376: ILS +0368: IQD +0364: IRR +0360: IDR +0356: INR +0352: ISK +0348: HUF +0344: HKD +0340: HNL +0332: HTG +0328: GYD +0324: GNF +0320: GTQ +0292: GIP +0270: GMD +0262: DJF +0242: FJD +0238: FKP +0232: ERN +0230: ETB +0222: SVC +0214: DOP +0208: DKK +0203: CZK +0192: CUP +0191: HRK +0188: CRC +0174: KMF +0170: COP +0156: CNY +0152: CLP +0144: LKR +0136: KYD +0132: CVE +0124: CAD +0116: KHR +0108: BIF +0104: MMK +0096: BND +0090: SBD +0084: BZD +0072: BWP +0068: BOB +0064: BTN +0060: BMD +0052: BBD +0051: AMD +0050: BDT +0048: BHD +0044: BSD +0036: AUD +0032: ARS +0012: DZD +0008: ALL \ No newline at end of file