[FL-1526] Mifare Ultralight emulation (#645)

* rfal: add discovery parameter for passing listen activation
* nfc: add discovery parameter to furi_hal_nfc_listen
* mifare_ul: add emulation parsing commands
* nfc: add mifare ul emulation
* nfc: switch to mifare ultralight emulation form menu
* furi-hal-nfc: add first frame reception in emulation mode
* nfc: change argument check
* nfc: rework nfc worker and mifare ul lib
* mifare_ul: add write and cnt increment commands
* nfc: add card modification check
* mifare_ul: add data changed flag
* nfc: add shodow files
* nfc: add restore original file

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
gornekich
2021-08-17 00:45:04 +03:00
committed by GitHub
parent e1d80d5402
commit c122317468
16 changed files with 354 additions and 69 deletions

View File

@@ -8,6 +8,7 @@
static const char* nfc_app_folder = "/any/nfc";
static const char* nfc_app_extension = ".nfc";
static const char* nfc_app_shadow_extension = ".shd";
static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len) {
string_strim(str);
@@ -259,7 +260,11 @@ void nfc_device_set_name(NfcDevice* dev, const char* name) {
strlcpy(dev->dev_name, name, NFC_DEV_NAME_MAX_LEN);
}
bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
static bool nfc_device_save_file(
NfcDevice* dev,
const char* dev_name,
const char* folder,
const char* extension) {
furi_assert(dev);
FileWorker* file_worker = file_worker_alloc(false);
@@ -275,7 +280,7 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
break;
};
// First remove nfc device file if it was saved
string_printf(dev_file_name, "%s/%s%s", nfc_app_folder, dev_name, nfc_app_extension);
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;
};
@@ -316,16 +321,42 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
return true;
}
bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
return nfc_device_save_file(dev, dev_name, nfc_app_folder, nfc_app_extension);
}
bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name) {
dev->shadow_file_exist = true;
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);
bool parsed = false;
do {
// Open key file
if(!file_worker_open(file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
// 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;
}
// 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;
}
} else {
if(!file_worker_open(
file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
break;
}
}
// Read and parse format from 1st line
if(!file_worker_read_until(file_worker, temp_string, '\n')) {
break;
@@ -427,13 +458,61 @@ void nfc_device_clear(NfcDevice* dev) {
bool nfc_device_delete(NfcDevice* dev) {
furi_assert(dev);
bool result = false;
bool result = true;
FileWorker* file_worker = file_worker_alloc(false);
string_t file_path;
string_init_printf(file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension);
result = file_worker_remove(file_worker, string_get_cstr(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;
}
// 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;
}
}
} while(0);
string_clear(file_path);
file_worker_close(file_worker);
file_worker_free(file_worker);
return result;
}
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);
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;
}
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;
}
} while(0);
string_clear(path);
file_worker_close(file_worker);
file_worker_free(file_worker);
return result;
}