[FL-1919] NFC rework with Flipper File Format (#756)
* nfc: allocate nfc device on heap * nfc: rework save with flipper file format * nfc: rework nfc device load with flipper file * nfc: save AID length and data * nfc: remove file worker usage * nfc: format sources * nfc: rework with flipper file format addons * assets: update EMV resources with flipper file format * nfc: rework EMV resources parsing with new file format * assets: fix EMV AID file format * nfc: fix nfc_device usage Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
54dc16134d
commit
90d450368c
applications/nfc
helpers
nfc.cnfc_device.cnfc_device.hnfc_device_i.hnfc_i.hnfc_worker.cscenes
nfc_scene_card_menu.cnfc_scene_delete.cnfc_scene_device_info.cnfc_scene_emulate_apdu_sequence.cnfc_scene_emulate_mifare_ul.cnfc_scene_emulate_uid.cnfc_scene_file_select.cnfc_scene_mifare_ul_menu.cnfc_scene_read_card.cnfc_scene_read_card_success.cnfc_scene_read_emv_app.cnfc_scene_read_emv_app_success.cnfc_scene_read_emv_data.cnfc_scene_read_emv_data_success.cnfc_scene_read_mifare_ul.cnfc_scene_read_mifare_ul_success.cnfc_scene_save_name.cnfc_scene_saved_menu.cnfc_scene_set_atqa.cnfc_scene_set_sak.cnfc_scene_set_type.cnfc_scene_set_uid.cnfc_scene_start.c
views
assets/resources/nfc/emv
@ -1,49 +1,80 @@
|
||||
#include "nfc_emv_parser.h"
|
||||
#include <lib/flipper_file/flipper_file.h>
|
||||
|
||||
#include <file-worker.h>
|
||||
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;
|
||||
}
|
||||
|
@ -3,25 +3,39 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <m-string.h>
|
||||
#include <storage/storage.h>
|
||||
|
||||
/** 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);
|
||||
|
@ -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);
|
||||
|
@ -1,45 +1,38 @@
|
||||
#include "nfc_device_i.h"
|
||||
#include "nfc_device.h"
|
||||
|
||||
#include <file-worker.h>
|
||||
#include <lib/toolbox/path.h>
|
||||
#include <lib/toolbox/hex.h>
|
||||
|
||||
#define NFC_DEVICE_MAX_DATA_LEN 14
|
||||
#include <lib/flipper_file/flipper_file.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <storage/storage.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
|
||||
#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);
|
||||
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "nfc_device.h"
|
||||
#include <m-string.h>
|
||||
|
||||
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);
|
@ -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];
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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]);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
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
|
@ -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
|
||||
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
|
@ -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
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user