[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:
gornekich 2021-11-09 00:55:06 +03:00 committed by GitHub
parent 54dc16134d
commit 90d450368c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1008 additions and 1070 deletions

View File

@ -1,49 +1,80 @@
#include "nfc_emv_parser.h" #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 static bool nfc_emv_parser_search_data(
nfc_emv_parser_get_value(const char* file_path, string_t key, char delimiter, string_t value) { Storage* storage,
bool found = false; const char* file_name,
FileWorker* file_worker = file_worker_alloc(true); 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)) { do {
if(file_worker_get_value_from_key(file_worker, key, delimiter, value)) { // Open file
found = true; 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); string_clear(temp_str);
file_worker_free(file_worker); flipper_file_free(file);
return found; return parsed;
} }
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(
bool result = false; Storage* storage,
uint8_t* aid,
uint8_t aid_len,
string_t aid_name) {
furi_assert(storage);
bool parsed = false;
string_t key; string_t key;
string_init(key); string_init(key);
for(uint8_t i = 0; i < aid_len; i++) { for(uint8_t i = 0; i < aid_len; i++) {
string_cat_printf(key, "%02X", aid[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); string_clear(key);
return result; return parsed;
} }
bool nfc_emv_parser_get_country_name(uint16_t country_code, string_t country_name) { bool nfc_emv_parser_get_country_name(
bool result = false; Storage* storage,
uint16_t country_code,
string_t country_name) {
bool parsed = false;
string_t key; string_t key;
string_init_printf(key, "%04X", country_code); 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); string_clear(key);
return result; return parsed;
} }
bool nfc_emv_parser_get_currency_name(uint16_t currency_code, string_t currency_name) { bool nfc_emv_parser_get_currency_name(
bool result = false; Storage* storage,
uint16_t currency_code,
string_t currency_name) {
bool parsed = false;
string_t key; string_t key;
string_init_printf(key, "%04X", currency_code); 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); string_clear(key);
return result; return parsed;
} }

View File

