mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-21 20:42:15 -07:00
Improve ISO SELECT naming and handling
This commit is contained in:
@@ -9,8 +9,8 @@
|
||||
|
||||
#define TYPE_4_TAG_FFF_NDEF_DATA_PER_LINE (16U)
|
||||
|
||||
const uint8_t type_4_tag_iso_picc_name[TYPE_4_TAG_ISO_NAME_LEN] = {TYPE_4_TAG_ISO_PICC_NAME};
|
||||
const uint8_t type_4_tag_iso_app_name[TYPE_4_TAG_ISO_NAME_LEN] = {TYPE_4_TAG_ISO_APP_NAME};
|
||||
const uint8_t type_4_tag_iso_mf_name[TYPE_4_TAG_ISO_NAME_LEN] = {TYPE_4_TAG_ISO_MF_NAME};
|
||||
const uint8_t type_4_tag_iso_df_name[TYPE_4_TAG_ISO_NAME_LEN] = {TYPE_4_TAG_ISO_DF_NAME};
|
||||
|
||||
Type4TagError type_4_tag_process_error(Iso14443_4aError error) {
|
||||
switch(error) {
|
||||
@@ -46,11 +46,11 @@ void type_4_tag_cc_dump(const Type4TagData* data, uint8_t* buf, size_t len) {
|
||||
cc->tlv[0].len = sizeof(cc->tlv[0].value.ndef_file_ctrl);
|
||||
|
||||
bit_lib_num_to_bytes_be(
|
||||
data->is_tag_specific ? data->ndef_file_id : TYPE_4_TAG_T4T_DEFAULT_FILE_ID,
|
||||
data->is_tag_specific ? data->ndef_file_id : TYPE_4_TAG_T4T_NDEF_EF_ID,
|
||||
sizeof(cc->tlv[0].value.ndef_file_ctrl.file_id),
|
||||
(void*)&cc->tlv[0].value.ndef_file_ctrl.file_id);
|
||||
bit_lib_num_to_bytes_be(
|
||||
data->is_tag_specific ? data->ndef_max_len : TYPE_4_TAG_DEFAULT_SIZE,
|
||||
data->is_tag_specific ? data->ndef_max_len : TYPE_4_TAG_DEFAULT_NDEF_SIZE,
|
||||
sizeof(cc->tlv[0].value.ndef_file_ctrl.max_len),
|
||||
(void*)&cc->tlv[0].value.ndef_file_ctrl.max_len);
|
||||
cc->tlv[0].value.ndef_file_ctrl.read_perm =
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
#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_DF_NAME (0x04)
|
||||
#define TYPE_4_TAG_ISO_SELECT_P1_BY_EF_ID (0x02)
|
||||
#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)
|
||||
#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_EF_ID (0x02)
|
||||
#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
|
||||
@@ -32,23 +32,34 @@
|
||||
#define TYPE_4_TAG_ISO_STATUS_BAD_PARAMS 0x6A, 0x86
|
||||
#define TYPE_4_TAG_ISO_STATUS_NO_CMD 0x68, 0x00
|
||||
#define TYPE_4_TAG_ISO_RW_CHUNK_LEN (255U)
|
||||
#define TYPE_4_TAG_ISO_NAME_LEN (7U)
|
||||
#define TYPE_4_TAG_ISO_PICC_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00
|
||||
#define TYPE_4_TAG_ISO_APP_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01
|
||||
#define TYPE_4_TAG_T4T_CC_FILE_ID 0xE103
|
||||
#define TYPE_4_TAG_T4T_CC_VNO (0x20)
|
||||
#define TYPE_4_TAG_T4T_DEFAULT_FILE_ID 0xE104
|
||||
#define TYPE_4_TAG_T4T_CC_RW_LOCK_NONE 0x00
|
||||
#define TYPE_4_TAG_T4T_CC_MIN_SIZE (sizeof(Type4TagCc) + sizeof(Type4TagCcTlv))
|
||||
|
||||
// Common IDs and Names, note:
|
||||
// MF = Master File (PICC/Card Level)
|
||||
// DF = Dedicated File (Application)
|
||||
// EF = Elementary File (File)
|
||||
#define TYPE_4_TAG_ISO_NAME_LEN (7U)
|
||||
#define TYPE_4_TAG_ISO_MF_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00
|
||||
#define TYPE_4_TAG_ISO_DF_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01
|
||||
#define TYPE_4_TAG_ISO_ID_LEN (2U)
|
||||
#define TYPE_4_TAG_ISO_MF_ID (0x3F00)
|
||||
#define TYPE_4_TAG_ISO_DF_ID (0xE110)
|
||||
#define TYPE_4_TAG_T4T_CC_EF_ID (0xE103)
|
||||
#define TYPE_4_TAG_T4T_NDEF_EF_ID (0xE104)
|
||||
|
||||
// Capability Container parsing parameters
|
||||
#define TYPE_4_TAG_T4T_CC_VNO (0x20)
|
||||
#define TYPE_4_TAG_T4T_CC_RW_LOCK_NONE (0x00)
|
||||
#define TYPE_4_TAG_T4T_CC_MIN_SIZE (sizeof(Type4TagCc) + sizeof(Type4TagCcTlv))
|
||||
|
||||
// Implementation-specific sizes and defaults
|
||||
// 4a layer adds 1..3 byte prefix, 3a layer adds 2 byte suffix and has 256 byte buffer
|
||||
#define TYPE_4_TAG_BUF_SIZE (256U - 3U - 2U)
|
||||
#define TYPE_4_TAG_BUF_SIZE (256U - 3U - 2U)
|
||||
// Read returns 2 byte status trailer, write sends 5 byte command header
|
||||
#define TYPE_4_TAG_CHUNK_LEN MIN(TYPE_4_TAG_BUF_SIZE - 5U, TYPE_4_TAG_ISO_RW_CHUNK_LEN)
|
||||
#define TYPE_4_TAG_DEFAULT_SIZE (2048U)
|
||||
#define TYPE_4_TAG_CHUNK_LEN MIN(TYPE_4_TAG_BUF_SIZE - 5U, TYPE_4_TAG_ISO_RW_CHUNK_LEN)
|
||||
#define TYPE_4_TAG_DEFAULT_NDEF_SIZE (2048U)
|
||||
|
||||
extern const uint8_t type_4_tag_iso_picc_name[TYPE_4_TAG_ISO_NAME_LEN];
|
||||
extern const uint8_t type_4_tag_iso_app_name[TYPE_4_TAG_ISO_NAME_LEN];
|
||||
extern const uint8_t type_4_tag_iso_mf_name[TYPE_4_TAG_ISO_NAME_LEN];
|
||||
extern const uint8_t type_4_tag_iso_df_name[TYPE_4_TAG_ISO_NAME_LEN];
|
||||
|
||||
// Capability Container parsing structures
|
||||
|
||||
|
||||
@@ -35,17 +35,15 @@ static Type4TagError type_4_tag_listener_iso_select(
|
||||
UNUSED(p2);
|
||||
UNUSED(le);
|
||||
|
||||
if(p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_DF_NAME) {
|
||||
if(lc == sizeof(type_4_tag_iso_picc_name) &&
|
||||
memcmp(type_4_tag_iso_picc_name, data, sizeof(type_4_tag_iso_picc_name)) == 0) {
|
||||
if(p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_NAME && lc == TYPE_4_TAG_ISO_NAME_LEN) {
|
||||
if(memcmp(type_4_tag_iso_mf_name, data, sizeof(type_4_tag_iso_mf_name)) == 0) {
|
||||
instance->state = Type4TagListenerStateSelectedPicc;
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu));
|
||||
return Type4TagErrorNone;
|
||||
}
|
||||
|
||||
if(lc == sizeof(type_4_tag_iso_app_name) &&
|
||||
memcmp(type_4_tag_iso_app_name, data, sizeof(type_4_tag_iso_app_name)) == 0) {
|
||||
if(memcmp(type_4_tag_iso_df_name, data, sizeof(type_4_tag_iso_df_name)) == 0) {
|
||||
instance->state = Type4TagListenerStateSelectedApplication;
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu));
|
||||
@@ -53,23 +51,41 @@ static Type4TagError type_4_tag_listener_iso_select(
|
||||
}
|
||||
|
||||
} else if(
|
||||
instance->state >= Type4TagListenerStateSelectedApplication &&
|
||||
(p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_ID || p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_EF_ID) &&
|
||||
lc == sizeof(uint16_t)) {
|
||||
uint16_t file_id = bit_lib_bytes_to_num_be(data, sizeof(uint16_t));
|
||||
if(file_id == TYPE_4_TAG_T4T_CC_FILE_ID) {
|
||||
instance->state = Type4TagListenerStateSelectedCapabilityContainer;
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu));
|
||||
return Type4TagErrorNone;
|
||||
lc == TYPE_4_TAG_ISO_ID_LEN) {
|
||||
uint16_t id = bit_lib_bytes_to_num_be(data, sizeof(uint16_t));
|
||||
|
||||
if(p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_ID) {
|
||||
if(id == TYPE_4_TAG_ISO_MF_ID) {
|
||||
instance->state = Type4TagListenerStateSelectedPicc;
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu));
|
||||
return Type4TagErrorNone;
|
||||
}
|
||||
|
||||
if(id == TYPE_4_TAG_ISO_DF_ID) {
|
||||
instance->state = Type4TagListenerStateSelectedApplication;
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu));
|
||||
return Type4TagErrorNone;
|
||||
}
|
||||
}
|
||||
|
||||
if(file_id == (instance->data->is_tag_specific ? instance->data->ndef_file_id :
|
||||
TYPE_4_TAG_T4T_DEFAULT_FILE_ID)) {
|
||||
instance->state = Type4TagListenerStateSelectedNdefMessage;
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu));
|
||||
return Type4TagErrorNone;
|
||||
if(instance->state >= Type4TagListenerStateSelectedApplication) {
|
||||
if(id == TYPE_4_TAG_T4T_CC_EF_ID) {
|
||||
instance->state = Type4TagListenerStateSelectedCapabilityContainer;
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu));
|
||||
return Type4TagErrorNone;
|
||||
}
|
||||
|
||||
if(id == (instance->data->is_tag_specific ? instance->data->ndef_file_id :
|
||||
TYPE_4_TAG_T4T_NDEF_EF_ID)) {
|
||||
instance->state = Type4TagListenerStateSelectedNdefMessage;
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu));
|
||||
return Type4TagErrorNone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +197,7 @@ static Type4TagError type_4_tag_listener_iso_write(
|
||||
|
||||
if(instance->state == Type4TagListenerStateSelectedNdefMessage) {
|
||||
if(offset + lc > (instance->data->is_tag_specific ? instance->data->ndef_max_len :
|
||||
TYPE_4_TAG_DEFAULT_SIZE)) {
|
||||
TYPE_4_TAG_DEFAULT_NDEF_SIZE)) {
|
||||
bit_buffer_append_bytes(
|
||||
instance->tx_buffer,
|
||||
type_4_tag_offset_error_apdu,
|
||||
|
||||
@@ -41,11 +41,11 @@ Type4TagError type_4_tag_apdu_trx(Type4TagPoller* instance, BitBuffer* tx_buf, B
|
||||
|
||||
static Type4TagError type_5_tag_poller_iso_select_name(
|
||||
Type4TagPoller* instance,
|
||||
const uint8_t* df_name,
|
||||
uint8_t df_name_len) {
|
||||
const uint8_t* name,
|
||||
uint8_t name_len) {
|
||||
const uint8_t type_4_tag_iso_select_name_apdu[] = {
|
||||
TYPE_4_TAG_ISO_SELECT_CMD,
|
||||
TYPE_4_TAG_ISO_SELECT_P1_BY_DF_NAME,
|
||||
TYPE_4_TAG_ISO_SELECT_P1_BY_NAME,
|
||||
TYPE_4_TAG_ISO_SELECT_P2_EMPTY,
|
||||
};
|
||||
|
||||
@@ -53,8 +53,8 @@ static Type4TagError type_5_tag_poller_iso_select_name(
|
||||
instance->tx_buffer,
|
||||
type_4_tag_iso_select_name_apdu,
|
||||
sizeof(type_4_tag_iso_select_name_apdu));
|
||||
bit_buffer_append_byte(instance->tx_buffer, df_name_len);
|
||||
bit_buffer_append_bytes(instance->tx_buffer, df_name, df_name_len);
|
||||
bit_buffer_append_byte(instance->tx_buffer, name_len);
|
||||
bit_buffer_append_bytes(instance->tx_buffer, name, name_len);
|
||||
|
||||
return type_4_tag_apdu_trx(instance, instance->tx_buffer, instance->rx_buffer);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ static Type4TagError
|
||||
type_5_tag_poller_iso_select_file(Type4TagPoller* instance, uint16_t file_id) {
|
||||
const uint8_t type_4_tag_iso_select_file_apdu[] = {
|
||||
TYPE_4_TAG_ISO_SELECT_CMD,
|
||||
TYPE_4_TAG_ISO_SELECT_P1_BY_ID,
|
||||
TYPE_4_TAG_ISO_SELECT_P1_BY_EF_ID,
|
||||
TYPE_4_TAG_ISO_SELECT_P2_EMPTY,
|
||||
sizeof(file_id),
|
||||
};
|
||||
@@ -134,7 +134,7 @@ Type4TagError type_4_tag_poller_select_app(Type4TagPoller* instance) {
|
||||
|
||||
FURI_LOG_D(TAG, "Select application");
|
||||
return type_5_tag_poller_iso_select_name(
|
||||
instance, type_4_tag_iso_app_name, sizeof(type_4_tag_iso_app_name));
|
||||
instance, type_4_tag_iso_df_name, sizeof(type_4_tag_iso_df_name));
|
||||
}
|
||||
|
||||
Type4TagError type_4_tag_poller_read_cc(Type4TagPoller* instance) {
|
||||
@@ -144,7 +144,7 @@ Type4TagError type_4_tag_poller_read_cc(Type4TagPoller* instance) {
|
||||
|
||||
do {
|
||||
FURI_LOG_D(TAG, "Select CC");
|
||||
error = type_5_tag_poller_iso_select_file(instance, TYPE_4_TAG_T4T_CC_FILE_ID);
|
||||
error = type_5_tag_poller_iso_select_file(instance, TYPE_4_TAG_T4T_CC_EF_ID);
|
||||
if(error != Type4TagErrorNone) break;
|
||||
|
||||
FURI_LOG_D(TAG, "Read CC len");
|
||||
|
||||
Reference in New Issue
Block a user