mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-10 05:59:08 -07:00
NFC: Implement Type 4 Tag saving
This commit is contained in:
@@ -41,6 +41,7 @@ void type_4_tag_reset(Type4TagData* data) {
|
||||
|
||||
iso14443_4a_reset(data->iso14443_4a_data);
|
||||
|
||||
data->is_tag_specific = false;
|
||||
data->t4t_version.value = 0;
|
||||
data->chunk_max_read = 0;
|
||||
data->chunk_max_write = 0;
|
||||
@@ -60,6 +61,7 @@ void type_4_tag_copy(Type4TagData* data, const Type4TagData* other) {
|
||||
|
||||
iso14443_4a_copy(data->iso14443_4a_data, other->iso14443_4a_data);
|
||||
|
||||
data->is_tag_specific = other->is_tag_specific;
|
||||
data->t4t_version.value = other->t4t_version.value;
|
||||
data->chunk_max_read = other->chunk_max_read;
|
||||
data->chunk_max_write = other->chunk_max_write;
|
||||
@@ -89,6 +91,8 @@ bool type_4_tag_load(Type4TagData* data, FlipperFormat* ff, uint32_t version) {
|
||||
do {
|
||||
if(!iso14443_4a_load(data->iso14443_4a_data, ff, version)) break;
|
||||
|
||||
if(!type_4_tag_ndef_data_load(data, ff)) break;
|
||||
|
||||
success = true;
|
||||
} while(false);
|
||||
|
||||
@@ -109,6 +113,7 @@ bool type_4_tag_save(const Type4TagData* data, FlipperFormat* ff) {
|
||||
|
||||
if(!flipper_format_write_comment_cstr(ff, TYPE_4_TAG_PROTOCOL_NAME " specific data"))
|
||||
break;
|
||||
if(!type_4_tag_ndef_data_save(data, ff)) break;
|
||||
|
||||
success = true;
|
||||
} while(false);
|
||||
@@ -122,6 +127,7 @@ bool type_4_tag_is_equal(const Type4TagData* data, const Type4TagData* other) {
|
||||
furi_check(other);
|
||||
|
||||
return iso14443_4a_is_equal(data->iso14443_4a_data, other->iso14443_4a_data) &&
|
||||
data->is_tag_specific == other->is_tag_specific &&
|
||||
data->t4t_version.value == other->t4t_version.value &&
|
||||
data->chunk_max_read == other->chunk_max_read &&
|
||||
data->chunk_max_write == other->chunk_max_write &&
|
||||
|
||||
@@ -17,7 +17,8 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
Iso14443_4aData* iso14443_4a_data;
|
||||
// Tag specific
|
||||
// Tag specific data
|
||||
bool is_tag_specific;
|
||||
union {
|
||||
struct {
|
||||
uint8_t minor : 4;
|
||||
|
||||
@@ -1,3 +1,63 @@
|
||||
#include "type_4_tag_i.h"
|
||||
|
||||
#define TAG "Type4Tag"
|
||||
|
||||
#define TYPE_4_TAG_FFF_NDEF_DATA_SIZE_KEY "NDEF Data Size"
|
||||
#define TYPE_4_TAG_FFF_NDEF_DATA_KEY "NDEF Data"
|
||||
|
||||
#define TYPE_4_TAG_FFF_NDEF_DATA_PER_LINE (16U)
|
||||
|
||||
bool type_4_tag_ndef_data_load(Type4TagData* data, FlipperFormat* ff) {
|
||||
uint32_t ndef_data_size;
|
||||
if(!flipper_format_read_uint32(ff, TYPE_4_TAG_FFF_NDEF_DATA_SIZE_KEY, &ndef_data_size, 1)) {
|
||||
return false;
|
||||
}
|
||||
if(ndef_data_size == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
simple_array_init(data->ndef_data, ndef_data_size);
|
||||
|
||||
uint32_t ndef_data_pos = 0;
|
||||
uint8_t* ndef_data = simple_array_get_data(data->ndef_data);
|
||||
while(ndef_data_size > 0) {
|
||||
uint8_t ndef_line_size = MIN(ndef_data_size, TYPE_4_TAG_FFF_NDEF_DATA_PER_LINE);
|
||||
|
||||
if(!flipper_format_read_hex(
|
||||
ff, TYPE_4_TAG_FFF_NDEF_DATA_KEY, &ndef_data[ndef_data_pos], ndef_line_size)) {
|
||||
simple_array_reset(data->ndef_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
ndef_data_pos += ndef_line_size;
|
||||
ndef_data_size -= ndef_line_size;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool type_4_tag_ndef_data_save(const Type4TagData* data, FlipperFormat* ff) {
|
||||
uint32_t ndef_data_size = simple_array_get_count(data->ndef_data);
|
||||
if(!flipper_format_write_uint32(ff, TYPE_4_TAG_FFF_NDEF_DATA_SIZE_KEY, &ndef_data_size, 1)) {
|
||||
return false;
|
||||
}
|
||||
if(ndef_data_size == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t ndef_data_pos = 0;
|
||||
uint8_t* ndef_data = simple_array_get_data(data->ndef_data);
|
||||
while(ndef_data_size > 0) {
|
||||
uint8_t ndef_line_size = MIN(ndef_data_size, TYPE_4_TAG_FFF_NDEF_DATA_PER_LINE);
|
||||
|
||||
if(!flipper_format_write_hex(
|
||||
ff, TYPE_4_TAG_FFF_NDEF_DATA_KEY, &ndef_data[ndef_data_pos], ndef_line_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ndef_data_pos += ndef_line_size;
|
||||
ndef_data_size -= ndef_line_size;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,26 +2,30 @@
|
||||
|
||||
#include "type_4_tag.h"
|
||||
|
||||
// ISO SELECT FILE command and parameters
|
||||
#define TYPE_4_TAG_ISO_SELECT_CMD 0x00, 0xA4
|
||||
#define TYPE_4_TAG_ISO_SELECT_P1_BY_NAME (0x04)
|
||||
#define TYPE_4_TAG_ISO_SELECT_P1_BY_ID (0x00)
|
||||
#define TYPE_4_TAG_ISO_SELECT_P2_EMPTY (0x0C)
|
||||
#define TYPE_4_TAG_ISO_SELECT_LE_EMPTY (0x00)
|
||||
|
||||
// ISO READ BINARY command and parameters
|
||||
#define TYPE_4_TAG_ISO_READ_CMD 0x00, 0xB0
|
||||
#define TYPE_4_TAG_ISO_READ_P1_EMPTY (0x00)
|
||||
#define TYPE_4_TAG_ISO_READ_P2_BEGINNING (0x00)
|
||||
#define TYPE_4_TAG_ISO_READ_LE_FULL (0x00)
|
||||
|
||||
#define TYPE_4_TAG_ISO_STATUS_LEN (2)
|
||||
// Common APDU parameters and values
|
||||
#define TYPE_4_TAG_ISO_STATUS_LEN (2U)
|
||||
#define TYPE_4_TAG_ISO_STATUS_SUCCESS 0x90, 0x00
|
||||
#define TYPE_4_TAG_ISO_RW_CHUNK_LEN (255)
|
||||
#define TYPE_4_TAG_ISO_APP_NAME_LEN (7)
|
||||
#define TYPE_4_TAG_ISO_RW_CHUNK_LEN (255U)
|
||||
#define TYPE_4_TAG_ISO_APP_NAME_LEN (7U)
|
||||
#define TYPE_4_TAG_ISO_APP_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01
|
||||
#define TYPE_4_TAG_T4T_CC_FILE_ID_LEN (2)
|
||||
#define TYPE_4_TAG_T4T_CC_FILE_ID_LEN (2U)
|
||||
#define TYPE_4_TAG_T4T_CC_FILE_ID 0xE1, 0x03
|
||||
#define TYPE_4_TAG_T4T_CC_VNO (0x20)
|
||||
|
||||
#define TYPE_4_TAG_T4T_CC_VNO 0x20
|
||||
// Capability Container parsing structures
|
||||
|
||||
typedef enum FURI_PACKED {
|
||||
Type4TagCcTlvTypeNdefFileCtrl = 0x04,
|
||||
@@ -52,3 +56,11 @@ typedef struct FURI_PACKED {
|
||||
uint16_t mlc;
|
||||
Type4TagCcTlv tlv[];
|
||||
} Type4TagCc;
|
||||
|
||||
// Load internal Type4Tag structures
|
||||
|
||||
bool type_4_tag_ndef_data_load(Type4TagData* data, FlipperFormat* ff);
|
||||
|
||||
// Save internal Type4Tag structures
|
||||
|
||||
bool type_4_tag_ndef_data_save(const Type4TagData* data, FlipperFormat* ff);
|
||||
|
||||
@@ -137,6 +137,7 @@ Type4TagError type_4_tag_poller_read_cc(Type4TagPoller* instance) {
|
||||
break;
|
||||
}
|
||||
|
||||
instance->data->is_tag_specific = true;
|
||||
instance->data->t4t_version.value = cc->t4t_vno;
|
||||
instance->data->chunk_max_read = bit_lib_bytes_to_num_be((void*)&cc->mle, sizeof(cc->mle));
|
||||
instance->data->chunk_max_write =
|
||||
|
||||
Reference in New Issue
Block a user