diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index aee0bb9..df0f9f3 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -407,14 +407,65 @@ void nfc_process_iblock(uint8_t * buf, int len) void nfc_process_block(uint8_t * buf, int len) { + static uint8_t ibuf[1024]; + static int ibuflen = 0; + + if (!len) + return; + if (IS_PPSS_CMD(buf[0])) { printf1(TAG_NFC, "NFC_CMD_PPSS\r\n"); } else if (IS_IBLOCK(buf[0])) { - printf1(TAG_NFC, "NFC_CMD_IBLOCK\r\n"); - nfc_process_iblock(buf, len); + if (buf[0] & 0x10) + { + printf1(TAG_NFC, "NFC_CMD_IBLOCK chaining blen=%d len=%d\r\n", ibuflen, len); + if (ibuflen + len > sizeof(ibuf)) + { + printf1(TAG_NFC, "I block memory error! must have %d but have only %d\r\n", ibuflen + len, sizeof(ibuf)); + nfc_write_response(buf[0], SW_INTERNAL_EXCEPTION); + return; + } + + printf1(TAG_NFC,"i> "); + dump_hex1(TAG_NFC, buf, len); + + if (len) + { + memcpy(&ibuf[ibuflen], &buf[1], len - 1); + ibuflen += len - 1; + } + + // send R block + uint8_t rb = NFC_CMD_RBLOCK | NFC_CMD_RBLOCK_ACK | (buf[0] & 3); + nfc_write_frame(&rb, 1); + } else { + if (ibuflen) + { + if (len) + { + memcpy(&ibuf[ibuflen], &buf[1], len - 1); + ibuflen += len - 1; + } + + memmove(&ibuf[1], ibuf, ibuflen); + ibuf[0] = buf[0]; + ibuflen++; + + printf1(TAG_NFC, "NFC_CMD_IBLOCK chaining last block. blen=%d len=%d\r\n", ibuflen, len); + + printf1(TAG_NFC,"i> "); + dump_hex1(TAG_NFC, buf, len); + + nfc_process_iblock(ibuf, ibuflen); + } else { + printf1(TAG_NFC, "NFC_CMD_IBLOCK\r\n"); + nfc_process_iblock(buf, len); + } + ibuflen = 0; + } } else if (IS_RBLOCK(buf[0])) { diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 16257a7..c1c3042 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -37,6 +37,7 @@ typedef struct #define NFC_CMD_IBLOCK 0x00 #define IS_IBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_IBLOCK) && (((x) & 0x02) == 0x02) ) #define NFC_CMD_RBLOCK 0x80 +#define NFC_CMD_RBLOCK_ACK 0x20 #define IS_RBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_RBLOCK) && (((x) & 0x02) == 0x02) ) #define NFC_CMD_SBLOCK 0xc0 #define IS_SBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_SBLOCK) && (((x) & 0x02) == 0x02) ) @@ -67,10 +68,10 @@ typedef enum } APPLETS; #define SW_SUCCESS 0x9000 -#define SW_GET_RESPONSE 0x6100 //Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE. +#define SW_GET_RESPONSE 0x6100 // Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE. #define SW_COND_USE_NOT_SATISFIED 0x6985 #define SW_FILE_NOT_FOUND 0x6a82 -#define SW_INS_INVALID 0x6d00 +#define SW_INS_INVALID 0x6d00 // Instruction code not supported or invalid #define SW_INTERNAL_EXCEPTION 0x6f00 #endif