diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index e5b4616..e441a74 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -232,7 +232,9 @@ static data_frame_tx_t *cmd_processor_hf14a_scan(uint16_t cmd, uint16_t status, memcpy(&payload[offset], taginfo.atqa, sizeof(taginfo.atqa)); offset += sizeof(taginfo.atqa); payload[offset++] = taginfo.sak; - payload[offset++] = 0; // TODO: no ATS support yet + payload[offset++] = taginfo.ats_len; + memcpy(&payload[offset], taginfo.ats, taginfo.ats_len); + offset += taginfo.ats_len; return data_frame_make(cmd, HF_TAG_OK, offset, payload); } diff --git a/firmware/application/src/app_main.c b/firmware/application/src/app_main.c index 2d4620b..fbc33ad 100644 --- a/firmware/application/src/app_main.c +++ b/firmware/application/src/app_main.c @@ -648,11 +648,15 @@ static void btn_fn_copy_ic_uid(void) { status = pcd_14a_reader_scan_auto(&tag); if (status == HF_TAG_OK) { // copy uid + antres->size = tag.uid_len; memcpy(antres->uid, tag.uid, tag.uid_len); // copy atqa memcpy(antres->atqa, tag.atqa, 2); // copy sak antres->sak[0] = tag.sak; + // copy ats + antres->ats.length = tag.ats_len; + memcpy(antres->ats.data, tag.ats, tag.ats_len); NRF_LOG_INFO("Offline HF uid copied") offline_status_ok(); } else { diff --git a/firmware/application/src/app_status.h b/firmware/application/src/app_status.h index f084827..574768d 100644 --- a/firmware/application/src/app_status.h +++ b/firmware/application/src/app_status.h @@ -13,7 +13,7 @@ #define HF_ERR_BCC (0x05) // IC card BCC error #define MF_ERR_AUTH (0x06) // MF card verification failed #define HF_ERR_PARITY (0x07) // IC card parity error - +#define HF_ERR_ATS (0x08) // ATS should be present but card NAKed ///////////////////////////////////////////////////////////////////// // lf status diff --git a/firmware/application/src/rfid/reader/hf/rc522.c b/firmware/application/src/rfid/reader/hf/rc522.c index 29d3c27..aff574d 100644 --- a/firmware/application/src/rfid/reader/hf/rc522.c +++ b/firmware/application/src/rfid/reader/hf/rc522.c @@ -491,6 +491,7 @@ uint8_t pcd_14a_reader_scan_once(picc_14a_tag_t *tag) { if (tag) { tag->uid_len = 0; memset(tag->uid, 0, 10); + tag->ats_len = 0; } else { return STATUS_PAR_ERR; // Finding cards are not allowed to be transmitted to the label information structure } @@ -578,6 +579,26 @@ uint8_t pcd_14a_reader_scan_once(picc_14a_tag_t *tag) { // Only 1 2 3 Three types, corresponding 4 7 10 Byte card number // Therefore + 1 tag->cascade = cascade_level + 1; + if ((!do_cascade) && (tag->sak & 0x20)) { + // Tag supports 14443-4, sending RATS + uint16_t ats_size; + status = pcd_14a_reader_ats_request(tag->ats, &ats_size, 0xFF*8); + ats_size -= 2; // size returned by pcd_14a_reader_ats_request includes CRC + if (ats_size > 254) { + NRF_LOG_INFO("Invalid ATS > 254!"); + return HF_ERR_ATS; + } + tag->ats_len = ats_size; + // We do not validate ATS here as we want to report ATS as it is without breaking 14a scan + if (tag->ats[0] != ats_size - 1) { + NRF_LOG_INFO("Invalid ATS! First byte doesn't match received length"); + // return HF_ERR_ATS; + } + if (status != HF_TAG_OK) { + NRF_LOG_INFO("Tag SAK claimed to support ATS but tag NAKd RATS"); + // return HF_ERR_ATS; + } + } } return HF_TAG_OK; } @@ -619,6 +640,7 @@ uint8_t pcd_14a_reader_ats_request(uint8_t *pAts, uint16_t *szAts, uint16_t szAt status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, rats, sizeof(rats), pAts, szAts, szAtsBitMax); if (status != HF_TAG_OK) { + *szAts = 0; NRF_LOG_INFO("Err at ats receive.\n"); return status; } diff --git a/firmware/application/src/rfid/reader/hf/rc522.h b/firmware/application/src/rfid/reader/hf/rc522.h index 2c4d00f..9546aef 100644 --- a/firmware/application/src/rfid/reader/hf/rc522.h +++ b/firmware/application/src/rfid/reader/hf/rc522.h @@ -159,6 +159,8 @@ typedef struct { uint8_t cascade; // theAntiCollisionLevelValueIs1Representation 4Byte,2Represents7Byte,3Means10Byte uint8_t sak; // chooseToConfirm uint8_t atqa[2]; // requestResponse + uint8_t ats[0xFF];// 14443-4 answer to select + uint8_t ats_len; // 14443-4 answer to select size } PACKED picc_14a_tag_t; #ifdef __cplusplus diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index d0cf82f..b76453a 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -335,7 +335,6 @@ class HF14AScan(ReaderRequiredUnit): print(f"- ATQA : {data_tag['atqa'].hex().upper()}") print(f"- SAK : {data_tag['sak'].hex().upper()}") if len(data_tag['ats']) > 0: - print(data_tag['ats']) print(f"- ATS : {data_tag['ats'].hex().upper()}") if deep: self.sak_info(data_tag) diff --git a/software/script/chameleon_status.py b/software/script/chameleon_status.py index cf82057..da467f5 100644 --- a/software/script/chameleon_status.py +++ b/software/script/chameleon_status.py @@ -30,6 +30,7 @@ class Device(metaclass=MetaDevice): HF_ERR_BCC = 0x05 # IC card BCC error MF_ERR_AUTH = 0x06 # MF card verification failed HF_ERR_PARITY = 0x07 # IC card parity error + HF_ERR_ATS = 0x08 # ATS should be present but card NAKed, or ATS too large # Some operations with low frequency cards succeeded! LF_TAG_OK = 0x40 @@ -57,6 +58,7 @@ message = { Device.HF_ERR_BCC: "HF tag uid bcc error", Device.MF_ERR_AUTH: "HF tag auth fail", Device.HF_ERR_PARITY: "HF tag data parity error", + Device.HF_ERR_ATS: "HF tag was supposed to send ATS but didn't", Device.LF_TAG_OK: "LF tag operation succeeded", Device.EM410X_TAG_NO_FOUND: "EM410x tag no found",