diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 20ca3bdb2..7da7ef8e5 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1126,6 +1126,24 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) { AddCrc14A(emdata, len); EmSendCmd(emdata, len + 2); p_response = NULL; + } else if ((receivedCmd[0] == MIFARE_ULC_WRITE || receivedCmd[0] == MIFARE_ULC_COMP_WRITE) && (tagType == 2 || tagType == 7)) { // Received a WRITE + // cmd + block + 4/16 bytes data + 2 bytes crc + if (len == 8 || len == 20) { + bool isCrcCorrect = CheckCrc14A(receivedCmd, len); + if (isCrcCorrect) { + int block = receivedCmd[1] + 12; // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + emlSetMem_xt(&receivedCmd[2], block, 1, 4); + // send ACK + EmSend4bit(CARD_ACK); + } else { + // send NACK 0x1 == crc/parity error + EmSend4bit(CARD_NACK_PA); + } + } else { + // send NACK 0x0 == invalid argument + EmSend4bit(CARD_NACK_IV); + } + p_response = NULL; } else if (receivedCmd[0] == MIFARE_ULEV1_READSIG && tagType == 7) { // Received a READ SIGNATURE -- // first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] uint16_t start = 4 * 4; diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 4d28a8dfb..777932540 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -93,6 +93,10 @@ typedef struct { # define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) #endif +#ifndef CheckCrc14A +# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len)) +#endif + extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par); extern tDemod *GetDemod(void); diff --git a/common/protocols.h b/common/protocols.h index f8ed2781e..1752d75ed 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -166,7 +166,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_EV1_SETMODE 0x43 #define MIFARE_ULC_WRITE 0xA2 -//#define MIFARE_ULC__COMP_WRITE 0xA0 +#define MIFARE_ULC_COMP_WRITE 0xA0 #define MIFARE_ULC_AUTH_1 0x1A #define MIFARE_ULC_AUTH_2 0xAF