@ -3,25 +3,39 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <m-string.h> #include <m-string.h>
#include <storage/storage.h>
/** Get EMV application name by number /** Get EMV application name by number
* @param storage Storage instance
* @param aid - AID number array * @param aid - AID number array
* @param aid_len - AID length * @param aid_len - AID length
* @param aid_name - string to keep AID name * @param aid_name - string to keep AID name
* @return - true if AID found, false otherwies * @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 /** Get country name by country code
* @param storage Storage instance
* @param country_code - ISO 3166 country code * @param country_code - ISO 3166 country code
* @param country_name - string to keep country name * @param country_name - string to keep country name
* @return - true if country found, false otherwies * @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 /** Get currency name by currency code
* @param storage Storage instance
* @param currency_code - ISO 3166 currency code * @param currency_code - ISO 3166 currency code
* @param currency_name - string to keep currency name * @param currency_name - string to keep currency name
* @return - true if currency found, false otherwies * @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);

View File

@ -31,6 +31,9 @@ Nfc* nfc_alloc() {
view_dispatcher_set_navigation_event_callback(nfc->view_dispatcher, nfc_back_event_callback); 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); view_dispatcher_set_tick_event_callback(nfc->view_dispatcher, nfc_tick_event_callback, 100);
// Nfc device
nfc->dev = nfc_device_alloc();
// Open GUI record // Open GUI record
nfc->gui = furi_record_open("gui"); nfc->gui = furi_record_open("gui");
view_dispatcher_attach_to_gui(nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); view_dispatcher_attach_to_gui(nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen);
@ -82,6 +85,9 @@ Nfc* nfc_alloc() {
void nfc_free(Nfc* nfc) { void nfc_free(Nfc* nfc) {
furi_assert(nfc); furi_assert(nfc);
// Nfc device
nfc_device_free(nfc->dev);
// Submenu // Submenu
view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewMenu); view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewMenu);
submenu_free(nfc->submenu); submenu_free(nfc->submenu);
@ -154,8 +160,8 @@ int32_t nfc_app(void* p) {
char* args = p; char* args = p;
// Check argument and run corresponding scene // Check argument and run corresponding scene
if((*args != '\0') && nfc_device_load(&nfc->dev, p)) { if((*args != '\0') && nfc_device_load(nfc->dev, p)) {
if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl);
} else { } else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);

View File

@ -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/path.h>
#include <lib/toolbox/hex.h> #include <lib/flipper_file/flipper_file.h>
#define NFC_DEVICE_MAX_DATA_LEN 14
static const char* nfc_app_folder = "/any/nfc"; static const char* nfc_app_folder = "/any/nfc";
static const char* nfc_app_extension = ".nfc"; static const char* nfc_app_extension = ".nfc";
static const char* nfc_app_shadow_extension = ".shd"; 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) { NfcDevice* nfc_device_alloc() {
string_strim(str); NfcDevice* nfc_dev = furi_alloc(sizeof(NfcDevice));
uint8_t nibble_high = 0; nfc_dev->storage = furi_record_open("storage");
uint8_t nibble_low = 0; nfc_dev->dialogs = furi_record_open("dialogs");
bool parsed = true; return nfc_dev;
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;
} }
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) { if(dev->format == NfcDeviceSaveFormatUid) {
string_set_str(format_string, "UID\n"); string_set_str(format_string, "UID");
} else if(dev->format == NfcDeviceSaveFormatBankCard) { } 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) { } else if(dev->format == NfcDeviceSaveFormatMifareUl) {
string_set_str(format_string, "Mifare Ultralight\n"); string_set_str(format_string, "Mifare Ultralight");
} else { } 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) { 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; return false;
} }
uint16_t nfc_device_prepare_uid_string(NfcDevice* dev, string_t uid_string) { static bool nfc_device_save_mifare_ul_data(FlipperFile* file, NfcDevice* dev) {
NfcDeviceCommonData* uid_data = &dev->dev_data.nfc_data; bool saved = false;
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) {
MifareUlData* data = &dev->dev_data.mf_ul_data; MifareUlData* data = &dev->dev_data.mf_ul_data;
string_printf(mifare_ul_string, "Signature:"); string_t temp_str;
for(uint8_t i = 0; i < sizeof(data->signature); i++) { string_init(temp_str);
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;
// Save Mifare Ultralight specific data
do { do {
// strlen("Signature: ") = 11 if(!flipper_file_write_comment_cstr(file, "Mifare Ultralight specific data")) break;
string_right(mifare_ul_string, 11); if(!flipper_file_write_hex(file, "Signature", data->signature, sizeof(data->signature)))
if(!nfc_device_read_hex(mifare_ul_string, data->signature, sizeof(data->signature), 1)) {
break; break;
} if(!flipper_file_write_hex(
// strlen("Version: ") = 9 file, "Mifare version", (uint8_t*)&data->version, sizeof(data->version)))
string_right(mifare_ul_string, 9);
if(!nfc_device_read_hex(
mifare_ul_string, (uint8_t*)&data->version, sizeof(data->version), 1)) {
break; break;
} // Write conters and tearing flags data
string_strim(mifare_ul_string); bool counters_saved = true;
// Read counters and tearing flags
for(uint8_t i = 0; i < 3; i++) { for(uint8_t i = 0; i < 3; i++) {
res = sscanf( string_printf(temp_str, "Counter %d", i);
string_get_cstr(mifare_ul_string), if(!flipper_file_write_uint32(file, string_get_cstr(temp_str), &data->counter[i], 1)) {
"Counter %hX: %lu Tearing flag %hX: %02hX", counters_saved = false;
&cnt_num, break;
&data->counter[i], }
&cnt_num, string_printf(temp_str, "Tearing %d", i);
&tearing_tmp); if(!flipper_file_write_hex(file, string_get_cstr(temp_str), &data->tearing[i], 1)) {
if(res != 4) { counters_saved = false;
break; break;
} }
data->tearing[i] = tearing_tmp;
ws = string_search_char(mifare_ul_string, '\n');
string_right(mifare_ul_string, ws + 1);
} }
// Read data size if(!counters_saved) break;
res = sscanf(string_get_cstr(mifare_ul_string), "Data size: %hu", &data->data_size); // Write pages data
if(res != 1) { uint32_t pages_total = data->data_size / 4;
break; if(!flipper_file_write_uint32(file, "Pages total", &pages_total, 1)) break;
} bool pages_saved = true;
ws = string_search_char(mifare_ul_string, '\n');
string_right(mifare_ul_string, ws + 1);
// Read data
for(uint16_t i = 0; i < data->data_size; i += 4) { 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; break;
} }
} }
parsed = true; if(!pages_saved) break;
} while(0); 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; 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; NfcEmvData* data = &dev->dev_data.emv_data;
string_printf(bank_card_string, "AID len: %d, AID:", data->aid_len); uint32_t data_temp = 0;
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));
do { do {
res = sscanf(string_get_cstr(bank_card_string), "AID len: %hu", &data->aid_len); // Write Bank card specific data
if(res != 1) { if(!flipper_file_write_comment_cstr(file, "Bank card specific data")) break;
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 if(data->country_code) {
string_right(bank_card_string, 9); data_temp = data->country_code;
size_t ws = string_search_char(bank_card_string, ':'); if(!flipper_file_write_uint32(file, "Country code", &data_temp, 1)) break;
string_right(bank_card_string, ws + 1);
if(!nfc_device_read_hex(bank_card_string, data->aid, data->aid_len, 1)) {
break;
} }
res = sscanf(string_get_cstr(bank_card_string), "Name: %s\n", data->name); if(data->currency_code) {
if(res != 1) { data_temp = data->currency_code;
break; if(!flipper_file_write_uint32(file, "Currency code", &data_temp, 1)) break;
} }
ws = string_search_char(bank_card_string, '\n'); saved = true;
string_right(bank_card_string, ws + 1); } while(false);
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);
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; return parsed;
} }
@ -297,58 +228,49 @@ static bool nfc_device_save_file(
const char* extension) { const char* extension) {
furi_assert(dev); furi_assert(dev);
FileWorker* file_worker = file_worker_alloc(false); bool saved = false;
string_t dev_file_name; FlipperFile* file = flipper_file_alloc(dev->storage);
string_init(dev_file_name); NfcDeviceCommonData* data = &dev->dev_data.nfc_data;
string_t temp_str; string_t temp_str;
string_init(temp_str); string_init(temp_str);
uint16_t string_len = 0;
do { do {
// Create nfc directory if necessary // Create nfc directory if necessary
if(!file_worker_mkdir(file_worker, nfc_app_folder)) { if(!storage_simply_mkdir(dev->storage, nfc_app_folder)) break;
break;
};
// First remove nfc device file if it was saved // First remove nfc device file if it was saved
string_printf(dev_file_name, "%s/%s%s", folder, dev_name, extension); string_printf(temp_str, "%s/%s%s", folder, dev_name, extension);
if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) {
break;
};
// Open file // Open file
if(!file_worker_open( if(!flipper_file_open_always(file, string_get_cstr(temp_str))) break;
file_worker, string_get_cstr(dev_file_name), FSAM_WRITE, FSOM_CREATE_ALWAYS)) { // 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; break;
} nfc_device_prepare_format_string(dev, temp_str);
// Prepare and write format name on 1st line if(!flipper_file_write_string(file, "Device type", temp_str)) break;
string_len = nfc_device_prepare_format_string(dev, temp_str); // Write UID, ATQA, SAK
if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) { if(!flipper_file_write_comment_cstr(file, "UID, ATQA and SAK are common for all formats"))
break; break;
} if(!flipper_file_write_hex(file, "UID", data->uid, data->uid_len)) break;
// Prepare and write UID data on 2nd line if(!flipper_file_write_hex(file, "ATQA", data->atqa, 2)) break;
string_len = nfc_device_prepare_uid_string(dev, temp_str); if(!flipper_file_write_hex(file, "SAK", &data->sak, 1)) break;
if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) {
break;
}
// Save more data if necessary // Save more data if necessary
if(dev->format == NfcDeviceSaveFormatMifareUl) { if(dev->format == NfcDeviceSaveFormatMifareUl) {
string_len = nfc_device_prepare_mifare_ul_string(dev, temp_str); if(!nfc_device_save_mifare_ul_data(file, dev)) break;
if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) {
break;
}
} else if(dev->format == NfcDeviceSaveFormatBankCard) { } else if(dev->format == NfcDeviceSaveFormatBankCard) {
string_len = nfc_device_prepare_bank_card_string(dev, temp_str); if(!nfc_device_save_bank_card_data(file, dev)) break;
if(!file_worker_write(file_worker, string_get_cstr(temp_str), string_len)) {
break;
}
} }
saved = true;
} while(0); } while(0);
if(!saved) {
dialog_message_show_storage_error(dev->dialogs, "Can not save\nkey file");
}
string_clear(temp_str); string_clear(temp_str);
string_clear(dev_file_name); flipper_file_close(file);
file_worker_close(file_worker); flipper_file_free(file);
file_worker_free(file_worker); return saved;
return true;
} }
bool nfc_device_save(NfcDevice* dev, const char* dev_name) { 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); 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) { static bool nfc_device_load_data(NfcDevice* dev, string_t path) {
string_t temp_string;
string_init(temp_string);
bool parsed = false; 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 { do {
// Check existance of shadow file // Check existance of shadow file
size_t ext_start = string_search_str(path, nfc_app_extension); size_t ext_start = string_search_str(path, nfc_app_extension);
string_set_n(temp_string, path, 0, ext_start); string_set_n(temp_str, path, 0, ext_start);
string_cat_printf(temp_string, "%s", nfc_app_shadow_extension); string_cat_printf(temp_str, "%s", nfc_app_shadow_extension);
if(!file_worker_is_file_exist( dev->shadow_file_exist =
file_worker, string_get_cstr(temp_string), &dev->shadow_file_exist)) { storage_common_stat(dev->storage, string_get_cstr(temp_str), NULL) == FSE_OK;
break;
}
// Open shadow file if it exists. If not - open original // Open shadow file if it exists. If not - open original
if(dev->shadow_file_exist) { if(dev->shadow_file_exist) {
if(!file_worker_open( if(!flipper_file_open_existing(file, string_get_cstr(temp_str))) break;
file_worker, string_get_cstr(temp_string), FSAM_READ, FSOM_OPEN_EXISTING)) {
break;
}
} else { } else {
if(!file_worker_open( if(!flipper_file_open_existing(file, string_get_cstr(path))) break;
file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
break;
}
} }
// Read and verify file header
// Read and parse format from 1st line uint32_t version = 0;
if(!file_worker_read_until(file_worker, temp_string, '\n')) { if(!flipper_file_read_header(file, temp_str, &version)) break;
break; if(string_cmp_str(temp_str, nfc_file_header) || (version != nfc_file_version)) {
} depricated_version = true;
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)) {
break; 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 // Parse other data
if(dev->format == NfcDeviceSaveFormatMifareUl) { if(dev->format == NfcDeviceSaveFormatMifareUl) {
// Read until EOF if(!nfc_device_load_mifare_ul_data(file, dev)) break;
if(!file_worker_read_until(file_worker, temp_string, 0x05)) {
break;
}
if(!nfc_device_parse_mifare_ul_string(dev, temp_string)) {
break;
}
} else if(dev->format == NfcDeviceSaveFormatBankCard) { } else if(dev->format == NfcDeviceSaveFormatBankCard) {
// Read until EOF if(!nfc_device_load_bank_card_data(file, dev)) break;
if(!file_worker_read_until(file_worker, temp_string, 0x05)) {
break;
}
if(!nfc_device_parse_bank_card_string(dev, temp_string)) {
break;
}
} }
parsed = true; parsed = true;
} while(0); } while(false);
if(!parsed) { 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; return parsed;
} }
@ -434,19 +347,16 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path) {
furi_assert(dev); furi_assert(dev);
furi_assert(file_path); furi_assert(file_path);
FileWorker* file_worker = file_worker_alloc(false);
// Load device data // Load device data
string_t path; string_t path;
string_init_set_str(path, file_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) { if(dev_load) {
// Set device name // Set device name
path_extract_filename_no_ext(file_path, path); path_extract_filename_no_ext(file_path, path);
nfc_device_set_name(dev, string_get_cstr(path)); nfc_device_set_name(dev, string_get_cstr(path));
} }
string_clear(path); string_clear(path);
file_worker_close(file_worker);
file_worker_free(file_worker);
return dev_load; return dev_load;
} }
@ -454,10 +364,9 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path) {
bool nfc_file_select(NfcDevice* dev) { bool nfc_file_select(NfcDevice* dev) {
furi_assert(dev); furi_assert(dev);
FileWorker* file_worker = file_worker_alloc(false);
// Input events and views are managed by file_select // Input events and views are managed by file_select
bool res = file_worker_file_select( bool res = dialog_file_select_show(
file_worker, dev->dialogs,
nfc_app_folder, nfc_app_folder,
nfc_app_extension, nfc_app_extension,
dev->file_name, dev->file_name,
@ -465,18 +374,14 @@ bool nfc_file_select(NfcDevice* dev) {
dev->dev_name); dev->dev_name);
if(res) { if(res) {
string_t dev_str; string_t dev_str;
// Get key file path // Get key file path
string_init_printf(dev_str, "%s/%s%s", nfc_app_folder, dev->file_name, nfc_app_extension); string_init_printf(dev_str, "%s/%s%s", nfc_app_folder, dev->file_name, nfc_app_extension);
res = nfc_device_load_data(dev, dev_str);
res = nfc_device_load_data(file_worker, dev_str, dev);
if(res) { if(res) {
nfc_device_set_name(dev, dev->file_name); nfc_device_set_name(dev, dev->file_name);
} }
string_clear(dev_str); string_clear(dev_str);
} }
file_worker_close(file_worker);
file_worker_free(file_worker);
return res; return res;
} }
@ -491,61 +396,48 @@ void nfc_device_clear(NfcDevice* dev) {
bool nfc_device_delete(NfcDevice* dev) { bool nfc_device_delete(NfcDevice* dev) {
furi_assert(dev); furi_assert(dev);
bool result = true; bool deleted = false;
FileWorker* file_worker = file_worker_alloc(false);
string_t file_path; string_t file_path;
string_init(file_path);
do { do {
// Delete original file // Delete original file
string_init_printf(file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension); 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))) { if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break;
result = false;
break;
}
// Delete shadow file if it exists // Delete shadow file if it exists
if(dev->shadow_file_exist) { if(dev->shadow_file_exist) {
string_clean(file_path);
string_printf( string_printf(
file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension); 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))) { if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break;
result = false;
break;
}
} }
deleted = true;
} while(0); } while(0);
if(!deleted) {
dialog_message_show_storage_error(dev->dialogs, "Can not remove file");
}
string_clear(file_path); string_clear(file_path);
file_worker_close(file_worker); return deleted;
file_worker_free(file_worker);
return result;
} }
bool nfc_device_restore(NfcDevice* dev) { bool nfc_device_restore(NfcDevice* dev) {
furi_assert(dev); furi_assert(dev);
furi_assert(dev->shadow_file_exist); furi_assert(dev->shadow_file_exist);
bool result = true; bool restored = false;
FileWorker* file_worker = file_worker_alloc(false);
string_t path; string_t path;
do { do {
string_init_printf( string_init_printf(
path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension); path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension);
if(!file_worker_remove(file_worker, string_get_cstr(path))) { if(!storage_simply_remove(dev->storage, string_get_cstr(path))) break;
result = false;
break;
}
dev->shadow_file_exist = false; dev->shadow_file_exist = false;
string_clean(path);
string_printf(path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension); string_printf(path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension);
if(!nfc_device_load_data(file_worker, path, dev)) { if(!nfc_device_load_data(dev, path)) break;
result = false; restored = true;
break;
}
} while(0); } while(0);
string_clear(path); string_clear(path);
file_worker_close(file_worker); return restored;
file_worker_free(file_worker);
return result;
} }

View File

@ -2,6 +2,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <storage/storage.h>
#include <dialogs/dialogs.h>
#include "mifare_ultralight.h" #include "mifare_ultralight.h"
@ -57,6 +59,8 @@ typedef struct {
} NfcDeviceData; } NfcDeviceData;
typedef struct { typedef struct {
Storage* storage;
DialogsApp* dialogs;
NfcDeviceData dev_data; NfcDeviceData dev_data;
char dev_name[NFC_DEV_NAME_MAX_LEN + 1]; char dev_name[NFC_DEV_NAME_MAX_LEN + 1];
char file_name[NFC_FILE_NAME_MAX_LEN]; char file_name[NFC_FILE_NAME_MAX_LEN];
@ -64,6 +68,10 @@ typedef struct {
bool shadow_file_exist; bool shadow_file_exist;
} NfcDevice; } NfcDevice;
NfcDevice* nfc_device_alloc();
void nfc_device_free(NfcDevice* nfc_dev);
void nfc_device_set_name(NfcDevice* dev, const char* name); void nfc_device_set_name(NfcDevice* dev, const char* name);
bool nfc_device_save(NfcDevice* dev, const char* dev_name); bool nfc_device_save(NfcDevice* dev, const char* dev_name);

View File

@ -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);

View File

@ -36,7 +36,7 @@ struct Nfc {
Gui* gui; Gui* gui;
NotificationApp* notifications; NotificationApp* notifications;
SceneManager* scene_manager; SceneManager* scene_manager;
NfcDevice dev; NfcDevice* dev;
NfcDeviceCommonData dev_edit_data; NfcDeviceCommonData dev_edit_data;
char text_store[NFC_TEXT_STORE_SIZE + 1]; char text_store[NFC_TEXT_STORE_SIZE + 1];

View File

@ -248,6 +248,8 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) {
NFC_WORKER_TAG, "Select PPSE response received. Start parsing response"); NFC_WORKER_TAG, "Select PPSE response received. Start parsing response");
if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) { if(emv_decode_ppse_response(rx_buff, *rx_len, &emv_app)) {
FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced"); 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 { } else {
FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application"); FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application");
furi_hal_nfc_deactivate(); furi_hal_nfc_deactivate();

View File

@ -17,7 +17,7 @@ void nfc_scene_card_menu_on_enter(void* context) {
Nfc* nfc = (Nfc*)context; Nfc* nfc = (Nfc*)context;
Submenu* submenu = nfc->submenu; 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_add_item(
submenu, submenu,
"Run compatible app", "Run compatible app",
@ -48,9 +48,9 @@ bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
if(event.event == SubmenuIndexRunApp) { if(event.event == SubmenuIndexRunApp) {
scene_manager_set_scene_state( scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneCardMenu, SubmenuIndexRunApp); 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); 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); scene_manager_next_scene(nfc->scene_manager, NfcSceneReadEmvApp);
} }
return true; return true;
@ -66,7 +66,7 @@ bool nfc_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
return true; return true;
} else if(event.event == SubmenuIndexSave) { } else if(event.event == SubmenuIndexSave) {
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneCardMenu, 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); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true; return true;
} }

View File

@ -12,14 +12,14 @@ void nfc_scene_delete_on_enter(void* context) {
// Setup Custom Widget view // Setup Custom Widget view
char delete_str[64]; 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_text_box_element(nfc->widget, 0, 0, 128, 24, AlignCenter, AlignCenter, delete_str);
widget_add_button_element( widget_add_button_element(
nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_delete_widget_callback, nfc); nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_delete_widget_callback, nfc);
widget_add_button_element( widget_add_button_element(
nfc->widget, GuiButtonTypeRight, "Delete", nfc_scene_delete_widget_callback, nfc); nfc->widget, GuiButtonTypeRight, "Delete", nfc_scene_delete_widget_callback, nfc);
char uid_str[32]; 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) { if(data->uid_len == 4) {
snprintf( snprintf(
uid_str, uid_str,
@ -73,7 +73,7 @@ bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) {
if(event.event == GuiButtonTypeLeft) { if(event.event == GuiButtonTypeLeft) {
return scene_manager_previous_scene(nfc->scene_manager); return scene_manager_previous_scene(nfc->scene_manager);
} else if(event.event == GuiButtonTypeRight) { } 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); scene_manager_next_scene(nfc->scene_manager, NfcSceneDeleteSuccess);
} else { } else {
scene_manager_search_and_switch_to_previous_scene( scene_manager_search_and_switch_to_previous_scene(

View File

@ -1,4 +1,5 @@
#include "../nfc_i.h" #include "../nfc_i.h"
#include "../helpers/nfc_emv_parser.h"
#define NFC_SCENE_DEVICE_INFO_BACK_EVENT (0UL) #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 // Setup Custom Widget view
widget_add_text_box_element( 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( widget_add_button_element(
nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_device_info_widget_callback, nfc); nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_device_info_widget_callback, nfc);
widget_add_button_element( widget_add_button_element(
nfc->widget, GuiButtonTypeRight, "Data", nfc_scene_device_info_widget_callback, nfc); nfc->widget, GuiButtonTypeRight, "Data", nfc_scene_device_info_widget_callback, nfc);
char uid_str[32]; 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) { if(data->uid_len == 4) {
snprintf( snprintf(
uid_str, 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); widget_add_string_element(nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, atqa_str);
// Setup Data View // Setup Data View
if(nfc->dev.format == NfcDeviceSaveFormatUid) { if(nfc->dev->format == NfcDeviceSaveFormatUid) {
DialogEx* dialog_ex = nfc->dialog_ex; DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Back"); dialog_ex_set_left_button_text(dialog_ex, "Back");
dialog_ex_set_text(dialog_ex, "No data", 64, 32, AlignCenter, AlignCenter); dialog_ex_set_text(dialog_ex, "No data", 64, 32, AlignCenter, AlignCenter);
dialog_ex_set_context(dialog_ex, nfc); dialog_ex_set_context(dialog_ex, nfc);
dialog_ex_set_result_callback(dialog_ex, nfc_scene_device_info_dialog_callback); dialog_ex_set_result_callback(dialog_ex, nfc_scene_device_info_dialog_callback);
} else if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
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; TextBox* text_box = nfc->text_box;
text_box_set_context(text_box, nfc); text_box_set_context(text_box, nfc);
text_box_set_exit_callback(text_box, nfc_scene_device_info_text_box_callback); 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]); 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)); text_box_set_text(text_box, string_get_cstr(nfc->text_box_store));
} else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) { } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
NfcEmvData* emv_data = &nfc->dev.dev_data.emv_data; NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data;
BankCard* bank_card = nfc->bank_card; BankCard* bank_card = nfc->bank_card;
bank_card_set_name(bank_card, emv_data->name); bank_card_set_name(bank_card, emv_data->name);
bank_card_set_number(bank_card, emv_data->number, emv_data->number_len); 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) { if(emv_data->exp_mon) {
bank_card_set_exp_date(bank_card, emv_data->exp_mon, emv_data->exp_year); 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) { 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) { 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); scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); 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)) { if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeLeft)) {
consumed = scene_manager_previous_scene(nfc->scene_manager); consumed = scene_manager_previous_scene(nfc->scene_manager);
} else if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeRight)) { } else if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeRight)) {
if(nfc->dev.format == NfcDeviceSaveFormatUid) { if(nfc->dev->format == NfcDeviceSaveFormatUid) {
scene_manager_set_scene_state( scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData); nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
consumed = true; consumed = true;
} else if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
scene_manager_set_scene_state( scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData); nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
consumed = true; consumed = true;
} else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) { } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
scene_manager_set_scene_state( scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData); nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewBankCard); 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 // Clear Custom Widget
widget_clear(nfc->widget); widget_clear(nfc->widget);
if(nfc->dev.format == NfcDeviceSaveFormatUid) { if(nfc->dev->format == NfcDeviceSaveFormatUid) {
// Clear Dialog // Clear Dialog
DialogEx* dialog_ex = nfc->dialog_ex; DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); 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_center_button_text(dialog_ex, NULL);
dialog_ex_set_result_callback(dialog_ex, NULL); dialog_ex_set_result_callback(dialog_ex, NULL);
dialog_ex_set_context(dialog_ex, NULL); dialog_ex_set_context(dialog_ex, NULL);
} else if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
// Clear TextBox // Clear TextBox
text_box_clean(nfc->text_box); text_box_clean(nfc->text_box);
string_clean(nfc->text_box_store); string_clean(nfc->text_box_store);
} else if(nfc->dev.format == NfcDeviceSaveFormatBankCard) { } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
// Clear Bank Card // Clear Bank Card
bank_card_clear(nfc->bank_card); bank_card_clear(nfc->bank_card);
} }

View File

@ -11,7 +11,7 @@ void nfc_scene_emulate_apdu_sequence_on_enter(void* context) {
// Setup and start worker // Setup and start worker
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); 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) { bool nfc_scene_emulate_apdu_sequence_on_event(void* context, SceneManagerEvent event) {

View File

@ -14,8 +14,8 @@ void nfc_scene_emulate_mifare_ul_on_enter(void* context) {
// Setup view // Setup view
Popup* popup = nfc->popup; Popup* popup = nfc->popup;
if(strcmp(nfc->dev.dev_name, "")) { if(strcmp(nfc->dev->dev_name, "")) {
nfc_text_store_set(nfc, "%s", 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_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
popup_set_header(popup, "Emulating\nMf Ultralight", 56, 31, AlignLeft, AlignTop); 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_start(
nfc->worker, nfc->worker,
NfcWorkerStateEmulateMifareUl, NfcWorkerStateEmulateMifareUl,
&nfc->dev.dev_data, &nfc->dev->dev_data,
nfc_emulate_mifare_ul_worker_callback, nfc_emulate_mifare_ul_worker_callback,
nfc); nfc);
} }
@ -45,7 +45,7 @@ bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event
NFC_MF_UL_DATA_CHANGED) { NFC_MF_UL_DATA_CHANGED) {
scene_manager_set_scene_state( scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_UL_DATA_NOT_CHANGED); 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; consumed = false;
} }

View File

@ -5,10 +5,10 @@ void nfc_scene_emulate_uid_on_enter(void* context) {
// Setup view // Setup view
Popup* popup = nfc->popup; 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, "")) { if(strcmp(nfc->dev->dev_name, "")) {
nfc_text_store_set(nfc, "%s", nfc->dev.dev_name); nfc_text_store_set(nfc, "%s", nfc->dev->dev_name);
} else if(data->uid_len == 4) { } else if(data->uid_len == 4) {
nfc_text_store_set( nfc_text_store_set(
nfc, "%02X %02X %02X %02X", data->uid[0], data->uid[1], data->uid[2], data->uid[3]); 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 // Setup and start worker
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); 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) { bool nfc_scene_emulate_uid_on_event(void* context, SceneManagerEvent event) {

View File

@ -3,7 +3,7 @@
void nfc_scene_file_select_on_enter(void* context) { void nfc_scene_file_select_on_enter(void* context) {
Nfc* nfc = (Nfc*)context; Nfc* nfc = (Nfc*)context;
// Process file_select return // Process file_select return
if(nfc_file_select(&nfc->dev)) { if(nfc_file_select(nfc->dev)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu); scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu);
} else { } else {
scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart); scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart);

View File

@ -32,9 +32,9 @@ bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent event) {
if(event.event == SubmenuIndexSave) { if(event.event == SubmenuIndexSave) {
scene_manager_set_scene_state( scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexSave); nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexSave);
nfc->dev.format = NfcDeviceSaveFormatMifareUl; nfc->dev->format = NfcDeviceSaveFormatMifareUl;
// Clear device name // Clear device name
nfc_device_set_name(&nfc->dev, ""); nfc_device_set_name(nfc->dev, "");
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true; return true;
} else if(event.event == SubmenuIndexEmulate) { } else if(event.event == SubmenuIndexEmulate) {

View File

@ -18,7 +18,7 @@ void nfc_scene_read_card_on_enter(void* context) {
// Start worker // Start worker
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
nfc_worker_start( 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) { bool nfc_scene_read_card_on_event(void* context, SceneManagerEvent event) {

View File

@ -15,7 +15,7 @@ void nfc_scene_read_card_success_on_enter(void* context) {
notification_message(nfc->notifications, &sequence_success); notification_message(nfc->notifications, &sequence_success);
// Setup view // 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; DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_left_button_text(dialog_ex, "Retry");
dialog_ex_set_right_button_text(dialog_ex, "More"); 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); return scene_manager_previous_scene(nfc->scene_manager);
} else if(event.event == DialogExResultRight) { } else if(event.event == DialogExResultRight) {
// Clear device name // Clear device name
nfc_device_set_name(&nfc->dev, ""); nfc_device_set_name(nfc->dev, "");
scene_manager_next_scene(nfc->scene_manager, NfcSceneCardMenu); scene_manager_next_scene(nfc->scene_manager, NfcSceneCardMenu);
return true; return true;
} }

View File

@ -20,7 +20,7 @@ void nfc_scene_read_emv_app_on_enter(void* context) {
nfc_worker_start( nfc_worker_start(
nfc->worker, nfc->worker,
NfcWorkerStateReadEMVApp, NfcWorkerStateReadEMVApp,
&nfc->dev.dev_data, &nfc->dev->dev_data,
nfc_read_emv_app_worker_callback, nfc_read_emv_app_worker_callback,
nfc); nfc);
} }

View File

@ -13,8 +13,8 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context; Nfc* nfc = (Nfc*)context;
// Setup view // Setup view
NfcDeviceCommonData* nfc_data = &nfc->dev.dev_data.nfc_data; NfcDeviceCommonData* nfc_data = &nfc->dev->dev_data.nfc_data;
NfcEmvData* emv_data = &nfc->dev.dev_data.emv_data; NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data;
DialogEx* dialog_ex = nfc->dialog_ex; DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_left_button_text(dialog_ex, "Retry");
dialog_ex_set_right_button_text(dialog_ex, "Run app"); 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 // Display UID and AID
string_t aid; string_t aid;
string_init(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) { if(!aid_found) {
for(uint8_t i = 0; i < emv_data->aid_len; i++) { for(uint8_t i = 0; i < emv_data->aid_len; i++) {
string_cat_printf(aid, "%02X", emv_data->aid[i]); string_cat_printf(aid, "%02X", emv_data->aid[i]);

View File

@ -17,12 +17,12 @@ void nfc_scene_read_emv_data_on_enter(void* context) {
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
// Clear emv data // 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 // Start worker
nfc_worker_start( nfc_worker_start(
nfc->worker, nfc->worker,
NfcWorkerStateReadEMV, NfcWorkerStateReadEMV,
&nfc->dev.dev_data, &nfc->dev->dev_data,
nfc_read_emv_data_worker_callback, nfc_read_emv_data_worker_callback,
nfc); nfc);
} }

View File

@ -13,8 +13,8 @@ void nfc_scene_read_emv_data_success_widget_callback(
void nfc_scene_read_emv_data_success_on_enter(void* context) { void nfc_scene_read_emv_data_success_on_enter(void* context) {
Nfc* nfc = (Nfc*)context; Nfc* nfc = (Nfc*)context;
NfcEmvData* emv_data = &nfc->dev.dev_data.emv_data; NfcEmvData* emv_data = &nfc->dev->dev_data.emv_data;
NfcDeviceCommonData* nfc_data = &nfc->dev.dev_data.nfc_data; NfcDeviceCommonData* nfc_data = &nfc->dev->dev_data.nfc_data;
// Setup Custom Widget view // Setup Custom Widget view
// Add frame // Add frame
@ -34,7 +34,7 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) {
nfc); nfc);
// Add card name // Add card name
widget_add_string_element( 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 // Add cad number
string_t pan_str; string_t pan_str;
string_init(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_t country_name;
string_init(country_name); string_init(country_name);
if((emv_data->country_code) && 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_t disp_country;
string_init_printf(disp_country, "Reg:%s", country_name); string_init_printf(disp_country, "Reg:%s", country_name);
widget_add_string_element( widget_add_string_element(
@ -61,7 +61,8 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) {
string_t currency_name; string_t currency_name;
string_init(currency_name); string_init(currency_name);
if((emv_data->currency_code) && 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_t disp_currency;
string_init_printf(disp_currency, "Cur:%s", currency_name); string_init_printf(disp_currency, "Cur:%s", currency_name);
widget_add_string_element( 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); nfc->scene_manager, NfcSceneReadEmvAppSuccess);
} else if(event.event == GuiButtonTypeRight) { } else if(event.event == GuiButtonTypeRight) {
// Clear device name // Clear device name
nfc_device_set_name(&nfc->dev, ""); nfc_device_set_name(nfc->dev, "");
nfc->dev.format = NfcDeviceSaveFormatBankCard; nfc->dev->format = NfcDeviceSaveFormatBankCard;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
return true; return true;
} }

View File

@ -20,7 +20,7 @@ void nfc_scene_read_mifare_ul_on_enter(void* context) {
nfc_worker_start( nfc_worker_start(
nfc->worker, nfc->worker,
NfcWorkerStateReadMifareUl, NfcWorkerStateReadMifareUl,
&nfc->dev.dev_data, &nfc->dev->dev_data,
nfc_read_mifare_ul_worker_callback, nfc_read_mifare_ul_worker_callback,
nfc); nfc);
} }

View File

@ -27,7 +27,7 @@ void nfc_scene_read_mifare_ul_success_on_enter(void* context) {
notification_message(nfc->notifications, &sequence_success); notification_message(nfc->notifications, &sequence_success);
// Setup dialog view // 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; DialogEx* dialog_ex = nfc->dialog_ex;
dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_left_button_text(dialog_ex, "Retry");
dialog_ex_set_right_button_text(dialog_ex, "More"); 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); dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_mifare_ul_success_dialog_callback);
// Setup TextBox view // 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; TextBox* text_box = nfc->text_box;
text_box_set_context(text_box, nfc); text_box_set_context(text_box, nfc);
text_box_set_exit_callback(text_box, nfc_scene_read_mifare_ul_success_text_box_callback); text_box_set_exit_callback(text_box, nfc_scene_read_mifare_ul_success_text_box_callback);

View File

@ -15,11 +15,11 @@ void nfc_scene_save_name_on_enter(void* context) {
// Setup view // Setup view
TextInput* text_input = nfc->text_input; TextInput* text_input = nfc->text_input;
bool dev_name_empty = false; 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)); set_random_name(nfc->text_store, sizeof(nfc->text_store));
dev_name_empty = true; dev_name_empty = true;
} else { } 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_header_text(text_input, "Name the card");
text_input_set_result_callback( 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.type == SceneManagerEventTypeCustom) {
if(event.event == SCENE_SAVE_NAME_CUSTOM_EVENT) { if(event.event == SCENE_SAVE_NAME_CUSTOM_EVENT) {
if(strcmp(nfc->dev.dev_name, "")) { if(strcmp(nfc->dev->dev_name, "")) {
nfc_device_delete(&nfc->dev); nfc_device_delete(nfc->dev);
} }
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetUid)) { 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); strlcpy(nfc->dev->dev_name, nfc->text_store, strlen(nfc->text_store) + 1);
if(nfc_device_save(&nfc->dev, nfc->text_store)) { if(nfc_device_save(nfc->dev, nfc->text_store)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess);
return true; return true;
} else { } else {

View File

@ -18,7 +18,7 @@ void nfc_scene_saved_menu_on_enter(void* context) {
Nfc* nfc = (Nfc*)context; Nfc* nfc = (Nfc*)context;
Submenu* submenu = nfc->submenu; Submenu* submenu = nfc->submenu;
if(nfc->dev.format != NfcDeviceSaveFormatBankCard) { if(nfc->dev->format != NfcDeviceSaveFormatBankCard) {
submenu_add_item( submenu_add_item(
submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc); 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, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc);
submenu_set_selected_item( submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSavedMenu)); 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_add_item(
submenu, submenu,
"Restore original", "Restore original",
@ -49,7 +49,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, event.event); scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, event.event);
if(event.event == SubmenuIndexEmulate) { if(event.event == SubmenuIndexEmulate) {
if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) { if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl); scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl);
} else { } else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); 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); scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
consumed = true; consumed = true;
} else if(event.event == SubmenuIndexRestoreOriginal) { } 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( scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneStart); nfc->scene_manager, NfcSceneStart);
} else { } else {

View File

@ -19,7 +19,7 @@ void nfc_scene_set_atqa_on_enter(void* context) {
nfc_scene_set_atqa_byte_input_callback, nfc_scene_set_atqa_byte_input_callback,
NULL, NULL,
nfc, nfc,
nfc->dev.dev_data.nfc_data.atqa, nfc->dev->dev_data.nfc_data.atqa,
2); 2);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput);
} }

View File

@ -19,7 +19,7 @@ void nfc_scene_set_sak_on_enter(void* context) {
nfc_scene_set_sak_byte_input_callback, nfc_scene_set_sak_byte_input_callback,
NULL, NULL,
nfc, nfc,
&nfc->dev.dev_data.nfc_data.sak, &nfc->dev->dev_data.nfc_data.sak,
1); 1);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewByteInput);
} }

View File

@ -15,7 +15,7 @@ void nfc_scene_set_type_on_enter(void* context) {
Nfc* nfc = (Nfc*)context; Nfc* nfc = (Nfc*)context;
Submenu* submenu = nfc->submenu; Submenu* submenu = nfc->submenu;
// Clear device name // Clear device name
nfc_device_set_name(&nfc->dev, ""); nfc_device_set_name(nfc->dev, "");
submenu_add_item( submenu_add_item(
submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc); submenu, "NFC-A 7-bytes UID", SubmenuIndexNFCA7, nfc_scene_set_type_submenu_callback, nfc);
submenu_add_item( submenu_add_item(
@ -28,13 +28,13 @@ bool nfc_scene_set_type_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexNFCA7) { if(event.event == SubmenuIndexNFCA7) {
nfc->dev.dev_data.nfc_data.uid_len = 7; nfc->dev->dev_data.nfc_data.uid_len = 7;
nfc->dev.format = NfcDeviceSaveFormatUid; nfc->dev->format = NfcDeviceSaveFormatUid;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak); scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak);
return true; return true;
} else if(event.event == SubmenuIndexNFCA4) { } else if(event.event == SubmenuIndexNFCA4) {
nfc->dev.dev_data.nfc_data.uid_len = 4; nfc->dev->dev_data.nfc_data.uid_len = 4;
nfc->dev.format = NfcDeviceSaveFormatUid; nfc->dev->format = NfcDeviceSaveFormatUid;
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak); scene_manager_next_scene(nfc->scene_manager, NfcSceneSetSak);
return true; return true;
} }

View File

@ -14,7 +14,7 @@ void nfc_scene_set_uid_on_enter(void* context) {
// Setup view // Setup view
ByteInput* byte_input = nfc->byte_input; ByteInput* byte_input = nfc->byte_input;
byte_input_set_header_text(byte_input, "Enter uid in hex"); 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_set_result_callback(
byte_input, byte_input,
nfc_scene_set_uid_byte_input_callback, nfc_scene_set_uid_byte_input_callback,

View File

@ -34,7 +34,7 @@ void nfc_scene_start_on_enter(void* context) {
submenu_set_selected_item( submenu_set_selected_item(
submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneStart)); 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); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
} }

View File

@ -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); 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); furi_assert(bank_card);
string_t country_name; widget_add_string_element(
string_init(country_name); bank_card->widget, 120, 18, AlignRight, AlignTop, FontSecondary, country_name);
if(nfc_emv_parser_get_country_name(country_code, country_name)) {
string_t disp_country;
string_init_printf(disp_country, "Reg:%s", country_name);
widget_add_string_element(
bank_card->widget,
120,
18,
AlignRight,
AlignTop,
FontSecondary,
string_get_cstr(disp_country));
string_clear(disp_country);
}
string_clear(country_name);
} }
void bank_card_set_currency_name(BankCard* bank_card, uint16_t currency_code) { void bank_card_set_currency_name(BankCard* bank_card, const char* currency_name) {
furi_assert(bank_card); furi_assert(bank_card);
string_t currency_name; widget_add_string_element(
string_init(currency_name); bank_card->widget, 31, 18, AlignLeft, AlignTop, FontSecondary, 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);
} }

View File

@ -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_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);

View File

@ -1,148 +1,151 @@
A00000000305076010 VISA ELO Credit Filetype: Flipper EMV resources
A0000000031010 VISA Debit/Credit (Classic) Version: 1
A000000003101001 VISA Credit # EMV Application ID code: Application ID name
A000000003101002 VISA Debit A00000000305076010: VISA ELO Credit
A0000000032010 VISA Electron A0000000031010: VISA Debit/Credit (Classic)
A0000000032020 VISA A000000003101001: VISA Credit
A0000000033010 VISA Interlink A000000003101002: VISA Debit
A0000000034010 VISA Specific A0000000032010: VISA Electron
A0000000035010 VISA Specific A0000000032020: VISA
A0000000036010 Domestic Visa Cash A0000000033010: VISA Interlink
A0000000036020 International Visa Cash A0000000034010: VISA Specific
A0000000038002 VISA Auth EMV-CAP (DPA) A0000000035010: VISA Specific
A0000000038010 VISA Plus A0000000036010: Domestic Visa Cash
A0000000039010 VISA Loyalty A0000000036020: International Visa Cash
A000000003999910 VISA Proprietary ATM A0000000038002: VISA Auth EMV-CAP (DPA)
A00000000401 MasterCard PayPass A0000000038010: VISA Plus
A0000000041010 MasterCard Global A0000000039010: VISA Loyalty
A00000000410101213 MasterCard Credit A000000003999910: VISA Proprietary ATM
A00000000410101215 MasterCard Credit A00000000401: MasterCard PayPass
A0000000042010 MasterCard Specific A0000000041010: MasterCard Global
A0000000043010 MasterCard Specific A00000000410101213: MasterCard Credit
A0000000043060 Maestro (Debit) A00000000410101215: MasterCard Credit
A000000004306001 Maestro (Debit) A0000000042010: MasterCard Specific
A0000000044010 MasterCard Specific A0000000043010: MasterCard Specific
A0000000045010 MasterCard Specific A0000000043060: Maestro (Debit)
A0000000046000 Cirrus A000000004306001: Maestro (Debit)
A0000000048002 SecureCode EMV-CAP A0000000044010: MasterCard Specific
A0000000049999 MasterCard PayPass A0000000045010: MasterCard Specific
A0000000050001 Maestro UK A0000000046000: Cirrus
A0000000050002 Solo A0000000048002: SecureCode EMV-CAP
A00000002401 Self Service A0000000049999: MasterCard PayPass
A000000025 American Express A0000000050001: Maestro UK
A0000000250000 American Express A0000000050002: Solo
A00000002501 American Express A00000002401: Self Service
A000000025010402 American Express A000000025: American Express
A000000025010701 ExpressPay A0000000250000: American Express
A000000025010801 American Express A00000002501: American Express
A0000000291010 Link / American Express A000000025010402: American Express
A0000000421010 Cartes Bancaire EMV Card A000000025010701: ExpressPay
A0000000426010 Apple Pay A000000025010801: American Express
A00000006510 JCB A0000000291010: Link / American Express
A0000000651010 JCB J Smart Credit A0000000421010: Cartes Bancaire EMV Card
A00000006900 Moneo A0000000426010: Apple Pay
A000000077010000021000000000003B Visa AEPN A00000006510: JCB
A000000098 Debit Card A0000000651010: JCB J Smart Credit
A0000000980848 Debit Card A00000006900: Moneo
A0000001211010 Dankort VISA GEM Vision A000000077010000021000000000003B: Visa AEPN
A0000001410001 PagoBANCOMAT A000000098: Debit Card
A0000001523010 Discover, Pulse D Pas A0000000980848: Debit Card
A0000001524010 Discover A0000001211010: Dankort VISA GEM Vision
A0000001544442 Banricompras Debito A0000001410001: PagoBANCOMAT
A000000172950001 BAROC Taiwan A0000001523010: Discover, Pulse D Pas
A0000002281010 SPAN (M/Chip) A0000001524010: Discover
A0000002282010 SPAN (VIS) A0000001544442: Banricompras Debito
A0000002771010 INTERAC A000000172950001: BAROC Taiwan
A00000031510100528 Currence PuC A0000002281010: SPAN (M/Chip)
A0000003156020 Chipknip A0000002282010: SPAN (VIS)
A0000003591010028001 Girocard EAPS A0000002771010: INTERAC
A0000003710001 InterSwitch Verve Card A00000031510100528: Currence PuC
A0000004540010 Etranzact Genesis Card A0000003156020: Chipknip
A0000004540011 Etranzact Genesis Card 2 A0000003591010028001: Girocard EAPS
A0000004766C GOOGLE_PAYMENT A0000003710001: InterSwitch Verve Card
A0000005241010 RuPay A0000004540010: Etranzact Genesis Card
A0000006723010 TROY chip credit card A0000004540011: Etranzact Genesis Card 2
A0000006723020 TROY chip debit card A0000004766C: GOOGLE_PAYMENT
A0000007705850 XTRAPOWER A0000005241010: RuPay
B012345678 Maestro TEST A0000006723010: TROY chip credit card
D27600002545500100 Girocard A0000006723020: TROY chip debit card
D5780000021010 Bankaxept A0000007705850: XTRAPOWER
F0000000030001 BRADESCO B012345678: Maestro TEST
A000000003000000 (VISA) Card Manager D27600002545500100: Girocard
A000000003534441 Schlumberger SD D5780000021010: Bankaxept
A0000000035350 Security Domain F0000000030001: BRADESCO
A000000003535041 Security Domain A000000003000000: (VISA) Card Manager
A0000000040000 MasterCard Card Manager A000000003534441: Schlumberger SD
A000000018434D Gemplus card manager A0000000035350: Security Domain
A000000018434D00 Gemplus Security Domain A000000003535041: Security Domain
A0000000960200 Proton WISD A0000000040000: MasterCard Card Manager
A0000001510000 Global Platform SD A000000018434D: Gemplus card manager
A00000015153504341534400 CASD_AID A000000018434D00: Gemplus Security Domain
A000000476A010 GSD_MANAGER_AID A0000000960200: Proton WISD
A000000476A110 GSD_MANAGER_AID A0000001510000: Global Platform SD
315041592E5359532E4444463031 Visa PSE A00000015153504341534400: CASD_AID
325041592E5359532E4444463031 Visa PPSE A000000476A010: GSD_MANAGER_AID
A0000000042203 MasterCard Specific A000000476A110: GSD_MANAGER_AID
A0000000045555 APDULogger 315041592E5359532E4444463031: Visa PSE
A0000000090001FF44FF1289 Orange 325041592E5359532E4444463031: Visa PPSE
A0000000101030 Maestro-CH A0000000042203: MasterCard Specific
A00000001800 Gemplus A0000000045555: APDULogger
A0000000181001 gemplus util packages A0000000090001FF44FF1289: Orange
A000000025010104 American Express A0000000101030: Maestro-CH
A00000002949034010100001 HSBC A00000001800: Gemplus
A00000002949282010100000 Barclay A0000000181001: gemplus util packages
A00000005945430100 Girocard Electronic Cash A000000025010104: American Express
A0000000980840 Visa Common Debit A00000002949034010100001: HSBC
A0000001570010 AMEX A00000002949282010100000: Barclay
A0000001570020 MasterCard A00000005945430100: Girocard Electronic Cash
A0000001570021 Maestro A0000000980840: Visa Common Debit
A0000001570022 Maestro A0000001570010: AMEX
A0000001570023 CASH A0000001570020: MasterCard
A0000001570030 VISA A0000001570021: Maestro
A0000001570031 VISA A0000001570022: Maestro
A0000001570040 JCB A0000001570023: CASH
A0000001570050 Postcard A0000001570030: VISA
A0000001570051 Postcard A0000001570031: VISA
A0000001570100 MCard A0000001570040: JCB
A0000001570104 MyOne A0000001570050: Postcard
A000000157010C WIRCard A0000001570051: Postcard
A000000157010D Power Card A0000001570100: MCard
A0000001574443 DINERS CLUB A0000001570104: MyOne
A0000001574444 Supercard Plus A000000157010C: WIRCard
A00000022820101010 SPAN A000000157010D: Power Card
A000000308000010000100 ID-ONE PIV BIO A0000001574443: DINERS CLUB
A0000003241010 Discover Zip A0000001574444: Supercard Plus
A000000333010101 UnionPay Debit A00000022820101010: SPAN
A000000333010102 UnionPay Credit A000000308000010000100: ID-ONE PIV BIO
A000000333010103 UnionPay Quasi Credit A0000003241010: Discover Zip
A000000333010106 UnionPay Electronic Cash A000000333010101: UnionPay Debit
A000000333010108 U.S. UnionPay Common Debit A000000333010102: UnionPay Credit
A000000337102000 Classic A000000333010103: UnionPay Quasi Credit
A000000337101001 Prepaye Online A000000333010106: UnionPay Electronic Cash
A000000337102001 Prepaye Possibile Offiline A000000333010108: U.S. UnionPay Common Debit
A000000337601001 Porte Monnaie Electronique A000000337102000: Classic
A0000006581010 MIR Credit A000000337101001: Prepaye Online
A0000006581011 MIR Credit A000000337102001: Prepaye Possibile Offiline
A0000006582010 MIR Debit A000000337601001: Porte Monnaie Electronique
D040000001000002 Paylife Quick IEP A0000006581010: MIR Credit
D040000002000002 RFU A0000006581011: MIR Credit
D040000003000002 POS A0000006582010: MIR Debit
D040000004000002 ATM D040000001000002: Paylife Quick IEP
D04000000B000002 Retail D040000002000002: RFU
D04000000C000002 Bank_Data D040000003000002: POS
D04000000D000002 Shopping D040000004000002: ATM
D040000013000001 DF_UNI_Kepler1 D04000000B000002: Retail
D040000013000001 DF_Schüler1 D04000000C000002: Bank_Data
D040000013000002 DF_UNI_Kepler2 D04000000D000002: Shopping
D040000013000002 DF_Schüler2 D040000013000001: DF_UNI_Kepler1
D040000014000001 DF_Mensa D040000013000001: DF_Schüler1
D040000015000001 DF_UNI_Ausweis D040000013000002: DF_UNI_Kepler2
D040000015000001 DF_Ausweis D040000013000002: DF_Schüler2
D0400000190001 EMV ATM Maestro D040000014000001: DF_Mensa
D0400000190002 EMV POS Maestro D040000015000001: DF_UNI_Ausweis
D0400000190003 EMV ATM MasterCard D040000015000001: DF_Ausweis
D0400000190004 EMV POS MasterCard D0400000190001: EMV ATM Maestro
D276000025 Girocard D0400000190002: EMV POS Maestro
D27600002547410100 Girocard ATM D0400000190003: EMV ATM MasterCard
D7560000010101 Reka Card D0400000190004: EMV POS MasterCard
D7560000300101 M Budget D276000025: Girocard
D27600002547410100: Girocard ATM
D7560000010101: Reka Card
D7560000300101: M Budget

View File

@ -1,249 +1,252 @@
0004 AFG Filetype: Flipper EMV resources
0008 ALB Version: 1
0010 ATA # EMV country code: country name
0012 DZA 0004: AFG
0016 ASM 0008: ALB
0020 AND 0010: ATA
0024 AGO 0012: DZA
0028 ATG 0016: ASM
0031 AZE 0020: AND
0032 ARG 0024: AGO
0036 AUS 0028: ATG
0040 AUT 0031: AZE
0044 BHS 0032: ARG
0048 BHR 0036: AUS
0050 BGD 0040: AUT
0051 ARM 0044: BHS
0052 BRB 0048: BHR
0056 BEL 0050: BGD
0060 BMU 0051: ARM
0064 BTN 0052: BRB
0068 BOL 0056: BEL
0070 BIH 0060: BMU
0072 BWA 0064: BTN
0074 BVT 0068: BOL
0076 BRA 0070: BIH
0084 BLZ 0072: BWA
0086 IOT 0074: BVT
0090 SLB 0076: BRA
0092 VGB 0084: BLZ
0096 BRN 0086: IOT
0100 BGR 0090: SLB
0104 MMR 0092: VGB
0108 BDI 0096: BRN
0112 BLR 0100: BGR
0116 KHM 0104: MMR
0120 CMR 0108: BDI
0124 CAN 0112: BLR
0132 CPV 0116: KHM
0136 CYM 0120: CMR
0140 CAF 0124: CAN
0144 LKA 0132: CPV
0148 TCD 0136: CYM
0152 CHL 0140: CAF
0156 CHN 0144: LKA
0158 TWN 0148: TCD
0162 CXR 0152: CHL
0166 CCK 0156: CHN
0170 COL 0158: TWN
0174 COM 0162: CXR
0175 MYT 0166: CCK
0178 COG 0170: COL
0180 COD 0174: COM
0184 COK 0175: MYT
0188 CRI 0178: COG
0191 HRV 0180: COD
0192 CUB 0184: COK
0196 CYP 0188: CRI
0203 CZE 0191: HRV
0204 BEN 0192: CUB
0208 DNK 0196: CYP
0212 DMA 0203: CZE
0214 DOM 0204: BEN
0218 ECU 0208: DNK
0222 SLV 0212: DMA
0226 GNQ 0214: DOM
0231 ETH 0218: ECU
0232 ERI 0222: SLV
0233 EST 0226: GNQ
0234 FRO 0231: ETH
0238 FLK 0232: ERI
0239 SGS 0233: EST
0242 FJI 0234: FRO
0246 FIN 0238: FLK
0248 ALA 0239: SGS
0250 FRA 0242: FJI
0254 GUF 0246: FIN
0258 PYF 0248: ALA
0260 ATF 0250: FRA
0262 DJI 0254: GUF
0266 GAB 0258: PYF
0268 GEO 0260: ATF
0270 GMB 0262: DJI
0275 PSE 0266: GAB
0276 DEU 0268: GEO
0288 GHA 0270: GMB
0292 GIB 0275: PSE
0296 KIR 0276: DEU
0300 GRC 0288: GHA
0304 GRL 0292: GIB
0308 GRD 0296: KIR
0312 GLP 0300: GRC
0316 GUM 0304: GRL
0320 GTM 0308: GRD
0324 GIN 0312: GLP
0328 GUY 0316: GUM
0332 HTI 0320: GTM
0334 HMD 0324: GIN
0336 VAT 0328: GUY
0340 HND 0332: HTI
0344 HKG 0334: HMD
0348 HUN 0336: VAT
0352 ISL 0340: HND
0356 IND 0344: HKG
0360 IDN 0348: HUN
0364 IRN 0352: ISL
0368 IRQ 0356: IND
0372 IRL 0360: IDN
0376 ISR 0364: IRN
0380 ITA 0368: IRQ
0384 CIV 0372: IRL
0388 JAM 0376: ISR
0392 JPN 0380: ITA
0398 KAZ 0384: CIV
0400 JOR 0388: JAM
0404 KEN 0392: JPN
0408 PRK 0398: KAZ
0410 KOR 0400: JOR
0414 KWT 0404: KEN
0417 KGZ 0408: PRK
0418 LAO 0410: KOR
0422 LBN 0414: KWT
0426 LSO 0417: KGZ
0428 LVA 0418: LAO
0430 LBR 0422: LBN
0434 LBY 0426: LSO
0438 LIE 0428: LVA
0440 LTU 0430: LBR
0442 LUX 0434: LBY
0446 MAC 0438: LIE
0450 MDG 0440: LTU
0454 MWI 0442: LUX
0458 MYS 0446: MAC
0462 MDV 0450: MDG
0466 MLI 0454: MWI
0470 MLT 0458: MYS
0474 MTQ 0462: MDV
0478 MRT 0466: MLI
0480 MUS 0470: MLT
0484 MEX 0474: MTQ
0492 MCO 0478: MRT
0496 MNG 0480: MUS
0498 MDA 0484: MEX
0499 MNE 0492: MCO
0500 MSR 0496: MNG
0504 MAR 0498: MDA
0508 MOZ 0499: MNE
0512 OMN 0500: MSR
0516 NAM 0504: MAR
0520 NRU 0508: MOZ
0524 NPL 0512: OMN
0528 NLD 0516: NAM
0531 CUW 0520: NRU
0533 ABW 0524: NPL
0534 SXM 0528: NLD
0535 BES 0531: CUW
0540 NCL 0533: ABW
0548 VUT 0534: SXM
0554 NZL 0535: BES
0558 NIC 0540: NCL
0562 NER 0548: VUT
0566 NGA 0554: NZL
0570 NIU 0558: NIC
0574 NFK 0562: NER
0578 NOR 0566: NGA
0580 MNP 0570: NIU
0581 UMI 0574: NFK
0583 FSM 0578: NOR
0584 MHL 0580: MNP
0585 PLW 0581: UMI
0586 PAK 0583: FSM
0591 PAN 0584: MHL
0598 PNG 0585: PLW
0600 PRY 0586: PAK
0604 PER 0591: PAN
0608 PHL 0598: PNG
0612 PCN 0600: PRY
0616 POL 0604: PER
0620 PRT 0608: PHL
0624 GNB 0612: PCN
0626 TLS 0616: POL
0630 PRI 0620: PRT
0634 QAT 0624: GNB
0638 REU 0626: TLS
0642 ROU 0630: PRI
0643 RUS 0634: QAT
0646 RWA 0638: REU
0652 BLM 0642: ROU
0654 SHN 0643: RUS
0659 KNA 0646: RWA
0660 AIA 0652: BLM
0662 LCA 0654: SHN
0663 MAF 0659: KNA
0666 SPM 0660: AIA
0670 VCT 0662: LCA
0674 SMR 0663: MAF
0678 STP 0666: SPM
0682 SAU 0670: VCT
0686 SEN 0674: SMR
0688 SRB 0678: STP
0690 SYC 0682: SAU
0694 SLE 0686: SEN
0702 SGP 0688: SRB
0703 SVK 0690: SYC
0704 VNM 0694: SLE
0705 SVN 0702: SGP
0706 SOM 0703: SVK
0710 ZAF 0704: VNM
0716 ZWE 0705: SVN
0724 ESP 0706: SOM
0728 SSD 0710: ZAF
0729 SDN 0716: ZWE
0732 ESH 0724: ESP
0740 SUR 0728: SSD
0744 SJM 0729: SDN
0748 SWZ 0732: ESH
0752 SWE 0740: SUR
0756 CHE 0744: SJM
0760 SYR 0748: SWZ
0762 TJK 0752: SWE
0764 THA 0756: CHE
0768 TGO 0760: SYR
0772 TKL 0762: TJK
0776 TON 0764: THA
0780 TTO 0768: TGO
0784 ARE 0772: TKL
0788 TUN 0776: TON
0792 TUR 0780: TTO
0795 TKM 0784: ARE
0796 TCA 0788: TUN
0798 TUV 0792: TUR
0800 UGA 0795: TKM
0804 UKR 0796: TCA
0807 MKD 0798: TUV
0818 EGY 0800: UGA
0826 GBR 0804: UKR
0831 GGY 0807: MKD
0832 JEY 0818: EGY
0833 IMN 0826: GBR
0834 TZA 0831: GGY
0840 USA 0832: JEY
0850 VIR 0833: IMN
0854 BFA 0834: TZA
0858 URY 0840: USA
0860 UZB 0850: VIR
0862 VEN 0854: BFA
0876 WLF 0858: URY
0882 WSM 0860: UZB
0887 YEM 0862: VEN
0894 ZMB 0876: WLF
0882: WSM
0887: YEM
0894: ZMB

View File

@ -1,168 +1,171 @@
0997 USN Filetype: Flipper EMV resources
0994 XSU Version: 1
0990 CLF # EMV currency code: currency name
0986 BRL 0997: USN
0985 PLN 0994: XSU
0984 BOV 0990: CLF
0981 GEL 0986: BRL
0980 UAH 0985: PLN
0979 MXV 0984: BOV
0978 EUR 0981: GEL
0977 BAM 0980: UAH
0976 CDF 0979: MXV
0975 BGN 0978: EUR
0973 AOA 0977: BAM
0972 TJS 0976: CDF
0971 AFN 0975: BGN
0970 COU 0973: AOA
0969 MGA 0972: TJS
0968 SRD 0971: AFN
0967 ZMW 0970: COU
0965 XUA 0969: MGA
0960 XDR 0968: SRD
0953 XPF 0967: ZMW
0952 XOF 0965: XUA
0951 XCD 0960: XDR
0950 XAF 0953: XPF
0949 TRY 0952: XOF
0948 CHW 0951: XCD
0947 CHE 0950: XAF
0946 RON 0949: TRY
0944 AZN 0948: CHW
0943 MZN 0947: CHE
0941 RSD 0946: RON
0940 UYI 0944: AZN
0938 SDG 0943: MZN
0937 VEF 0941: RSD
0936 GHS 0940: UYI
0934 TMT 0938: SDG
0933 BYN 0937: VEF
0932 ZWL 0936: GHS
0931 CUC 0934: TMT
0930 STN 0933: BYN
0929 MRU 0932: ZWL
0901 TWD 0931: CUC
0886 YER 0930: STN
0882 WST 0929: MRU
0860 UZS 0901: TWD
0858 UYU 0886: YER
0840 USD 0882: WST
0834 TZS 0860: UZS
0826 GBP 0858: UYU
0818 EGP 0840: USD
0807 MKD 0834: TZS
0800 UGX 0826: GBP
0788 TND 0818: EGP
0784 AED 0807: MKD
0780 TTD 0800: UGX
0776 TOP 0788: TND
0764 THB 0784: AED
0760 SYP 0780: TTD
0756 CHF 0776: TOP
0752 SEK 0764: THB
0748 SZL 0760: SYP
0728 SSP 0756: CHF
0710 ZAR 0752: SEK
0706 SOS 0748: SZL
0704 VND 0728: SSP
0702 SGD 0710: ZAR
0694 SLL 0706: SOS
0690 SCR 0704: VND
0682 SAR 0702: SGD
0654 SHP 0694: SLL
0646 RWF 0690: SCR
0643 RUB 0682: SAR
0634 QAR 0654: SHP
0608 PHP 0646: RWF
0604 PEN 0643: RUB
0600 PYG 0634: QAR
0598 PGK 0608: PHP
0590 PAB 0604: PEN
0586 PKR 0600: PYG
0578 NOK 0598: PGK
0566 NGN 0590: PAB
0558 NIO 0586: PKR
0554 NZD 0578: NOK
0548 VUV 0566: NGN
0533 AWG 0558: NIO
0532 ANG 0554: NZD
0524 NPR 0548: VUV
0516 NAD 0533: AWG
0512 OMR 0532: ANG
0504 MAD 0524: NPR
0498 MDL 0516: NAD
0496 MNT 0512: OMR
0484 MXN 0504: MAD
0480 MUR 0498: MDL
0462 MVR 0496: MNT
0458 MYR 0484: MXN
0454 MWK 0480: MUR
0446 MOP 0462: MVR
0434 LYD 0458: MYR
0430 LRD 0454: MWK
0426 LSL 0446: MOP
0422 LBP 0434: LYD
0418 LAK 0430: LRD
0417 KGS 0426: LSL
0414 KWD 0422: LBP
0410 KRW 0418: LAK
0408 KPW 0417: KGS
0404 KES 0414: KWD
0400 JOD 0410: KRW
0398 KZT 0408: KPW
0392 JPY 0404: KES
0388 JMD 0400: JOD
0376 ILS 0398: KZT
0368 IQD 0392: JPY
0364 IRR 0388: JMD
0360 IDR 0376: ILS
0356 INR 0368: IQD
0352 ISK 0364: IRR
0348 HUF 0360: IDR
0344 HKD 0356: INR
0340 HNL 0352: ISK
0332 HTG 0348: HUF
0328 GYD 0344: HKD
0324 GNF 0340: HNL
0320 GTQ 0332: HTG
0292 GIP 0328: GYD
0270 GMD 0324: GNF
0262 DJF 0320: GTQ
0242 FJD 0292: GIP
0238 FKP 0270: GMD
0232 ERN 0262: DJF
0230 ETB 0242: FJD
0222 SVC 0238: FKP
0214 DOP 0232: ERN
0208 DKK 0230: ETB
0203 CZK 0222: SVC
0192 CUP 0214: DOP
0191 HRK 0208: DKK
0188 CRC 0203: CZK
0174 KMF 0192: CUP
0170 COP 0191: HRK
0156 CNY 0188: CRC
0152 CLP 0174: KMF
0144 LKR 0170: COP
0136 KYD 0156: CNY
0132 CVE 0152: CLP
0124 CAD 0144: LKR
0116 KHR 0136: KYD
0108 BIF 0132: CVE
0104 MMK 0124: CAD
0096 BND 0116: KHR
0090 SBD 0108: BIF
0084 BZD 0104: MMK
0072 BWP 0096: BND
0068 BOB 0090: SBD
0064 BTN 0084: BZD
0060 BMD 0072: BWP
0052 BBD 0068: BOB
0051 AMD 0064: BTN
0050 BDT 0060: BMD
0048 BHD 0052: BBD
0044 BSD 0051: AMD
0036 AUD 0050: BDT
0032 ARS 0048: BHD
0012 DZD 0044: BSD
0008 ALL 0036: AUD
0032: ARS
0012: DZD
0008: ALL