From ebd6ab58421b85a9c6d090b8751718be6807934e Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 10 Sep 2020 16:05:35 +0200 Subject: [PATCH] Fixed timing issues with Read Multiple Blocks ISO15693 CRC calculation is slow and it delayed too much transmission of long frames. Some readers marked transmission as unsuccesfull and ignored data. Moving CRC calculation inside the codec allows to start modulating the field while the CRC is not yet ready but, by the time it has to be trasmitted, calculation will be done. This fixes https://github.com/emsec/ChameleonMini/issues/262 In EM4233, there still are issues with Read Multiple command when block locking status is requested for more than 0x1F blocks Implemented a check in ISO15693 codec to avoid out of bound CRC writes. --- Firmware/Chameleon-Mini/Application/EM4233.c | 10 ++-------- Firmware/Chameleon-Mini/Application/Sl2s2002.c | 6 ------ .../Chameleon-Mini/Application/TITagitstandard.c | 6 ------ Firmware/Chameleon-Mini/Application/Vicinity.c | 6 ------ Firmware/Chameleon-Mini/Codec/ISO15693.c | 13 ++++++++++++- 5 files changed, 14 insertions(+), 27 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index 4fa98b3e..5a8856a9 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -137,7 +137,7 @@ uint16_t EM4233_Read_Single(uint8_t *FrameBuf, uint16_t FrameBytes) { if (BlockAddress >= EM4233_NUMBER_OF_BLCKS) { /* check if the reader is requesting a sector out of bound */ if (FrameInfo.Addressed) { /* If the request is addressed */ FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = 0x0F; /* Magic number from real tag */ + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; ResponseByteCount += 2; /* Copied this behaviour from real tag, not specified in ISO documents */ } return ResponseByteCount; /* If not addressed real tag does not respond */ @@ -178,7 +178,7 @@ uint16_t EM4233_Read_Multiple(uint8_t *FrameBuf, uint16_t FrameBytes) { if (BlockAddress >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a block out of bound */ if (FrameInfo.Addressed) { /* If the request is addressed */ FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = 0x0F; /* Magic number from real tag */ + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; ResponseByteCount += 2; /* Copied this behaviour from real tag, not specified in ISO documents */ } return ResponseByteCount; /* If not addressed real tag does not respond */ @@ -669,12 +669,6 @@ uint16_t EM4233AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) { } } - if (ResponseByteCount > 0) { - /* There is data to send. Append CRC */ - ISO15693AppendCRC(FrameBuf, ResponseByteCount); - ResponseByteCount += ISO15693_CRC16_SIZE; - } - return ResponseByteCount; } diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.c b/Firmware/Chameleon-Mini/Application/Sl2s2002.c index e8a242e5..ffdbed1e 100644 --- a/Firmware/Chameleon-Mini/Application/Sl2s2002.c +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.c @@ -141,12 +141,6 @@ uint16_t Sl2s2002AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) { break; } - if (ResponseByteCount > 0) { - /* There is data to be sent. Append CRC */ - ISO15693AppendCRC(FrameBuf, ResponseByteCount); - ResponseByteCount += ISO15693_CRC16_SIZE; - } - return ResponseByteCount; } else { // Invalid CRC diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index b770b8b8..2d4618c9 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -198,12 +198,6 @@ uint16_t TITagitstandardAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) { break; } - if (ResponseByteCount > 0) { - /* There is data to be sent. Append CRC */ - ISO15693AppendCRC(FrameBuf, ResponseByteCount); - ResponseByteCount += ISO15693_CRC16_SIZE; - } - return ResponseByteCount; } diff --git a/Firmware/Chameleon-Mini/Application/Vicinity.c b/Firmware/Chameleon-Mini/Application/Vicinity.c index a79e167c..c3bc1716 100644 --- a/Firmware/Chameleon-Mini/Application/Vicinity.c +++ b/Firmware/Chameleon-Mini/Application/Vicinity.c @@ -92,12 +92,6 @@ uint16_t VicinityAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) { break; } - if (ResponseByteCount > 0) { - /* There is data to be sent. Append CRC */ - ISO15693AppendCRC(FrameBuf, ResponseByteCount); - ResponseByteCount += ISO15693_CRC16_SIZE; - } - return ResponseByteCount; } else { // Invalid CRC diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index 30f38a2a..02214847 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -638,7 +638,13 @@ void ISO15693CodecTask(void) { /* This is only reached when we've received a valid frame */ if (AppReceivedByteCount != ISO15693_APP_NO_RESPONSE) { - LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount); + if (AppReceivedByteCount > CODEC_BUFFER_SIZE - ISO15693_CRC16_SIZE) { /* CRC would be written outside codec buffer */ + CodecBuffer[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + CodecBuffer[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; + AppReceivedByteCount = 2; + LogEntry(LOG_INFO_GENERIC, "Too much data requested - See PR #274", 38); + } + LEDHook(LED_CODEC_TX, LED_PULSE); ByteCount = AppReceivedByteCount; @@ -653,6 +659,11 @@ void ISO15693CodecTask(void) { StateRegister = LOADMOD_START_SINGLE; } + /* Calculate the CRC while modulation is already ongoing */ + ISO15693AppendCRC(CodecBuffer, AppReceivedByteCount); + ByteCount += ISO15693_CRC16_SIZE; /* Increase this variable as it will be read by the codec during loadmodulation */ + LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount + ISO15693_CRC16_SIZE); + } else { /* Overwrite the PERBUF register, which was configured in ISO15693_EOC, with the new appropriate value. * This is expecially needed because, since load modulation has not been performed, we're jumping here straight after