mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-29 06:24:45 -07:00
NFC: add Slix capabilities (#3652)
* iso15693 listener: fix inventory cmd and buffer overflow * iso15 listener: fix read multiple blocks command * slix: print password * slix: add capabilities field * slix listener: skip password validation for special capability * slix: fix capability name * slix: add capabilities handler to verify and reset * nfc test: introduce slix tests * fbt: change toolchain back to 33 version * slix: fix saving capablities comment * unit tests: add slix files to resources * slix: fix set passwrd signature * nfc tests: add set correct password test * nfc test: complete slix password tests * nfc test: add slix file test * nfc test: handle errors in worker callback * iso15693_3: code clean up * iso15693_listener: fix incorrect afi handling * slix: chage capabilities format to one word camel case * unit tests: update nfc files with new slix format Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#define SLIX_TYPE_INDICATOR_SLIX (0x02U)
|
||||
#define SLIX_TYPE_INDICATOR_SLIX2 (0x01U)
|
||||
|
||||
#define SLIX_CAPABILITIES_KEY "Capabilities"
|
||||
#define SLIX_PASSWORD_READ_KEY "Password Read"
|
||||
#define SLIX_PASSWORD_WRITE_KEY "Password Write"
|
||||
#define SLIX_PASSWORD_PRIVACY_KEY "Password Privacy"
|
||||
@@ -69,6 +70,11 @@ static const SlixTypeFeatures slix_type_features[] = {
|
||||
[SlixTypeSlix2] = SLIX_TYPE_FEATURES_SLIX2,
|
||||
};
|
||||
|
||||
static const char* slix_capabilities_names[SlixCapabilitiesCount] = {
|
||||
[SlixCapabilitiesDefault] = "Default",
|
||||
[SlixCapabilitiesAcceptAllPasswords] = "AcceptAllPasswords",
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char* key;
|
||||
SlixTypeFeatures feature_flag;
|
||||
@@ -110,6 +116,7 @@ void slix_reset(SlixData* data) {
|
||||
furi_check(data);
|
||||
|
||||
iso15693_3_reset(data->iso15693_3_data);
|
||||
data->capabilities = SlixCapabilitiesDefault;
|
||||
slix_password_set_defaults(data->passwords);
|
||||
|
||||
memset(&data->system_info, 0, sizeof(SlixSystemInfo));
|
||||
@@ -123,6 +130,7 @@ void slix_copy(SlixData* data, const SlixData* other) {
|
||||
furi_check(other);
|
||||
|
||||
iso15693_3_copy(data->iso15693_3_data, other->iso15693_3_data);
|
||||
data->capabilities = other->capabilities;
|
||||
|
||||
memcpy(data->passwords, other->passwords, sizeof(SlixPassword) * SlixPasswordTypeCount);
|
||||
memcpy(data->signature, other->signature, sizeof(SlixSignature));
|
||||
@@ -138,6 +146,30 @@ bool slix_verify(SlixData* data, const FuriString* device_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool slix_load_capabilities(SlixData* data, FlipperFormat* ff) {
|
||||
bool capabilities_loaded = false;
|
||||
FuriString* capabilities_str = furi_string_alloc();
|
||||
|
||||
if(!flipper_format_read_string(ff, SLIX_CAPABILITIES_KEY, capabilities_str)) {
|
||||
if(flipper_format_rewind(ff)) {
|
||||
data->capabilities = SlixCapabilitiesDefault;
|
||||
capabilities_loaded = true;
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; i < COUNT_OF(slix_capabilities_names); i++) {
|
||||
if(furi_string_cmp_str(capabilities_str, slix_capabilities_names[i]) == 0) {
|
||||
data->capabilities = i;
|
||||
capabilities_loaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
furi_string_free(capabilities_str);
|
||||
|
||||
return capabilities_loaded;
|
||||
}
|
||||
|
||||
static bool slix_load_passwords(SlixPassword* passwords, SlixType slix_type, FlipperFormat* ff) {
|
||||
bool ret = true;
|
||||
|
||||
@@ -164,13 +196,14 @@ bool slix_load(SlixData* data, FlipperFormat* ff, uint32_t version) {
|
||||
furi_check(ff);
|
||||
|
||||
bool loaded = false;
|
||||
|
||||
do {
|
||||
if(!iso15693_3_load(data->iso15693_3_data, ff, version)) break;
|
||||
|
||||
const SlixType slix_type = slix_get_type(data);
|
||||
if(slix_type >= SlixTypeCount) break;
|
||||
|
||||
if(!slix_load_capabilities(data, ff)) break;
|
||||
|
||||
if(!slix_load_passwords(data->passwords, slix_type, ff)) break;
|
||||
|
||||
if(slix_type_has_features(slix_type, SLIX_TYPE_FEATURE_SIGNATURE)) {
|
||||
@@ -220,6 +253,33 @@ bool slix_load(SlixData* data, FlipperFormat* ff, uint32_t version) {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
static bool slix_save_capabilities(const SlixData* data, FlipperFormat* ff) {
|
||||
bool save_success = false;
|
||||
|
||||
FuriString* tmp_str = furi_string_alloc();
|
||||
do {
|
||||
furi_string_set_str(
|
||||
tmp_str, "SLIX capabilities field affects emulation modes. Possible options: ");
|
||||
for(size_t i = 0; i < SlixCapabilitiesCount; i++) {
|
||||
furi_string_cat_str(tmp_str, slix_capabilities_names[i]);
|
||||
if(i < SlixCapabilitiesCount - 1) {
|
||||
furi_string_cat(tmp_str, ", ");
|
||||
}
|
||||
}
|
||||
if(!flipper_format_write_comment_cstr(ff, furi_string_get_cstr(tmp_str))) break;
|
||||
|
||||
if(!flipper_format_write_string_cstr(
|
||||
ff, SLIX_CAPABILITIES_KEY, slix_capabilities_names[data->capabilities]))
|
||||
break;
|
||||
|
||||
save_success = true;
|
||||
} while(false);
|
||||
|
||||
furi_string_free(tmp_str);
|
||||
|
||||
return save_success;
|
||||
}
|
||||
|
||||
static bool
|
||||
slix_save_passwords(const SlixPassword* passwords, SlixType slix_type, FlipperFormat* ff) {
|
||||
bool ret = true;
|
||||
@@ -251,6 +311,8 @@ bool slix_save(const SlixData* data, FlipperFormat* ff) {
|
||||
if(!iso15693_3_save(data->iso15693_3_data, ff)) break;
|
||||
if(!flipper_format_write_comment_cstr(ff, SLIX_PROTOCOL_NAME " specific data")) break;
|
||||
|
||||
if(!slix_save_capabilities(data, ff)) break;
|
||||
|
||||
if(!flipper_format_write_comment_cstr(
|
||||
ff,
|
||||
"Passwords are optional. If a password is omitted, a default value will be used"))
|
||||
|
||||
Reference in New Issue
Block a user