From b1f0da0c331c74a5c2321c15e6dc4ead4ebd5531 Mon Sep 17 00:00:00 2001 From: georg Date: Thu, 31 Aug 2017 14:00:59 +0200 Subject: [PATCH 01/67] added ISO15693 codec --- .../Chameleon-Mini/Application/Application.h | 2 + .../Chameleon-Mini/Application/ISO15693-A.c | 52 ++ .../Chameleon-Mini/Application/ISO15693-A.h | 104 ++++ .../Chameleon-Mini/Application/Vicinity.c | 132 ++++ .../Chameleon-Mini/Application/Vicinity.h | 27 + Firmware/Chameleon-Mini/Codec/Codec.h | 12 +- Firmware/Chameleon-Mini/Codec/ISO14443-2A.c | 6 +- Firmware/Chameleon-Mini/Codec/ISO15693.c | 575 ++++++++++++++++++ Firmware/Chameleon-Mini/Codec/ISO15693.h | 47 ++ Firmware/Chameleon-Mini/Configuration.c | 20 + Firmware/Chameleon-Mini/Configuration.h | 3 + Firmware/Chameleon-Mini/Makefile | 5 +- 12 files changed, 978 insertions(+), 7 deletions(-) create mode 100644 Firmware/Chameleon-Mini/Application/ISO15693-A.c create mode 100644 Firmware/Chameleon-Mini/Application/ISO15693-A.h create mode 100644 Firmware/Chameleon-Mini/Application/Vicinity.c create mode 100644 Firmware/Chameleon-Mini/Application/Vicinity.h create mode 100644 Firmware/Chameleon-Mini/Codec/ISO15693.c create mode 100644 Firmware/Chameleon-Mini/Codec/ISO15693.h diff --git a/Firmware/Chameleon-Mini/Application/Application.h b/Firmware/Chameleon-Mini/Application/Application.h index 0b94960..b732796 100644 --- a/Firmware/Chameleon-Mini/Application/Application.h +++ b/Firmware/Chameleon-Mini/Application/Application.h @@ -16,6 +16,8 @@ #include "MifareUltralight.h" #include "MifareClassic.h" #include "Reader14443A.h" +#include "Vicinity.h" + /* Function wrappers */ INLINE void ApplicationInit(void) { diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c new file mode 100644 index 0000000..0f7f3d3 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -0,0 +1,52 @@ +#include "ISO15693-A.h" +#include "../Common.h" +#include + +//Refer to ISO/IEC 15693-3:2001 page 41 +uint16_t calculateCRC(void* FrameBuf, uint16_t FrameBufSize) +{ + uint16_t reg = ISO15693_CRC16_PRESET; + uint8_t i, j; + + uint8_t *DataPtr = (uint8_t *)FrameBuf; + + for(i = 0; i < FrameBufSize; i++) { + reg = reg ^ *DataPtr++; + for (j = 0; j < 8; j++) { + if (reg & 0x0001) { + reg = (reg >> 1) ^ ISO15693_CRC16_POLYNORMAL; + } else { + reg = (reg >> 1); + } + } + } + + return ~reg; +} + +void ISO15693AppendCRC(uint8_t* FrameBuf, uint16_t FrameBufSize) +{ + uint16_t crc; + + crc = calculateCRC(FrameBuf, FrameBufSize); + + uint8_t crcLb = crc & 0xFF; + uint8_t crcHb = crc >> 8; + + + FrameBuf[FrameBufSize] = crcLb; + FrameBuf[FrameBufSize + 1] = crcHb; +} + +bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) +{ + uint16_t crc; + uint8_t *DataPtr = (uint8_t *)FrameBuf; + + crc = calculateCRC(DataPtr, FrameBufSize); + + uint8_t crcLb = crc & 0xFF; + uint8_t crcHb = crc >> 8; + + return (DataPtr[FrameBufSize] == crcLb && DataPtr[FrameBufSize + 1] == crcHb); +} diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h new file mode 100644 index 0000000..2a40482 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -0,0 +1,104 @@ +/* + * ISO15693-3.h + * + * Created on: 24.08.2013 + * Author: skuser + */ + +#ifndef ISO15693_3_H_ +#define ISO15693_3_H_ + +#include "../Common.h" + +#define ISO15693_CMD_INVENTORY 0x01 +#define ISO15693_CMD_STAY_QUIET 0x02 +#define ISO15693_CMD_READ_SINGLE 0x20 +#define ISO15693_CMD_WRITE_SINGLE 0x21 +#define ISO15693_CMD_LOCK_BLOCK 0x22 +#define ISO15693_CMD_READ_MULTIPLE 0x23 +#define ISO15693_CMD_WRITE_MULTIPLE 0x24 +#define ISO15693_CMD_SELECT 0x25 +#define ISO15693_CMD_RESET_TO_READY 0x26 +#define ISO15693_CMD_WRITE_AFI 0x27 +#define ISO15693_CMD_LOCK_AFI 0x28 +#define ISO15693_CMD_WRITE_DSFID 0x29 +#define ISO15693_CMD_LOCK_DSFID 0x2A +#define ISO15693_CMD_GET_SYS_INFO 0x2B +#define ISO15693_CMD_GET_BLOCK_SEC 0x2C + +#define ISO15693_REQ_FLAG_SUBCARRIER 0x01 +#define ISO15693_REQ_FLAG_DATARATE 0x02 +#define ISO15693_REQ_FLAG_INVENTORY 0x04 +#define ISO15693_REQ_FLAG_PROT_EXT 0x08 +#define ISO15693_REQ_FLAG_OPTION 0x40 +#define ISO15693_REQ_FLAG_RFU 0x80 +/* When INVENTORY flag is not set: */ +#define ISO15693_REQ_FLAG_SELECT 0x10 +#define ISO15693_REQ_FLAG_ADDRESS 0x20 +/* When INVENTORY flag is set: */ +#define ISO15693_REQ_FLAG_AFI 0x10 +#define ISO15693_REQ_FLAG_NB_SLOTS 0x20 + +#define ISO15693_RES_FLAG_ERROR 0x01 +#define ISO15693_RES_FLAG_PROT_EXT 0x08 + + +#define ISO15693_MIN_FRAME_SIZE 5 + +#define ISO15693_CRC16_SIZE 2 /* Bytes */ +#define ISO15693_CRC16_POLYNORMAL 0x8408 +#define ISO15693_CRC16_PRESET 0xFFFF + +typedef uint8_t ISO15693UidType[8]; + +void ISO15693AppendCRC(uint8_t* FrameBuf, uint16_t FrameBufSize); +bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize); + +INLINE +bool ISO15693CompareUid(uint8_t* Uid1, uint8_t* Uid2) +{ + if ( (Uid1[0] == Uid2[0]) + && (Uid1[1] == Uid2[1]) + && (Uid1[2] == Uid2[2]) + && (Uid1[3] == Uid2[3]) + && (Uid1[4] == Uid2[4]) + && (Uid1[5] == Uid2[5]) + && (Uid1[6] == Uid2[6]) + && (Uid1[7] == Uid2[7]) ) { + return true; + } else { + return false; + } +} + +INLINE +void ISO15693CopyUid(uint8_t* DstUid, uint8_t* SrcUid) +{ + DstUid[0] = SrcUid[0]; + DstUid[1] = SrcUid[1]; + DstUid[2] = SrcUid[2]; + DstUid[3] = SrcUid[3]; + DstUid[4] = SrcUid[4]; + DstUid[5] = SrcUid[5]; + DstUid[6] = SrcUid[6]; + DstUid[7] = SrcUid[7]; +} + +INLINE +bool ISO15693Addressed(uint8_t* Buffer, uint8_t* MyUid) { + if (Buffer[0] & ISO15693_REQ_FLAG_ADDRESS) { + /* Addressed mode */ + if ( ISO15693CompareUid(&Buffer[2], MyUid) ) { + /* Our UID addressed */ + return true; + } else { + /* Our UID not addressed */ + return false; + } + } else { + /* Non-Addressed mode */ + return true; + } +} + +#endif /* ISO15693_3_H_ */ diff --git a/Firmware/Chameleon-Mini/Application/Vicinity.c b/Firmware/Chameleon-Mini/Application/Vicinity.c new file mode 100644 index 0000000..7a3a961 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/Vicinity.c @@ -0,0 +1,132 @@ +/* + * ISO15693.c + * + * Created on: 01-03-2017 + * Author: Phillip Nash + */ + + +#include "Vicinity.h" +#include "../Codec/ISO15693.h" +#include "../Memory.h" +#include "Crypto1.h" +#include "../Random.h" +#include "ISO15693-A.h" + + +static enum { + STATE_READY, + STATE_SELECTED, + STATE_QUIET +} State; + +ISO15693UidType MyUid = {0x60, 0x0B, 0x88, 0x77, 0x06, 0x44, 0x02, 0xE1}; + + + +void VicinityAppInit(void) +{ + State = STATE_READY; +} + +void VicinityAppReset(void) +{ + State = STATE_READY; +} + + +void VicinityAppTask(void) +{ + +} + +void VicinityAppTick(void) +{ + + +} + +void sendIntToTermina(uint8_t val) +{ + char buf[16]; + snprintf(buf,16, "%d,",val); + TerminalSendString(buf); +} + +uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { + if(ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) { + // At this point, we have a valid ISO15693 frame + uint8_t Command = FrameBuf[1]; + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + + + switch(State) { + case STATE_READY: + if (Command == ISO15693_CMD_INVENTORY) { + FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[1] = 0x00; /* DSFID */ + ISO15693CopyUid(&FrameBuf[2], MyUid); + ResponseByteCount = 10; + } else if (Command == ISO15693_CMD_STAY_QUIET) { + if (ISO15693Addressed(FrameBuf, MyUid)) { + State = STATE_QUIET; + } + } else if (Command == ISO15693_CMD_GET_SYS_INFO) { + if (ISO15693Addressed(FrameBuf, MyUid)) { + FrameBuf[0] = 0; /* Flags */ + FrameBuf[1] = 0; /* InfoFlags */ + ISO15693CopyUid(&FrameBuf[2], MyUid); + ResponseByteCount = 10; + } + } + break; + + case STATE_SELECTED: + + break; + + case STATE_QUIET: + if (Command == ISO15693_CMD_RESET_TO_READY) { + if (ISO15693Addressed(FrameBuf, MyUid)) { + FrameBuf[0] = 0; + ResponseByteCount = 1; + State = STATE_READY; + } + } + break; + + default: + break; + } + + if (ResponseByteCount > 0) { + /* There is data to be sent. Append CRC */ + ISO15693AppendCRC(FrameBuf, ResponseByteCount); + ResponseByteCount += ISO15693_CRC16_SIZE; + } + + return ResponseByteCount; + + } else { // Invalid CRC + return ISO15693_APP_NO_RESPONSE; + } + } else { // Min frame size not met + return ISO15693_APP_NO_RESPONSE; + } + +} + +void VicinityGetUid(ConfigurationUidType Uid) +{ + memcpy(Uid, MyUid, sizeof(ConfigurationUidType)); +} + +void VicinitySetUid(ConfigurationUidType Uid) +{ + memcpy(MyUid, Uid, sizeof(ConfigurationUidType)); +} + + + diff --git a/Firmware/Chameleon-Mini/Application/Vicinity.h b/Firmware/Chameleon-Mini/Application/Vicinity.h new file mode 100644 index 0000000..797ff01 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/Vicinity.h @@ -0,0 +1,27 @@ +/* + * MifareClassic.h + * + * Created on: 01.03.2017 + * Author: skuser + */ + +#ifndef VICINITY_H_ +#define VICINITY_H_ + +#include "Application.h" +#include "ISO15693-A.h" + +#define ISO15693_GENERIC_UID_SIZE 8 //ISO15693_UID_SIZE +#define ISO15693_GENERIC_MEM_SIZE 8192 //ISO15693_MAX_MEM_SIZE + +void VicinityAppInit(void); +void VicinityAppReset(void); +void VicinityAppTask(void); +void VicinityAppTick(void); +uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes); +void VicinityGetUid(ConfigurationUidType Uid); +void VicinitySetUid(ConfigurationUidType Uid); + + + +#endif /* VICINITY_H_ */ diff --git a/Firmware/Chameleon-Mini/Codec/Codec.h b/Firmware/Chameleon-Mini/Codec/Codec.h index cf9d67d..4324126 100644 --- a/Firmware/Chameleon-Mini/Codec/Codec.h +++ b/Firmware/Chameleon-Mini/Codec/Codec.h @@ -17,6 +17,7 @@ #include "ISO14443-2A.h" #include "Reader14443-2A.h" +#include "ISO15693.h" /* Timing definitions for ISO14443A */ #define ISO14443A_SUBCARRIER_DIVIDER 16 @@ -38,6 +39,7 @@ #define CODEC_DEMOD_IN_EVMUX0 EVSYS_CHMUX_PORTB_PIN1_gc #define CODEC_DEMOD_IN_EVMUX1 EVSYS_CHMUX_PORTB_PIN2_gc #define CODEC_DEMOD_IN_INT0_VECT PORTB_INT0_vect +#define CODEC_DEMOD_IN_INT1_VECT PORTB_INT1_vect #define CODEC_LOADMOD_PORT PORTC #define CODEC_LOADMOD_MASK PIN6_bm #define CODEC_CARRIER_IN_PORT PORTC @@ -56,7 +58,8 @@ #define CODEC_SUBCARRIER_CCEN_OOK TC1_CCBEN_bm #define CODEC_TIMER_SAMPLING TCD0 #define CODEC_TIMER_SAMPLING_CCA_VECT TCD0_CCA_vect -#define CODEC_TIMER_SAMPLING_CCB_VECT TCD0_CCB_vect +#define CODEC_TIMER_SAMPLING_CCB_VECT TCD0_CCB_vect +#define CODEC_TIMER_SAMPLING_CCC_VECT TCD0_CCC_vect #define CODEC_TIMER_LOADMOD TCE0 #define CODEC_TIMER_LOADMOD_OVF_VECT TCE0_OVF_vect #define CODEC_TIMER_LOADMOD_CCA_VECT TCE0_CCA_vect @@ -140,7 +143,7 @@ INLINE void CodecInitCommon(void) CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL0 = PORT_ISC_RISING_gc; CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL1 = PORT_ISC_FALLING_gc; CODEC_DEMOD_IN_PORT.INT0MASK = 0; - CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc; + CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc | PORT_INT1LVL_HI_gc; EVSYS.CH0MUX = CODEC_DEMOD_IN_EVMUX0; EVSYS.CH1MUX = CODEC_DEMOD_IN_EVMUX1; @@ -201,6 +204,11 @@ INLINE void CodecSetSubcarrier(SubcarrierModType ModType, uint16_t Divider) } } +INLINE void CodecChangeDivider(uint16_t Divider) +{ + CODEC_SUBCARRIER_TIMER.PER = Divider - 1; +} + INLINE void CodecStartSubcarrier(void) { CODEC_SUBCARRIER_TIMER.CTRLA = CODEC_TIMER_CARRIER_CLKSEL; diff --git a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c index e43ea61..ba91594 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c +++ b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c @@ -76,10 +76,10 @@ static void StartDemod(void) { /* Start looking out for modulation pause via interrupt. */ CODEC_DEMOD_IN_PORT.INTFLAGS = 0x03; - CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; + CODEC_DEMOD_IN_PORT.INT1MASK = CODEC_DEMOD_IN_MASK0; } -ISR(CODEC_DEMOD_IN_INT0_VECT) { +ISR(CODEC_DEMOD_IN_INT1_VECT) { /* This is the first edge of the first modulation-pause after StartDemod. * Now we have time to start * demodulating beginning from one bit-width after this edge. */ @@ -109,7 +109,7 @@ ISR(CODEC_DEMOD_IN_INT0_VECT) { CODEC_TIMER_LOADMOD.CTRLA = CODEC_TIMER_CARRIER_CLKSEL; /* Disable this interrupt */ - CODEC_DEMOD_IN_PORT.INT0MASK = 0; + CODEC_DEMOD_IN_PORT.INT1MASK = 0; } ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c new file mode 100644 index 0000000..ac4d99a --- /dev/null +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -0,0 +1,575 @@ +/* + * ISO15693.c + * + * Created on: 25.01.2017 + * Author: Phillip Nash + */ + +#include "ISO15693.h" +#include "../System.h" +#include "../Application/Application.h" +#include "LEDHook.h" +#include "AntennaLevel.h" +#include "Terminal/Terminal.h" +#include +#include +#include + + +#define SOC_1_OF_4_CODE 0x7B +#define SOC_1_OF_256_CODE 0x7E +#define EOC_CODE 0xDF +#define ISO15693_SAMPLE_CLK TC_CLKSEL_DIV2_gc // 13.56MHz +#define ISO15693_SAMPLE_PERIOD 128 // 9.4us + +#define WRITE_GRID_CYCLES 4096 +#define SUBCARRIER_1 32 +#define SUBCARRIER_2 28 +#define SUBCARRIER_OFF 0 +#define SOF_PATTERN 0x1D +#define EOF_PATTERN 0xB8 + +// These registers provide quick access but are limited +// so global vars will be necessary +#define DataRegister Codec8Reg0 +#define StateRegister Codec8Reg1 +#define ModulationPauseCount Codec8Reg2 +#define SampleRegister Codec8Reg3 +#define BitSent CodecCount16Register1 +#define BitSampleCount CodecCount16Register2 +#define CodecBufferPtr CodecPtrRegister1 + +static volatile struct { + volatile bool DemodFinished; + volatile bool LoadmodFinished; + volatile bool DemodAborted; +} Flags = { 0 }; + +typedef enum { + DEMOD_SOC_STATE, + DEMOD_1_OUT_OF_4_STATE, + DEMOD_1_OUT_OF_256_STATE +} DemodStateType; + +static volatile enum { + LOADMOD_WAIT, + + /* Single subcarrier */ + LOADMOD_START_SINGLE, + LOADMOD_SOF_SINGLE, + LOADMOD_BIT0_SINGLE, + LOADMOD_BIT1_SINGLE, + LOADMOD_EOF_SINGLE, + + /* Dual subcarrier */ + LOADMOD_START_DUAL, + LOADMOD_SOF_DUAL, + LOADMOD_BIT0_DUAL, + LOADMOD_BIT1_DUAL, + LOADMOD_EOF_DUAL, + + LOADMOD_FINISHED +} LoadModState; + +static volatile DemodStateType DemodState; +static volatile uint8_t ShiftRegister; +static volatile uint8_t ByteCount; +static volatile uint16_t BitRate1; +static volatile uint16_t BitRate2; +static volatile uint16_t SampleDataCount; +static volatile uint16_t ReadCommandFromReader = 0; + +#ifdef CONFIG_VICINITY_SUPPORT + +// Started when a single pulse has been detected +ISR(CODEC_DEMOD_IN_INT0_VECT) { + // Start sample timer + CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm; + CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_HI_gc; + /* Disable this interrupt */ + CODEC_DEMOD_IN_PORT.INT0MASK = 0; +} + +INLINE void ISO15693_EOC(void) +{ + BitRate1 = 256 * 4; + if (CodecBuffer[0] & ISO15693_REQ_DATARATE_HIGH) + BitRate1 = 256; + + if (CodecBuffer[0] & ISO15693_REQ_SUBCARRIER_DUAL) + { + BitRate2 = 252 * 4; + if (CodecBuffer[0] & ISO15693_REQ_DATARATE_HIGH) + BitRate2 = 252; + } else { + BitRate2 = BitRate1; + } + + CODEC_TIMER_LOADMOD.CTRLD = 0; + CODEC_TIMER_LOADMOD.INTFLAGS = TC0_CCBIF_bm; + CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_HI_gc; + CODEC_TIMER_LOADMOD.PERBUF = BitRate1 - 1; + + Flags.DemodFinished = 1; + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + CODEC_TIMER_SAMPLING.INTCTRLB = 0; +} + +ISR(CODEC_TIMER_SAMPLING_CCC_VECT) // Reading data sent from the reader +{ + /* Shift demod data */ + SampleRegister = (SampleRegister << 1) | (!(CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK) ? 0x01 : 0x00); + + if (++BitSampleCount == 8) + { + BitSampleCount = 0; + switch (DemodState) + { + case DEMOD_SOC_STATE: + if (SampleRegister == SOC_1_OF_4_CODE) + { + DemodState = DEMOD_1_OUT_OF_4_STATE; + SampleDataCount = 0; + ModulationPauseCount = 0; + } else if (SampleRegister == SOC_1_OF_256_CODE) { + DemodState = DEMOD_1_OUT_OF_256_STATE; + SampleDataCount = 0; + } else { // No SOC. Restart and try again + Flags.DemodFinished = 1; + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + CODEC_TIMER_SAMPLING.INTCTRLB = 0; + } + break; + + case DEMOD_1_OUT_OF_4_STATE: + if (SampleRegister == EOC_CODE) + { + ISO15693_EOC(); + } else { + uint8_t SampleData = ~SampleRegister; + if (SampleData == (0x01 << 6)) + { + /* ^_^^^^^^ -> 00 */ + ModulationPauseCount++; + DataRegister >>= 2; + + } else if (SampleData == (0x01 << 4)) { + /* ^^^_^^^^ -> 01 */ + ModulationPauseCount++; + DataRegister >>= 2; + DataRegister |= 0b01 << 6; + + } else if (SampleData == (0x01 << 2)) { + /* ^^^^^_^^ -> 10 */ + ModulationPauseCount++; + DataRegister >>= 2; + DataRegister |= 0b10 << 6; + + } else if (SampleData == (0x01 << 0)) { + /* ^^^^^^^_ -> 11 */ + ModulationPauseCount++; + DataRegister >>= 2; + DataRegister |= 0b11 << 6; + } + + if (ModulationPauseCount == 4) + { + ModulationPauseCount = 0; + *CodecBufferPtr = DataRegister; + ++CodecBufferPtr; + ++ByteCount; + } + } + break; + + case DEMOD_1_OUT_OF_256_STATE: + if (SampleRegister == EOC_CODE) + { + ISO15693_EOC(); + } else { + uint8_t Position = ((SampleDataCount / 2) % 256) - 1; + uint8_t SampleData = ~SampleRegister; + + if (SampleData == (0x01 << 6)) + { + /* ^_^^^^^^ -> N-3 */ + DataRegister = Position - 3; + ModulationPauseCount++; + + } else if (SampleData == (0x01 << 4)) { + /* ^^^_^^^^ -> N-2 */ + DataRegister = Position - 2; + ModulationPauseCount++; + + } else if (SampleData == (0x01 << 2)) { + /* ^^^^^_^^ -> N-1 */ + DataRegister = Position - 1; + ModulationPauseCount++; + + } else if (SampleData == (0x01 << 0)) { + /* ^^^^^^^_ -> N-0 */ + DataRegister = Position - 0; + ModulationPauseCount++; + } + + if (ModulationPauseCount == 1) + { + ModulationPauseCount = 0; + *CodecBufferPtr = DataRegister; + ++CodecBufferPtr; + ++ByteCount; + } + } + break; + } + } + SampleDataCount++; +} + + +ISR(CODEC_TIMER_LOADMOD_CCB_VECT) +{ + static void* JumpTable[] = { + [LOADMOD_START_SINGLE] = &&LOADMOD_START_SINGLE_LABEL, + [LOADMOD_SOF_SINGLE] = &&LOADMOD_SOF_SINGLE_LABEL, + [LOADMOD_BIT0_SINGLE] = &&LOADMOD_BIT0_SINGLE_LABEL, + [LOADMOD_BIT1_SINGLE] = &&LOADMOD_BIT1_SINGLE_LABEL, + [LOADMOD_EOF_SINGLE] = &&LOADMOD_EOF_SINGLE_LABEL, + [LOADMOD_START_DUAL] = &&LOADMOD_START_DUAL_LABEL, + [LOADMOD_SOF_DUAL] = &&LOADMOD_SOF_DUAL_LABEL, + [LOADMOD_BIT0_DUAL] = &&LOADMOD_BIT0_DUAL_LABEL, + [LOADMOD_BIT1_DUAL] = &&LOADMOD_BIT1_DUAL_LABEL, + [LOADMOD_EOF_DUAL] = &&LOADMOD_EOF_DUAL_LABEL, + [LOADMOD_FINISHED] = &&LOADMOD_FINISHED_LABEL + }; + + if ( (StateRegister >= LOADMOD_START_SINGLE) && (StateRegister <= LOADMOD_FINISHED) ) { + goto *JumpTable[StateRegister]; + } else { + return; + } + + LOADMOD_START_SINGLE_LABEL: + CodecStartSubcarrier(); + ShiftRegister = SOF_PATTERN; + BitSent = 0; + // fallthrough + LOADMOD_SOF_SINGLE_LABEL: + if (ShiftRegister & 0x80) { + CodecSetLoadmodState(true); + } else { + CodecSetLoadmodState(false); + } + + ShiftRegister <<= 1; + BitSent++; + + if ( (BitSent % 8) == 0) { + /* Last SOF bit has been put out. Start sending out data */ + StateRegister = LOADMOD_BIT0_SINGLE; + ShiftRegister = (*CodecBufferPtr++); + } else { + StateRegister = LOADMOD_SOF_SINGLE; + } + return; + + LOADMOD_BIT0_SINGLE_LABEL: //Manchester encoding + + if (ShiftRegister & 0x01) { + /* Deactivate carrier */ + CodecSetLoadmodState(false); + } else { + /* Activate carrier */ + CodecSetLoadmodState(true); + } + + StateRegister = LOADMOD_BIT1_SINGLE; + return; + + LOADMOD_BIT1_SINGLE_LABEL: //Manchester encoding + if (ShiftRegister & 0x01) { + CodecSetLoadmodState(true); + } else { + CodecSetLoadmodState(false); + } + + ShiftRegister >>= 1; + BitSent++; + + StateRegister = LOADMOD_BIT0_SINGLE; + + if ( (BitSent % 8) == 0 ) { + /* Byte boundary */ + if (--ByteCount == 0) { + /* No more data left */ + ShiftRegister = EOF_PATTERN; + StateRegister = LOADMOD_EOF_SINGLE; + } else { + ShiftRegister = (*CodecBufferPtr++); + } + } + return; + + LOADMOD_EOF_SINGLE_LABEL: //End of Manchester encoding + + /* Output EOF */ + if (ShiftRegister & 0x80) { + CodecSetLoadmodState(true); + } else { + CodecSetLoadmodState(false); + } + + ShiftRegister <<= 1; + BitSent++; + + if ( (BitSent % 8) == 0) { + /* Last bit has been put out */ + StateRegister = LOADMOD_FINISHED; + } else { + StateRegister = LOADMOD_EOF_SINGLE; + } + return; + + + + + + + + LOADMOD_START_DUAL_LABEL: + CodecStartSubcarrier(); + ShiftRegister = SOF_PATTERN; + BitSent = 0; + CodecSetLoadmodState(true); + // fallthrough + LOADMOD_SOF_DUAL_LABEL: + if (ShiftRegister & 0x80) { + CodecChangeDivider(SUBCARRIER_1); + CODEC_TIMER_LOADMOD.PER = BitRate1 - 1; + } else { + CodecChangeDivider(SUBCARRIER_2); + CODEC_TIMER_LOADMOD.PER = BitRate2 - 1; + } + + ShiftRegister <<= 1; + BitSent++; + + if ( (BitSent % 8) == 0) { + /* Last SOF bit has been put out. Start sending out data */ + StateRegister = LOADMOD_BIT0_DUAL; + ShiftRegister = (*CodecBufferPtr++); + } else { + StateRegister = LOADMOD_BIT0_DUAL; + } + return; + + LOADMOD_BIT0_DUAL_LABEL: //Manchester encoding + + if (ShiftRegister & 0x01) { + /* fc / 32 */ + CodecChangeDivider(SUBCARRIER_1); + CODEC_TIMER_LOADMOD.PER = BitRate1 - 1; + } else { + /* fc / 28 */ + CodecChangeDivider(SUBCARRIER_2); + CODEC_TIMER_LOADMOD.PER = BitRate2 - 1; + } + + StateRegister = LOADMOD_BIT1_DUAL; + return; + + LOADMOD_BIT1_DUAL_LABEL: //Manchester encoding + if (ShiftRegister & 0x01) { + CodecChangeDivider(SUBCARRIER_2); + CODEC_TIMER_LOADMOD.PER = BitRate2 - 1; + } else { + CodecChangeDivider(SUBCARRIER_1); + CODEC_TIMER_LOADMOD.PER = BitRate1 - 1; + } + + ShiftRegister >>= 1; + BitSent++; + + StateRegister = LOADMOD_BIT0_DUAL; + + if ( (BitSent % 8) == 0 ) { + /* Byte boundary */ + if (--ByteCount == 0) { + /* No more data left */ + ShiftRegister = EOF_PATTERN; + StateRegister = LOADMOD_EOF_DUAL; + } else { + ShiftRegister = (*CodecBufferPtr++); + } + } + return; + + LOADMOD_EOF_DUAL_LABEL: //End of Manchester encoding + + /* Output EOF */ + if (ShiftRegister & 0x80) { + CodecChangeDivider(SUBCARRIER_1); + CODEC_TIMER_LOADMOD.PER = BitRate1 - 1; + } else { + CodecChangeDivider(SUBCARRIER_2); + CODEC_TIMER_LOADMOD.PER = BitRate2 - 1; + } + + ShiftRegister <<= 1; + BitSent++; + + if ( (BitSent % 8) == 0) { + /* Last bit has been put out */ + StateRegister = LOADMOD_FINISHED; + } else { + StateRegister = LOADMOD_EOF_DUAL; + } + return; + + + + + + + + LOADMOD_FINISHED_LABEL: + + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + CODEC_TIMER_LOADMOD.INTCTRLB = 0; + CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, SUBCARRIER_1); + Flags.LoadmodFinished = 1; + return; +} + +#endif /* CONFIG_VICINITY_SUPPORT */ + +void StartISO15693Demod(void) { + + CodecBufferPtr = CodecBuffer; + Flags.DemodFinished = 0; + Flags.LoadmodFinished = 0; + DemodState = DEMOD_SOC_STATE; + DataRegister = 0; + SampleRegister = 0; + BitSampleCount = 0; + SampleDataCount = 0; + ModulationPauseCount = 0; + ByteCount = 0; + ShiftRegister = 0; + + CodecSetDemodPower(true); + + /* Configure sampling-timer free running and sync to first modulation-pause. */ + CODEC_TIMER_SAMPLING.CNT = 0; + CODEC_TIMER_SAMPLING.PER = ISO15693_SAMPLE_PERIOD - 1; + CODEC_TIMER_SAMPLING.CCC = ISO15693_SAMPLE_PERIOD / 2 - 14 - 1; /* Half bit. ISR compensate*/ + CODEC_TIMER_SAMPLING.CTRLA = ISO15693_SAMPLE_CLK; + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL; + CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm; + CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc; + + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL; + CODEC_TIMER_LOADMOD.PER = 4192 + 128 + 128 - 1; + CODEC_TIMER_LOADMOD.INTCTRLA = 0; + CODEC_TIMER_LOADMOD.INTCTRLB = 0; + CODEC_TIMER_LOADMOD.CTRLA = ISO15693_SAMPLE_CLK; + + /* Start looking out for modulation pause via interrupt. */ + CODEC_DEMOD_IN_PORT.INTFLAGS = 0x03; + CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; +} + +void ISO15693CodecInit(void) +{ + CodecInitCommon(); + StartISO15693Demod(); +} + +void ISO15693CodecDeInit(void) +{ + /* Gracefully shutdown codec */ + CODEC_DEMOD_IN_PORT.INT0MASK = 0; + + CodecBufferPtr = CodecBuffer; + Flags.DemodFinished = 0; + Flags.LoadmodFinished = 0; + DemodState = DEMOD_SOC_STATE; + DataRegister = 0; + SampleRegister = 0; + BitSampleCount = 0; + SampleDataCount = 0; + ModulationPauseCount = 0; + ByteCount = 0; + ShiftRegister = 0; + + //Disable sample timer + CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc; + CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc; + CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm; + + //Disable load modulation + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; + CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_OFF_gc; + CODEC_TIMER_LOADMOD.INTFLAGS = TC0_CCBIF_bm; + + CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, 0); + CodecSetDemodPower(false); + CodecSetLoadmodState(false); +} + +void ISO15693CodecTask(void) +{ + if (Flags.DemodFinished) { + Flags.DemodFinished = 0; + + uint16_t DemodByteCount = ByteCount; + uint16_t AppReceivedByteCount = 0; + bool bDualSubcarrier = false; + + if (DemodByteCount > 0) + { + if (CodecBuffer[0] & ISO15693_REQ_SUBCARRIER_DUAL) + { + bDualSubcarrier = true; + } + LogEntry(LOG_INFO_CODEC_RX_DATA, CodecBuffer, DemodByteCount); + AppReceivedByteCount = ApplicationProcess(CodecBuffer, DemodByteCount); + + } else { + ApplicationReset(); + } + + //This is only reached when we've received a valid frame + if (AppReceivedByteCount > 0) { + LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount); + CodecBufferPtr = CodecBuffer; + ByteCount = AppReceivedByteCount; + + CodecStartSubcarrier(); + + /* Start loadmodulating */ + if (bDualSubcarrier) { + StateRegister = LOADMOD_START_DUAL; + CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_2); + } else { + StateRegister = LOADMOD_START_SINGLE; + CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_1); + } + + } else { + /* No data to be processed. Disable T1 waiting and + * start listening again */ + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_OFF_gc; + StartISO15693Demod(); + } + } + + if (Flags.LoadmodFinished) { + Flags.LoadmodFinished = 0; + /* Load modulation has been finished. Stop it and start to listen + * for incoming data again. */ + StartISO15693Demod(); + } +} diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.h b/Firmware/Chameleon-Mini/Codec/ISO15693.h new file mode 100644 index 0000000..93162d7 --- /dev/null +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.h @@ -0,0 +1,47 @@ +/* + * ISO15693.h + * + * Created on: 25.01.2017 + * Author: Phillip Nash + */ + +#ifndef ISO15693_H_ +#define ISO15693_H_ + +#include "Terminal/CommandLine.h" + +#define ISO15693_APP_NO_RESPONSE 0x0000 + +/* VERY OUTDATED */ +#define TIMER_SAMPLING TCC0 +#define TIMER_T1_BITRATE TCD1 +#define TIMER_SUBCARRIER TCD0 + +#define SUBCARRIER_1 32 +#define SUBCARRIER_2 28 +#define SUBCARRIER_OFF 0 +#define SOF_PATTERN 0x1D +#define EOF_PATTERN 0xB8 + +#define T1_NOMINAL_CYCLES 4352 - 14//4352 - 25 /* ISR prologue compensation */ +#define WRITE_GRID_CYCLES 4096 + +//Used when checking the request sent from the reader +#define ISO15693_REQ_SUBCARRIER_SINGLE 0x00 +#define ISO15693_REQ_SUBCARRIER_DUAL 0x01 +#define ISO15693_REQ_DATARATE_LOW 0x00 +#define ISO15693_REQ_DATARATE_HIGH 0x02 + + +/* Codec Interface */ +void ISO15693CodecInit(void); +void ISO15693CodecDeInit(void); +void ISO15693CodecTask(void); + +/* Application Interface */ +void ISO15693CodecStart(void); +void ISO15693CodecReset(void); + + + +#endif /* ISO15693_H_ */ diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c index 72ffce1..0727eda 100644 --- a/Firmware/Chameleon-Mini/Configuration.c +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -37,6 +37,9 @@ static const MapEntryType PROGMEM ConfigurationMap[] = { #ifdef CONFIG_ISO14443A_READER_SUPPORT { .Id = CONFIG_ISO14443A_READER, .Text = "ISO14443A_READER" }, #endif +#ifdef CONFIG_VICINITY_SUPPORT + { .Id = CONFIG_VICINITY, .Text = "VICINITY" }, +#endif }; /* Include all Codecs and Applications */ @@ -220,6 +223,23 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ReadOnly = false }, #endif +#ifdef CONFIG_VICINITY_SUPPORT + [CONFIG_VICINITY] = { + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = VicinityAppInit, + .ApplicationResetFunc = VicinityAppReset, + .ApplicationTaskFunc = VicinityAppTask, + .ApplicationTickFunc = VicinityAppTick, + .ApplicationProcessFunc = VicinityAppProcess, + .ApplicationGetUidFunc = VicinityGetUid, + .ApplicationSetUidFunc = VicinitySetUid, + .UidSize = ISO15693_GENERIC_UID_SIZE, + .MemorySize = ISO15693_GENERIC_MEM_SIZE, + .ReadOnly = false + }, +#endif }; ConfigurationType ActiveConfiguration; diff --git a/Firmware/Chameleon-Mini/Configuration.h b/Firmware/Chameleon-Mini/Configuration.h index 2ca4944..8eeba79 100644 --- a/Firmware/Chameleon-Mini/Configuration.h +++ b/Firmware/Chameleon-Mini/Configuration.h @@ -42,6 +42,9 @@ typedef enum { #endif #ifdef CONFIG_ISO14443A_READER_SUPPORT CONFIG_ISO14443A_READER, +#endif +#ifdef CONFIG_VICINITY_SUPPORT + CONFIG_VICINITY, #endif /* This HAS to be the last element */ CONFIG_COUNT diff --git a/Firmware/Chameleon-Mini/Makefile b/Firmware/Chameleon-Mini/Makefile index 9d3175f..13300c1 100644 --- a/Firmware/Chameleon-Mini/Makefile +++ b/Firmware/Chameleon-Mini/Makefile @@ -12,6 +12,7 @@ SETTINGS += -DCONFIG_MF_CLASSIC_4K_7B_SUPPORT SETTINGS += -DCONFIG_MF_ULTRALIGHT_SUPPORT SETTINGS += -DCONFIG_ISO14443A_SNIFF_SUPPORT SETTINGS += -DCONFIG_ISO14443A_READER_SUPPORT +SETTINGS += -DCONFIG_VICINITY_SUPPORT #Support magic mode on mifare classic configuration SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE @@ -92,8 +93,8 @@ TARGET = Chameleon-Mini OPTIMIZATION = s SRC += $(TARGET).c LUFADescriptors.c System.c Configuration.c Random.c Common.c Memory.c MemoryAsm.S Button.c Log.c Settings.c LED.c Map.c AntennaLevel.c SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Terminal/CommandLine.c -SRC += Codec/Codec.c Codec/ISO14443-2A.c Codec/Reader14443-2A.c Codec/Reader14443-ISR.S -SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c +SRC += Codec/Codec.c Codec/ISO14443-2A.c Codec/Reader14443-2A.c Codec/Reader14443-ISR.S Codec/ISO15693.c +SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c Application/Vicinity.c Application/ISO15693-A.c SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) LUFA_PATH = ../LUFA CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) -DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) -DCOMMIT_ID=\"$(COMMIT_ID)\" $(SETTINGS) From 60607f37a847b95ab03be11437396f50016b727a Mon Sep 17 00:00:00 2001 From: georg Date: Wed, 20 Sep 2017 16:40:55 +0200 Subject: [PATCH 02/67] added vdwels changes --- .../Chameleon-Mini/Application/Application.h | 1 + .../Chameleon-Mini/Application/Sl2s2002.c | 171 ++++++++++++++++++ .../Chameleon-Mini/Application/Sl2s2002.h | 27 +++ Firmware/Chameleon-Mini/Configuration.c | 40 ++++ Firmware/Chameleon-Mini/Configuration.h | 6 + Firmware/Chameleon-Mini/Makefile | 4 +- 6 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 Firmware/Chameleon-Mini/Application/Sl2s2002.c create mode 100644 Firmware/Chameleon-Mini/Application/Sl2s2002.h diff --git a/Firmware/Chameleon-Mini/Application/Application.h b/Firmware/Chameleon-Mini/Application/Application.h index b732796..82fbf9e 100644 --- a/Firmware/Chameleon-Mini/Application/Application.h +++ b/Firmware/Chameleon-Mini/Application/Application.h @@ -17,6 +17,7 @@ #include "MifareClassic.h" #include "Reader14443A.h" #include "Vicinity.h" +#include "Sl2s2002.h" /* Function wrappers */ diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.c b/Firmware/Chameleon-Mini/Application/Sl2s2002.c new file mode 100644 index 0000000..82c51ed --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.c @@ -0,0 +1,171 @@ +/* + * ISO15693.c + * + * Created on: 01-03-2017 + * Author: Phillip Nash + */ + + +#include "Sl2s2002.h" +#include "../Codec/ISO15693.h" +#include "../Memory.h" +#include "Crypto1.h" +#include "../Random.h" +#include "ISO15693-A.h" + +#define BYTES_PER_PAGE 4 + +static enum { + STATE_READY, + STATE_SELECTED, + STATE_QUIET +} State; + + +ISO15693UidType Sl2s2002Uid = {0x78, 0xD3, 0xF4, 0x3F, 0x50, 0x01, 0x04, 0xE0}; + +//ISO15693UidType Sl2s2002Uid = {0x60, 0x0B, 0x88, 0x77, 0x06, 0x44, 0x02, 0xE1}; + + + +void Sl2s2002AppInit(void) +{ + State = STATE_READY; +} + +void Sl2s2002AppReset(void) +{ + State = STATE_READY; +} + + +void Sl2s2002AppTask(void) +{ + +} + +void Sl2s2002AppTick(void) +{ + + +} + +// void sendIntToTermina(uint8_t val) +// { +// char buf[16]; +// snprintf(buf,16, "%02x",val); +// TerminalSendString(buf); +// } + +uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { + if(ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) { + // At this point, we have a valid ISO15693 frame + uint8_t Command = FrameBuf[1]; + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + + //TerminalSendString("Received command: "); +// for (int i = 0; i < (FrameBytes - 2); i++) { +// sendIntToTermina(FrameBuf[i]); +// } +// TerminalSendString("\n"); + + + switch(State) { + case STATE_READY: + if (Command == ISO15693_CMD_INVENTORY) { + FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[1] = 0x00; /* DSFID */ + ISO15693CopyUid(&FrameBuf[2], Sl2s2002Uid); + ResponseByteCount = 10; + } else if (Command == ISO15693_CMD_STAY_QUIET) { + if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + State = STATE_QUIET; + } + } else if (Command == ISO15693_CMD_GET_SYS_INFO) { + if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + FrameBuf[0] = 0; /* Flags */ + FrameBuf[1] = 0x0F; /* InfoFlags */ + ISO15693CopyUid(&FrameBuf[2], Sl2s2002Uid); + FrameBuf[10] = 0x00; + FrameBuf[11] = 0xC2; + FrameBuf[12] = 0x04; + FrameBuf[13] = 0x03; + FrameBuf[14] = 0x01; + ResponseByteCount = 15; + } + } else if (Command == ISO15693_CMD_READ_SINGLE) { + if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + uint8_t PageAddress = FrameBuf[10]; + FrameBuf[0] = 0; /* Flags */ + MemoryReadBlock(FrameBuf + 1, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + ResponseByteCount = 5; + } + } else if (Command == ISO15693_CMD_READ_MULTIPLE) { + if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + uint8_t PageAddressStart = FrameBuf[10]; + uint8_t PageAddressEnd = FrameBuf[11]; + FrameBuf[0] = 0; /* Flags */ + MemoryReadBlock(FrameBuf + 1, PageAddressStart * BYTES_PER_PAGE, BYTES_PER_PAGE * (PageAddressEnd - PageAddressStart + 1)); + ResponseByteCount = 1 + BYTES_PER_PAGE * (PageAddressEnd - PageAddressStart + 1); + } + } else if (Command == ISO15693_CMD_GET_BLOCK_SEC) { + if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + uint8_t PageAddressStart = FrameBuf[10]; + uint8_t PageAddressEnd = FrameBuf[11]; + FrameBuf[0] = 0; /* Flags */ + for (int i = 1; i <= (PageAddressEnd - PageAddressStart + 1); i++) { + FrameBuf[i] = 0x00; + } + ResponseByteCount = 1 + (PageAddressEnd - PageAddressStart + 1); + } + } + break; + case STATE_SELECTED: + + break; + + case STATE_QUIET: + if (Command == ISO15693_CMD_RESET_TO_READY) { + if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + FrameBuf[0] = 0; + ResponseByteCount = 1; + State = STATE_READY; + } + } + break; + + default: + break; + } + + if (ResponseByteCount > 0) { + /* There is data to be sent. Append CRC */ + ISO15693AppendCRC(FrameBuf, ResponseByteCount); + ResponseByteCount += ISO15693_CRC16_SIZE; + } + + return ResponseByteCount; + + } else { // Invalid CRC + return ISO15693_APP_NO_RESPONSE; + } + } else { // Min frame size not met + return ISO15693_APP_NO_RESPONSE; + } + +} + +void Sl2s2002GetUid(ConfigurationUidType Uid) +{ + memcpy(Uid, Sl2s2002Uid, sizeof(ConfigurationUidType)); +} + +void Sl2s2002SetUid(ConfigurationUidType Uid) +{ + memcpy(Sl2s2002Uid, Uid, sizeof(ConfigurationUidType)); +} + + + diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.h b/Firmware/Chameleon-Mini/Application/Sl2s2002.h new file mode 100644 index 0000000..be37eb2 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.h @@ -0,0 +1,27 @@ +/* + * MifareClassic.h + * + * Created on: 01.03.2017 + * Author: skuser + */ + +#ifndef SL2S2002_H_ +#define SL2S2002_H_ + +#include "Application.h" +#include "ISO15693-A.h" + +#define ISO15693_GENERIC_UID_SIZE 8 //ISO15693_UID_SIZE +#define ISO15693_GENERIC_MEM_SIZE 8192 //ISO15693_MAX_MEM_SIZE + +void Sl2s2002AppInit(void); +void Sl2s2002AppReset(void); +void Sl2s2002AppTask(void); +void Sl2s2002AppTick(void); +uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes); +void Sl2s2002GetUid(ConfigurationUidType Uid); +void Sl2s2002SetUid(ConfigurationUidType Uid); + + + +#endif /* VICINITY_H_ */ diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c index 0727eda..03c368a 100644 --- a/Firmware/Chameleon-Mini/Configuration.c +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -40,6 +40,12 @@ static const MapEntryType PROGMEM ConfigurationMap[] = { #ifdef CONFIG_VICINITY_SUPPORT { .Id = CONFIG_VICINITY, .Text = "VICINITY" }, #endif +#ifdef CONFIG_ISO15693_SNIFF_SUPPORT + { .Id = CONFIG_ISO15693_SNIFF, .Text = "ISO15693_SNIFF" }, +#endif +#ifdef CONFIG_SL2S2002_SUPPORT + { .Id = CONFIG_SL2S2002, .Text = "SL2S2002" }, +#endif }; /* Include all Codecs and Applications */ @@ -240,6 +246,40 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ReadOnly = false }, #endif +#ifdef CONFIG_ISO15693_SNIFF_SUPPORT + [CONFIG_ISO15693_SNIFF] = { + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = ApplicationInitDummy, + .ApplicationResetFunc = ApplicationResetDummy, + .ApplicationTaskFunc = ApplicationTaskDummy, + .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationProcessFunc = ApplicationProcessDummy, + .ApplicationGetUidFunc = ApplicationGetUidDummy, + .ApplicationSetUidFunc = ApplicationSetUidDummy, + .UidSize = 0, + .MemorySize = 0, + .ReadOnly = true + }, +#endif +#ifdef CONFIG_SL2S2002_SUPPORT + [CONFIG_SL2S2002] = { + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = Sl2s2002AppInit, + .ApplicationResetFunc = Sl2s2002AppReset, + .ApplicationTaskFunc = Sl2s2002AppTask, + .ApplicationTickFunc = Sl2s2002AppTick, + .ApplicationProcessFunc = Sl2s2002AppProcess, + .ApplicationGetUidFunc = Sl2s2002GetUid, + .ApplicationSetUidFunc = Sl2s2002SetUid, + .UidSize = ISO15693_GENERIC_UID_SIZE, + .MemorySize = ISO15693_GENERIC_MEM_SIZE, + .ReadOnly = false + }, +#endif }; ConfigurationType ActiveConfiguration; diff --git a/Firmware/Chameleon-Mini/Configuration.h b/Firmware/Chameleon-Mini/Configuration.h index 8eeba79..6de5873 100644 --- a/Firmware/Chameleon-Mini/Configuration.h +++ b/Firmware/Chameleon-Mini/Configuration.h @@ -45,6 +45,12 @@ typedef enum { #endif #ifdef CONFIG_VICINITY_SUPPORT CONFIG_VICINITY, +#endif +#ifdef CONFIG_ISO15693_SNIFF_SUPPORT + CONFIG_ISO15693_SNIFF, +#endif +#ifdef CONFIG_SL2S2002_SUPPORT + CONFIG_SL2S2002, #endif /* This HAS to be the last element */ CONFIG_COUNT diff --git a/Firmware/Chameleon-Mini/Makefile b/Firmware/Chameleon-Mini/Makefile index 13300c1..e00a9bb 100644 --- a/Firmware/Chameleon-Mini/Makefile +++ b/Firmware/Chameleon-Mini/Makefile @@ -13,6 +13,8 @@ SETTINGS += -DCONFIG_MF_ULTRALIGHT_SUPPORT SETTINGS += -DCONFIG_ISO14443A_SNIFF_SUPPORT SETTINGS += -DCONFIG_ISO14443A_READER_SUPPORT SETTINGS += -DCONFIG_VICINITY_SUPPORT +SETTINGS += -DCONFIG_SL2S2002_SUPPORT +SETTINGS += -DCONFIG_ISO15693_SNIFF_SUPPORT #Support magic mode on mifare classic configuration SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE @@ -94,7 +96,7 @@ OPTIMIZATION = s SRC += $(TARGET).c LUFADescriptors.c System.c Configuration.c Random.c Common.c Memory.c MemoryAsm.S Button.c Log.c Settings.c LED.c Map.c AntennaLevel.c SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Terminal/CommandLine.c SRC += Codec/Codec.c Codec/ISO14443-2A.c Codec/Reader14443-2A.c Codec/Reader14443-ISR.S Codec/ISO15693.c -SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c Application/Vicinity.c Application/ISO15693-A.c +SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c Application/Vicinity.c Application/Sl2s2002.c Application/ISO15693-A.c SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) LUFA_PATH = ../LUFA CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) -DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) -DCOMMIT_ID=\"$(COMMIT_ID)\" $(SETTINGS) From 6c1dabd92f1406ddea5df6235df2d572ff607c5e Mon Sep 17 00:00:00 2001 From: georg Date: Fri, 22 Sep 2017 18:16:24 +0200 Subject: [PATCH 03/67] fixes (e.g. PageAddressCount instead of ...End) --- .../Chameleon-Mini/Application/Sl2s2002.c | 31 ++++++++++++++----- Firmware/Chameleon-Mini/Codec/ISO15693.c | 2 +- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.c b/Firmware/Chameleon-Mini/Application/Sl2s2002.c index 82c51ed..2d3af40 100644 --- a/Firmware/Chameleon-Mini/Application/Sl2s2002.c +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.c @@ -90,7 +90,7 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ISO15693CopyUid(&FrameBuf[2], Sl2s2002Uid); FrameBuf[10] = 0x00; FrameBuf[11] = 0xC2; - FrameBuf[12] = 0x04; + FrameBuf[12] = 0x03; FrameBuf[13] = 0x03; FrameBuf[14] = 0x01; ResponseByteCount = 15; @@ -104,21 +104,36 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } } else if (Command == ISO15693_CMD_READ_MULTIPLE) { if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { - uint8_t PageAddressStart = FrameBuf[10]; - uint8_t PageAddressEnd = FrameBuf[11]; + uint16_t PageAddress = FrameBuf[10]; + uint16_t PageAddressCount = FrameBuf[11] + 1; + + uint8_t * FrameBufPtr = FrameBuf + 1; + if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) + { + uint8_t count; + for (count = 0; count < PageAddressCount; count++) + { + *FrameBufPtr++ = 0; // block security status = unlocked + MemoryReadBlock(FrameBufPtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + FrameBufPtr += BYTES_PER_PAGE; + PageAddress += 1; + } + ResponseByteCount = 1 + (BYTES_PER_PAGE + 1) * PageAddressCount; + } else { + MemoryReadBlock(FrameBufPtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE * PageAddressCount); + ResponseByteCount = 1 + BYTES_PER_PAGE * PageAddressCount; + } FrameBuf[0] = 0; /* Flags */ - MemoryReadBlock(FrameBuf + 1, PageAddressStart * BYTES_PER_PAGE, BYTES_PER_PAGE * (PageAddressEnd - PageAddressStart + 1)); - ResponseByteCount = 1 + BYTES_PER_PAGE * (PageAddressEnd - PageAddressStart + 1); } } else if (Command == ISO15693_CMD_GET_BLOCK_SEC) { if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { uint8_t PageAddressStart = FrameBuf[10]; - uint8_t PageAddressEnd = FrameBuf[11]; + uint8_t PageAddressCount = FrameBuf[11] + 1; FrameBuf[0] = 0; /* Flags */ - for (int i = 1; i <= (PageAddressEnd - PageAddressStart + 1); i++) { + for (uint8_t i = 0; i < PageAddressCount; i++) { FrameBuf[i] = 0x00; } - ResponseByteCount = 1 + (PageAddressEnd - PageAddressStart + 1); + ResponseByteCount = 1 + PageAddressCount; } } break; diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index ac4d99a..dcfac35 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -472,7 +472,7 @@ void StartISO15693Demod(void) { CODEC_TIMER_LOADMOD.PER = 4192 + 128 + 128 - 1; CODEC_TIMER_LOADMOD.INTCTRLA = 0; CODEC_TIMER_LOADMOD.INTCTRLB = 0; - CODEC_TIMER_LOADMOD.CTRLA = ISO15693_SAMPLE_CLK; + CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_EVCH6_gc; /* Start looking out for modulation pause via interrupt. */ CODEC_DEMOD_IN_PORT.INTFLAGS = 0x03; From d0c0da7d70f4dbc09142ca0c2b914eae9920ab2c Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Sat, 18 Aug 2018 12:35:35 +0200 Subject: [PATCH 04/67] get iso15 buildable, runable and accepted by android reader --- .../Chameleon-Mini/Application/ISO15693-A.h | 32 +++++++------- .../Chameleon-Mini/Application/Sl2s2002.c | 44 ++++++------------- .../Chameleon-Mini/Application/Vicinity.c | 30 +++++-------- Firmware/Chameleon-Mini/Codec/Codec.h | 7 +++ Firmware/Chameleon-Mini/Codec/ISO14443-2A.c | 15 +++++-- Firmware/Chameleon-Mini/Codec/ISO15693.c | 9 +++- .../Chameleon-Mini/Codec/Reader14443-2A.c | 7 +++ 7 files changed, 73 insertions(+), 71 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 2a40482..5bf0b0e 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -57,14 +57,14 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize); INLINE bool ISO15693CompareUid(uint8_t* Uid1, uint8_t* Uid2) { - if ( (Uid1[0] == Uid2[0]) - && (Uid1[1] == Uid2[1]) - && (Uid1[2] == Uid2[2]) - && (Uid1[3] == Uid2[3]) - && (Uid1[4] == Uid2[4]) - && (Uid1[5] == Uid2[5]) - && (Uid1[6] == Uid2[6]) - && (Uid1[7] == Uid2[7]) ) { + if ( (Uid1[0] == Uid2[7]) + && (Uid1[1] == Uid2[6]) + && (Uid1[2] == Uid2[5]) + && (Uid1[3] == Uid2[4]) + && (Uid1[4] == Uid2[3]) + && (Uid1[5] == Uid2[2]) + && (Uid1[6] == Uid2[1]) + && (Uid1[7] == Uid2[0]) ) { return true; } else { return false; @@ -74,14 +74,14 @@ bool ISO15693CompareUid(uint8_t* Uid1, uint8_t* Uid2) INLINE void ISO15693CopyUid(uint8_t* DstUid, uint8_t* SrcUid) { - DstUid[0] = SrcUid[0]; - DstUid[1] = SrcUid[1]; - DstUid[2] = SrcUid[2]; - DstUid[3] = SrcUid[3]; - DstUid[4] = SrcUid[4]; - DstUid[5] = SrcUid[5]; - DstUid[6] = SrcUid[6]; - DstUid[7] = SrcUid[7]; + DstUid[0] = SrcUid[7]; + DstUid[1] = SrcUid[6]; + DstUid[2] = SrcUid[5]; + DstUid[3] = SrcUid[4]; + DstUid[4] = SrcUid[3]; + DstUid[5] = SrcUid[2]; + DstUid[6] = SrcUid[1]; + DstUid[7] = SrcUid[0]; } INLINE diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.c b/Firmware/Chameleon-Mini/Application/Sl2s2002.c index 2d3af40..1feec3f 100644 --- a/Firmware/Chameleon-Mini/Application/Sl2s2002.c +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.c @@ -14,6 +14,7 @@ #include "ISO15693-A.h" #define BYTES_PER_PAGE 4 +#define MEM_UID_ADDRESS 0x00 static enum { STATE_READY, @@ -21,13 +22,6 @@ static enum { STATE_QUIET } State; - -ISO15693UidType Sl2s2002Uid = {0x78, 0xD3, 0xF4, 0x3F, 0x50, 0x01, 0x04, 0xE0}; - -//ISO15693UidType Sl2s2002Uid = {0x60, 0x0B, 0x88, 0x77, 0x06, 0x44, 0x02, 0xE1}; - - - void Sl2s2002AppInit(void) { State = STATE_READY; @@ -50,13 +44,6 @@ void Sl2s2002AppTick(void) } -// void sendIntToTermina(uint8_t val) -// { -// char buf[16]; -// snprintf(buf,16, "%02x",val); -// TerminalSendString(buf); -// } - uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { @@ -64,30 +51,25 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) // At this point, we have a valid ISO15693 frame uint8_t Command = FrameBuf[1]; uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - - //TerminalSendString("Received command: "); -// for (int i = 0; i < (FrameBytes - 2); i++) { -// sendIntToTermina(FrameBuf[i]); -// } -// TerminalSendString("\n"); - + uint8_t Uid[8]; + MemoryReadBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); switch(State) { case STATE_READY: if (Command == ISO15693_CMD_INVENTORY) { FrameBuf[0] = 0x00; /* Flags */ FrameBuf[1] = 0x00; /* DSFID */ - ISO15693CopyUid(&FrameBuf[2], Sl2s2002Uid); + ISO15693CopyUid(&FrameBuf[2], Uid); ResponseByteCount = 10; } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { State = STATE_QUIET; } } else if (Command == ISO15693_CMD_GET_SYS_INFO) { - if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { FrameBuf[0] = 0; /* Flags */ FrameBuf[1] = 0x0F; /* InfoFlags */ - ISO15693CopyUid(&FrameBuf[2], Sl2s2002Uid); + ISO15693CopyUid(&FrameBuf[2], Uid); FrameBuf[10] = 0x00; FrameBuf[11] = 0xC2; FrameBuf[12] = 0x03; @@ -96,14 +78,14 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ResponseByteCount = 15; } } else if (Command == ISO15693_CMD_READ_SINGLE) { - if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { uint8_t PageAddress = FrameBuf[10]; FrameBuf[0] = 0; /* Flags */ MemoryReadBlock(FrameBuf + 1, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); ResponseByteCount = 5; } } else if (Command == ISO15693_CMD_READ_MULTIPLE) { - if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { uint16_t PageAddress = FrameBuf[10]; uint16_t PageAddressCount = FrameBuf[11] + 1; @@ -126,7 +108,7 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[0] = 0; /* Flags */ } } else if (Command == ISO15693_CMD_GET_BLOCK_SEC) { - if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { uint8_t PageAddressStart = FrameBuf[10]; uint8_t PageAddressCount = FrameBuf[11] + 1; FrameBuf[0] = 0; /* Flags */ @@ -143,7 +125,7 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf, Sl2s2002Uid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { FrameBuf[0] = 0; ResponseByteCount = 1; State = STATE_READY; @@ -174,12 +156,12 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) void Sl2s2002GetUid(ConfigurationUidType Uid) { - memcpy(Uid, Sl2s2002Uid, sizeof(ConfigurationUidType)); + MemoryReadBlock(&Uid[0], MEM_UID_ADDRESS, ActiveConfiguration.UidSize); } void Sl2s2002SetUid(ConfigurationUidType Uid) { - memcpy(Sl2s2002Uid, Uid, sizeof(ConfigurationUidType)); + MemoryWriteBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); } diff --git a/Firmware/Chameleon-Mini/Application/Vicinity.c b/Firmware/Chameleon-Mini/Application/Vicinity.c index 7a3a961..3bfca1f 100644 --- a/Firmware/Chameleon-Mini/Application/Vicinity.c +++ b/Firmware/Chameleon-Mini/Application/Vicinity.c @@ -13,6 +13,7 @@ #include "../Random.h" #include "ISO15693-A.h" +#define MEM_UID_ADDRESS 0x00 static enum { STATE_READY, @@ -20,10 +21,6 @@ static enum { STATE_QUIET } State; -ISO15693UidType MyUid = {0x60, 0x0B, 0x88, 0x77, 0x06, 0x44, 0x02, 0xE1}; - - - void VicinityAppInit(void) { State = STATE_READY; @@ -46,13 +43,6 @@ void VicinityAppTick(void) } -void sendIntToTermina(uint8_t val) -{ - char buf[16]; - snprintf(buf,16, "%d,",val); - TerminalSendString(buf); -} - uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { @@ -60,24 +50,25 @@ uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) // At this point, we have a valid ISO15693 frame uint8_t Command = FrameBuf[1]; uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - + uint8_t Uid[8]; + MemoryReadBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); switch(State) { case STATE_READY: if (Command == ISO15693_CMD_INVENTORY) { FrameBuf[0] = 0x00; /* Flags */ FrameBuf[1] = 0x00; /* DSFID */ - ISO15693CopyUid(&FrameBuf[2], MyUid); + ISO15693CopyUid(&FrameBuf[2], Uid); ResponseByteCount = 10; } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf, MyUid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { State = STATE_QUIET; } } else if (Command == ISO15693_CMD_GET_SYS_INFO) { - if (ISO15693Addressed(FrameBuf, MyUid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { FrameBuf[0] = 0; /* Flags */ FrameBuf[1] = 0; /* InfoFlags */ - ISO15693CopyUid(&FrameBuf[2], MyUid); + ISO15693CopyUid(&FrameBuf[2], Uid); ResponseByteCount = 10; } } @@ -89,7 +80,8 @@ uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf, MyUid)) { + MemoryReadBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); + if (ISO15693Addressed(FrameBuf, Uid)) { FrameBuf[0] = 0; ResponseByteCount = 1; State = STATE_READY; @@ -120,12 +112,12 @@ uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) void VicinityGetUid(ConfigurationUidType Uid) { - memcpy(Uid, MyUid, sizeof(ConfigurationUidType)); + MemoryReadBlock(&Uid[0], MEM_UID_ADDRESS, ActiveConfiguration.UidSize); } void VicinitySetUid(ConfigurationUidType Uid) { - memcpy(MyUid, Uid, sizeof(ConfigurationUidType)); + MemoryWriteBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); } diff --git a/Firmware/Chameleon-Mini/Codec/Codec.h b/Firmware/Chameleon-Mini/Codec/Codec.h index 4324126..0eb47d0 100644 --- a/Firmware/Chameleon-Mini/Codec/Codec.h +++ b/Firmware/Chameleon-Mini/Codec/Codec.h @@ -108,6 +108,13 @@ typedef enum { extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE]; +volatile void (*isr_func_TCD0_CCC_vect)(void); +void isr_Reader14443_2A_TCD0_CCC_vect(void); +void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void); +volatile void (*isr_func_CODEC_DEMOD_IN_INT0_VECT)(void); +void isr_ISO14443_2A_TCD0_CCC_vect(void); +void isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void); + INLINE void CodecInit(void) { ActiveConfiguration.CodecInitFunc(); } diff --git a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c index ba91594..c024b85 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c +++ b/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c @@ -76,10 +76,17 @@ static void StartDemod(void) { /* Start looking out for modulation pause via interrupt. */ CODEC_DEMOD_IN_PORT.INTFLAGS = 0x03; - CODEC_DEMOD_IN_PORT.INT1MASK = CODEC_DEMOD_IN_MASK0; + CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; } -ISR(CODEC_DEMOD_IN_INT1_VECT) { +ISR (CODEC_DEMOD_IN_INT0_VECT) +{ + isr_func_CODEC_DEMOD_IN_INT0_VECT(); +} + +// ISR(CODEC_DEMOD_IN_INT0_VECT) +void isr_ISO14443_2A_TCD0_CCC_vect(void) +{ /* This is the first edge of the first modulation-pause after StartDemod. * Now we have time to start * demodulating beginning from one bit-width after this edge. */ @@ -109,7 +116,7 @@ ISR(CODEC_DEMOD_IN_INT1_VECT) { CODEC_TIMER_LOADMOD.CTRLA = CODEC_TIMER_CARRIER_CLKSEL; /* Disable this interrupt */ - CODEC_DEMOD_IN_PORT.INT1MASK = 0; + CODEC_DEMOD_IN_PORT.INT0MASK = 0; } ISR(CODEC_TIMER_SAMPLING_CCA_VECT) { @@ -381,6 +388,8 @@ void ISO14443ACodecInit(void) { Flags.DemodFinished = 0; Flags.LoadmodFinished = 0; + isr_func_TCD0_CCC_vect = &isr_Reader14443_2A_TCD0_CCC_vect; + isr_func_CODEC_DEMOD_IN_INT0_VECT = &isr_ISO14443_2A_TCD0_CCC_vect; CodecInitCommon(); StartDemod(); } diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index dcfac35..ea14517 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -82,7 +82,9 @@ static volatile uint16_t ReadCommandFromReader = 0; #ifdef CONFIG_VICINITY_SUPPORT // Started when a single pulse has been detected -ISR(CODEC_DEMOD_IN_INT0_VECT) { +// ISR(CODEC_DEMOD_IN_INT0_VECT) +void isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void) +{ // Start sample timer CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm; CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_HI_gc; @@ -115,7 +117,8 @@ INLINE void ISO15693_EOC(void) CODEC_TIMER_SAMPLING.INTCTRLB = 0; } -ISR(CODEC_TIMER_SAMPLING_CCC_VECT) // Reading data sent from the reader +// ISR(CODEC_TIMER_SAMPLING_CCC_VECT) // Reading data sent from the reader +void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) { /* Shift demod data */ SampleRegister = (SampleRegister << 1) | (!(CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK) ? 0x01 : 0x00); @@ -482,6 +485,8 @@ void StartISO15693Demod(void) { void ISO15693CodecInit(void) { CodecInitCommon(); + isr_func_TCD0_CCC_vect = &isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT; + isr_func_CODEC_DEMOD_IN_INT0_VECT = &isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT; StartISO15693Demod(); } diff --git a/Firmware/Chameleon-Mini/Codec/Reader14443-2A.c b/Firmware/Chameleon-Mini/Codec/Reader14443-2A.c index 6a70968..bc9869a 100644 --- a/Firmware/Chameleon-Mini/Codec/Reader14443-2A.c +++ b/Firmware/Chameleon-Mini/Codec/Reader14443-2A.c @@ -48,6 +48,7 @@ void Reader14443ACodecInit(void) { /* Initialize common peripherals and start listening * for incoming data. */ CodecInitCommon(); + isr_func_TCD0_CCC_vect = &isr_Reader14443_2A_TCD0_CCC_vect; CodecSetDemodPower(true); CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1; @@ -177,6 +178,12 @@ INLINE void BufferToSequence(void) } ISR (TCD0_CCC_vect) +{ + isr_func_TCD0_CCC_vect(); +} + +// ISR (TCD0_CCC_vect) +void isr_Reader14443_2A_TCD0_CCC_vect(void) { CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm; CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc; From ade232808776cf720f7fe4ee64b3f6890e074897 Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Tue, 16 Oct 2018 23:45:43 +0200 Subject: [PATCH 05/67] ISO15: changed empty lines, fixed LOADMOD_SOF_DUAL + LOADMOD_BIT0_DUAL + LOADMOD_BIT1_DUAL --- Firmware/Chameleon-Mini/Codec/ISO15693.c | 49 ++++++++---------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index ea14517..4a81672 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -26,8 +26,8 @@ #define SUBCARRIER_1 32 #define SUBCARRIER_2 28 #define SUBCARRIER_OFF 0 -#define SOF_PATTERN 0x1D -#define EOF_PATTERN 0xB8 +#define SOF_PATTERN 0x1D // 0001 1101 +#define EOF_PATTERN 0xB8 // 1011 1000 // These registers provide quick access but are limited // so global vars will be necessary @@ -277,7 +277,6 @@ ISR(CODEC_TIMER_LOADMOD_CCB_VECT) return; LOADMOD_BIT0_SINGLE_LABEL: //Manchester encoding - if (ShiftRegister & 0x01) { /* Deactivate carrier */ CodecSetLoadmodState(false); @@ -314,7 +313,6 @@ ISR(CODEC_TIMER_LOADMOD_CCB_VECT) return; LOADMOD_EOF_SINGLE_LABEL: //End of Manchester encoding - /* Output EOF */ if (ShiftRegister & 0x80) { CodecSetLoadmodState(true); @@ -332,14 +330,10 @@ ISR(CODEC_TIMER_LOADMOD_CCB_VECT) StateRegister = LOADMOD_EOF_SINGLE; } return; - - - - - - - LOADMOD_START_DUAL_LABEL: + // ------------------------------------------------------------- + + LOADMOD_START_DUAL_LABEL: CodecStartSubcarrier(); ShiftRegister = SOF_PATTERN; BitSent = 0; @@ -362,12 +356,23 @@ ISR(CODEC_TIMER_LOADMOD_CCB_VECT) StateRegister = LOADMOD_BIT0_DUAL; ShiftRegister = (*CodecBufferPtr++); } else { - StateRegister = LOADMOD_BIT0_DUAL; + StateRegister = LOADMOD_SOF_DUAL; } return; LOADMOD_BIT0_DUAL_LABEL: //Manchester encoding + if (ShiftRegister & 0x01) { + CodecChangeDivider(SUBCARRIER_2); + CODEC_TIMER_LOADMOD.PER = BitRate2 - 1; + } else { + CodecChangeDivider(SUBCARRIER_1); + CODEC_TIMER_LOADMOD.PER = BitRate1 - 1; + } + StateRegister = LOADMOD_BIT1_DUAL; + return; + + LOADMOD_BIT1_DUAL_LABEL: //Manchester encoding if (ShiftRegister & 0x01) { /* fc / 32 */ CodecChangeDivider(SUBCARRIER_1); @@ -378,18 +383,6 @@ ISR(CODEC_TIMER_LOADMOD_CCB_VECT) CODEC_TIMER_LOADMOD.PER = BitRate2 - 1; } - StateRegister = LOADMOD_BIT1_DUAL; - return; - - LOADMOD_BIT1_DUAL_LABEL: //Manchester encoding - if (ShiftRegister & 0x01) { - CodecChangeDivider(SUBCARRIER_2); - CODEC_TIMER_LOADMOD.PER = BitRate2 - 1; - } else { - CodecChangeDivider(SUBCARRIER_1); - CODEC_TIMER_LOADMOD.PER = BitRate1 - 1; - } - ShiftRegister >>= 1; BitSent++; @@ -408,7 +401,6 @@ ISR(CODEC_TIMER_LOADMOD_CCB_VECT) return; LOADMOD_EOF_DUAL_LABEL: //End of Manchester encoding - /* Output EOF */ if (ShiftRegister & 0x80) { CodecChangeDivider(SUBCARRIER_1); @@ -429,14 +421,7 @@ ISR(CODEC_TIMER_LOADMOD_CCB_VECT) } return; - - - - - - LOADMOD_FINISHED_LABEL: - CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; CODEC_TIMER_LOADMOD.INTCTRLB = 0; CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, SUBCARRIER_1); From 35cd58d0482a9a792bb031b2fcdf37a75ed786c9 Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Wed, 17 Oct 2018 07:46:57 +0200 Subject: [PATCH 06/67] Buildable, ISR sharing --- Firmware/Chameleon-Mini/Codec/Codec.h | 3 +++ Firmware/Chameleon-Mini/Codec/ISO15693.c | 4 +++- Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Firmware/Chameleon-Mini/Codec/Codec.h b/Firmware/Chameleon-Mini/Codec/Codec.h index 6d8b364..a63ef9d 100644 --- a/Firmware/Chameleon-Mini/Codec/Codec.h +++ b/Firmware/Chameleon-Mini/Codec/Codec.h @@ -121,6 +121,9 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void); volatile void (*isr_func_CODEC_DEMOD_IN_INT0_VECT)(void); void isr_ISO14443_2A_TCD0_CCC_vect(void); void isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void); +volatile void (*isr_func_CODEC_TIMER_LOADMOD_CCB_VECT)(void); +void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void); +void isr_SniffISO14443_2A_CODEC_TIMER_LOADMOD_CCB_VECT(void); INLINE void CodecInit(void) { ActiveConfiguration.CodecInitFunc(); diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index 4a81672..8c84219 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -230,7 +230,8 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) } -ISR(CODEC_TIMER_LOADMOD_CCB_VECT) +//ISR(CODEC_TIMER_LOADMOD_CCB_VECT) +void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) { static void* JumpTable[] = { [LOADMOD_START_SINGLE] = &&LOADMOD_START_SINGLE_LABEL, @@ -472,6 +473,7 @@ void ISO15693CodecInit(void) CodecInitCommon(); isr_func_TCD0_CCC_vect = &isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT; isr_func_CODEC_DEMOD_IN_INT0_VECT = &isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT; + isr_func_CODEC_TIMER_LOADMOD_CCB_VECT = &isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT; StartISO15693Demod(); } diff --git a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c index 628eead..499bd54 100644 --- a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c +++ b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c @@ -367,7 +367,8 @@ ISR(ACA_AC0_vect) // this interrupt either finds the SOC or gets triggered befor // according to the pause and modulated period // if the half bit duration is modulated, then add 1 to buffer // if the half bit duration is not modulated, then add 0 to buffer -ISR(CODEC_TIMER_LOADMOD_CCB_VECT) // pause found +//ISR(CODEC_TIMER_LOADMOD_CCB_VECT) // pause found +void isr_SniffISO14443_2A_CODEC_TIMER_LOADMOD_CCB_VECT(void) { uint8_t tmp = CODEC_TIMER_TIMESTAMPS.CNTL; CODEC_TIMER_TIMESTAMPS.CNT = 0; @@ -487,6 +488,7 @@ void Sniff14443ACodecInit(void) PORTE.DIRSET= PIN3_bm | PIN2_bm; // Common Codec Register settings CodecInitCommon(); + isr_func_CODEC_TIMER_LOADMOD_CCB_VECT = &isr_SniffISO14443_2A_CODEC_TIMER_LOADMOD_CCB_VECT; // Enable demodulator power CodecSetDemodPower(true); From 94a1f460eb55333e5b278eec0770f3709bc05eb4 Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Sat, 20 Oct 2018 21:28:16 +0200 Subject: [PATCH 07/67] forgot setting ISR - feels very slow now with sharing ISR --- Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c index 499bd54..b86e7ce 100644 --- a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c +++ b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c @@ -363,6 +363,12 @@ ISR(ACA_AC0_vect) // this interrupt either finds the SOC or gets triggered befor CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_DIV1_gc; StateRegister = PICC_FRAME; } + +ISR(CODEC_TIMER_LOADMOD_CCB_VECT) // pause found +{ + isr_func_CODEC_TIMER_LOADMOD_CCB_VECT(); +} + // Decode the Card -> Reader signal // according to the pause and modulated period // if the half bit duration is modulated, then add 1 to buffer From 9636574341389c8f63f880f4e37adb0119be0729 Mon Sep 17 00:00:00 2001 From: Thorsten <12600404+bosb@users.noreply.github.com> Date: Sun, 28 Oct 2018 23:34:55 +0100 Subject: [PATCH 08/67] Update Sl2s2002.c option bit also for sending security state in single read --- .../Chameleon-Mini/Application/Sl2s2002.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.c b/Firmware/Chameleon-Mini/Application/Sl2s2002.c index 1feec3f..936bfb8 100644 --- a/Firmware/Chameleon-Mini/Application/Sl2s2002.c +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.c @@ -78,12 +78,20 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ResponseByteCount = 15; } } else if (Command == ISO15693_CMD_READ_SINGLE) { - if (ISO15693Addressed(FrameBuf, Uid)) { - uint8_t PageAddress = FrameBuf[10]; - FrameBuf[0] = 0; /* Flags */ - MemoryReadBlock(FrameBuf + 1, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); - ResponseByteCount = 5; - } + if (ISO15693Addressed(FrameBuf, Uid)) { + uint8_t PageAddress = FrameBuf[10]; + if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) + { + FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[1] = 0x00; /* security dummy to 0 */ + MemoryReadBlock(FrameBuf + 2, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + ResponseByteCount = 6; + } else { + FrameBuf[0] = 0x00; /* Flags */ + MemoryReadBlock(FrameBuf + 1, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + ResponseByteCount = 5; + } + } } else if (Command == ISO15693_CMD_READ_MULTIPLE) { if (ISO15693Addressed(FrameBuf, Uid)) { uint16_t PageAddress = FrameBuf[10]; From 429f541eabe137e1a3bae4035b21f3970bff51f5 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Mon, 5 Nov 2018 15:59:56 +0100 Subject: [PATCH 09/67] Porting Rickventura changes to the main repo --- .../Chameleon-Mini/Application/Application.h | 110 +++++----- .../Application/TITagitstandard.c | 192 ++++++++++++++++++ .../Application/TITagitstandard.h | 28 +++ Firmware/Chameleon-Mini/Configuration.c | 22 ++ Firmware/Chameleon-Mini/Configuration.h | 3 + Firmware/Chameleon-Mini/Makefile | 3 +- 6 files changed, 303 insertions(+), 55 deletions(-) create mode 100644 Firmware/Chameleon-Mini/Application/TITagitstandard.c create mode 100644 Firmware/Chameleon-Mini/Application/TITagitstandard.h diff --git a/Firmware/Chameleon-Mini/Application/Application.h b/Firmware/Chameleon-Mini/Application/Application.h index cf113ec..31c7363 100644 --- a/Firmware/Chameleon-Mini/Application/Application.h +++ b/Firmware/Chameleon-Mini/Application/Application.h @@ -1,54 +1,56 @@ -/* - * Application.h - * - * Created on: 18.02.2013 - * Author: skuser - */ - -#ifndef APPLICATION_H_ -#define APPLICATION_H_ - -#include "../Common.h" -#include "../Configuration.h" -#include "../Log.h" - -/* Applications */ -#include "MifareUltralight.h" -#include "MifareClassic.h" -#include "Reader14443A.h" -#include "Vicinity.h" -#include "Sl2s2002.h" -#include "Sniff14443A.h" - -/* Function wrappers */ -INLINE void ApplicationInit(void) { - ActiveConfiguration.ApplicationInitFunc(); -} - -INLINE void ApplicationTask(void) { - ActiveConfiguration.ApplicationTaskFunc(); -} - -INLINE void ApplicationTick(void) { - ActiveConfiguration.ApplicationTickFunc(); -} - -INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { - return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); -} - -INLINE void ApplicationReset(void) { - ActiveConfiguration.ApplicationResetFunc(); - //LogEntry(LOG_INFO_RESET_APP, NULL, 0); -} - -INLINE void ApplicationGetUid(ConfigurationUidType Uid) { - ActiveConfiguration.ApplicationGetUidFunc(Uid); -} - -INLINE void ApplicationSetUid(ConfigurationUidType Uid) { - ActiveConfiguration.ApplicationSetUidFunc(Uid); - LogEntry(LOG_INFO_UID_SET, Uid, ActiveConfiguration.UidSize); -} - -#endif /* APPLICATION_H_ */ +/* + * Application.h + * + * Created on: 18.02.2013 + * Author: skuser + */ + +#ifndef APPLICATION_H_ +#define APPLICATION_H_ + +#include "../Common.h" +#include "../Configuration.h" +#include "../Log.h" + +/* Applications */ +#include "MifareUltralight.h" +#include "MifareClassic.h" +#include "Reader14443A.h" +#include "Vicinity.h" +#include "Sl2s2002.h" +#include "TITagitstandard.h" +#include "Sniff14443A.h" + + +/* Function wrappers */ +INLINE void ApplicationInit(void) { + ActiveConfiguration.ApplicationInitFunc(); +} + +INLINE void ApplicationTask(void) { + ActiveConfiguration.ApplicationTaskFunc(); +} + +INLINE void ApplicationTick(void) { + ActiveConfiguration.ApplicationTickFunc(); +} + +INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { + return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); +} + +INLINE void ApplicationReset(void) { + ActiveConfiguration.ApplicationResetFunc(); + //LogEntry(LOG_INFO_RESET_APP, NULL, 0); +} + +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); +} + +INLINE void ApplicationSetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationSetUidFunc(Uid); + LogEntry(LOG_INFO_UID_SET, Uid, ActiveConfiguration.UidSize); +} + +#endif /* APPLICATION_H_ */ diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c new file mode 100644 index 0000000..287e3d2 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -0,0 +1,192 @@ +/* + * TITagitstandard.c + * + * Created on: 01-03-2017 + * Author: Phillip Nash + * modified by rickventura for texas 15693 tag-it STANDARD + */ + + +#include "TITagitstandard.h" +#include "../Codec/ISO15693.h" +#include "../Memory.h" +#include "Crypto1.h" +#include "../Random.h" +#include "ISO15693-A.h" + +#define BYTES_PER_PAGE 4 +#define MEM_UID_ADDRESS 0x20 + +static enum { + STATE_READY, + STATE_SELECTED, + STATE_QUIET +} State; + +//ISO15693UidType Uid = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xE0}; +//0xE0 = iso15693 +//0x07 = TEXAS INSTRUMENTS +//0xC0 0xC1 = "Tagitstandard" 0xC4 or 0xC5 "TagitPro" 0x00 or 0x01 or 0x80 or 0x81 "Tagitplus" + + +void TITagitstandardAppInit(void) +{ + State = STATE_READY; +} + +void TITagitstandardAppReset(void) +{ + State = STATE_READY; +} + + +void TITagitstandardAppTask(void) +{ + +} + +void TITagitstandardAppTick(void) +{ + + +} + +// void sendIntToTermina(uint8_t val) +// { +// char buf[16]; +// snprintf(buf,16, "%02x",val); +// TerminalSendString(buf); +// } + +uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + + + + if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { + if(ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) { + // At this point, we have a valid ISO15693 frame + uint8_t Command = FrameBuf[1]; + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t Uid[8]; + + //MemoryReadBlock(actualTagIt, 0, 44); // read the whole tag from FRAM + MemoryReadBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); + + //for (j==0 ; j < ActiveConfiguration.UidSize; j++) Uid[j] = actualTagIt[MEM_UID_ADDRESS + j] ; + + switch(State) { + case STATE_READY: + if (Command == ISO15693_CMD_INVENTORY) { + FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[1] = 0x00; /* DSFID */ + ISO15693CopyUid(&FrameBuf[2], Uid); + + ResponseByteCount = 10; + + + } else if (Command == ISO15693_CMD_STAY_QUIET) { + if (ISO15693Addressed(FrameBuf,Uid)) { + State = STATE_QUIET; + + } + + } else if (Command == ISO15693_CMD_READ_SINGLE) { + uint8_t *FramePtr ; + uint8_t PageAddress ; + + + if ((FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) ) + PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from the 10th byte in the request*/ + else + PageAddress = FrameBuf[2]; + + + if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) + { /*request with option flag set */ + FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status:when request has the option flag set*/ + FramePtr = FrameBuf + 2; + ResponseByteCount = 6; + + } else { /*request with option flag not set*/ + FrameBuf[0] = 0x00; /* Flags */ + FramePtr = FrameBuf + 1 ; + ResponseByteCount = 5; + } + + MemoryReadBlock(FramePtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + + } + + else if (Command ==ISO15693_CMD_WRITE_SINGLE){ + uint8_t* Dataptr; + uint8_t PageAddress ; + + + if ((FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) ){ + PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from 10th byte in the request*/ + Dataptr = &FrameBuf[11]; + } + else { + + PageAddress = FrameBuf[2];/*when receiving an unanaddressed request pick block number from 2nd byte in the request*/ + Dataptr = &FrameBuf[3]; + + } + + MemoryWriteBlock( Dataptr , PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + FrameBuf[0] = 0x00; + ResponseByteCount = 1; + + } + break; + case STATE_SELECTED: + + break; + + case STATE_QUIET: + if (Command == ISO15693_CMD_RESET_TO_READY) { + if (ISO15693Addressed(FrameBuf,Uid)) { + FrameBuf[0] = 0; + ResponseByteCount = 1; + State = STATE_READY; + } + } + break; + + default: + break; + } + + if (ResponseByteCount > 0) { + /* There is data to be sent. Append CRC */ + ISO15693AppendCRC(FrameBuf, ResponseByteCount); + ResponseByteCount += ISO15693_CRC16_SIZE; + } + + return ResponseByteCount; + + } else { // Invalid CRC + return ISO15693_APP_NO_RESPONSE; + } + } else { // Min frame size not met + return ISO15693_APP_NO_RESPONSE; + } + +} + +void TITagitstandardGetUid(ConfigurationUidType Uid) +{ + MemoryReadBlock(&Uid[0], MEM_UID_ADDRESS, ActiveConfiguration.UidSize); +} + +void TITagitstandardSetUid(ConfigurationUidType Uid) +{ + MemoryWriteBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); +} + + + + + diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.h b/Firmware/Chameleon-Mini/Application/TITagitstandard.h new file mode 100644 index 0000000..1562fbc --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.h @@ -0,0 +1,28 @@ +/* + * MifareClassic.h + * + * Created on: 01.03.2017 + * Author: skuser + * modified by rickventura + */ + +#ifndef TITAGITSTANDARD_H_ +#define TITAGITSTANDARD_H_ + +#include "Application.h" +#include "ISO15693-A.h" + +#define ISO15693_GENERIC_UID_SIZE 8 //ISO15693_UID_SIZE +#define ISO15693_GENERIC_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE + +void TITagitstandardAppInit(void); +void TITagitstandardAppReset(void); +void TITagitstandardAppTask(void); +void TITagitstandardAppTick(void); +uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes); +void TITagitstandardGetUid(ConfigurationUidType Uid); +void TITagitstandardSetUid(ConfigurationUidType Uid); + + + +#endif /* VICINITY_H_ */ diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c index 9761ec3..14c26df 100644 --- a/Firmware/Chameleon-Mini/Configuration.c +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -46,6 +46,10 @@ static const MapEntryType PROGMEM ConfigurationMap[] = { #ifdef CONFIG_SL2S2002_SUPPORT { .Id = CONFIG_SL2S2002, .Text = "SL2S2002" }, #endif + +#ifdef CONFIG_TITAGITSTANDARD_SUPPORT + { .Id = CONFIG_TITAGITSTANDARD, .Text = "TITAGITSTANDARD" }, +#endif }; /* Include all Codecs and Applications */ @@ -280,6 +284,24 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ReadOnly = false }, #endif + +#ifdef CONFIG_TITAGITSTANDARD_SUPPORT + [CONFIG_TITAGITSTANDARD] = { + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = TITagitstandardAppInit, + .ApplicationResetFunc = TITagitstandardAppReset, + .ApplicationTaskFunc = TITagitstandardAppTask, + .ApplicationTickFunc = TITagitstandardAppTick, + .ApplicationProcessFunc = TITagitstandardAppProcess, + .ApplicationGetUidFunc = TITagitstandardGetUid, + .ApplicationSetUidFunc = TITagitstandardSetUid, + .UidSize = ISO15693_GENERIC_UID_SIZE, + .MemorySize = ISO15693_GENERIC_MEM_SIZE, + .ReadOnly = false + }, +#endif }; ConfigurationType ActiveConfiguration; diff --git a/Firmware/Chameleon-Mini/Configuration.h b/Firmware/Chameleon-Mini/Configuration.h index 6de5873..ae87e7d 100644 --- a/Firmware/Chameleon-Mini/Configuration.h +++ b/Firmware/Chameleon-Mini/Configuration.h @@ -51,6 +51,9 @@ typedef enum { #endif #ifdef CONFIG_SL2S2002_SUPPORT CONFIG_SL2S2002, +#endif +#ifdef CONFIG_TITAGITSTANDARD_SUPPORT + CONFIG_TITAGITSTANDARD, #endif /* This HAS to be the last element */ CONFIG_COUNT diff --git a/Firmware/Chameleon-Mini/Makefile b/Firmware/Chameleon-Mini/Makefile index d07b63b..441e7a9 100644 --- a/Firmware/Chameleon-Mini/Makefile +++ b/Firmware/Chameleon-Mini/Makefile @@ -14,6 +14,7 @@ SETTINGS += -DCONFIG_ISO14443A_SNIFF_SUPPORT SETTINGS += -DCONFIG_ISO14443A_READER_SUPPORT SETTINGS += -DCONFIG_VICINITY_SUPPORT SETTINGS += -DCONFIG_SL2S2002_SUPPORT +SETTINGS += -DCONFIG_TITAGITSTANDARD_SUPPORT SETTINGS += -DCONFIG_ISO15693_SNIFF_SUPPORT #Support magic mode on mifare classic configuration @@ -98,7 +99,7 @@ SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Termina SRC += Codec/Codec.c Codec/ISO14443-2A.c Codec/Reader14443-2A.c Codec/SniffISO14443-2A.c Codec/Reader14443-ISR.S SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c Application/Sniff14443A.c SRC += Codec/ISO15693.c -SRC += Application/Vicinity.c Application/Sl2s2002.c Application/ISO15693-A.c +SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) LUFA_PATH = ../LUFA CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) -DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) -DCOMMIT_ID=\"$(COMMIT_ID)\" $(SETTINGS) From cbfa4855bca4d03a38eadbeddbd3f7567c940a93 Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Sat, 10 Nov 2018 09:55:20 +0100 Subject: [PATCH 10/67] Application.h back to unix lineends --- .../Chameleon-Mini/Application/Application.h | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/Application.h b/Firmware/Chameleon-Mini/Application/Application.h index 31c7363..6fca8b6 100644 --- a/Firmware/Chameleon-Mini/Application/Application.h +++ b/Firmware/Chameleon-Mini/Application/Application.h @@ -1,56 +1,56 @@ -/* - * Application.h - * - * Created on: 18.02.2013 - * Author: skuser - */ - -#ifndef APPLICATION_H_ -#define APPLICATION_H_ - -#include "../Common.h" -#include "../Configuration.h" -#include "../Log.h" - -/* Applications */ -#include "MifareUltralight.h" -#include "MifareClassic.h" -#include "Reader14443A.h" -#include "Vicinity.h" -#include "Sl2s2002.h" -#include "TITagitstandard.h" -#include "Sniff14443A.h" - - -/* Function wrappers */ -INLINE void ApplicationInit(void) { - ActiveConfiguration.ApplicationInitFunc(); -} - -INLINE void ApplicationTask(void) { - ActiveConfiguration.ApplicationTaskFunc(); -} - -INLINE void ApplicationTick(void) { - ActiveConfiguration.ApplicationTickFunc(); -} - -INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { - return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); -} - -INLINE void ApplicationReset(void) { - ActiveConfiguration.ApplicationResetFunc(); - //LogEntry(LOG_INFO_RESET_APP, NULL, 0); -} - -INLINE void ApplicationGetUid(ConfigurationUidType Uid) { - ActiveConfiguration.ApplicationGetUidFunc(Uid); -} - -INLINE void ApplicationSetUid(ConfigurationUidType Uid) { - ActiveConfiguration.ApplicationSetUidFunc(Uid); - LogEntry(LOG_INFO_UID_SET, Uid, ActiveConfiguration.UidSize); -} - -#endif /* APPLICATION_H_ */ +/* + * Application.h + * + * Created on: 18.02.2013 + * Author: skuser + */ + +#ifndef APPLICATION_H_ +#define APPLICATION_H_ + +#include "../Common.h" +#include "../Configuration.h" +#include "../Log.h" + +/* Applications */ +#include "MifareUltralight.h" +#include "MifareClassic.h" +#include "Reader14443A.h" +#include "Vicinity.h" +#include "Sl2s2002.h" +#include "TITagitstandard.h" +#include "Sniff14443A.h" + + +/* Function wrappers */ +INLINE void ApplicationInit(void) { + ActiveConfiguration.ApplicationInitFunc(); +} + +INLINE void ApplicationTask(void) { + ActiveConfiguration.ApplicationTaskFunc(); +} + +INLINE void ApplicationTick(void) { + ActiveConfiguration.ApplicationTickFunc(); +} + +INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { + return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); +} + +INLINE void ApplicationReset(void) { + ActiveConfiguration.ApplicationResetFunc(); + //LogEntry(LOG_INFO_RESET_APP, NULL, 0); +} + +INLINE void ApplicationGetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationGetUidFunc(Uid); +} + +INLINE void ApplicationSetUid(ConfigurationUidType Uid) { + ActiveConfiguration.ApplicationSetUidFunc(Uid); + LogEntry(LOG_INFO_UID_SET, Uid, ActiveConfiguration.UidSize); +} + +#endif /* APPLICATION_H_ */ From 681e793c8d1258841306dacfcf57c27741a684e7 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Wed, 7 Nov 2018 21:50:09 +0100 Subject: [PATCH 11/67] Added all response error codes from the standard --- Firmware/Chameleon-Mini/Application/ISO15693-A.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 5bf0b0e..1c21828 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -42,6 +42,16 @@ #define ISO15693_RES_FLAG_ERROR 0x01 #define ISO15693_RES_FLAG_PROT_EXT 0x08 +#define ISO15693_RES_ERR_NOT_SUPP 0x01 +#define ISO15693_RES_ERR_NOT_REC 0x02 +#define ISO15693_RES_ERR_OPT_NOT_SUPP 0x03 +#define ISO15693_RES_ERR_GENERIC 0x0F +#define ISO15693_RES_ERR_BLK_NOT_AVL 0x10 +#define ISO15693_RES_ERR_BLK_ALRD_LKD 0x11 +#define ISO15693_RES_ERR_BLK_CHG_LKD 0x12 +#define ISO15693_RES_ERR_BLK_NOT_PRGR 0x13 +#define ISO15693_RES_ERR_BLK_NOT_LKD 0x14 + #define ISO15693_MIN_FRAME_SIZE 5 From b0f40ebc9a8253f603b2f2efa8cdd0dc38986f2c Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Wed, 7 Nov 2018 21:51:33 +0100 Subject: [PATCH 12/67] Testing a check for out of bound access when requesting invalind sectors from the tag. Fixed indentation. --- .../Application/TITagitstandard.c | 120 ++++++++---------- 1 file changed, 55 insertions(+), 65 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 287e3d2..f60839f 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -3,7 +3,8 @@ * * Created on: 01-03-2017 * Author: Phillip Nash - * modified by rickventura for texas 15693 tag-it STANDARD + * Modified by rickventura for texas 15693 tag-it STANDARD + * Modified by ceres-c to finish things up */ @@ -15,6 +16,7 @@ #include "ISO15693-A.h" #define BYTES_PER_PAGE 4 +#define NUMBER_OF_SECTORS ( ISO15693_GENERIC_MEM_SIZE / BYTES_PER_PAGE ) #define MEM_UID_ADDRESS 0x20 static enum { @@ -28,7 +30,6 @@ static enum { //0x07 = TEXAS INSTRUMENTS //0xC0 0xC1 = "Tagitstandard" 0xC4 or 0xC5 "TagitPro" 0x00 or 0x01 or 0x80 or 0x81 "Tagitplus" - void TITagitstandardAppInit(void) { State = STATE_READY; @@ -42,13 +43,13 @@ void TITagitstandardAppReset(void) void TITagitstandardAppTask(void) { - + } void TITagitstandardAppTick(void) { - + } // void sendIntToTermina(uint8_t val) @@ -60,9 +61,6 @@ void TITagitstandardAppTick(void) uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { - - - if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { if(ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) { // At this point, we have a valid ISO15693 frame @@ -70,20 +68,20 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t Uid[8]; - //MemoryReadBlock(actualTagIt, 0, 44); // read the whole tag from FRAM + //MemoryReadBlock(actualTagIt, 0, 44); // read the whole tag from FRAM MemoryReadBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); - + //for (j==0 ; j < ActiveConfiguration.UidSize; j++) Uid[j] = actualTagIt[MEM_UID_ADDRESS + j] ; switch(State) { case STATE_READY: if (Command == ISO15693_CMD_INVENTORY) { FrameBuf[0] = 0x00; /* Flags */ - FrameBuf[1] = 0x00; /* DSFID */ + FrameBuf[1] = 0x00; /* DSFID */ ISO15693CopyUid(&FrameBuf[2], Uid); - + ResponseByteCount = 10; - + } else if (Command == ISO15693_CMD_STAY_QUIET) { if (ISO15693Addressed(FrameBuf,Uid)) { @@ -92,57 +90,54 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } } else if (Command == ISO15693_CMD_READ_SINGLE) { - uint8_t *FramePtr ; - uint8_t PageAddress ; - - - if ((FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) ) - PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from the 10th byte in the request*/ - else - PageAddress = FrameBuf[2]; - - - if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) - { /*request with option flag set */ - FrameBuf[0] = 0x00; /* Flags */ - FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status:when request has the option flag set*/ - FramePtr = FrameBuf + 2; - ResponseByteCount = 6; + uint8_t *FramePtr ; + uint8_t PageAddress ; - } else { /*request with option flag not set*/ - FrameBuf[0] = 0x00; /* Flags */ - FramePtr = FrameBuf + 1 ; - ResponseByteCount = 5; - } - - MemoryReadBlock(FramePtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + if ((FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) ) + PageAddress = FrameBuf[10]; /* when receiving an addressed request pick block number from the 10th byte in the request*/ + else + PageAddress = FrameBuf[2]; + + if (PageAddress > NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ + FrameBuf[0] = ISO15693_RES_FLAG_ERROR; + FrameBuf[1] = ISO15693_RES_ERR_BLK_NOT_AVL; // Is this enough? + ResponseByteCount = 2; + break; + } + if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ + FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status:when request has the option flag set*/ + FramePtr = FrameBuf + 2; + ResponseByteCount = 6; + } else { /* request with option flag not set*/ + FrameBuf[0] = 0x00; /* Flags */ + FramePtr = FrameBuf + 1 ; + ResponseByteCount = 5; } - - else if (Command ==ISO15693_CMD_WRITE_SINGLE){ - uint8_t* Dataptr; - uint8_t PageAddress ; - - - if ((FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) ){ - PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from 10th byte in the request*/ - Dataptr = &FrameBuf[11]; - } - else { - - PageAddress = FrameBuf[2];/*when receiving an unanaddressed request pick block number from 2nd byte in the request*/ - Dataptr = &FrameBuf[3]; - - } - - MemoryWriteBlock( Dataptr , PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); - FrameBuf[0] = 0x00; - ResponseByteCount = 1; - } + MemoryReadBlock(FramePtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + } + + else if (Command ==ISO15693_CMD_WRITE_SINGLE){ + uint8_t* Dataptr; + uint8_t PageAddress ; + + + if ((FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) ){ + PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from 10th byte in the request*/ + Dataptr = &FrameBuf[11]; + } else { + PageAddress = FrameBuf[2]; /*when receiving an unanaddressed request pick block number from 2nd byte in the request*/ + Dataptr = &FrameBuf[3]; + } + + MemoryWriteBlock( Dataptr , PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + FrameBuf[0] = 0x00; + ResponseByteCount = 1; + } break; case STATE_SELECTED: - break; case STATE_QUIET: @@ -166,14 +161,14 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } return ResponseByteCount; - + } else { // Invalid CRC return ISO15693_APP_NO_RESPONSE; } } else { // Min frame size not met return ISO15693_APP_NO_RESPONSE; } - + } void TITagitstandardGetUid(ConfigurationUidType Uid) @@ -184,9 +179,4 @@ void TITagitstandardGetUid(ConfigurationUidType Uid) void TITagitstandardSetUid(ConfigurationUidType Uid) { MemoryWriteBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); -} - - - - - +} \ No newline at end of file From be48e0b7518fa3891dad6304555e79b70952eaee Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 8 Nov 2018 01:11:34 +0100 Subject: [PATCH 13/67] Checked with a real tag and the error is correct. Also fixed a small error which let the tag still go out of bound. --- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index f60839f..31bb710 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -98,9 +98,9 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) else PageAddress = FrameBuf[2]; - if (PageAddress > NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ + if (PageAddress >= NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ FrameBuf[0] = ISO15693_RES_FLAG_ERROR; - FrameBuf[1] = ISO15693_RES_ERR_BLK_NOT_AVL; // Is this enough? + FrameBuf[1] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ ResponseByteCount = 2; break; } From c9f04089172f7d01e648af43519a73312170bccd Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 8 Nov 2018 02:26:06 +0100 Subject: [PATCH 14/67] Reverse the UID before sending or saving it (Thanks @m2otech). Fixed a double define on the same constant --- .../Application/TITagitstandard.c | 18 +++++++++++++++++- .../Application/TITagitstandard.h | 4 ++-- Firmware/Chameleon-Mini/Configuration.c | 4 ++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 31bb710..0b52743 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -69,7 +69,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t Uid[8]; //MemoryReadBlock(actualTagIt, 0, 44); // read the whole tag from FRAM - MemoryReadBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); + TITagitstandardGetUid(Uid); //for (j==0 ; j < ActiveConfiguration.UidSize; j++) Uid[j] = actualTagIt[MEM_UID_ADDRESS + j] ; @@ -174,9 +174,25 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) void TITagitstandardGetUid(ConfigurationUidType Uid) { MemoryReadBlock(&Uid[0], MEM_UID_ADDRESS, ActiveConfiguration.UidSize); + + // Reverse UID after reading it + uint8_t* UidTemp = calloc(ActiveConfiguration.UidSize, sizeof(UidTemp)); + int i; + for (i = 0; i < ActiveConfiguration.UidSize; i++) + UidTemp[i] = Uid[i]; + for (i = 0; i < ActiveConfiguration.UidSize; i++) + Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; } void TITagitstandardSetUid(ConfigurationUidType Uid) { + // Reverse UID before writing it + uint8_t* UidTemp = calloc(ActiveConfiguration.UidSize, sizeof(UidTemp)); + int i; + for (i = 0; i < ActiveConfiguration.UidSize; i++) + UidTemp[i] = Uid[i]; + for (i = 0; i < ActiveConfiguration.UidSize; i++) + Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; + MemoryWriteBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); } \ No newline at end of file diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.h b/Firmware/Chameleon-Mini/Application/TITagitstandard.h index 1562fbc..066d10e 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.h +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.h @@ -12,8 +12,8 @@ #include "Application.h" #include "ISO15693-A.h" -#define ISO15693_GENERIC_UID_SIZE 8 //ISO15693_UID_SIZE -#define ISO15693_GENERIC_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE +#define TITAGIT_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE +#define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE void TITagitstandardAppInit(void); void TITagitstandardAppReset(void); diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c index 14c26df..1945549 100644 --- a/Firmware/Chameleon-Mini/Configuration.c +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -297,8 +297,8 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationProcessFunc = TITagitstandardAppProcess, .ApplicationGetUidFunc = TITagitstandardGetUid, .ApplicationSetUidFunc = TITagitstandardSetUid, - .UidSize = ISO15693_GENERIC_UID_SIZE, - .MemorySize = ISO15693_GENERIC_MEM_SIZE, + .UidSize = TITAGIT_STD_UID_SIZE, + .MemorySize = TITAGIT_STD_MEM_SIZE, .ReadOnly = false }, #endif From 2ba1441d1bf0cb4baa64f7dc020097a4b823240b Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 8 Nov 2018 14:38:22 +0100 Subject: [PATCH 15/67] Switched to ISO15693Addressed. Fixing indentation --- .../Chameleon-Mini/Application/ISO15693-A.h | 2 ++ .../Application/TITagitstandard.c | 26 +++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 1c21828..b954d60 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -111,4 +111,6 @@ bool ISO15693Addressed(uint8_t* Buffer, uint8_t* MyUid) { } } +// (FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) + #endif /* ISO15693_3_H_ */ diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 0b52743..8c1dc08 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -90,10 +90,10 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } } else if (Command == ISO15693_CMD_READ_SINGLE) { - uint8_t *FramePtr ; - uint8_t PageAddress ; + uint8_t *FramePtr; + uint8_t PageAddress; - if ((FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) ) + if (ISO15693Addressed(FrameBuf,Uid)) PageAddress = FrameBuf[10]; /* when receiving an addressed request pick block number from the 10th byte in the request*/ else PageAddress = FrameBuf[2]; @@ -112,27 +112,27 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ResponseByteCount = 6; } else { /* request with option flag not set*/ FrameBuf[0] = 0x00; /* Flags */ - FramePtr = FrameBuf + 1 ; + FramePtr = FrameBuf + 1; ResponseByteCount = 5; } MemoryReadBlock(FramePtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); } - else if (Command ==ISO15693_CMD_WRITE_SINGLE){ + else if (Command == ISO15693_CMD_WRITE_SINGLE){ uint8_t* Dataptr; - uint8_t PageAddress ; + uint8_t PageAddress; - if ((FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) ){ - PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from 10th byte in the request*/ - Dataptr = &FrameBuf[11]; + if (ISO15693Addressed(FrameBuf, Uid)) { + PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from 10th byte in the request*/ + Dataptr = &FrameBuf[11]; } else { - PageAddress = FrameBuf[2]; /*when receiving an unanaddressed request pick block number from 2nd byte in the request*/ - Dataptr = &FrameBuf[3]; + PageAddress = FrameBuf[2]; /*when receiving an unanaddressed request pick block number from 2nd byte in the request*/ + Dataptr = &FrameBuf[3]; } - MemoryWriteBlock( Dataptr , PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + MemoryWriteBlock(Dataptr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); FrameBuf[0] = 0x00; ResponseByteCount = 1; } @@ -142,7 +142,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf,Uid)) { + if (ISO15693Addressed(FrameBuf, Uid)) { FrameBuf[0] = 0; ResponseByteCount = 1; State = STATE_READY; From ede8b48820a9cda03eea3203130ce87a733dc48b Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 8 Nov 2018 16:17:00 +0100 Subject: [PATCH 16/67] Fu..ed up a define with commit 288f6721b10299548e6a4cdd34017535f9e0b542 --- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 8c1dc08..3c94535 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -16,7 +16,7 @@ #include "ISO15693-A.h" #define BYTES_PER_PAGE 4 -#define NUMBER_OF_SECTORS ( ISO15693_GENERIC_MEM_SIZE / BYTES_PER_PAGE ) +#define NUMBER_OF_SECTORS ( TITAGIT_STD_MEM_SIZE / BYTES_PER_PAGE ) #define MEM_UID_ADDRESS 0x20 static enum { From db9dc8efd8d7b43f291faaae6c7aa0a73acdbf3b Mon Sep 17 00:00:00 2001 From: Thorsten Bosbach Date: Sat, 10 Nov 2018 10:11:50 +0100 Subject: [PATCH 17/67] TITagitstandard to unix lineends --- .../Application/TITagitstandard.c | 394 +++++++++--------- .../Application/TITagitstandard.h | 56 +-- 2 files changed, 225 insertions(+), 225 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 3c94535..8f03a48 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -1,198 +1,198 @@ -/* - * TITagitstandard.c - * - * Created on: 01-03-2017 - * Author: Phillip Nash - * Modified by rickventura for texas 15693 tag-it STANDARD - * Modified by ceres-c to finish things up - */ - - -#include "TITagitstandard.h" -#include "../Codec/ISO15693.h" -#include "../Memory.h" -#include "Crypto1.h" -#include "../Random.h" -#include "ISO15693-A.h" - -#define BYTES_PER_PAGE 4 -#define NUMBER_OF_SECTORS ( TITAGIT_STD_MEM_SIZE / BYTES_PER_PAGE ) -#define MEM_UID_ADDRESS 0x20 - -static enum { - STATE_READY, - STATE_SELECTED, - STATE_QUIET -} State; - -//ISO15693UidType Uid = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xE0}; -//0xE0 = iso15693 -//0x07 = TEXAS INSTRUMENTS -//0xC0 0xC1 = "Tagitstandard" 0xC4 or 0xC5 "TagitPro" 0x00 or 0x01 or 0x80 or 0x81 "Tagitplus" - -void TITagitstandardAppInit(void) -{ - State = STATE_READY; -} - -void TITagitstandardAppReset(void) -{ - State = STATE_READY; -} - - -void TITagitstandardAppTask(void) -{ - -} - -void TITagitstandardAppTick(void) -{ - - -} - -// void sendIntToTermina(uint8_t val) -// { -// char buf[16]; -// snprintf(buf,16, "%02x",val); -// TerminalSendString(buf); -// } - -uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) -{ - if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { - if(ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) { - // At this point, we have a valid ISO15693 frame - uint8_t Command = FrameBuf[1]; - uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t Uid[8]; - - //MemoryReadBlock(actualTagIt, 0, 44); // read the whole tag from FRAM - TITagitstandardGetUid(Uid); - - //for (j==0 ; j < ActiveConfiguration.UidSize; j++) Uid[j] = actualTagIt[MEM_UID_ADDRESS + j] ; - - switch(State) { - case STATE_READY: - if (Command == ISO15693_CMD_INVENTORY) { - FrameBuf[0] = 0x00; /* Flags */ - FrameBuf[1] = 0x00; /* DSFID */ - ISO15693CopyUid(&FrameBuf[2], Uid); - - ResponseByteCount = 10; - - - } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf,Uid)) { - State = STATE_QUIET; - - } - - } else if (Command == ISO15693_CMD_READ_SINGLE) { - uint8_t *FramePtr; - uint8_t PageAddress; - - if (ISO15693Addressed(FrameBuf,Uid)) - PageAddress = FrameBuf[10]; /* when receiving an addressed request pick block number from the 10th byte in the request*/ - else - PageAddress = FrameBuf[2]; - - if (PageAddress >= NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ - FrameBuf[0] = ISO15693_RES_FLAG_ERROR; - FrameBuf[1] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ - ResponseByteCount = 2; - break; - } - - if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - FrameBuf[0] = 0x00; /* Flags */ - FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status:when request has the option flag set*/ - FramePtr = FrameBuf + 2; - ResponseByteCount = 6; - } else { /* request with option flag not set*/ - FrameBuf[0] = 0x00; /* Flags */ - FramePtr = FrameBuf + 1; - ResponseByteCount = 5; - } - - MemoryReadBlock(FramePtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); - } - - else if (Command == ISO15693_CMD_WRITE_SINGLE){ - uint8_t* Dataptr; - uint8_t PageAddress; - - - if (ISO15693Addressed(FrameBuf, Uid)) { - PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from 10th byte in the request*/ - Dataptr = &FrameBuf[11]; - } else { - PageAddress = FrameBuf[2]; /*when receiving an unanaddressed request pick block number from 2nd byte in the request*/ - Dataptr = &FrameBuf[3]; - } - - MemoryWriteBlock(Dataptr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); - FrameBuf[0] = 0x00; - ResponseByteCount = 1; - } - break; - case STATE_SELECTED: - break; - - case STATE_QUIET: - if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf, Uid)) { - FrameBuf[0] = 0; - ResponseByteCount = 1; - State = STATE_READY; - } - } - break; - - default: - break; - } - - if (ResponseByteCount > 0) { - /* There is data to be sent. Append CRC */ - ISO15693AppendCRC(FrameBuf, ResponseByteCount); - ResponseByteCount += ISO15693_CRC16_SIZE; - } - - return ResponseByteCount; - - } else { // Invalid CRC - return ISO15693_APP_NO_RESPONSE; - } - } else { // Min frame size not met - return ISO15693_APP_NO_RESPONSE; - } - -} - -void TITagitstandardGetUid(ConfigurationUidType Uid) -{ - MemoryReadBlock(&Uid[0], MEM_UID_ADDRESS, ActiveConfiguration.UidSize); - - // Reverse UID after reading it - uint8_t* UidTemp = calloc(ActiveConfiguration.UidSize, sizeof(UidTemp)); - int i; - for (i = 0; i < ActiveConfiguration.UidSize; i++) - UidTemp[i] = Uid[i]; - for (i = 0; i < ActiveConfiguration.UidSize; i++) - Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; -} - -void TITagitstandardSetUid(ConfigurationUidType Uid) -{ - // Reverse UID before writing it - uint8_t* UidTemp = calloc(ActiveConfiguration.UidSize, sizeof(UidTemp)); - int i; - for (i = 0; i < ActiveConfiguration.UidSize; i++) - UidTemp[i] = Uid[i]; - for (i = 0; i < ActiveConfiguration.UidSize; i++) - Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; - - MemoryWriteBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); +/* + * TITagitstandard.c + * + * Created on: 01-03-2017 + * Author: Phillip Nash + * Modified by rickventura for texas 15693 tag-it STANDARD + * Modified by ceres-c to finish things up + */ + + +#include "TITagitstandard.h" +#include "../Codec/ISO15693.h" +#include "../Memory.h" +#include "Crypto1.h" +#include "../Random.h" +#include "ISO15693-A.h" + +#define BYTES_PER_PAGE 4 +#define NUMBER_OF_SECTORS ( TITAGIT_STD_MEM_SIZE / BYTES_PER_PAGE ) +#define MEM_UID_ADDRESS 0x20 + +static enum { + STATE_READY, + STATE_SELECTED, + STATE_QUIET +} State; + +//ISO15693UidType Uid = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xE0}; +//0xE0 = iso15693 +//0x07 = TEXAS INSTRUMENTS +//0xC0 0xC1 = "Tagitstandard" 0xC4 or 0xC5 "TagitPro" 0x00 or 0x01 or 0x80 or 0x81 "Tagitplus" + +void TITagitstandardAppInit(void) +{ + State = STATE_READY; +} + +void TITagitstandardAppReset(void) +{ + State = STATE_READY; +} + + +void TITagitstandardAppTask(void) +{ + +} + +void TITagitstandardAppTick(void) +{ + + +} + +// void sendIntToTermina(uint8_t val) +// { +// char buf[16]; +// snprintf(buf,16, "%02x",val); +// TerminalSendString(buf); +// } + +uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { + if(ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) { + // At this point, we have a valid ISO15693 frame + uint8_t Command = FrameBuf[1]; + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t Uid[8]; + + //MemoryReadBlock(actualTagIt, 0, 44); // read the whole tag from FRAM + TITagitstandardGetUid(Uid); + + //for (j==0 ; j < ActiveConfiguration.UidSize; j++) Uid[j] = actualTagIt[MEM_UID_ADDRESS + j] ; + + switch(State) { + case STATE_READY: + if (Command == ISO15693_CMD_INVENTORY) { + FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[1] = 0x00; /* DSFID */ + ISO15693CopyUid(&FrameBuf[2], Uid); + + ResponseByteCount = 10; + + + } else if (Command == ISO15693_CMD_STAY_QUIET) { + if (ISO15693Addressed(FrameBuf,Uid)) { + State = STATE_QUIET; + + } + + } else if (Command == ISO15693_CMD_READ_SINGLE) { + uint8_t *FramePtr; + uint8_t PageAddress; + + if (ISO15693Addressed(FrameBuf,Uid)) + PageAddress = FrameBuf[10]; /* when receiving an addressed request pick block number from the 10th byte in the request*/ + else + PageAddress = FrameBuf[2]; + + if (PageAddress >= NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ + FrameBuf[0] = ISO15693_RES_FLAG_ERROR; + FrameBuf[1] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ + ResponseByteCount = 2; + break; + } + + if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ + FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status:when request has the option flag set*/ + FramePtr = FrameBuf + 2; + ResponseByteCount = 6; + } else { /* request with option flag not set*/ + FrameBuf[0] = 0x00; /* Flags */ + FramePtr = FrameBuf + 1; + ResponseByteCount = 5; + } + + MemoryReadBlock(FramePtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + } + + else if (Command == ISO15693_CMD_WRITE_SINGLE){ + uint8_t* Dataptr; + uint8_t PageAddress; + + + if (ISO15693Addressed(FrameBuf, Uid)) { + PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from 10th byte in the request*/ + Dataptr = &FrameBuf[11]; + } else { + PageAddress = FrameBuf[2]; /*when receiving an unanaddressed request pick block number from 2nd byte in the request*/ + Dataptr = &FrameBuf[3]; + } + + MemoryWriteBlock(Dataptr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + FrameBuf[0] = 0x00; + ResponseByteCount = 1; + } + break; + case STATE_SELECTED: + break; + + case STATE_QUIET: + if (Command == ISO15693_CMD_RESET_TO_READY) { + if (ISO15693Addressed(FrameBuf, Uid)) { + FrameBuf[0] = 0; + ResponseByteCount = 1; + State = STATE_READY; + } + } + break; + + default: + break; + } + + if (ResponseByteCount > 0) { + /* There is data to be sent. Append CRC */ + ISO15693AppendCRC(FrameBuf, ResponseByteCount); + ResponseByteCount += ISO15693_CRC16_SIZE; + } + + return ResponseByteCount; + + } else { // Invalid CRC + return ISO15693_APP_NO_RESPONSE; + } + } else { // Min frame size not met + return ISO15693_APP_NO_RESPONSE; + } + +} + +void TITagitstandardGetUid(ConfigurationUidType Uid) +{ + MemoryReadBlock(&Uid[0], MEM_UID_ADDRESS, ActiveConfiguration.UidSize); + + // Reverse UID after reading it + uint8_t* UidTemp = calloc(ActiveConfiguration.UidSize, sizeof(UidTemp)); + int i; + for (i = 0; i < ActiveConfiguration.UidSize; i++) + UidTemp[i] = Uid[i]; + for (i = 0; i < ActiveConfiguration.UidSize; i++) + Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; +} + +void TITagitstandardSetUid(ConfigurationUidType Uid) +{ + // Reverse UID before writing it + uint8_t* UidTemp = calloc(ActiveConfiguration.UidSize, sizeof(UidTemp)); + int i; + for (i = 0; i < ActiveConfiguration.UidSize; i++) + UidTemp[i] = Uid[i]; + for (i = 0; i < ActiveConfiguration.UidSize; i++) + Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; + + MemoryWriteBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); } \ No newline at end of file diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.h b/Firmware/Chameleon-Mini/Application/TITagitstandard.h index 066d10e..839506f 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.h +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.h @@ -1,28 +1,28 @@ -/* - * MifareClassic.h - * - * Created on: 01.03.2017 - * Author: skuser - * modified by rickventura - */ - -#ifndef TITAGITSTANDARD_H_ -#define TITAGITSTANDARD_H_ - -#include "Application.h" -#include "ISO15693-A.h" - -#define TITAGIT_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE -#define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE - -void TITagitstandardAppInit(void); -void TITagitstandardAppReset(void); -void TITagitstandardAppTask(void); -void TITagitstandardAppTick(void); -uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes); -void TITagitstandardGetUid(ConfigurationUidType Uid); -void TITagitstandardSetUid(ConfigurationUidType Uid); - - - -#endif /* VICINITY_H_ */ +/* + * MifareClassic.h + * + * Created on: 01.03.2017 + * Author: skuser + * modified by rickventura + */ + +#ifndef TITAGITSTANDARD_H_ +#define TITAGITSTANDARD_H_ + +#include "Application.h" +#include "ISO15693-A.h" + +#define TITAGIT_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE +#define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE + +void TITagitstandardAppInit(void); +void TITagitstandardAppReset(void); +void TITagitstandardAppTask(void); +void TITagitstandardAppTick(void); +uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes); +void TITagitstandardGetUid(ConfigurationUidType Uid); +void TITagitstandardSetUid(ConfigurationUidType Uid); + + + +#endif /* VICINITY_H_ */ From 10ad3cb4913cbe804e24e147484ee000189b81a2 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Sat, 10 Nov 2018 17:41:05 +0100 Subject: [PATCH 18/67] Modified ISO15692-A.h CompareUid, temporary fix to Sl2s2002.c and Vicinity.c --- .../Chameleon-Mini/Application/ISO15693-A.h | 16 ++------- .../Chameleon-Mini/Application/Sl2s2002.c | 18 ++++++---- .../Application/TITagitstandard.c | 34 ++++++++++++------- .../Chameleon-Mini/Application/Vicinity.c | 9 +++-- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index b954d60..1d0996b 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -95,20 +95,8 @@ void ISO15693CopyUid(uint8_t* DstUid, uint8_t* SrcUid) } INLINE -bool ISO15693Addressed(uint8_t* Buffer, uint8_t* MyUid) { - if (Buffer[0] & ISO15693_REQ_FLAG_ADDRESS) { - /* Addressed mode */ - if ( ISO15693CompareUid(&Buffer[2], MyUid) ) { - /* Our UID addressed */ - return true; - } else { - /* Our UID not addressed */ - return false; - } - } else { - /* Non-Addressed mode */ - return true; - } +bool ISO15693Addressed(uint8_t* Buffer) { + return (Buffer[0] & ISO15693_REQ_FLAG_ADDRESS); /* if the flag is set, the command is addressed */ } // (FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.c b/Firmware/Chameleon-Mini/Application/Sl2s2002.c index 936bfb8..4010ed4 100644 --- a/Firmware/Chameleon-Mini/Application/Sl2s2002.c +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.c @@ -62,11 +62,13 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ISO15693CopyUid(&FrameBuf[2], Uid); ResponseByteCount = 10; } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { State = STATE_QUIET; } } else if (Command == ISO15693_CMD_GET_SYS_INFO) { - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { FrameBuf[0] = 0; /* Flags */ FrameBuf[1] = 0x0F; /* InfoFlags */ ISO15693CopyUid(&FrameBuf[2], Uid); @@ -78,7 +80,8 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ResponseByteCount = 15; } } else if (Command == ISO15693_CMD_READ_SINGLE) { - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { uint8_t PageAddress = FrameBuf[10]; if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) { @@ -93,7 +96,8 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } } } else if (Command == ISO15693_CMD_READ_MULTIPLE) { - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { uint16_t PageAddress = FrameBuf[10]; uint16_t PageAddressCount = FrameBuf[11] + 1; @@ -116,7 +120,8 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[0] = 0; /* Flags */ } } else if (Command == ISO15693_CMD_GET_BLOCK_SEC) { - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { uint8_t PageAddressStart = FrameBuf[10]; uint8_t PageAddressCount = FrameBuf[11] + 1; FrameBuf[0] = 0; /* Flags */ @@ -133,7 +138,8 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { FrameBuf[0] = 0; ResponseByteCount = 1; State = STATE_READY; diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 8f03a48..0830b20 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -84,17 +84,21 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf,Uid)) { + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { State = STATE_QUIET; - } } else if (Command == ISO15693_CMD_READ_SINGLE) { uint8_t *FramePtr; uint8_t PageAddress; - if (ISO15693Addressed(FrameBuf,Uid)) - PageAddress = FrameBuf[10]; /* when receiving an addressed request pick block number from the 10th byte in the request*/ + if (ISO15693Addressed(FrameBuf)) + if (ISO15693CompareUid(&FrameBuf[2], Uid)) /* read is addressed to us */ + PageAddress = FrameBuf[10]; /* when receiving an addressed request pick block number from the 10th byte in the request*/ + else { /* we are not the addressee of the read command */ + ResponseByteCount = 0; + break; + } else PageAddress = FrameBuf[2]; @@ -124,13 +128,19 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t PageAddress; - if (ISO15693Addressed(FrameBuf, Uid)) { - PageAddress = FrameBuf[10]; /*when receiving anaddressed request pick block number from 10th byte in the request*/ - Dataptr = &FrameBuf[11]; - } else { - PageAddress = FrameBuf[2]; /*when receiving an unanaddressed request pick block number from 2nd byte in the request*/ - Dataptr = &FrameBuf[3]; - } + if (ISO15693Addressed(FrameBuf)) + if (ISO15693CompareUid(&FrameBuf[2], Uid)) {/* write is addressed to us */ + PageAddress = FrameBuf[10]; /*when receiving an addressed request pick block number from 10th byte in the request*/ + Dataptr = &FrameBuf[11]; + } + else { /* we are not the addressee of the write command */ + ResponseByteCount = 0; + break; + } + else { + PageAddress = FrameBuf[2]; + Dataptr = &FrameBuf[3]; + } MemoryWriteBlock(Dataptr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); FrameBuf[0] = 0x00; @@ -142,7 +152,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf, Uid)) { + if (ISO15693Addressed(FrameBuf)) { FrameBuf[0] = 0; ResponseByteCount = 1; State = STATE_READY; diff --git a/Firmware/Chameleon-Mini/Application/Vicinity.c b/Firmware/Chameleon-Mini/Application/Vicinity.c index 3bfca1f..ac0e7d4 100644 --- a/Firmware/Chameleon-Mini/Application/Vicinity.c +++ b/Firmware/Chameleon-Mini/Application/Vicinity.c @@ -61,11 +61,13 @@ uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ISO15693CopyUid(&FrameBuf[2], Uid); ResponseByteCount = 10; } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { State = STATE_QUIET; } } else if (Command == ISO15693_CMD_GET_SYS_INFO) { - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { FrameBuf[0] = 0; /* Flags */ FrameBuf[1] = 0; /* InfoFlags */ ISO15693CopyUid(&FrameBuf[2], Uid); @@ -81,7 +83,8 @@ uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { MemoryReadBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); - if (ISO15693Addressed(FrameBuf, Uid)) { + /* TODO: check for unaddressed requests */ + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { FrameBuf[0] = 0; ResponseByteCount = 1; State = STATE_READY; From 804ed4cb021c4acc05cdd7cd6ae61fca43fb069f Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Sat, 10 Nov 2018 20:56:17 +0100 Subject: [PATCH 19/67] Added standard error codes and flags in ISO15693-A.h. Replaced magic numbers in TITagstandard.c and refined the state machine, also @m2otech moved UID flipping to TITagitstandardFlipUid. calloc is not used anymore (to avoid compiler warnings and unnecessary includes). Moved definitions to TITagstandard.h. Changed ISO15693Addressed calls in Vicinity.c and Sl2s2002.c to ISO15693AddressedLegacy. The latter should be removed sooner or later... --- .../Chameleon-Mini/Application/ISO15693-A.h | 30 ++++- .../Chameleon-Mini/Application/Sl2s2002.c | 22 ++-- .../Application/TITagitstandard.c | 118 ++++++++---------- .../Application/TITagitstandard.h | 12 +- .../Chameleon-Mini/Application/Vicinity.c | 13 +- 5 files changed, 102 insertions(+), 93 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 1d0996b..3f45a6f 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -10,6 +10,14 @@ #include "../Common.h" +/* request and response fields addresses */ +#define ISO15693_ADDR_FLAGS 0x00 +#define ISO15693_REQ_ADDR_CMD 0x01 +#define ISO15693_REQ_ADDR_PARAM 0x02 + +#define ISO15693_RES_ADDR_PARAM 0x01 + +/* command codes */ #define ISO15693_CMD_INVENTORY 0x01 #define ISO15693_CMD_STAY_QUIET 0x02 #define ISO15693_CMD_READ_SINGLE 0x20 @@ -39,6 +47,7 @@ #define ISO15693_REQ_FLAG_AFI 0x10 #define ISO15693_REQ_FLAG_NB_SLOTS 0x20 +#define ISO15693_RES_FLAG_NO_ERROR 0x00 #define ISO15693_RES_FLAG_ERROR 0x01 #define ISO15693_RES_FLAG_PROT_EXT 0x08 @@ -52,6 +61,7 @@ #define ISO15693_RES_ERR_BLK_NOT_PRGR 0x13 #define ISO15693_RES_ERR_BLK_NOT_LKD 0x14 +#define ISO15693_RES_INVENTORY_DSFID 0x00 #define ISO15693_MIN_FRAME_SIZE 5 @@ -96,9 +106,25 @@ void ISO15693CopyUid(uint8_t* DstUid, uint8_t* SrcUid) INLINE bool ISO15693Addressed(uint8_t* Buffer) { - return (Buffer[0] & ISO15693_REQ_FLAG_ADDRESS); /* if the flag is set, the command is addressed */ + return (Buffer[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS); /* if the flag is set, the command is addressed */ } -// (FrameBuf[0] & ISO15693_REQ_FLAG_ADDRESS) && ISO15693CompareUid(&FrameBuf[2], Uid) + +INLINE +bool ISO15693AddressedLegacy(uint8_t* Buffer, uint8_t* MyUid) { + if (Buffer[0] & ISO15693_REQ_FLAG_ADDRESS) { + /* Addressed mode */ + if ( ISO15693CompareUid(&Buffer[2], MyUid) ) { + /* Our UID addressed */ + return true; + } else { + /* Our UID not addressed */ + return false; + } + } else { + /* Non-Addressed mode */ + return true; + } +} #endif /* ISO15693_3_H_ */ diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.c b/Firmware/Chameleon-Mini/Application/Sl2s2002.c index 4010ed4..dbef868 100644 --- a/Firmware/Chameleon-Mini/Application/Sl2s2002.c +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.c @@ -3,6 +3,10 @@ * * Created on: 01-03-2017 * Author: Phillip Nash + * + * TODO: + * - ISO15693AddressedLegacy should be replaced with ISO15693Addressed and appropriate check + * should be performed (see TITagitstandard.c) - ceres-c */ @@ -62,13 +66,11 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ISO15693CopyUid(&FrameBuf[2], Uid); ResponseByteCount = 10; } else if (Command == ISO15693_CMD_STAY_QUIET) { - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { State = STATE_QUIET; } } else if (Command == ISO15693_CMD_GET_SYS_INFO) { - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { FrameBuf[0] = 0; /* Flags */ FrameBuf[1] = 0x0F; /* InfoFlags */ ISO15693CopyUid(&FrameBuf[2], Uid); @@ -80,8 +82,7 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ResponseByteCount = 15; } } else if (Command == ISO15693_CMD_READ_SINGLE) { - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { uint8_t PageAddress = FrameBuf[10]; if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) { @@ -96,8 +97,7 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } } } else if (Command == ISO15693_CMD_READ_MULTIPLE) { - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { uint16_t PageAddress = FrameBuf[10]; uint16_t PageAddressCount = FrameBuf[11] + 1; @@ -120,8 +120,7 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[0] = 0; /* Flags */ } } else if (Command == ISO15693_CMD_GET_BLOCK_SEC) { - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { uint8_t PageAddressStart = FrameBuf[10]; uint8_t PageAddressCount = FrameBuf[11] + 1; FrameBuf[0] = 0; /* Flags */ @@ -138,8 +137,7 @@ uint16_t Sl2s2002AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { FrameBuf[0] = 0; ResponseByteCount = 1; State = STATE_READY; diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 0830b20..5c54241 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -5,9 +5,10 @@ * Author: Phillip Nash * Modified by rickventura for texas 15693 tag-it STANDARD * Modified by ceres-c to finish things up + * TODO: + * - Selected mode has to be impemented altogether - ceres-c */ - #include "TITagitstandard.h" #include "../Codec/ISO15693.h" #include "../Memory.h" @@ -15,10 +16,6 @@ #include "../Random.h" #include "ISO15693-A.h" -#define BYTES_PER_PAGE 4 -#define NUMBER_OF_SECTORS ( TITAGIT_STD_MEM_SIZE / BYTES_PER_PAGE ) -#define MEM_UID_ADDRESS 0x20 - static enum { STATE_READY, STATE_SELECTED, @@ -49,16 +46,8 @@ void TITagitstandardAppTask(void) void TITagitstandardAppTick(void) { - } -// void sendIntToTermina(uint8_t val) -// { -// char buf[16]; -// snprintf(buf,16, "%02x",val); -// TerminalSendString(buf); -// } - uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { @@ -66,94 +55,87 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) // At this point, we have a valid ISO15693 frame uint8_t Command = FrameBuf[1]; uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t Uid[8]; - - //MemoryReadBlock(actualTagIt, 0, 44); // read the whole tag from FRAM + uint8_t Uid[ActiveConfiguration.UidSize]; TITagitstandardGetUid(Uid); - //for (j==0 ; j < ActiveConfiguration.UidSize; j++) Uid[j] = actualTagIt[MEM_UID_ADDRESS + j] ; - switch(State) { case STATE_READY: if (Command == ISO15693_CMD_INVENTORY) { - FrameBuf[0] = 0x00; /* Flags */ - FrameBuf[1] = 0x00; /* DSFID */ - ISO15693CopyUid(&FrameBuf[2], Uid); - + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_INVENTORY_DSFID; + ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); ResponseByteCount = 10; - } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) State = STATE_QUIET; - } } else if (Command == ISO15693_CMD_READ_SINGLE) { uint8_t *FramePtr; uint8_t PageAddress; - if (ISO15693Addressed(FrameBuf)) - if (ISO15693CompareUid(&FrameBuf[2], Uid)) /* read is addressed to us */ - PageAddress = FrameBuf[10]; /* when receiving an addressed request pick block number from the 10th byte in the request*/ - else { /* we are not the addressee of the read command */ - ResponseByteCount = 0; + if (ISO15693Addressed(FrameBuf)) { + if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) /* read is addressed to us */ + /* pick block 2 + 8 (UID Lenght) */ + PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; + else /* we are not the addressee of the read command */ break; - } - else - PageAddress = FrameBuf[2]; - - if (PageAddress >= NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ - FrameBuf[0] = ISO15693_RES_FLAG_ERROR; - FrameBuf[1] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ + } else /* request is not addressed */ + PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; + + if (PageAddress >= TITAGIT_NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ ResponseByteCount = 2; break; } - if (FrameBuf[0] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - FrameBuf[0] = 0x00; /* Flags */ - FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status:when request has the option flag set*/ + if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + /* UID is stored in blocks 8 and 9 which are blocked */ + FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status: when request has the option flag set */ FramePtr = FrameBuf + 2; ResponseByteCount = 6; } else { /* request with option flag not set*/ - FrameBuf[0] = 0x00; /* Flags */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_REQ_FLAG_OPTION; /* Flags */ FramePtr = FrameBuf + 1; ResponseByteCount = 5; } - MemoryReadBlock(FramePtr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); + MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); } - else if (Command == ISO15693_CMD_WRITE_SINGLE){ + else if (Command == ISO15693_CMD_WRITE_SINGLE) { uint8_t* Dataptr; uint8_t PageAddress; - - if (ISO15693Addressed(FrameBuf)) - if (ISO15693CompareUid(&FrameBuf[2], Uid)) {/* write is addressed to us */ - PageAddress = FrameBuf[10]; /*when receiving an addressed request pick block number from 10th byte in the request*/ - Dataptr = &FrameBuf[11]; + if (ISO15693Addressed(FrameBuf)) { + if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ + /* pick block 2 + 8 (UID Lenght) */ + PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ + /* pick block 2 + 8 (UID Lenght) + 1 (data starts here) */ + Dataptr = &FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08 + 0x01]; /* addr of sent data to write in memory */ } - else { /* we are not the addressee of the write command */ - ResponseByteCount = 0; + else /* we are not the addressee of the write command */ break; - } - else { - PageAddress = FrameBuf[2]; - Dataptr = &FrameBuf[3]; + } else { /* request is not addressed */ + PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; + Dataptr = &FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x01]; } - MemoryWriteBlock(Dataptr, PageAddress * BYTES_PER_PAGE, BYTES_PER_PAGE); - FrameBuf[0] = 0x00; + MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; } break; case STATE_SELECTED: + /* TODO: Selected has to be impemented altogether */ break; case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { if (ISO15693Addressed(FrameBuf)) { - FrameBuf[0] = 0; + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; State = STATE_READY; } @@ -183,26 +165,26 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) void TITagitstandardGetUid(ConfigurationUidType Uid) { - MemoryReadBlock(&Uid[0], MEM_UID_ADDRESS, ActiveConfiguration.UidSize); - + MemoryReadBlock(&Uid[0], TITAGIT_MEM_UID_ADDRESS, ActiveConfiguration.UidSize); + // Reverse UID after reading it - uint8_t* UidTemp = calloc(ActiveConfiguration.UidSize, sizeof(UidTemp)); - int i; - for (i = 0; i < ActiveConfiguration.UidSize; i++) - UidTemp[i] = Uid[i]; - for (i = 0; i < ActiveConfiguration.UidSize; i++) - Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; + TITagitstandardFlipUid(Uid); } void TITagitstandardSetUid(ConfigurationUidType Uid) { // Reverse UID before writing it - uint8_t* UidTemp = calloc(ActiveConfiguration.UidSize, sizeof(UidTemp)); + TITagitstandardFlipUid(Uid); + + MemoryWriteBlock(Uid, TITAGIT_MEM_UID_ADDRESS, ActiveConfiguration.UidSize); +} + +void TITagitstandardFlipUid(ConfigurationUidType Uid) +{ + uint8_t UidTemp[ActiveConfiguration.UidSize]; int i; for (i = 0; i < ActiveConfiguration.UidSize; i++) UidTemp[i] = Uid[i]; for (i = 0; i < ActiveConfiguration.UidSize; i++) Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; - - MemoryWriteBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); } \ No newline at end of file diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.h b/Firmware/Chameleon-Mini/Application/TITagitstandard.h index 839506f..bd984c5 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.h +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.h @@ -12,8 +12,11 @@ #include "Application.h" #include "ISO15693-A.h" -#define TITAGIT_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE -#define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE +#define TITAGIT_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE +#define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE +#define TITAGIT_BYTES_PER_PAGE 4 +#define TITAGIT_NUMBER_OF_SECTORS ( TITAGIT_STD_MEM_SIZE / TITAGIT_BYTES_PER_PAGE ) +#define TITAGIT_MEM_UID_ADDRESS 0x20 void TITagitstandardAppInit(void); void TITagitstandardAppReset(void); @@ -22,7 +25,6 @@ void TITagitstandardAppTick(void); uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes); void TITagitstandardGetUid(ConfigurationUidType Uid); void TITagitstandardSetUid(ConfigurationUidType Uid); +void TITagitstandardFlipUid(ConfigurationUidType Uid); - - -#endif /* VICINITY_H_ */ +#endif /* VICINITY_H_ */ \ No newline at end of file diff --git a/Firmware/Chameleon-Mini/Application/Vicinity.c b/Firmware/Chameleon-Mini/Application/Vicinity.c index ac0e7d4..0b8b9a4 100644 --- a/Firmware/Chameleon-Mini/Application/Vicinity.c +++ b/Firmware/Chameleon-Mini/Application/Vicinity.c @@ -3,6 +3,10 @@ * * Created on: 01-03-2017 * Author: Phillip Nash + * + * TODO: + * - ISO15693AddressedLegacy should be replaced with ISO15693Addressed and appropriate check + * should be performed (see TITagitstandard.c) - ceres-c */ @@ -61,13 +65,11 @@ uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ISO15693CopyUid(&FrameBuf[2], Uid); ResponseByteCount = 10; } else if (Command == ISO15693_CMD_STAY_QUIET) { - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { State = STATE_QUIET; } } else if (Command == ISO15693_CMD_GET_SYS_INFO) { - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { FrameBuf[0] = 0; /* Flags */ FrameBuf[1] = 0; /* InfoFlags */ ISO15693CopyUid(&FrameBuf[2], Uid); @@ -83,8 +85,7 @@ uint16_t VicinityAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_QUIET: if (Command == ISO15693_CMD_RESET_TO_READY) { MemoryReadBlock(Uid, MEM_UID_ADDRESS, ActiveConfiguration.UidSize); - /* TODO: check for unaddressed requests */ - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[2], Uid)) { + if (ISO15693AddressedLegacy(FrameBuf, Uid)) { FrameBuf[0] = 0; ResponseByteCount = 1; State = STATE_READY; From d1cc3e02567396b29ebc53858c5163204f25e4c8 Mon Sep 17 00:00:00 2001 From: m2otech Date: Sun, 11 Nov 2018 11:45:17 +0100 Subject: [PATCH 20/67] Fixed flags in response to addressed signle read without option flags --- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 5c54241..103e964 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -97,7 +97,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FramePtr = FrameBuf + 2; ResponseByteCount = 6; } else { /* request with option flag not set*/ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_REQ_FLAG_OPTION; /* Flags */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* Flags */ FramePtr = FrameBuf + 1; ResponseByteCount = 5; } From 258ea95de268c7b7bef6dd12c7409f4e01d49f59 Mon Sep 17 00:00:00 2001 From: Rickventura <43839047+Rickventura@users.noreply.github.com> Date: Mon, 12 Nov 2018 14:01:16 +0100 Subject: [PATCH 21/67] TITagitstandardFlipUid refactored --- .../Application/TITagitstandard.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 103e964..b68a243 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -76,6 +76,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (ISO15693Addressed(FrameBuf)) { if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) /* read is addressed to us */ + /* pick block 2 + 8 (UID Lenght) */ PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; else /* we are not the addressee of the read command */ @@ -103,6 +104,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + } else if (Command == ISO15693_CMD_WRITE_SINGLE) { @@ -181,10 +183,13 @@ void TITagitstandardSetUid(ConfigurationUidType Uid) void TITagitstandardFlipUid(ConfigurationUidType Uid) { - uint8_t UidTemp[ActiveConfiguration.UidSize]; - int i; - for (i = 0; i < ActiveConfiguration.UidSize; i++) - UidTemp[i] = Uid[i]; - for (i = 0; i < ActiveConfiguration.UidSize; i++) - Uid[i] = UidTemp[ActiveConfiguration.UidSize - i - 1]; + + uint8_t tmp , *tail ; + tail = Uid + ActiveConfiguration.UidSize - 1; + while ( Uid < tail ){ + tmp = *Uid; + *Uid++ = *tail ; + *tail-- = tmp; + } + } \ No newline at end of file From 119096971efedf476076bccc105a4219a4e7c669 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Mon, 12 Nov 2018 15:12:01 +0100 Subject: [PATCH 22/67] Fixed indentation. Sorry, it's driving me nuts --- .../Chameleon-Mini/Application/TITagitstandard.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index b68a243..73784fb 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -183,13 +183,11 @@ void TITagitstandardSetUid(ConfigurationUidType Uid) void TITagitstandardFlipUid(ConfigurationUidType Uid) { - - uint8_t tmp , *tail ; - tail = Uid + ActiveConfiguration.UidSize - 1; - while ( Uid < tail ){ - tmp = *Uid; - *Uid++ = *tail ; - *tail-- = tmp; - } - + uint8_t tmp, *tail; + tail = Uid + ActiveConfiguration.UidSize - 1; + while ( Uid < tail ) { + tmp = *Uid; + *Uid++ = *tail; + *tail-- = tmp; + } } \ No newline at end of file From d65f88d4082ef73a212d84879de837b360a1c3cc Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Mon, 12 Nov 2018 15:12:01 +0100 Subject: [PATCH 23/67] Fixed indentation. Sorry, it's driving me nuts --- .../Chameleon-Mini/Application/TITagitstandard.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index b68a243..73784fb 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -183,13 +183,11 @@ void TITagitstandardSetUid(ConfigurationUidType Uid) void TITagitstandardFlipUid(ConfigurationUidType Uid) { - - uint8_t tmp , *tail ; - tail = Uid + ActiveConfiguration.UidSize - 1; - while ( Uid < tail ){ - tmp = *Uid; - *Uid++ = *tail ; - *tail-- = tmp; - } - + uint8_t tmp, *tail; + tail = Uid + ActiveConfiguration.UidSize - 1; + while ( Uid < tail ) { + tmp = *Uid; + *Uid++ = *tail; + *tail-- = tmp; + } } \ No newline at end of file From d6ac530972dbd3a3b199ec429a31ed4159bfba82 Mon Sep 17 00:00:00 2001 From: Thorsten <12600404+bosb@users.noreply.github.com> Date: Thu, 22 Nov 2018 17:00:29 +0100 Subject: [PATCH 24/67] ISO15693_MIN_FRAME_SIZE for iso15 should be 4 --- Firmware/Chameleon-Mini/Application/ISO15693-A.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 3f45a6f..48cace8 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -63,7 +63,7 @@ #define ISO15693_RES_INVENTORY_DSFID 0x00 -#define ISO15693_MIN_FRAME_SIZE 5 +#define ISO15693_MIN_FRAME_SIZE 4 #define ISO15693_CRC16_SIZE 2 /* Bytes */ #define ISO15693_CRC16_POLYNORMAL 0x8408 From b83b4f80e7de5ee4c910ba9c3681dc61315c9562 Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Wed, 28 Nov 2018 18:40:51 +0100 Subject: [PATCH 25/67] Added tag family configuration --- Firmware/Chameleon-Mini/Button.c | 5 + Firmware/Chameleon-Mini/Configuration.c | 122 +++++++++++--------- Firmware/Chameleon-Mini/Configuration.h | 11 ++ Firmware/Chameleon-Mini/Terminal/Commands.c | 5 + 4 files changed, 89 insertions(+), 54 deletions(-) diff --git a/Firmware/Chameleon-Mini/Button.c b/Firmware/Chameleon-Mini/Button.c index 3791783..33f3eb5 100644 --- a/Firmware/Chameleon-Mini/Button.c +++ b/Firmware/Chameleon-Mini/Button.c @@ -4,6 +4,7 @@ #include "Settings.h" #include "Memory.h" #include "Map.h" +#include "Configuration.h" #include "Terminal/CommandLine.h" #include "Application/Application.h" @@ -42,6 +43,10 @@ static void ExecuteButtonAction(ButtonActionEnum ButtonAction) for (uint8_t i=0; i Date: Thu, 29 Nov 2018 18:00:36 +0100 Subject: [PATCH 26/67] Added bitmask to track locked blocks, Lock Block command, sanity checks on received data. --- .../Application/TITagitstandard.c | 73 ++++++++++++++++--- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 73784fb..f334b99 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -22,6 +22,9 @@ static enum { STATE_QUIET } State; +uint16_t UserLockBits_Mask = 0; /* Holds lock state of blocks */ +uint16_t FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ + //ISO15693UidType Uid = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xE0}; //0xE0 = iso15693 //0x07 = TEXAS INSTRUMENTS @@ -30,6 +33,9 @@ static enum { void TITagitstandardAppInit(void) { State = STATE_READY; + FactoryLockBits_Mask |= (1 << 8); /* Locks block 8... */ + FactoryLockBits_Mask |= (1 << 9); /* ...and 9, which contains the UID */ + UserLockBits_Mask |= (1 << 3); /* TESTING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ } void TITagitstandardAppReset(void) @@ -92,19 +98,24 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - /* UID is stored in blocks 8 and 9 which are blocked */ - FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status: when request has the option flag set */ + if (FactoryLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ + FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ + } + else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ + FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ + } + else + FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ FramePtr = FrameBuf + 2; ResponseByteCount = 6; - } else { /* request with option flag not set*/ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* Flags */ + } else { /* request with option flag not set */ FramePtr = FrameBuf + 1; ResponseByteCount = 5; } - MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); } else if (Command == ISO15693_CMD_WRITE_SINGLE) { @@ -112,6 +123,8 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t PageAddress; if (ISO15693Addressed(FrameBuf)) { + if (FrameBytes < (0x01 + 0x01 + 0x08 + 0x01 + 0x04)) /* flag + cmd + uid + block number + data */ + break; /* malformed: not enough data */ if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ /* pick block 2 + 8 (UID Lenght) */ PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ @@ -121,17 +134,57 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) else /* we are not the addressee of the write command */ break; } else { /* request is not addressed */ + if (FrameBytes < (0x01 + 0x01 + 0x01 + 0x04)) /* flag + cmd + block number + data */ + break; /* malformed: not enough data */ PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; Dataptr = &FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x01]; } - MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; + if (FactoryLockBits_Mask & (1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; + } else if (UserLockBits_Mask & (1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_BLK_CHG_LKD; + ResponseByteCount = 2; + } else { + MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } } + + else if (Command == ISO15693_CMD_LOCK_BLOCK) { + uint8_t PageAddress; + if (ISO15693Addressed(FrameBuf)) { + if (FrameBytes < (0x01 + 0x01 + 0x08 + 0x01)) /* flag + cmd + uid + block number + data */ + break; /* malformed: not enough data */ + if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ + /* pick block 2 + 8 (UID Lenght) */ + PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ + } + else /* we are not the addressee of the write command */ + break; + } else { /* request is not addressed */ + if (FrameBytes < (0x01 + 0x01 + 0x01)) /* flag + cmd + block number + data */ + break; /* malformed: not enough data */ + PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; + } + + if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_BLK_ALRD_LKD; + ResponseByteCount = 2; + } else { + UserLockBits_Mask |= (1 << PageAddress); /* */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } + } break; case STATE_SELECTED: - /* TODO: Selected has to be impemented altogether */ + /* Selected state is not supported by Ti TagIt Standard */ break; case STATE_QUIET: From 3ce502158d1e9eb720dbad969d6df47385df5898 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 29 Nov 2018 18:17:34 +0100 Subject: [PATCH 27/67] Removed testing stuff and removed todo --- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index f334b99..27e734a 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -5,8 +5,6 @@ * Author: Phillip Nash * Modified by rickventura for texas 15693 tag-it STANDARD * Modified by ceres-c to finish things up - * TODO: - * - Selected mode has to be impemented altogether - ceres-c */ #include "TITagitstandard.h" @@ -35,7 +33,6 @@ void TITagitstandardAppInit(void) State = STATE_READY; FactoryLockBits_Mask |= (1 << 8); /* Locks block 8... */ FactoryLockBits_Mask |= (1 << 9); /* ...and 9, which contains the UID */ - UserLockBits_Mask |= (1 << 3); /* TESTING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ } void TITagitstandardAppReset(void) From 28f647818e644d955b14b2bd929a569145dcf1ed Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 29 Nov 2018 18:33:30 +0100 Subject: [PATCH 28/67] Removed unsupported command ISO15693_CMD_RESET_TO_READY --- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 27e734a..ddc787f 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -185,13 +185,18 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) break; case STATE_QUIET: + /* Ti TagIt Standard does not support reset to ready command */ + /* following code is lef for future reference for other tags */ + /* if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf)) { + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; State = STATE_READY; } } + */ + ResponseByteCount = 0; /* better safe than sorry */ break; default: From d091e2291b9095eddc33f10569c4ca62abafaada Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Mon, 3 Dec 2018 23:07:50 +0100 Subject: [PATCH 29/67] PrepareFrame function first draft, there might be performance issues --- .../Chameleon-Mini/Application/ISO15693-A.c | 40 +++ .../Chameleon-Mini/Application/ISO15693-A.h | 16 +- .../Application/TITagitstandard.c | 315 +++++++++--------- 3 files changed, 202 insertions(+), 169 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 0f7f3d3..7837111 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -50,3 +50,43 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) return (DataPtr[FrameBufSize] == crcLb && DataPtr[FrameBufSize + 1] == crcHb); } + +/* + * ISO15693PrepareFrame + * + * This function validates frame lenght and sets pointers in 'frame' struct + * to relevant byte(s) of 'FrameBuf'. Also sets frame.addressed as true if + * the command is addressed + * + * Returns: + * - true: Frame is valid and a response is needed + * - false: Request is not addressed to us + * Frame is not valid because it's too short or CRC is wrong + */ +bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid) +{ + if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) + /* malformed frame */ + return false; + + /* following declarations are not dependent on addressed/unaddressed state */ + FrameStruct -> Flags = &FrameBuf[ISO15693_ADDR_FLAGS]; + FrameStruct -> Command = &FrameBuf[ISO15693_REQ_ADDR_CMD]; + FrameStruct -> Addressed = ( !(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY) & (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS) ); + /* "inventory" flag must be 0, otherwise "addressed" flag have a different meaning (see ISO15693-3) */ + + if (FrameStruct -> Addressed) + /* UID sits between CMD and PARAM */ + FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM + ISO15693_GENERIC_UID_SIZE]; + else + FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM]; + + FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); + + if (FrameStruct -> Addressed && !ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], MyUid)) { + /* addressed request but we're not the addressee */ + return false; + } else { + return true; + } +} \ No newline at end of file diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 3f45a6f..936dbe4 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -63,16 +63,26 @@ #define ISO15693_RES_INVENTORY_DSFID 0x00 -#define ISO15693_MIN_FRAME_SIZE 5 +#define ISO15693_MIN_FRAME_SIZE 0x05 -#define ISO15693_CRC16_SIZE 2 /* Bytes */ +#define ISO15693_GENERIC_UID_SIZE 0x08 +#define ISO15693_GENERIC_MEM_SIZE 8192 + +#define ISO15693_CRC16_SIZE 2 /* Bytes */ #define ISO15693_CRC16_POLYNORMAL 0x8408 #define ISO15693_CRC16_PRESET 0xFFFF -typedef uint8_t ISO15693UidType[8]; +typedef struct { + uint8_t* Flags; + uint8_t* Command; + uint8_t* Parameters; + uint8_t ParamLen; + bool Addressed; +} CurrentFrame; void ISO15693AppendCRC(uint8_t* FrameBuf, uint16_t FrameBufSize); bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize); +bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid); INLINE bool ISO15693CompareUid(uint8_t* Uid1, uint8_t* Uid2) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index ddc787f..63fcb7f 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -5,6 +5,9 @@ * Author: Phillip Nash * Modified by rickventura for texas 15693 tag-it STANDARD * Modified by ceres-c to finish things up + * TODO: + * - Check actual tag's response (error?) when trying to WRITE out of bound sectors + * - Check actual tag's response (error?) when trying to LOCK out of bound sectors */ #include "TITagitstandard.h" @@ -22,22 +25,31 @@ static enum { uint16_t UserLockBits_Mask = 0; /* Holds lock state of blocks */ uint16_t FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ - -//ISO15693UidType Uid = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xE0}; -//0xE0 = iso15693 -//0x07 = TEXAS INSTRUMENTS -//0xC0 0xC1 = "Tagitstandard" 0xC4 or 0xC5 "TagitPro" 0x00 or 0x01 or 0x80 or 0x81 "Tagitplus" +CurrentFrame FrameInfo; void TITagitstandardAppInit(void) { State = STATE_READY; + FactoryLockBits_Mask |= (1 << 8); /* Locks block 8... */ FactoryLockBits_Mask |= (1 << 9); /* ...and 9, which contains the UID */ + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; } void TITagitstandardAppReset(void) { State = STATE_READY; + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; } @@ -53,171 +65,142 @@ void TITagitstandardAppTick(void) uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { - if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { - if(ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) { - // At this point, we have a valid ISO15693 frame - uint8_t Command = FrameBuf[1]; - uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t Uid[ActiveConfiguration.UidSize]; - TITagitstandardGetUid(Uid); + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t Uid[ActiveConfiguration.UidSize]; + TITagitstandardGetUid(Uid); - switch(State) { - case STATE_READY: - if (Command == ISO15693_CMD_INVENTORY) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_INVENTORY_DSFID; - ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); - ResponseByteCount = 10; - - } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) - State = STATE_QUIET; - - } else if (Command == ISO15693_CMD_READ_SINGLE) { - uint8_t *FramePtr; - uint8_t PageAddress; - - if (ISO15693Addressed(FrameBuf)) { - if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) /* read is addressed to us */ - - /* pick block 2 + 8 (UID Lenght) */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; - else /* we are not the addressee of the read command */ - break; - } else /* request is not addressed */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; - - if (PageAddress >= TITAGIT_NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ - ResponseByteCount = 2; - break; - } - - if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - if (FactoryLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ - FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ - } - else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ - FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ - } - else - FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ - FramePtr = FrameBuf + 2; - ResponseByteCount = 6; - } else { /* request with option flag not set */ - FramePtr = FrameBuf + 1; - ResponseByteCount = 5; - } - - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - - MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); - } - - else if (Command == ISO15693_CMD_WRITE_SINGLE) { - uint8_t* Dataptr; - uint8_t PageAddress; - - if (ISO15693Addressed(FrameBuf)) { - if (FrameBytes < (0x01 + 0x01 + 0x08 + 0x01 + 0x04)) /* flag + cmd + uid + block number + data */ - break; /* malformed: not enough data */ - if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ - /* pick block 2 + 8 (UID Lenght) */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ - /* pick block 2 + 8 (UID Lenght) + 1 (data starts here) */ - Dataptr = &FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08 + 0x01]; /* addr of sent data to write in memory */ - } - else /* we are not the addressee of the write command */ - break; - } else { /* request is not addressed */ - if (FrameBytes < (0x01 + 0x01 + 0x01 + 0x04)) /* flag + cmd + block number + data */ - break; /* malformed: not enough data */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; - Dataptr = &FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x01]; - } - - if (FactoryLockBits_Mask & (1 << PageAddress)) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_OPT_NOT_SUPP; - ResponseByteCount = 2; - } else if (UserLockBits_Mask & (1 << PageAddress)) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_BLK_CHG_LKD; - ResponseByteCount = 2; - } else { - MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; - } - } - - else if (Command == ISO15693_CMD_LOCK_BLOCK) { - uint8_t PageAddress; - if (ISO15693Addressed(FrameBuf)) { - if (FrameBytes < (0x01 + 0x01 + 0x08 + 0x01)) /* flag + cmd + uid + block number + data */ - break; /* malformed: not enough data */ - if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ - /* pick block 2 + 8 (UID Lenght) */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ - } - else /* we are not the addressee of the write command */ - break; - } else { /* request is not addressed */ - if (FrameBytes < (0x01 + 0x01 + 0x01)) /* flag + cmd + block number + data */ - break; /* malformed: not enough data */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; - } - - if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_BLK_ALRD_LKD; - ResponseByteCount = 2; - } else { - UserLockBits_Mask |= (1 << PageAddress); /* */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; - } - } - break; - case STATE_SELECTED: - /* Selected state is not supported by Ti TagIt Standard */ - break; - - case STATE_QUIET: - /* Ti TagIt Standard does not support reset to ready command */ - /* following code is lef for future reference for other tags */ - /* - if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; - State = STATE_READY; - } - } - */ - ResponseByteCount = 0; /* better safe than sorry */ - break; - - default: - break; - } - - if (ResponseByteCount > 0) { - /* There is data to be sent. Append CRC */ - ISO15693AppendCRC(FrameBuf, ResponseByteCount); - ResponseByteCount += ISO15693_CRC16_SIZE; - } - - return ResponseByteCount; - - } else { // Invalid CRC - return ISO15693_APP_NO_RESPONSE; - } - } else { // Min frame size not met + if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid)) return ISO15693_APP_NO_RESPONSE; + + switch(State) { + case STATE_READY: + if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_INVENTORY_DSFID; + ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); + ResponseByteCount = 10; + + } else if (*FrameInfo.Command == ISO15693_CMD_STAY_QUIET && FrameInfo.Addressed) { + State = STATE_QUIET; + + } else if (*FrameInfo.Command == ISO15693_CMD_READ_SINGLE) { + uint8_t *FramePtr; /* holds the address where block's data will be put */ + uint8_t PageAddress = *FrameInfo.Parameters; + + if (FrameInfo.ParamLen != 1) + break; /* malformed: not enough or too much data */ + + if (PageAddress >= TITAGIT_NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ + ResponseByteCount = 2; + break; + } + + if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ + if (FactoryLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ + FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ + } + else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ + FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ + } + else + FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ + FramePtr = FrameBuf + 2; /* block's data from byte 2 */ + ResponseByteCount = 6; + } else { /* request with option flag not set */ + FramePtr = FrameBuf + 1; /* block's data from byte 1 */ + ResponseByteCount = 5; + } + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + + MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + } else if (*FrameInfo.Command == ISO15693_CMD_WRITE_SINGLE) { + uint8_t* Dataptr; + uint8_t PageAddress = *FrameInfo.Parameters; + + if (FrameInfo.ParamLen != 5) + break; /* malformed: not enough or too much data */ + + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) + /* TODO: Check actual tag's response (error?) */ + break; /* malformed: trying to write in a non-existing block */ + + Dataptr = PageAddress + 0x01; + + if (FactoryLockBits_Mask & (1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; + } else if (UserLockBits_Mask & (1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_CHG_LKD; + ResponseByteCount = 2; + } else { + MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } + } else if (*FrameInfo.Command == ISO15693_CMD_LOCK_BLOCK) { + uint8_t PageAddress = *FrameInfo.Parameters; + + if (FrameInfo.ParamLen != 1) + break; /* malformed: not enough or too much data */ + + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) + /* TODO: Check actual tag's response (error?) */ + break; /* malformed: trying to lock a non-existing block */ + + if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_ALRD_LKD; + ResponseByteCount = 2; + } else { + UserLockBits_Mask |= (1 << PageAddress); /* */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } + } else { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; + ResponseByteCount = 2; + } + break; + case STATE_SELECTED: + /* Selected state is not supported by Ti TagIt Standard */ + break; + + case STATE_QUIET: + /* Ti TagIt Standard does not support reset to ready command */ + /* following code is lef for future reference for other tags */ + /* + if (Command == ISO15693_CMD_RESET_TO_READY) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + State = STATE_READY; + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; + } + */ + ResponseByteCount = 0; /* better safe than sorry */ + break; + + default: + break; } + if (ResponseByteCount > 0) { + /* There is data to be sent. Append CRC */ + ISO15693AppendCRC(FrameBuf, ResponseByteCount); + ResponseByteCount += ISO15693_CRC16_SIZE; + } + + return ResponseByteCount; } void TITagitstandardGetUid(ConfigurationUidType Uid) From c8496d2087daa1e902a742ffcb00b49d2285be82 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Tue, 4 Dec 2018 11:03:41 +0100 Subject: [PATCH 30/67] Fixed couple of indent mistakes --- .../Chameleon-Mini/Application/TITagitstandard.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 63fcb7f..8132fc7 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -100,11 +100,9 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ if (FactoryLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ - } - else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ + } else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ - } - else + } else FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ FramePtr = FrameBuf + 2; /* block's data from byte 2 */ ResponseByteCount = 6; @@ -114,15 +112,15 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + } else if (*FrameInfo.Command == ISO15693_CMD_WRITE_SINGLE) { uint8_t* Dataptr; uint8_t PageAddress = *FrameInfo.Parameters; if (FrameInfo.ParamLen != 5) break; /* malformed: not enough or too much data */ - + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) /* TODO: Check actual tag's response (error?) */ break; /* malformed: trying to write in a non-existing block */ @@ -142,6 +140,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; } + } else if (*FrameInfo.Command == ISO15693_CMD_LOCK_BLOCK) { uint8_t PageAddress = *FrameInfo.Parameters; @@ -161,12 +160,14 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; } + } else { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; ResponseByteCount = 2; } break; + case STATE_SELECTED: /* Selected state is not supported by Ti TagIt Standard */ break; From 168b565f237ee98b8758fdd274ba3479e433d445 Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Tue, 4 Dec 2018 17:33:46 +0100 Subject: [PATCH 31/67] Fixed nasty bug in ISO15693PrepareFrame, removed unnecessary includes and implemented failsafe to command not supported to fix problems with Android apps. Everything just works. --- Firmware/Chameleon-Mini/Application/ISO15693-A.c | 9 ++++++--- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 8 ++------ Firmware/Chameleon-Mini/Application/TITagitstandard.h | 3 +-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 7837111..5135135 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -72,8 +72,11 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* /* following declarations are not dependent on addressed/unaddressed state */ FrameStruct -> Flags = &FrameBuf[ISO15693_ADDR_FLAGS]; FrameStruct -> Command = &FrameBuf[ISO15693_REQ_ADDR_CMD]; - FrameStruct -> Addressed = ( !(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY) & (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS) ); - /* "inventory" flag must be 0, otherwise "addressed" flag have a different meaning (see ISO15693-3) */ + + if(!(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY)) /* if inventory flag is not set */ + FrameStruct -> Addressed = (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS); /* check for addressed flag */ + else /* otherwise always false */ + FrameStruct -> Addressed = false; if (FrameStruct -> Addressed) /* UID sits between CMD and PARAM */ @@ -89,4 +92,4 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* } else { return true; } -} \ No newline at end of file +} diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 8132fc7..8441907 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -10,12 +10,8 @@ * - Check actual tag's response (error?) when trying to LOCK out of bound sectors */ -#include "TITagitstandard.h" -#include "../Codec/ISO15693.h" -#include "../Memory.h" -#include "Crypto1.h" -#include "../Random.h" #include "ISO15693-A.h" +#include "TITagitstandard.h" static enum { STATE_READY, @@ -229,4 +225,4 @@ void TITagitstandardFlipUid(ConfigurationUidType Uid) *Uid++ = *tail; *tail-- = tmp; } -} \ No newline at end of file +} diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.h b/Firmware/Chameleon-Mini/Application/TITagitstandard.h index bd984c5..a433913 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.h +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.h @@ -10,7 +10,6 @@ #define TITAGITSTANDARD_H_ #include "Application.h" -#include "ISO15693-A.h" #define TITAGIT_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE #define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE @@ -27,4 +26,4 @@ void TITagitstandardGetUid(ConfigurationUidType Uid); void TITagitstandardSetUid(ConfigurationUidType Uid); void TITagitstandardFlipUid(ConfigurationUidType Uid); -#endif /* VICINITY_H_ */ \ No newline at end of file +#endif /* TITAGITSTANDARD_H_ */ From edb1d93084f9e1f2e21a24536e9dff6c19ebfa05 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Tue, 4 Dec 2018 18:00:37 +0100 Subject: [PATCH 32/67] Checked read and lock out of bound errors against real tag and implemented in software. Updated authors --- Firmware/Chameleon-Mini/Application/ISO15693-A.c | 2 ++ .../Chameleon-Mini/Application/TITagitstandard.c | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 5135135..f8a36da 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -62,6 +62,8 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) * - true: Frame is valid and a response is needed * - false: Request is not addressed to us * Frame is not valid because it's too short or CRC is wrong + * + * Authors: ceres-c & MrMoDDoM */ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid) { diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 8441907..f5618f5 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -4,10 +4,7 @@ * Created on: 01-03-2017 * Author: Phillip Nash * Modified by rickventura for texas 15693 tag-it STANDARD - * Modified by ceres-c to finish things up - * TODO: - * - Check actual tag's response (error?) when trying to WRITE out of bound sectors - * - Check actual tag's response (error?) when trying to LOCK out of bound sectors + * Modified by ceres-c & MrMoDDoM to finish things up */ #include "ISO15693-A.h" @@ -118,7 +115,8 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) break; /* malformed: not enough or too much data */ if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) - /* TODO: Check actual tag's response (error?) */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; break; /* malformed: trying to write in a non-existing block */ Dataptr = PageAddress + 0x01; @@ -144,7 +142,9 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) break; /* malformed: not enough or too much data */ if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) - /* TODO: Check actual tag's response (error?) */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; break; /* malformed: trying to lock a non-existing block */ if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { From 1da44037c69957372f15c5b099b08fb2546e7f33 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Tue, 4 Dec 2018 18:00:37 +0100 Subject: [PATCH 33/67] Checked read and lock out of bound errors against real tag and implemented in software. Updated authors --- Firmware/Chameleon-Mini/Application/ISO15693-A.c | 2 ++ .../Chameleon-Mini/Application/TITagitstandard.c | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 5135135..f8a36da 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -62,6 +62,8 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) * - true: Frame is valid and a response is needed * - false: Request is not addressed to us * Frame is not valid because it's too short or CRC is wrong + * + * Authors: ceres-c & MrMoDDoM */ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid) { diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 8441907..f5618f5 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -4,10 +4,7 @@ * Created on: 01-03-2017 * Author: Phillip Nash * Modified by rickventura for texas 15693 tag-it STANDARD - * Modified by ceres-c to finish things up - * TODO: - * - Check actual tag's response (error?) when trying to WRITE out of bound sectors - * - Check actual tag's response (error?) when trying to LOCK out of bound sectors + * Modified by ceres-c & MrMoDDoM to finish things up */ #include "ISO15693-A.h" @@ -118,7 +115,8 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) break; /* malformed: not enough or too much data */ if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) - /* TODO: Check actual tag's response (error?) */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; break; /* malformed: trying to write in a non-existing block */ Dataptr = PageAddress + 0x01; @@ -144,7 +142,9 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) break; /* malformed: not enough or too much data */ if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) - /* TODO: Check actual tag's response (error?) */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; break; /* malformed: trying to lock a non-existing block */ if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { From 3b88299a4686474a049b9e08aeaa68c767599d8c Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Wed, 28 Nov 2018 18:40:51 +0100 Subject: [PATCH 34/67] Added tag family configuration --- Firmware/Chameleon-Mini/Button.c | 5 + Firmware/Chameleon-Mini/Configuration.c | 122 +++++++++++--------- Firmware/Chameleon-Mini/Configuration.h | 11 ++ Firmware/Chameleon-Mini/Terminal/Commands.c | 5 + 4 files changed, 89 insertions(+), 54 deletions(-) diff --git a/Firmware/Chameleon-Mini/Button.c b/Firmware/Chameleon-Mini/Button.c index 3791783..33f3eb5 100644 --- a/Firmware/Chameleon-Mini/Button.c +++ b/Firmware/Chameleon-Mini/Button.c @@ -4,6 +4,7 @@ #include "Settings.h" #include "Memory.h" #include "Map.h" +#include "Configuration.h" #include "Terminal/CommandLine.h" #include "Application/Application.h" @@ -42,6 +43,10 @@ static void ExecuteButtonAction(ButtonActionEnum ButtonAction) for (uint8_t i=0; i Date: Thu, 29 Nov 2018 18:00:36 +0100 Subject: [PATCH 35/67] Added bitmask to track locked blocks, Lock Block command, sanity checks on received data. --- .../Application/TITagitstandard.c | 73 ++++++++++++++++--- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 73784fb..f334b99 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -22,6 +22,9 @@ static enum { STATE_QUIET } State; +uint16_t UserLockBits_Mask = 0; /* Holds lock state of blocks */ +uint16_t FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ + //ISO15693UidType Uid = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xE0}; //0xE0 = iso15693 //0x07 = TEXAS INSTRUMENTS @@ -30,6 +33,9 @@ static enum { void TITagitstandardAppInit(void) { State = STATE_READY; + FactoryLockBits_Mask |= (1 << 8); /* Locks block 8... */ + FactoryLockBits_Mask |= (1 << 9); /* ...and 9, which contains the UID */ + UserLockBits_Mask |= (1 << 3); /* TESTING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ } void TITagitstandardAppReset(void) @@ -92,19 +98,24 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - /* UID is stored in blocks 8 and 9 which are blocked */ - FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status: when request has the option flag set */ + if (FactoryLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ + FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ + } + else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ + FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ + } + else + FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ FramePtr = FrameBuf + 2; ResponseByteCount = 6; - } else { /* request with option flag not set*/ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* Flags */ + } else { /* request with option flag not set */ FramePtr = FrameBuf + 1; ResponseByteCount = 5; } - MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); } else if (Command == ISO15693_CMD_WRITE_SINGLE) { @@ -112,6 +123,8 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t PageAddress; if (ISO15693Addressed(FrameBuf)) { + if (FrameBytes < (0x01 + 0x01 + 0x08 + 0x01 + 0x04)) /* flag + cmd + uid + block number + data */ + break; /* malformed: not enough data */ if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ /* pick block 2 + 8 (UID Lenght) */ PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ @@ -121,17 +134,57 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) else /* we are not the addressee of the write command */ break; } else { /* request is not addressed */ + if (FrameBytes < (0x01 + 0x01 + 0x01 + 0x04)) /* flag + cmd + block number + data */ + break; /* malformed: not enough data */ PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; Dataptr = &FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x01]; } - MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; + if (FactoryLockBits_Mask & (1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; + } else if (UserLockBits_Mask & (1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_BLK_CHG_LKD; + ResponseByteCount = 2; + } else { + MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } } + + else if (Command == ISO15693_CMD_LOCK_BLOCK) { + uint8_t PageAddress; + if (ISO15693Addressed(FrameBuf)) { + if (FrameBytes < (0x01 + 0x01 + 0x08 + 0x01)) /* flag + cmd + uid + block number + data */ + break; /* malformed: not enough data */ + if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ + /* pick block 2 + 8 (UID Lenght) */ + PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ + } + else /* we are not the addressee of the write command */ + break; + } else { /* request is not addressed */ + if (FrameBytes < (0x01 + 0x01 + 0x01)) /* flag + cmd + block number + data */ + break; /* malformed: not enough data */ + PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; + } + + if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_BLK_ALRD_LKD; + ResponseByteCount = 2; + } else { + UserLockBits_Mask |= (1 << PageAddress); /* */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } + } break; case STATE_SELECTED: - /* TODO: Selected has to be impemented altogether */ + /* Selected state is not supported by Ti TagIt Standard */ break; case STATE_QUIET: From dfe0deccd720c0179e2563cd72f78676746d0794 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 29 Nov 2018 18:17:34 +0100 Subject: [PATCH 36/67] Removed testing stuff and removed todo --- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index f334b99..27e734a 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -5,8 +5,6 @@ * Author: Phillip Nash * Modified by rickventura for texas 15693 tag-it STANDARD * Modified by ceres-c to finish things up - * TODO: - * - Selected mode has to be impemented altogether - ceres-c */ #include "TITagitstandard.h" @@ -35,7 +33,6 @@ void TITagitstandardAppInit(void) State = STATE_READY; FactoryLockBits_Mask |= (1 << 8); /* Locks block 8... */ FactoryLockBits_Mask |= (1 << 9); /* ...and 9, which contains the UID */ - UserLockBits_Mask |= (1 << 3); /* TESTING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ } void TITagitstandardAppReset(void) From 3d253d2848c60da4c79f911950db03d02556ce78 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 29 Nov 2018 18:33:30 +0100 Subject: [PATCH 37/67] Removed unsupported command ISO15693_CMD_RESET_TO_READY --- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 27e734a..ddc787f 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -185,13 +185,18 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) break; case STATE_QUIET: + /* Ti TagIt Standard does not support reset to ready command */ + /* following code is lef for future reference for other tags */ + /* if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf)) { + if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; State = STATE_READY; } } + */ + ResponseByteCount = 0; /* better safe than sorry */ break; default: From ade5a9d5ab107c31e130f0382b2afe4b12b6e84b Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Mon, 3 Dec 2018 23:07:50 +0100 Subject: [PATCH 38/67] PrepareFrame function first draft, there might be performance issues --- .../Chameleon-Mini/Application/ISO15693-A.c | 40 +++ .../Chameleon-Mini/Application/ISO15693-A.h | 16 +- .../Application/TITagitstandard.c | 315 +++++++++--------- 3 files changed, 202 insertions(+), 169 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 0f7f3d3..7837111 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -50,3 +50,43 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) return (DataPtr[FrameBufSize] == crcLb && DataPtr[FrameBufSize + 1] == crcHb); } + +/* + * ISO15693PrepareFrame + * + * This function validates frame lenght and sets pointers in 'frame' struct + * to relevant byte(s) of 'FrameBuf'. Also sets frame.addressed as true if + * the command is addressed + * + * Returns: + * - true: Frame is valid and a response is needed + * - false: Request is not addressed to us + * Frame is not valid because it's too short or CRC is wrong + */ +bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid) +{ + if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) + /* malformed frame */ + return false; + + /* following declarations are not dependent on addressed/unaddressed state */ + FrameStruct -> Flags = &FrameBuf[ISO15693_ADDR_FLAGS]; + FrameStruct -> Command = &FrameBuf[ISO15693_REQ_ADDR_CMD]; + FrameStruct -> Addressed = ( !(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY) & (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS) ); + /* "inventory" flag must be 0, otherwise "addressed" flag have a different meaning (see ISO15693-3) */ + + if (FrameStruct -> Addressed) + /* UID sits between CMD and PARAM */ + FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM + ISO15693_GENERIC_UID_SIZE]; + else + FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM]; + + FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); + + if (FrameStruct -> Addressed && !ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], MyUid)) { + /* addressed request but we're not the addressee */ + return false; + } else { + return true; + } +} \ No newline at end of file diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 48cace8..897c9e1 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -63,16 +63,26 @@ #define ISO15693_RES_INVENTORY_DSFID 0x00 -#define ISO15693_MIN_FRAME_SIZE 4 +#define ISO15693_MIN_FRAME_SIZE 0x04 -#define ISO15693_CRC16_SIZE 2 /* Bytes */ +#define ISO15693_GENERIC_UID_SIZE 0x08 +#define ISO15693_GENERIC_MEM_SIZE 8192 + +#define ISO15693_CRC16_SIZE 2 /* Bytes */ #define ISO15693_CRC16_POLYNORMAL 0x8408 #define ISO15693_CRC16_PRESET 0xFFFF -typedef uint8_t ISO15693UidType[8]; +typedef struct { + uint8_t* Flags; + uint8_t* Command; + uint8_t* Parameters; + uint8_t ParamLen; + bool Addressed; +} CurrentFrame; void ISO15693AppendCRC(uint8_t* FrameBuf, uint16_t FrameBufSize); bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize); +bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid); INLINE bool ISO15693CompareUid(uint8_t* Uid1, uint8_t* Uid2) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index ddc787f..63fcb7f 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -5,6 +5,9 @@ * Author: Phillip Nash * Modified by rickventura for texas 15693 tag-it STANDARD * Modified by ceres-c to finish things up + * TODO: + * - Check actual tag's response (error?) when trying to WRITE out of bound sectors + * - Check actual tag's response (error?) when trying to LOCK out of bound sectors */ #include "TITagitstandard.h" @@ -22,22 +25,31 @@ static enum { uint16_t UserLockBits_Mask = 0; /* Holds lock state of blocks */ uint16_t FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ - -//ISO15693UidType Uid = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x07, 0xE0}; -//0xE0 = iso15693 -//0x07 = TEXAS INSTRUMENTS -//0xC0 0xC1 = "Tagitstandard" 0xC4 or 0xC5 "TagitPro" 0x00 or 0x01 or 0x80 or 0x81 "Tagitplus" +CurrentFrame FrameInfo; void TITagitstandardAppInit(void) { State = STATE_READY; + FactoryLockBits_Mask |= (1 << 8); /* Locks block 8... */ FactoryLockBits_Mask |= (1 << 9); /* ...and 9, which contains the UID */ + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; } void TITagitstandardAppReset(void) { State = STATE_READY; + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; } @@ -53,171 +65,142 @@ void TITagitstandardAppTick(void) uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { - if (FrameBytes >= ISO15693_MIN_FRAME_SIZE) { - if(ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) { - // At this point, we have a valid ISO15693 frame - uint8_t Command = FrameBuf[1]; - uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t Uid[ActiveConfiguration.UidSize]; - TITagitstandardGetUid(Uid); + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t Uid[ActiveConfiguration.UidSize]; + TITagitstandardGetUid(Uid); - switch(State) { - case STATE_READY: - if (Command == ISO15693_CMD_INVENTORY) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_INVENTORY_DSFID; - ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); - ResponseByteCount = 10; - - } else if (Command == ISO15693_CMD_STAY_QUIET) { - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) - State = STATE_QUIET; - - } else if (Command == ISO15693_CMD_READ_SINGLE) { - uint8_t *FramePtr; - uint8_t PageAddress; - - if (ISO15693Addressed(FrameBuf)) { - if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) /* read is addressed to us */ - - /* pick block 2 + 8 (UID Lenght) */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; - else /* we are not the addressee of the read command */ - break; - } else /* request is not addressed */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; - - if (PageAddress >= TITAGIT_NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ - ResponseByteCount = 2; - break; - } - - if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - if (FactoryLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ - FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ - } - else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ - FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ - } - else - FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ - FramePtr = FrameBuf + 2; - ResponseByteCount = 6; - } else { /* request with option flag not set */ - FramePtr = FrameBuf + 1; - ResponseByteCount = 5; - } - - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - - MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); - } - - else if (Command == ISO15693_CMD_WRITE_SINGLE) { - uint8_t* Dataptr; - uint8_t PageAddress; - - if (ISO15693Addressed(FrameBuf)) { - if (FrameBytes < (0x01 + 0x01 + 0x08 + 0x01 + 0x04)) /* flag + cmd + uid + block number + data */ - break; /* malformed: not enough data */ - if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ - /* pick block 2 + 8 (UID Lenght) */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ - /* pick block 2 + 8 (UID Lenght) + 1 (data starts here) */ - Dataptr = &FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08 + 0x01]; /* addr of sent data to write in memory */ - } - else /* we are not the addressee of the write command */ - break; - } else { /* request is not addressed */ - if (FrameBytes < (0x01 + 0x01 + 0x01 + 0x04)) /* flag + cmd + block number + data */ - break; /* malformed: not enough data */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; - Dataptr = &FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x01]; - } - - if (FactoryLockBits_Mask & (1 << PageAddress)) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_OPT_NOT_SUPP; - ResponseByteCount = 2; - } else if (UserLockBits_Mask & (1 << PageAddress)) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_BLK_CHG_LKD; - ResponseByteCount = 2; - } else { - MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; - } - } - - else if (Command == ISO15693_CMD_LOCK_BLOCK) { - uint8_t PageAddress; - if (ISO15693Addressed(FrameBuf)) { - if (FrameBytes < (0x01 + 0x01 + 0x08 + 0x01)) /* flag + cmd + uid + block number + data */ - break; /* malformed: not enough data */ - if (ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) {/* write is addressed to us */ - /* pick block 2 + 8 (UID Lenght) */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM + 0x08]; /*when receiving an addressed request pick block number from 10th byte in the request*/ - } - else /* we are not the addressee of the write command */ - break; - } else { /* request is not addressed */ - if (FrameBytes < (0x01 + 0x01 + 0x01)) /* flag + cmd + block number + data */ - break; /* malformed: not enough data */ - PageAddress = FrameBuf[ISO15693_REQ_ADDR_PARAM]; - } - - if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_ADDR_FLAGS + 1] = ISO15693_RES_ERR_BLK_ALRD_LKD; - ResponseByteCount = 2; - } else { - UserLockBits_Mask |= (1 << PageAddress); /* */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; - } - } - break; - case STATE_SELECTED: - /* Selected state is not supported by Ti TagIt Standard */ - break; - - case STATE_QUIET: - /* Ti TagIt Standard does not support reset to ready command */ - /* following code is lef for future reference for other tags */ - /* - if (Command == ISO15693_CMD_RESET_TO_READY) { - if (ISO15693Addressed(FrameBuf) && ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid)) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; - State = STATE_READY; - } - } - */ - ResponseByteCount = 0; /* better safe than sorry */ - break; - - default: - break; - } - - if (ResponseByteCount > 0) { - /* There is data to be sent. Append CRC */ - ISO15693AppendCRC(FrameBuf, ResponseByteCount); - ResponseByteCount += ISO15693_CRC16_SIZE; - } - - return ResponseByteCount; - - } else { // Invalid CRC - return ISO15693_APP_NO_RESPONSE; - } - } else { // Min frame size not met + if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid)) return ISO15693_APP_NO_RESPONSE; + + switch(State) { + case STATE_READY: + if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_INVENTORY_DSFID; + ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); + ResponseByteCount = 10; + + } else if (*FrameInfo.Command == ISO15693_CMD_STAY_QUIET && FrameInfo.Addressed) { + State = STATE_QUIET; + + } else if (*FrameInfo.Command == ISO15693_CMD_READ_SINGLE) { + uint8_t *FramePtr; /* holds the address where block's data will be put */ + uint8_t PageAddress = *FrameInfo.Parameters; + + if (FrameInfo.ParamLen != 1) + break; /* malformed: not enough or too much data */ + + if (PageAddress >= TITAGIT_NUMBER_OF_SECTORS) { /* the reader is requesting a sector out of bound */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ + ResponseByteCount = 2; + break; + } + + if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ + if (FactoryLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ + FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ + } + else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ + FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ + } + else + FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ + FramePtr = FrameBuf + 2; /* block's data from byte 2 */ + ResponseByteCount = 6; + } else { /* request with option flag not set */ + FramePtr = FrameBuf + 1; /* block's data from byte 1 */ + ResponseByteCount = 5; + } + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + + MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + } else if (*FrameInfo.Command == ISO15693_CMD_WRITE_SINGLE) { + uint8_t* Dataptr; + uint8_t PageAddress = *FrameInfo.Parameters; + + if (FrameInfo.ParamLen != 5) + break; /* malformed: not enough or too much data */ + + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) + /* TODO: Check actual tag's response (error?) */ + break; /* malformed: trying to write in a non-existing block */ + + Dataptr = PageAddress + 0x01; + + if (FactoryLockBits_Mask & (1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; + } else if (UserLockBits_Mask & (1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_CHG_LKD; + ResponseByteCount = 2; + } else { + MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } + } else if (*FrameInfo.Command == ISO15693_CMD_LOCK_BLOCK) { + uint8_t PageAddress = *FrameInfo.Parameters; + + if (FrameInfo.ParamLen != 1) + break; /* malformed: not enough or too much data */ + + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) + /* TODO: Check actual tag's response (error?) */ + break; /* malformed: trying to lock a non-existing block */ + + if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_ALRD_LKD; + ResponseByteCount = 2; + } else { + UserLockBits_Mask |= (1 << PageAddress); /* */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } + } else { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; + ResponseByteCount = 2; + } + break; + case STATE_SELECTED: + /* Selected state is not supported by Ti TagIt Standard */ + break; + + case STATE_QUIET: + /* Ti TagIt Standard does not support reset to ready command */ + /* following code is lef for future reference for other tags */ + /* + if (Command == ISO15693_CMD_RESET_TO_READY) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + State = STATE_READY; + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; + } + */ + ResponseByteCount = 0; /* better safe than sorry */ + break; + + default: + break; } + if (ResponseByteCount > 0) { + /* There is data to be sent. Append CRC */ + ISO15693AppendCRC(FrameBuf, ResponseByteCount); + ResponseByteCount += ISO15693_CRC16_SIZE; + } + + return ResponseByteCount; } void TITagitstandardGetUid(ConfigurationUidType Uid) From 314772a6ea7747e5b5f8dc6ccaae5f46b0b7d080 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Tue, 4 Dec 2018 11:03:41 +0100 Subject: [PATCH 39/67] Fixed couple of indent mistakes --- .../Chameleon-Mini/Application/TITagitstandard.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 63fcb7f..8132fc7 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -100,11 +100,9 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ if (FactoryLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ - } - else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ + } else if (UserLockBits_Mask & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ - } - else + } else FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ FramePtr = FrameBuf + 2; /* block's data from byte 2 */ ResponseByteCount = 6; @@ -114,15 +112,15 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + } else if (*FrameInfo.Command == ISO15693_CMD_WRITE_SINGLE) { uint8_t* Dataptr; uint8_t PageAddress = *FrameInfo.Parameters; if (FrameInfo.ParamLen != 5) break; /* malformed: not enough or too much data */ - + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) /* TODO: Check actual tag's response (error?) */ break; /* malformed: trying to write in a non-existing block */ @@ -142,6 +140,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; } + } else if (*FrameInfo.Command == ISO15693_CMD_LOCK_BLOCK) { uint8_t PageAddress = *FrameInfo.Parameters; @@ -161,12 +160,14 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; } + } else { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; ResponseByteCount = 2; } break; + case STATE_SELECTED: /* Selected state is not supported by Ti TagIt Standard */ break; From 612724f5b06384b3267b5cb5cfdd069ef950ad67 Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Tue, 4 Dec 2018 17:33:46 +0100 Subject: [PATCH 40/67] Fixed nasty bug in ISO15693PrepareFrame, removed unnecessary includes and implemented failsafe to command not supported to fix problems with Android apps. Everything just works. --- Firmware/Chameleon-Mini/Application/ISO15693-A.c | 9 ++++++--- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 8 ++------ Firmware/Chameleon-Mini/Application/TITagitstandard.h | 3 +-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 7837111..5135135 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -72,8 +72,11 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* /* following declarations are not dependent on addressed/unaddressed state */ FrameStruct -> Flags = &FrameBuf[ISO15693_ADDR_FLAGS]; FrameStruct -> Command = &FrameBuf[ISO15693_REQ_ADDR_CMD]; - FrameStruct -> Addressed = ( !(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY) & (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS) ); - /* "inventory" flag must be 0, otherwise "addressed" flag have a different meaning (see ISO15693-3) */ + + if(!(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY)) /* if inventory flag is not set */ + FrameStruct -> Addressed = (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS); /* check for addressed flag */ + else /* otherwise always false */ + FrameStruct -> Addressed = false; if (FrameStruct -> Addressed) /* UID sits between CMD and PARAM */ @@ -89,4 +92,4 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* } else { return true; } -} \ No newline at end of file +} diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 8132fc7..8441907 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -10,12 +10,8 @@ * - Check actual tag's response (error?) when trying to LOCK out of bound sectors */ -#include "TITagitstandard.h" -#include "../Codec/ISO15693.h" -#include "../Memory.h" -#include "Crypto1.h" -#include "../Random.h" #include "ISO15693-A.h" +#include "TITagitstandard.h" static enum { STATE_READY, @@ -229,4 +225,4 @@ void TITagitstandardFlipUid(ConfigurationUidType Uid) *Uid++ = *tail; *tail-- = tmp; } -} \ No newline at end of file +} diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.h b/Firmware/Chameleon-Mini/Application/TITagitstandard.h index bd984c5..a433913 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.h +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.h @@ -10,7 +10,6 @@ #define TITAGITSTANDARD_H_ #include "Application.h" -#include "ISO15693-A.h" #define TITAGIT_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE #define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE @@ -27,4 +26,4 @@ void TITagitstandardGetUid(ConfigurationUidType Uid); void TITagitstandardSetUid(ConfigurationUidType Uid); void TITagitstandardFlipUid(ConfigurationUidType Uid); -#endif /* VICINITY_H_ */ \ No newline at end of file +#endif /* TITAGITSTANDARD_H_ */ From 82d5a2c562f0c3ad8e6f996c88894393a0c52884 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Tue, 4 Dec 2018 18:00:37 +0100 Subject: [PATCH 41/67] Checked read and lock out of bound errors against real tag and implemented in software. Updated authors --- Firmware/Chameleon-Mini/Application/ISO15693-A.c | 2 ++ .../Chameleon-Mini/Application/TITagitstandard.c | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 5135135..f8a36da 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -62,6 +62,8 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) * - true: Frame is valid and a response is needed * - false: Request is not addressed to us * Frame is not valid because it's too short or CRC is wrong + * + * Authors: ceres-c & MrMoDDoM */ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid) { diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 8441907..f5618f5 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -4,10 +4,7 @@ * Created on: 01-03-2017 * Author: Phillip Nash * Modified by rickventura for texas 15693 tag-it STANDARD - * Modified by ceres-c to finish things up - * TODO: - * - Check actual tag's response (error?) when trying to WRITE out of bound sectors - * - Check actual tag's response (error?) when trying to LOCK out of bound sectors + * Modified by ceres-c & MrMoDDoM to finish things up */ #include "ISO15693-A.h" @@ -118,7 +115,8 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) break; /* malformed: not enough or too much data */ if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) - /* TODO: Check actual tag's response (error?) */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; break; /* malformed: trying to write in a non-existing block */ Dataptr = PageAddress + 0x01; @@ -144,7 +142,9 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) break; /* malformed: not enough or too much data */ if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) - /* TODO: Check actual tag's response (error?) */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; break; /* malformed: trying to lock a non-existing block */ if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { From fda9f07894e2022f022bb31d51741965a5ec0446 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Mon, 10 Dec 2018 12:55:38 +0100 Subject: [PATCH 42/67] Fixed a bug in write and lock commands - Missing parenthesis --- Firmware/Chameleon-Mini/Application/TITagitstandard.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index f5618f5..80ae1a2 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -114,10 +114,12 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (FrameInfo.ParamLen != 5) break; /* malformed: not enough or too much data */ - if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; break; /* malformed: trying to write in a non-existing block */ + } Dataptr = PageAddress + 0x01; @@ -141,11 +143,12 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (FrameInfo.ParamLen != 1) break; /* malformed: not enough or too much data */ - if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; ResponseByteCount = 2; break; /* malformed: trying to lock a non-existing block */ + } if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; From b28d8cb337748df7cf11a121c07b229bef4b8744 Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Mon, 10 Dec 2018 19:43:43 +0100 Subject: [PATCH 43/67] EM4233 first draft --- .../Chameleon-Mini/Application/Application.h | 2 +- Firmware/Chameleon-Mini/Application/EM4233.c | 241 ++++++++++++++++++ Firmware/Chameleon-Mini/Application/EM4233.h | 60 +++++ .../Chameleon-Mini/Application/ISO15693-A.h | 9 +- .../Application/TITagitstandard.c | 7 +- Firmware/Chameleon-Mini/Configuration.c | 23 +- Firmware/Chameleon-Mini/Configuration.h | 3 + Firmware/Chameleon-Mini/DUMP_TEST | Bin 0 -> 304 bytes Firmware/Chameleon-Mini/Makefile | 3 +- 9 files changed, 341 insertions(+), 7 deletions(-) create mode 100644 Firmware/Chameleon-Mini/Application/EM4233.c create mode 100644 Firmware/Chameleon-Mini/Application/EM4233.h create mode 100644 Firmware/Chameleon-Mini/DUMP_TEST diff --git a/Firmware/Chameleon-Mini/Application/Application.h b/Firmware/Chameleon-Mini/Application/Application.h index 6fca8b6..af0dd2a 100644 --- a/Firmware/Chameleon-Mini/Application/Application.h +++ b/Firmware/Chameleon-Mini/Application/Application.h @@ -20,7 +20,7 @@ #include "Sl2s2002.h" #include "TITagitstandard.h" #include "Sniff14443A.h" - +#include "EM4233.h" /* Function wrappers */ INLINE void ApplicationInit(void) { diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c new file mode 100644 index 0000000..a2fb430 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -0,0 +1,241 @@ +/* + * EM4233.c + * + * Created on: 12-05-2018 + * Author: ceres-c & MrMoDDoM + */ + +#include "ISO15693-A.h" +#include "EM4233.h" + +static enum { + STATE_READY, + STATE_SELECTED, + STATE_QUIET +} State; + +CurrentFrame FrameInfo; + +uint64_t EM4233_FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ +uint64_t EM4233_UserLockBits_Mask = 0; /* Holds lock state of blocks */ + +//uint8_t EM4233_Lock_Status[64] = { 1 }; + + +void EM4233AppInit(void) +{ + State = STATE_READY; + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; + + //MemoryReadBlock(EM4233_Lock_Status, EM4233_MEM_LSM_ADDRESS, 64); + //MemoryReadBlock(&EM4233_FactoryLockBits_Mask, EM4233_MEM_FLM_ADDRESS, 8); +} + +void EM4233AppReset(void) +{ + State = STATE_READY; + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; + + //MemoryReadBlock(&EM4233_UserLockBits_Mask, EM4233_MEM_ULM_ADDRESS, 8); + //MemoryReadBlock(&EM4233_FactoryLockBits_Mask, EM4233_MEM_FLM_ADDRESS, 8); +} + + +void EM4233AppTask(void) +{ + +} + +void EM4233AppTick(void) +{ + +} + +uint16_t EM4233_Lock_Block(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t PageAddress = *FrameInfo.Parameters; + + if (FrameInfo.ParamLen != 1) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + if (PageAddress > EM4233_NUMBER_OF_BLCKS) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; + return ResponseByteCount; /* malformed: trying to lock a non-existing block */ + } + + if ((EM4233_FactoryLockBits_Mask & (uint64_t)(1 << PageAddress)) || (EM4233_UserLockBits_Mask & (uint64_t)(1 << PageAddress))) { /* if already locked */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_ALRD_LKD; + ResponseByteCount = 2; + } else { + EM4233_UserLockBits_Mask |= (uint64_t)(1 << PageAddress); /* write the lock status in mask */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } + + return ResponseByteCount; +} + +uint16_t EM4233_Write_Single(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t* Dataptr; + uint8_t PageAddress = *FrameInfo.Parameters; + + if (FrameInfo.ParamLen != 5) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + if (PageAddress > EM4233_NUMBER_OF_BLCKS) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; /* malformed: trying to write in a non-existing block */ + return ResponseByteCount; + } + + Dataptr = PageAddress + 0x01; + + if (EM4233_FactoryLockBits_Mask & (uint64_t)(1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; + } else if (EM4233_UserLockBits_Mask & (uint64_t)(1 << PageAddress)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_CHG_LKD; + ResponseByteCount = 2; + } else { + MemoryWriteBlock(Dataptr, PageAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + } + + return ResponseByteCount; +} + +uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t *FramePtr; /* holds the address where block's data will be put */ + uint8_t PageAddress = *FrameInfo.Parameters; + uint8_t LockStatus = 0; + + if (FrameInfo.ParamLen != 1) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + if (PageAddress >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a sector out of bound */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ + ResponseByteCount = 2; + return ResponseByteCount; + } + + if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ + MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + PageAddress), 1); + if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { /* tests if the n-th bit of the factory bitmask if set to 1 */ + FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ + } else if (LockStatus & ISO15693_MASK_USER_LOCK) { /* tests if the n-th bit of the user bitmask if set to 1 */ + FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ + } else + FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ + FramePtr = FrameBuf + 2; /* block's data from byte 2 */ + ResponseByteCount = 6; + } else { /* request with option flag not set */ + FramePtr = FrameBuf + 1; /* block's data from byte 1 */ + ResponseByteCount = 5; + } + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + MemoryReadBlock(FramePtr, PageAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); + + return ResponseByteCount; +} + +uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t Uid[ActiveConfiguration.UidSize]; + EM4233GetUid(Uid); + + if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid)) + return ISO15693_APP_NO_RESPONSE; + + switch(State) { + case STATE_READY: + if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_INVENTORY_DSFID; + ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); + ResponseByteCount = 10; + + } else if (*FrameInfo.Command == ISO15693_CMD_STAY_QUIET && FrameInfo.Addressed) { + State = STATE_QUIET; + + } else if (*FrameInfo.Command == ISO15693_CMD_READ_SINGLE) { + ResponseByteCount = EM4233_Read_Single(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_WRITE_SINGLE) { + ResponseByteCount = EM4233_Write_Single(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_LOCK_BLOCK) { + ResponseByteCount = EM4233_Lock_Block(FrameBuf, FrameBytes); + + } else { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; + ResponseByteCount = 2; + } + break; + + case STATE_SELECTED: + /* TO-DO */ + break; + + case STATE_QUIET: + if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount = 1; + State = STATE_READY; + + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; + } + + break; + + default: + break; + } + + if (ResponseByteCount > 0) { + /* There is data to be sent. Append CRC */ + ISO15693AppendCRC(FrameBuf, ResponseByteCount); + ResponseByteCount += ISO15693_CRC16_SIZE; + } + + return ResponseByteCount; +} + +void EM4233GetUid(ConfigurationUidType Uid) +{ + MemoryReadBlock(&Uid[0], EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize); +} + +void EM4233SetUid(ConfigurationUidType Uid) +{ + MemoryWriteBlock(Uid, EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize); +} \ No newline at end of file diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h new file mode 100644 index 0000000..9e75160 --- /dev/null +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -0,0 +1,60 @@ +/* + * EM4233.h + * + * Created on: 04.12.2018 + * Author: ceres-c & MrMoDDoM + */ + +#ifndef EM4233_H_ +#define EM4233_H_ + +#include "Application.h" + +#define EM4233_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE +#define EM4233_STD_MEM_SIZE 256 // Bytes +#define EM4233_BYTES_PER_BLCK 4 +#define EM4233_BLCKS_PER_PAGE 4 +#define EM4233_NUMBER_OF_BLCKS ( EM4233_STD_MEM_SIZE / EM4233_BYTES_PER_BLCK ) +#define EM4233_NUMBER_OF_PAGES ( EM4233_STD_MEM_SIZE / (EM4233_BYTES_PER_BLCK * EM4233_BLCKS_PER_PAGE) ) + +#define EM4233_USR_MEM_SIZE 64 // Bytes, guessed, not described anywere +#define EM4233_MEM_UID_ADDRESS 0x0100 // From 0x0100 to 0x0107 - UID +#define EM4233_MEM_LSM_ADDRESS 0x0108 // From 0x0108 to 0x014F - Lock status masks +#define EM4233_MEM_PSW_ADDRESS 0x0150 // From 0x0118 to 0x011F - Password +#define EM4233_MEM_KEY_ADDRESS 0x0120 // From 0x0120 to 0x0127 - Encryption Key + +#define EM4233_MASK_READ_PROT ( 1 << 2 ) // For lock status byte +#define EM4233_MASK_WRITE_PROT ( 1 << 3 ) + +#define EM4233_TOT_MEM_SIZE ( EM4233_STD_MEM_SIZE + EM4233_USR_MEM_SIZE ) + +/* Custom command code */ +#define EM4233_CMD_SET_EAS 0xA2 +#define EM4233_CMD_RST_EAS 0xA3 +#define EM4233_CMD_LCK_EAS 0xA4 +#define EM4233_CMD_ACT_EAS 0xA5 +#define EM4233_CMD_PRT_EAS 0xA6 +#define EM4233_CMD_WRT_EAS_ID 0xA7 +#define EM4233_CMD_WRT_EAS_CFG 0xA8 +#define EM4233_CMD_WRT_PSW 0xB4 +#define EM4233_CMD_WRT_MEM_PAG 0xB6 +#define EM4233_CMD_GET_BLKS_PRT_STS 0xB8 +#define EM4233_CMD_DESTROY 0xB9 +#define EM4233_CMD_ENABLE_PRCY 0xBA +#define EM4233_CMD_DISBLE_PRCY 0xBB +#define EM4233_CMD_FST_READ_BLKS 0xC3 + +/* Proprietary command code */ +#define EM4233_CMD_LOGIN 0xE4 + + +void EM4233AppInit(void); +void EM4233AppReset(void); +void EM4233AppTask(void); +void EM4233AppTick(void); +uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes); +void EM4233GetUid(ConfigurationUidType Uid); +void EM4233SetUid(ConfigurationUidType Uid); +void EM4233FlipUid(ConfigurationUidType Uid); + +#endif /* EM4233_H_ */ diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 936dbe4..72e0d9f 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -68,10 +68,17 @@ #define ISO15693_GENERIC_UID_SIZE 0x08 #define ISO15693_GENERIC_MEM_SIZE 8192 -#define ISO15693_CRC16_SIZE 2 /* Bytes */ +#define ISO15693_CRC16_SIZE 0x2 /* Bytes */ #define ISO15693_CRC16_POLYNORMAL 0x8408 #define ISO15693_CRC16_PRESET 0xFFFF +/* + * The byte used for the lock status has its bits addressed as follow: + * + */ +#define ISO15693_MASK_FACTORY_LOCK ( 1 << 0 ) +#define ISO15693_MASK_USER_LOCK ( 1 << 1 ) + typedef struct { uint8_t* Flags; uint8_t* Command; diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index f5618f5..80ae1a2 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -114,10 +114,12 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (FrameInfo.ParamLen != 5) break; /* malformed: not enough or too much data */ - if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = 2; break; /* malformed: trying to write in a non-existing block */ + } Dataptr = PageAddress + 0x01; @@ -141,11 +143,12 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (FrameInfo.ParamLen != 1) break; /* malformed: not enough or too much data */ - if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) + if (PageAddress > TITAGIT_NUMBER_OF_SECTORS) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; ResponseByteCount = 2; break; /* malformed: trying to lock a non-existing block */ + } if ((FactoryLockBits_Mask & (1 << PageAddress)) || (UserLockBits_Mask & (1 << PageAddress))) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c index 2731cfc..35b0de5 100644 --- a/Firmware/Chameleon-Mini/Configuration.c +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -46,10 +46,12 @@ static const MapEntryType PROGMEM ConfigurationMap[] = { #ifdef CONFIG_SL2S2002_SUPPORT { .Id = CONFIG_SL2S2002, .Text = "SL2S2002" }, #endif - #ifdef CONFIG_TITAGITSTANDARD_SUPPORT { .Id = CONFIG_TITAGITSTANDARD, .Text = "TITAGITSTANDARD" }, #endif +#ifdef CONFIG_EM4233_SUPPORT + { .Id = CONFIG_EM4233, .Text = "EM4233" }, +#endif }; /* Include all Codecs and Applications */ @@ -297,7 +299,6 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .TagFamily = TAG_FAMILY_ISO15693 }, #endif - #ifdef CONFIG_TITAGITSTANDARD_SUPPORT [CONFIG_TITAGITSTANDARD] = { .CodecInitFunc = ISO15693CodecInit, @@ -316,6 +317,24 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .TagFamily = TAG_FAMILY_ISO15693 }, #endif +#ifdef CONFIG_EM4233_SUPPORT + [CONFIG_EM4233] = { + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = EM4233AppInit, + .ApplicationResetFunc = EM4233AppReset, + .ApplicationTaskFunc = EM4233AppTask, + .ApplicationTickFunc = EM4233AppTick, + .ApplicationProcessFunc = EM4233AppProcess, + .ApplicationGetUidFunc = EM4233GetUid, + .ApplicationSetUidFunc = EM4233SetUid, + .UidSize = EM4233_STD_UID_SIZE, + .MemorySize = EM4233_STD_MEM_SIZE, + .ReadOnly = false, + .TagFamily = TAG_FAMILY_ISO15693 + }, +#endif }; ConfigurationType ActiveConfiguration; diff --git a/Firmware/Chameleon-Mini/Configuration.h b/Firmware/Chameleon-Mini/Configuration.h index 7f8b91a..9d53936 100644 --- a/Firmware/Chameleon-Mini/Configuration.h +++ b/Firmware/Chameleon-Mini/Configuration.h @@ -54,6 +54,9 @@ typedef enum { #endif #ifdef CONFIG_TITAGITSTANDARD_SUPPORT CONFIG_TITAGITSTANDARD, +#endif +#ifdef CONFIG_EM4233_SUPPORT + CONFIG_EM4233, #endif /* This HAS to be the last element */ CONFIG_COUNT diff --git a/Firmware/Chameleon-Mini/DUMP_TEST b/Firmware/Chameleon-Mini/DUMP_TEST new file mode 100644 index 0000000000000000000000000000000000000000..afaba814cb8c50804cf382e1694caeee59185b29 GIT binary patch literal 304 zcmZ3526m%?Gicy08hD2W{-Xgj<5!^>zZ=c?Gib)&MKk^#n(_Yy(SQ;fFh&CmXyAcZ W7rT&2SOvrS=b? Date: Fri, 14 Dec 2018 17:02:15 +0100 Subject: [PATCH 44/67] Fixed some bugs and implemented almost all optionnal ISO standard commands --- Firmware/Chameleon-Mini/Application/EM4233.c | 371 +++++++++++++++--- Firmware/Chameleon-Mini/Application/EM4233.h | 17 +- .../Chameleon-Mini/Application/ISO15693-A.c | 9 +- .../Chameleon-Mini/Application/ISO15693-A.h | 7 +- .../Application/TITagitstandard.c | 2 + 5 files changed, 349 insertions(+), 57 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index a2fb430..f9251f1 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -19,9 +19,6 @@ CurrentFrame FrameInfo; uint64_t EM4233_FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ uint64_t EM4233_UserLockBits_Mask = 0; /* Holds lock state of blocks */ -//uint8_t EM4233_Lock_Status[64] = { 1 }; - - void EM4233AppInit(void) { State = STATE_READY; @@ -31,9 +28,7 @@ void EM4233AppInit(void) FrameInfo.Parameters = NULL; FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; - - //MemoryReadBlock(EM4233_Lock_Status, EM4233_MEM_LSM_ADDRESS, 64); - //MemoryReadBlock(&EM4233_FactoryLockBits_Mask, EM4233_MEM_FLM_ADDRESS, 8); + FrameInfo.Selected = false; } void EM4233AppReset(void) @@ -45,12 +40,9 @@ void EM4233AppReset(void) FrameInfo.Parameters = NULL; FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; - - //MemoryReadBlock(&EM4233_UserLockBits_Mask, EM4233_MEM_ULM_ADDRESS, 8); - //MemoryReadBlock(&EM4233_FactoryLockBits_Mask, EM4233_MEM_FLM_ADDRESS, 8); + FrameInfo.Selected = false; } - void EM4233AppTask(void) { @@ -70,20 +62,20 @@ uint16_t EM4233_Lock_Block(uint8_t* FrameBuf, uint16_t FrameBytes) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ if (PageAddress > EM4233_NUMBER_OF_BLCKS) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; - ResponseByteCount = 2; + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; /* malformed: trying to lock a non-existing block */ } if ((EM4233_FactoryLockBits_Mask & (uint64_t)(1 << PageAddress)) || (EM4233_UserLockBits_Mask & (uint64_t)(1 << PageAddress))) { /* if already locked */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_ALRD_LKD; - ResponseByteCount = 2; + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_ALRD_LKD; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ } else { EM4233_UserLockBits_Mask |= (uint64_t)(1 << PageAddress); /* write the lock status in mask */ FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ } return ResponseByteCount; @@ -94,31 +86,33 @@ uint16_t EM4233_Write_Single(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t* Dataptr; uint8_t PageAddress = *FrameInfo.Parameters; + uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 5) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ if (PageAddress > EM4233_NUMBER_OF_BLCKS) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; - ResponseByteCount = 2; /* malformed: trying to write in a non-existing block */ - return ResponseByteCount; + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ + return ResponseByteCount; /* malformed: trying to write in a non-existing block */ } + MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + PageAddress), 1); Dataptr = PageAddress + 0x01; - if (EM4233_FactoryLockBits_Mask & (uint64_t)(1 << PageAddress)) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; - ResponseByteCount = 2; - } else if (EM4233_UserLockBits_Mask & (uint64_t)(1 << PageAddress)) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_CHG_LKD; - ResponseByteCount = 2; + if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway - probably: no factory lock exists? */ + } else if (LockStatus & ISO15693_MASK_USER_LOCK) { + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_CHG_LKD; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ } else { MemoryWriteBlock(Dataptr, PageAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; + ResponseByteCount += 1; } return ResponseByteCount; @@ -127,7 +121,7 @@ uint16_t EM4233_Write_Single(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t *FramePtr; /* holds the address where block's data will be put */ + uint8_t FramePtr; /* holds the address where block's data will be put */ uint8_t PageAddress = *FrameInfo.Parameters; uint8_t LockStatus = 0; @@ -135,30 +129,293 @@ uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ if (PageAddress >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a sector out of bound */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ - ResponseByteCount = 2; + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } + FramePtr = 1; + if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + PageAddress), 1); if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { /* tests if the n-th bit of the factory bitmask if set to 1 */ - FrameBuf[1] = 0x02; /* return bit 1 set as 1 (factory locked) */ + FrameBuf[FramePtr] = 0x02; /* return bit 1 set as 1 (factory locked) */ } else if (LockStatus & ISO15693_MASK_USER_LOCK) { /* tests if the n-th bit of the user bitmask if set to 1 */ - FrameBuf[1] = 0x01; /* return bit 0 set as 1 (user locked) */ + FrameBuf[FramePtr] = 0x01; /* return bit 0 set as 1 (user locked) */ } else - FrameBuf[1] = 0x00; /* return lock status 00 (unlocked) */ - FramePtr = FrameBuf + 2; /* block's data from byte 2 */ - ResponseByteCount = 6; - } else { /* request with option flag not set */ - FramePtr = FrameBuf + 1; /* block's data from byte 1 */ - ResponseByteCount = 5; + FrameBuf[FramePtr] = 0x00; /* return lock status 00 (unlocked) */ + FramePtr += 1; /* block's data from byte 2 */ + ResponseByteCount += 1; + } + + MemoryReadBlock(&FrameBuf[FramePtr], PageAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); + ResponseByteCount += 4; + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + ResponseByteCount += 1; + + return ResponseByteCount; +} + +uint16_t EM4233_Read_Multiple(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t FramePtr; /* holds the address where block's data will be put */ + uint8_t BlockAddress = FrameInfo.Parameters[0]; + uint8_t BlocksNumber = 0; + uint8_t LockStatus = 0; + + if (FrameInfo.ParamLen != 2) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + BlocksNumber = FrameInfo.Parameters[1]; + + if (BlockAddress >= EM4233_NUMBER_OF_BLCKS || (BlockAddress + BlocksNumber) >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a sector out of bound */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ + ResponseByteCount += 2; + return ResponseByteCount; + } + + FramePtr = 1; /* Start of response data */ + + for (uint8_t blk = 0; blk <= BlocksNumber; blk++) { + if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ + MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + (BlockAddress + blk)), 1); + + if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { /* tests if the n-th bit of the factory bitmask if set to 1 */ + FrameBuf[FramePtr] = 0x02; /* return bit 1 set as 1 (factory locked) */ + } else if (LockStatus & ISO15693_MASK_USER_LOCK) { /* tests if the n-th bit of the user bitmask if set to 1 */ + FrameBuf[FramePtr] = 0x01; /* return bit 0 set as 1 (user locked) */ + } else + FrameBuf[FramePtr] = 0x00; /* return lock status 00 (unlocked) */ + + FramePtr += 1; /* Move forward the buffer data pointer */ + ResponseByteCount += 1; /* Increment the response count */ + + } + + MemoryReadBlock(&FrameBuf[FramePtr], (BlockAddress + blk ) * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); + FramePtr += 4; /* Move forward the buffer data pointer */ + ResponseByteCount += 4; /* Increment the response count */ + } + + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + ResponseByteCount += 1; + return ResponseByteCount; +} + +uint16_t EM4233_Write_AFI(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t AFI = FrameInfo.Parameters[0]; + uint8_t LockStatus = 0; + + if (FrameInfo.ParamLen != 1) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + MemoryReadBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); + + if (LockStatus & EM4233_MASK_AFI_STATUS ) { /* The afi is locked */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + ResponseByteCount += 2; + return ResponseByteCount; + } + + MemoryWriteBlock(&AFI, EM4233_MEM_AFI_ADDRESS, 1); /* Actually write new AFI */ + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + ResponseByteCount += 1; + return ResponseByteCount; +} + +uint16_t EM4233_Lock_AFI(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t LockStatus = 0; + + if (FrameInfo.ParamLen != 0) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + MemoryReadBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); + + if (LockStatus & EM4233_MASK_AFI_STATUS ) { /* The afi is already locked */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + ResponseByteCount += 2; + return ResponseByteCount; + } + + LockStatus |= EM4233_MASK_AFI_STATUS; + + MemoryWriteBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); /* Actually write new AFI */ + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + ResponseByteCount += 1; + return ResponseByteCount; +} + +uint16_t EM4233_Write_DSFID(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t DSFID = FrameInfo.Parameters[0]; + uint8_t LockStatus = 0; + + if (FrameInfo.ParamLen != 1) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + MemoryReadBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); + + if (LockStatus & EM4233_MASK_DSFID_STATUS ) { /* The afi is locked */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + ResponseByteCount += 2; + return ResponseByteCount; + } + + MemoryWriteBlock(&DSFID, EM4233_MEM_DSFID_ADDRESS, 1); /* Actually write new AFI */ + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + ResponseByteCount += 1; + return ResponseByteCount; +} + +uint16_t EM4233_Lock_DSFID(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t LockStatus = 0; + + if (FrameInfo.ParamLen != 0) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + MemoryReadBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); + + if (LockStatus & EM4233_MASK_DSFID_STATUS ) { /* The afi is already locked */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + ResponseByteCount += 2; + return ResponseByteCount; + } + + LockStatus |= EM4233_MASK_DSFID_STATUS; + + MemoryWriteBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); /* Actually write new AFI */ + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + ResponseByteCount += 1; + return ResponseByteCount; +} + +uint8_t EM4233_Get_SysInfo(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t FramePtr; /* holds the address where block's data will be put */ + + if (FrameInfo.ParamLen != 0) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + FramePtr = 1; + + /* I've no idea how this request could generate errors ._. + if ( ) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + ResponseByteCount += 2; + return ResponseByteCount; + } + */ + + /* System info flags */ + FrameBuf[FramePtr] = EM4233_SYSINFO_BYTE; /* check pdf for this */ + FramePtr += 1; /* Move forward the buffer data pointer */ + ResponseByteCount += 1; /* Increment the response count */ + + /* Then append UID */ + uint8_t Uid[ActiveConfiguration.UidSize]; + EM4233GetUid(Uid); + ISO15693CopyUid(&FrameBuf[FramePtr], Uid); + FramePtr += ISO15693_GENERIC_UID_SIZE; /* Move forward the buffer data pointer */ + ResponseByteCount += ISO15693_GENERIC_UID_SIZE; /* Increment the response count */ + + /* Append DSFID */ + if ( EM4233_SYSINFO_BYTE & ( 1 << 0 )) { + MemoryReadBlock(&FrameBuf[FramePtr], EM4233_MEM_DSFID_ADDRESS, 1); + FramePtr += 1; /* Move forward the buffer data pointer */ + ResponseByteCount += 1; /* Increment the response count */ + } + + /* Append AFI */ + if ( EM4233_SYSINFO_BYTE & ( 1 << 1 )) { + MemoryReadBlock(&FrameBuf[FramePtr], EM4233_MEM_AFI_ADDRESS, 1); + FramePtr += 1; /* Move forward the buffer data pointer */ + ResponseByteCount += 1; /* Increment the response count */ + } + + /* Append VICC memory size */ + if ( EM4233_SYSINFO_BYTE & ( 1 << 2 )) { + FrameBuf[FramePtr] = EM4233_NUMBER_OF_BLCKS - 0x01; + FramePtr += 1; /* Move forward the buffer data pointer */ + ResponseByteCount += 1; /* Increment the response count */ + + FrameBuf[FramePtr] = EM4233_BYTES_PER_BLCK - 0x01; + FramePtr += 1; /* Move forward the buffer data pointer */ + ResponseByteCount += 1; /* Increment the response count */ + } + + /* Append IC reference */ + if ( EM4233_SYSINFO_BYTE & ( 1 << 3 )) { + FrameBuf[FramePtr] = EM4233_IC_REFERENCE; + FramePtr += 1; /* Move forward the buffer data pointer */ + ResponseByteCount += 1; /* Increment the response count */ } FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - MemoryReadBlock(FramePtr, PageAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); + ResponseByteCount += 1; + return ResponseByteCount; +} +uint16_t EM4233_Get_Multi_Block_Sec_Stat(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t FramePtr; /* holds the address where block's data will be put */ + uint8_t BlockAddress = FrameInfo.Parameters[0]; + uint8_t BlocksNumber = 0; + uint8_t LockStatus = 0; + + if (FrameInfo.ParamLen != 2) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + BlocksNumber = FrameInfo.Parameters[1]; + + if (BlockAddress >= EM4233_NUMBER_OF_BLCKS || (BlockAddress + BlocksNumber) >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a sector out of bound */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ + ResponseByteCount += 2; + return ResponseByteCount; + } + + FramePtr = 1; /* Start of response data */ + + for (uint8_t blk = 0; blk <= BlocksNumber; blk++) { + + MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + (BlockAddress + blk)), 1); + + if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { /* tests if the n-th bit of the factory bitmask if set to 1 */ + FrameBuf[FramePtr] = 0x02; /* return bit 1 set as 1 (factory locked) */ + } else if (LockStatus & ISO15693_MASK_USER_LOCK) { /* tests if the n-th bit of the user bitmask if set to 1 */ + FrameBuf[FramePtr] = 0x01; /* return bit 0 set as 1 (user locked) */ + } else + FrameBuf[FramePtr] = 0x00; /* return lock status 00 (unlocked) */ + + FramePtr += 1; /* Move forward the buffer data pointer */ + ResponseByteCount += 1; /* Increment the response count */ + } + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + ResponseByteCount += 1; return ResponseByteCount; } @@ -175,7 +432,7 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) case STATE_READY: if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_INVENTORY_DSFID; + MemoryReadBlock(&FrameBuf[ISO15693_RES_ADDR_PARAM], EM4233_MEM_DSFID_ADDRESS, 1); ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); ResponseByteCount = 10; @@ -191,6 +448,27 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } else if (*FrameInfo.Command == ISO15693_CMD_LOCK_BLOCK) { ResponseByteCount = EM4233_Lock_Block(FrameBuf, FrameBytes); + } else if (*FrameInfo.Command == ISO15693_CMD_READ_MULTIPLE) { + ResponseByteCount = EM4233_Read_Multiple(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_WRITE_AFI) { + ResponseByteCount = EM4233_Write_AFI(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_LOCK_AFI) { + ResponseByteCount = EM4233_Lock_AFI(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_WRITE_DSFID) { + ResponseByteCount = EM4233_Write_DSFID(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_LOCK_DSFID) { + ResponseByteCount = EM4233_Lock_DSFID(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_GET_SYS_INFO) { + ResponseByteCount = EM4233_Get_SysInfo(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_GET_BLOCK_SEC) { + ResponseByteCount = EM4233_Get_Multi_Block_Sec_Stat(FrameBuf, FrameBytes); + } else { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; @@ -198,10 +476,6 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } break; - case STATE_SELECTED: - /* TO-DO */ - break; - case STATE_QUIET: if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; @@ -213,6 +487,7 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameInfo.Parameters = NULL; FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; + FrameInfo.Selected = false; } break; diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h index 9e75160..7179673 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.h +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -12,19 +12,30 @@ #define EM4233_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE #define EM4233_STD_MEM_SIZE 256 // Bytes -#define EM4233_BYTES_PER_BLCK 4 -#define EM4233_BLCKS_PER_PAGE 4 +#define EM4233_BYTES_PER_BLCK 0x4 +#define EM4233_BLCKS_PER_PAGE 0x4 #define EM4233_NUMBER_OF_BLCKS ( EM4233_STD_MEM_SIZE / EM4233_BYTES_PER_BLCK ) #define EM4233_NUMBER_OF_PAGES ( EM4233_STD_MEM_SIZE / (EM4233_BYTES_PER_BLCK * EM4233_BLCKS_PER_PAGE) ) +#define EM4233_IC_REFERENCE 0x02 + #define EM4233_USR_MEM_SIZE 64 // Bytes, guessed, not described anywere #define EM4233_MEM_UID_ADDRESS 0x0100 // From 0x0100 to 0x0107 - UID -#define EM4233_MEM_LSM_ADDRESS 0x0108 // From 0x0108 to 0x014F - Lock status masks +#define EM4233_MEM_AFI_ADDRESS 0x0108 // AFI byte address +#define EM4233_MEM_DSFID_ADDRESS 0x0109 // DSFID byte adress +#define EM4233_MEM_INF_ADDRESS 0x010C // Some status bits + +#define EM4233_MEM_LSM_ADDRESS 0x0110 // From 0x0108 to 0x0157 - Lock status masks #define EM4233_MEM_PSW_ADDRESS 0x0150 // From 0x0118 to 0x011F - Password #define EM4233_MEM_KEY_ADDRESS 0x0120 // From 0x0120 to 0x0127 - Encryption Key +#define EM4233_SYSINFO_BYTE 0x0F // DSFID - AFI - VICC mem size - IC ref are present + +/* Bit masks */ #define EM4233_MASK_READ_PROT ( 1 << 2 ) // For lock status byte #define EM4233_MASK_WRITE_PROT ( 1 << 3 ) +#define EM4233_MASK_AFI_STATUS ( 1 << 0 ) +#define EM4233_MASK_DSFID_STATUS ( 1 << 1 ) #define EM4233_TOT_MEM_SIZE ( EM4233_STD_MEM_SIZE + EM4233_USR_MEM_SIZE ) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index f8a36da..373a739 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -75,17 +75,20 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct -> Flags = &FrameBuf[ISO15693_ADDR_FLAGS]; FrameStruct -> Command = &FrameBuf[ISO15693_REQ_ADDR_CMD]; - if(!(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY)) /* if inventory flag is not set */ + if(!(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY)) { /* if inventory flag is not set */ FrameStruct -> Addressed = (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS); /* check for addressed flag */ - else /* otherwise always false */ + FrameStruct -> Selected = (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_SELECT); /* check for selected flag */ + } else { /* otherwise always false */ FrameStruct -> Addressed = false; + FrameStruct -> Selected = false; + } if (FrameStruct -> Addressed) /* UID sits between CMD and PARAM */ FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM + ISO15693_GENERIC_UID_SIZE]; else FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM]; - + FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); if (FrameStruct -> Addressed && !ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], MyUid)) { diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 72e0d9f..ac8fc31 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -63,7 +63,7 @@ #define ISO15693_RES_INVENTORY_DSFID 0x00 -#define ISO15693_MIN_FRAME_SIZE 0x05 +#define ISO15693_MIN_FRAME_SIZE 0x04 #define ISO15693_GENERIC_UID_SIZE 0x08 #define ISO15693_GENERIC_MEM_SIZE 8192 @@ -76,8 +76,8 @@ * The byte used for the lock status has its bits addressed as follow: * */ -#define ISO15693_MASK_FACTORY_LOCK ( 1 << 0 ) -#define ISO15693_MASK_USER_LOCK ( 1 << 1 ) +#define ISO15693_MASK_USER_LOCK ( 1 << 0 ) +#define ISO15693_MASK_FACTORY_LOCK ( 1 << 1 ) typedef struct { uint8_t* Flags; @@ -85,6 +85,7 @@ typedef struct { uint8_t* Parameters; uint8_t ParamLen; bool Addressed; + bool Selected; } CurrentFrame; void ISO15693AppendCRC(uint8_t* FrameBuf, uint16_t FrameBufSize); diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 80ae1a2..3208bf6 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -32,6 +32,7 @@ void TITagitstandardAppInit(void) FrameInfo.Parameters = NULL; FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; + FrameInfo.Selected = false; } void TITagitstandardAppReset(void) @@ -43,6 +44,7 @@ void TITagitstandardAppReset(void) FrameInfo.Parameters = NULL; FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; + FrameInfo.Selected = false; } From 0dfbe01b28bcd60103d9de196bebe023d8484b49 Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Fri, 14 Dec 2018 21:41:36 +0100 Subject: [PATCH 45/67] Added EM4233 example dump and bug fixes --- Dumps/EM4233_example.dmp | Bin 0 -> 352 bytes Firmware/Chameleon-Mini/Application/EM4233.h | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 Dumps/EM4233_example.dmp diff --git a/Dumps/EM4233_example.dmp b/Dumps/EM4233_example.dmp new file mode 100644 index 0000000000000000000000000000000000000000..7e87a0699926a0fc6571893f6a936792318e5649 GIT binary patch literal 352 zcmZ3526m%?Gicy08hD2W{-Xgj<5!^>zZ=c?Gib)&MKk^#n(_Yy(SQ;fFh&CmXyAdE S3fM>nCWr(hg#c_A5&-~iuDl2U literal 0 HcmV?d00001 diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h index 7179673..48357da 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.h +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -27,7 +27,7 @@ #define EM4233_MEM_LSM_ADDRESS 0x0110 // From 0x0108 to 0x0157 - Lock status masks #define EM4233_MEM_PSW_ADDRESS 0x0150 // From 0x0118 to 0x011F - Password -#define EM4233_MEM_KEY_ADDRESS 0x0120 // From 0x0120 to 0x0127 - Encryption Key +#define EM4233_MEM_KEY_ADDRESS 0x0154 // From 0x0120 to 0x0127 - Encryption Key #define EM4233_SYSINFO_BYTE 0x0F // DSFID - AFI - VICC mem size - IC ref are present From 7bc809cc165d873af1235ae808674eee904481f5 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Sun, 16 Dec 2018 20:03:02 +0100 Subject: [PATCH 46/67] Backporting bug fixes and additions from EM4233 branch --- Firmware/Chameleon-Mini/Application/ISO15693-A.c | 9 ++++++--- Firmware/Chameleon-Mini/Application/ISO15693-A.h | 12 ++++++++++-- .../Chameleon-Mini/Application/TITagitstandard.c | 2 ++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index f8a36da..373a739 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -75,17 +75,20 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct -> Flags = &FrameBuf[ISO15693_ADDR_FLAGS]; FrameStruct -> Command = &FrameBuf[ISO15693_REQ_ADDR_CMD]; - if(!(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY)) /* if inventory flag is not set */ + if(!(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_INVENTORY)) { /* if inventory flag is not set */ FrameStruct -> Addressed = (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS); /* check for addressed flag */ - else /* otherwise always false */ + FrameStruct -> Selected = (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_SELECT); /* check for selected flag */ + } else { /* otherwise always false */ FrameStruct -> Addressed = false; + FrameStruct -> Selected = false; + } if (FrameStruct -> Addressed) /* UID sits between CMD and PARAM */ FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM + ISO15693_GENERIC_UID_SIZE]; else FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM]; - + FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); if (FrameStruct -> Addressed && !ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], MyUid)) { diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 936dbe4..ac8fc31 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -63,21 +63,29 @@ #define ISO15693_RES_INVENTORY_DSFID 0x00 -#define ISO15693_MIN_FRAME_SIZE 0x05 +#define ISO15693_MIN_FRAME_SIZE 0x04 #define ISO15693_GENERIC_UID_SIZE 0x08 #define ISO15693_GENERIC_MEM_SIZE 8192 -#define ISO15693_CRC16_SIZE 2 /* Bytes */ +#define ISO15693_CRC16_SIZE 0x2 /* Bytes */ #define ISO15693_CRC16_POLYNORMAL 0x8408 #define ISO15693_CRC16_PRESET 0xFFFF +/* + * The byte used for the lock status has its bits addressed as follow: + * + */ +#define ISO15693_MASK_USER_LOCK ( 1 << 0 ) +#define ISO15693_MASK_FACTORY_LOCK ( 1 << 1 ) + typedef struct { uint8_t* Flags; uint8_t* Command; uint8_t* Parameters; uint8_t ParamLen; bool Addressed; + bool Selected; } CurrentFrame; void ISO15693AppendCRC(uint8_t* FrameBuf, uint16_t FrameBufSize); diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 80ae1a2..3208bf6 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -32,6 +32,7 @@ void TITagitstandardAppInit(void) FrameInfo.Parameters = NULL; FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; + FrameInfo.Selected = false; } void TITagitstandardAppReset(void) @@ -43,6 +44,7 @@ void TITagitstandardAppReset(void) FrameInfo.Parameters = NULL; FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; + FrameInfo.Selected = false; } From aa237f0767480fdc00e3f783ade978b502e713f3 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Tue, 18 Dec 2018 00:13:57 +0100 Subject: [PATCH 47/67] Implemented Select command and fixed PrepareFrame to be compliant with Custom and Proprietary commands --- Firmware/Chameleon-Mini/Application/EM4233.c | 60 +++++++++++++++---- .../Chameleon-Mini/Application/ISO15693-A.c | 12 +++- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index f9251f1..75e6684 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -123,7 +123,7 @@ uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t FramePtr; /* holds the address where block's data will be put */ uint8_t PageAddress = *FrameInfo.Parameters; - uint8_t LockStatus = 0; + uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 1) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ @@ -164,7 +164,7 @@ uint16_t EM4233_Read_Multiple(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t FramePtr; /* holds the address where block's data will be put */ uint8_t BlockAddress = FrameInfo.Parameters[0]; uint8_t BlocksNumber = 0; - uint8_t LockStatus = 0; + uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 2) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ @@ -419,6 +419,36 @@ uint16_t EM4233_Get_Multi_Block_Sec_Stat(uint8_t* FrameBuf, uint16_t FrameBytes) return ResponseByteCount; } +uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) +{ + /* I've no idea how this request could generate errors ._. + if ( ) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + ResponseByteCount += 2; + return ResponseByteCount; + } + */ + + bool UidEquals = ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid); + + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + if (!FrameInfo.Addressed || FrameInfo.Selected) { + /* tag should remain silent if Select is performed without address flag or with select flag */ + return ISO15693_APP_NO_RESPONSE; + } else if (State == STATE_SELECTED && !UidEquals) { + /* tag should remain silent if Select is performed while the tag is selected but against another tag */ + State == STATE_READY; + return ISO15693_APP_NO_RESPONSE; + } else if (State != STATE_SELECTED && !UidEquals) { + /* tag should remain silent if Select is performed against another UID */ + return ISO15693_APP_NO_RESPONSE; + } else if (State != STATE_SELECTED && UidEquals) { + State == STATE_SELECTED; + return ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ + } +} + uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; @@ -428,8 +458,14 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid)) return ISO15693_APP_NO_RESPONSE; - switch(State) { - case STATE_READY: + FrameBuf[ISO15693_ADDR_FLAGS] = FrameInfo.ParamLen; + ResponseByteCount = 1; + ISO15693AppendCRC(FrameBuf, ResponseByteCount); + ResponseByteCount += ISO15693_CRC16_SIZE; + return ResponseByteCount; + + + if (State == STATE_READY || State == STATE_SELECTED) { if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; MemoryReadBlock(&FrameBuf[ISO15693_RES_ADDR_PARAM], EM4233_MEM_DSFID_ADDRESS, 1); @@ -468,15 +504,20 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } else if (*FrameInfo.Command == ISO15693_CMD_GET_BLOCK_SEC) { ResponseByteCount = EM4233_Get_Multi_Block_Sec_Stat(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == ISO15693_CMD_SELECT) { + ResponseByteCount = EM4233_Select(FrameBuf, FrameBytes, Uid); + + } else if (*FrameInfo.Command == EM4233_CMD_LOGIN) { + // ResponseByteCount = EM4233_Select(FrameBuf, FrameBytes, Uid); } else { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; ResponseByteCount = 2; } - break; - - case STATE_QUIET: + } + else if (State == STATE_QUIET) { if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; @@ -489,11 +530,6 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameInfo.Addressed = false; FrameInfo.Selected = false; } - - break; - - default: - break; } if (ResponseByteCount > 0) { diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 373a739..a87ab33 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -88,10 +88,18 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM + ISO15693_GENERIC_UID_SIZE]; else FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM]; - + + if (*(FrameStruct -> Command) >= 0xA0) { /* if command is Custom or Proprietary */ + /* then between CMD and UID is placed another byte which is IC Mfg Code, but we don't need it */ + FrameStruct -> Parameters += 0x01; + if (FrameBuf[ISO15693_REQ_ADDR_PARAM] != MyUid[1]) + /* if IC Mfg Code is different from our Mfg code (2nd byte of UID), then don't respond */ + return false; + } + FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); - if (FrameStruct -> Addressed && !ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], MyUid)) { + if (FrameStruct -> Addressed && !ISO15693CompareUid(FrameStruct -> Parameters, MyUid)) { /* addressed request but we're not the addressee */ return false; } else { From 98141b676957ce5f23045f259114582772548e97 Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Tue, 18 Dec 2018 00:42:19 +0100 Subject: [PATCH 48/67] Added fake login command --- Firmware/Chameleon-Mini/Application/EM4233.c | 42 ++++++++++++++++---- Firmware/Chameleon-Mini/Application/EM4233.h | 4 +- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index 75e6684..ea617c2 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -14,6 +14,8 @@ static enum { STATE_QUIET } State; +bool loggedIn; + CurrentFrame FrameInfo; uint64_t EM4233_FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ @@ -29,6 +31,8 @@ void EM4233AppInit(void) FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; FrameInfo.Selected = false; + loggedIn = false; + } void EM4233AppReset(void) @@ -41,6 +45,7 @@ void EM4233AppReset(void) FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; FrameInfo.Selected = false; + loggedIn = false; } void EM4233AppTask(void) @@ -449,6 +454,34 @@ uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) } } +uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + uint8_t Password[4] = { 0 }; + + if (FrameInfo.ParamLen != 4) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + MemoryReadBlock(&Password, EM4233_MEM_PSW_ADDRESS, 4); + + if( false ){ // YES-MAN! +// if (!memcmp(Password, FrameInfo.Parameters, 4)) { /* Incorrect password */ + + loggedIn = false; + + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; + return ResponseByteCount; + } + + loggedIn = true; + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + ResponseByteCount += 1; + return ResponseByteCount; +} + uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; @@ -458,13 +491,6 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid)) return ISO15693_APP_NO_RESPONSE; - FrameBuf[ISO15693_ADDR_FLAGS] = FrameInfo.ParamLen; - ResponseByteCount = 1; - ISO15693AppendCRC(FrameBuf, ResponseByteCount); - ResponseByteCount += ISO15693_CRC16_SIZE; - return ResponseByteCount; - - if (State == STATE_READY || State == STATE_SELECTED) { if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; @@ -509,7 +535,7 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ResponseByteCount = EM4233_Select(FrameBuf, FrameBytes, Uid); } else if (*FrameInfo.Command == EM4233_CMD_LOGIN) { - // ResponseByteCount = EM4233_Select(FrameBuf, FrameBytes, Uid); + ResponseByteCount = EM4233_Login(FrameBuf, FrameBytes, Uid); } else { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h index 48357da..6660e09 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.h +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -25,8 +25,8 @@ #define EM4233_MEM_DSFID_ADDRESS 0x0109 // DSFID byte adress #define EM4233_MEM_INF_ADDRESS 0x010C // Some status bits -#define EM4233_MEM_LSM_ADDRESS 0x0110 // From 0x0108 to 0x0157 - Lock status masks -#define EM4233_MEM_PSW_ADDRESS 0x0150 // From 0x0118 to 0x011F - Password +#define EM4233_MEM_LSM_ADDRESS 0x0110 // From 0x0108 to 0x0149 - Lock status masks +#define EM4233_MEM_PSW_ADDRESS 0x0150 // From 0x0150 to 0x0153 - Password #define EM4233_MEM_KEY_ADDRESS 0x0154 // From 0x0120 to 0x0127 - Encryption Key #define EM4233_SYSINFO_BYTE 0x0F // DSFID - AFI - VICC mem size - IC ref are present From 31d2320e8e18c8aaa1ba8bb38fc4fd1b69ec59b3 Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Tue, 18 Dec 2018 01:06:25 +0100 Subject: [PATCH 49/67] Test to sniff EM4233 login password --- Firmware/Chameleon-Mini/Application/EM4233.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index ea617c2..475c277 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -307,7 +307,7 @@ uint16_t EM4233_Lock_DSFID(uint8_t* FrameBuf, uint16_t FrameBytes) LockStatus |= EM4233_MASK_DSFID_STATUS; - MemoryWriteBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); /* Actually write new AFI */ + MemoryWriteBlock(*FrameInfo.Parameters, EM4233_MEM_INF_ADDRESS, 4); /* Actually write the new PASSWORD */ FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ ResponseByteCount += 1; @@ -477,6 +477,9 @@ uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) loggedIn = true; + MemoryWriteBlock(Password, EM4233_MEM_PSW_ADDRESS, 1); /* Actually write new AFI */ + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ ResponseByteCount += 1; return ResponseByteCount; From d7f2b7525b507100f0772b225eddce44ca933b9a Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Tue, 18 Dec 2018 01:20:32 +0100 Subject: [PATCH 50/67] Modified EM4233_STD_MEM_SIZE to reflect real tag size --- Firmware/Chameleon-Mini/Application/EM4233.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h index 6660e09..88b79b3 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.h +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -11,7 +11,7 @@ #include "Application.h" #define EM4233_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE -#define EM4233_STD_MEM_SIZE 256 // Bytes +#define EM4233_STD_MEM_SIZE 208 // Bytes #define EM4233_BYTES_PER_BLCK 0x4 #define EM4233_BLCKS_PER_PAGE 0x4 #define EM4233_NUMBER_OF_BLCKS ( EM4233_STD_MEM_SIZE / EM4233_BYTES_PER_BLCK ) From be729b757326bd49eb66306f80b35a56718673ad Mon Sep 17 00:00:00 2001 From: MrMoDDoM Date: Tue, 18 Dec 2018 16:42:10 +0100 Subject: [PATCH 51/67] Fixed a bug in prepareFrame on uid pointer into buffer --- Dumps/EM4233_example.dmp | Bin 352 -> 352 bytes Firmware/Chameleon-Mini/Application/EM4233.c | 14 +++++++------- .../Chameleon-Mini/Application/ISO15693-A.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Dumps/EM4233_example.dmp b/Dumps/EM4233_example.dmp index 7e87a0699926a0fc6571893f6a936792318e5649..e9f4caaa5851d6022b8c6f217498f1dc7ec28296 100644 GIT binary patch literal 352 zcmZ3526m%?Gicy08hD2W{-Xgj<5!^>zZ=c?Gib)&MKk^#n(_Yy(SQ;fFh&CmXyAdE W3fM>nCNv2$x%bxYdk;1cN&o;?Qo95I literal 352 zcmZ3526m%?Gicy08hD2W{-Xgj<5!^>zZ=c?Gib)&MKk^#n(_Yy(SQ;fFh&CmXyAdE S3fM>nCWr(hg#c_A5&-~iuDl2U diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index 475c277..b9cfeb6 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -443,15 +443,17 @@ uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) return ISO15693_APP_NO_RESPONSE; } else if (State == STATE_SELECTED && !UidEquals) { /* tag should remain silent if Select is performed while the tag is selected but against another tag */ - State == STATE_READY; + State = STATE_READY; return ISO15693_APP_NO_RESPONSE; } else if (State != STATE_SELECTED && !UidEquals) { /* tag should remain silent if Select is performed against another UID */ return ISO15693_APP_NO_RESPONSE; } else if (State != STATE_SELECTED && UidEquals) { - State == STATE_SELECTED; + State = STATE_SELECTED; return ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ } + + return ISO15693_APP_NO_RESPONSE; } uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) @@ -477,8 +479,7 @@ uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) loggedIn = true; - MemoryWriteBlock(Password, EM4233_MEM_PSW_ADDRESS, 1); /* Actually write new AFI */ - + MemoryWriteBlock(Password, EM4233_MEM_PSW_ADDRESS, 4); /* Actually write new AFI */ FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ ResponseByteCount += 1; @@ -501,7 +502,7 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); ResponseByteCount = 10; - } else if (*FrameInfo.Command == ISO15693_CMD_STAY_QUIET && FrameInfo.Addressed) { + } else if ( (*FrameInfo.Command == ISO15693_CMD_STAY_QUIET ) && FrameInfo.Addressed) { State = STATE_QUIET; } else if (*FrameInfo.Command == ISO15693_CMD_READ_SINGLE) { @@ -545,8 +546,7 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; ResponseByteCount = 2; } - } - else if (State == STATE_QUIET) { + } else if (State == STATE_QUIET) { if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = 1; diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index a87ab33..38aa01b 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -89,7 +89,7 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* else FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM]; - if (*(FrameStruct -> Command) >= 0xA0) { /* if command is Custom or Proprietary */ + if ( (*FrameStruct -> Command) >= 0xA0) { /* if command is Custom or Proprietary */ /* then between CMD and UID is placed another byte which is IC Mfg Code, but we don't need it */ FrameStruct -> Parameters += 0x01; if (FrameBuf[ISO15693_REQ_ADDR_PARAM] != MyUid[1]) @@ -99,7 +99,9 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); - if (FrameStruct -> Addressed && !ISO15693CompareUid(FrameStruct -> Parameters, MyUid)) { + uint8_t *uid = (FrameStruct -> Parameters) - ISO15693_GENERIC_UID_SIZE; + + if (FrameStruct -> Addressed && !ISO15693CompareUid( uid, MyUid)) { /* addressed request but we're not the addressee */ return false; } else { From 1b38d14b2beb7970259e2821163f3f84a21424f3 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Wed, 19 Dec 2018 16:17:13 +0100 Subject: [PATCH 52/67] Refactored ReadMultipleBlocks command to partially cope with timing issues --- Firmware/Chameleon-Mini/Application/EM4233.c | 66 +++++++++++--------- Firmware/Chameleon-Mini/Application/EM4233.h | 4 +- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index b9cfeb6..18a26ac 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -168,47 +168,58 @@ uint16_t EM4233_Read_Multiple(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t FramePtr; /* holds the address where block's data will be put */ uint8_t BlockAddress = FrameInfo.Parameters[0]; - uint8_t BlocksNumber = 0; - uint8_t LockStatus = 0; + uint8_t BlocksNumber = FrameInfo.Parameters[1] + 0x01; /* according to ISO standard, we have to read 8 blocks if we get 0x07 in request */ if (FrameInfo.ParamLen != 2) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ - BlocksNumber = FrameInfo.Parameters[1]; - - if (BlockAddress >= EM4233_NUMBER_OF_BLCKS || (BlockAddress + BlocksNumber) >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a sector out of bound */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ - ResponseByteCount += 2; + if (BlockAddress > EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a starting block out of bound */ + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; + } else if ((BlockAddress + BlocksNumber) >= EM4233_NUMBER_OF_BLCKS) { /* last block is out of bound */ + BlocksNumber = EM4233_NUMBER_OF_BLCKS - BlockAddress; /* we read up to latest block, as real tag does */ } - FramePtr = 1; /* Start of response data */ + FramePtr = 1; /* start of response data */ - for (uint8_t blk = 0; blk <= BlocksNumber; blk++) { - if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + (BlockAddress + blk)), 1); + if ( (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) == 0 ) { /* blocks' lock status is not requested */ + /* read data straight into frame */ + MemoryReadBlock(&FrameBuf[FramePtr], BlockAddress * EM4233_BYTES_PER_BLCK, BlocksNumber * EM4233_BYTES_PER_BLCK); + ResponseByteCount += BlocksNumber * EM4233_BYTES_PER_BLCK; - if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { /* tests if the n-th bit of the factory bitmask if set to 1 */ - FrameBuf[FramePtr] = 0x02; /* return bit 1 set as 1 (factory locked) */ - } else if (LockStatus & ISO15693_MASK_USER_LOCK) { /* tests if the n-th bit of the user bitmask if set to 1 */ + } else { /* we have to slice blocks' data with lock statuses */ + uint8_t DataBuffer[ BlocksNumber * EM4233_BYTES_PER_BLCK ]; /* a temporary vector with blocks' content */ + uint8_t LockStatusBuffer[ BlocksNumber ]; /* a vector with blocks' lock status */ + + /* read all at once to reduce timing issues */ + MemoryReadBlock(&DataBuffer, BlockAddress * EM4233_BYTES_PER_BLCK, BlocksNumber * EM4233_BYTES_PER_BLCK); + MemoryReadBlock(&LockStatusBuffer, EM4233_MEM_LSM_ADDRESS + BlockAddress, BlocksNumber); + + for (uint8_t block = 0; block < BlocksNumber; block++) { /* we cycle through the blocks */ + + /* add lock status */ + if (LockStatusBuffer[block] & ISO15693_MASK_USER_LOCK) { /* tests if bit 0 of the status byte if set to 1 */ FrameBuf[FramePtr] = 0x01; /* return bit 0 set as 1 (user locked) */ + } else if (LockStatusBuffer[block] & ISO15693_MASK_FACTORY_LOCK) { /* tests if bit 1 of the status byte if set to 1 */ + FrameBuf[FramePtr] = 0x02; /* return bit 1 set as 1 (factory locked) */ } else FrameBuf[FramePtr] = 0x00; /* return lock status 00 (unlocked) */ + ResponseByteCount += 1; + FramePtr += 1; - FramePtr += 1; /* Move forward the buffer data pointer */ - ResponseByteCount += 1; /* Increment the response count */ - - } - - MemoryReadBlock(&FrameBuf[FramePtr], (BlockAddress + blk ) * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); - FramePtr += 4; /* Move forward the buffer data pointer */ - ResponseByteCount += 4; /* Increment the response count */ + /* then copy block's data */ + for (uint8_t byte = 0; byte < EM4233_BYTES_PER_BLCK; byte++) { /* we cycle through the bytes in every block */ + FrameBuf[FramePtr] = DataBuffer[block * EM4233_BYTES_PER_BLCK + byte]; /* to copy them in the frame from our temporary buffer */ + FramePtr += 1; + } + ResponseByteCount += EM4233_BYTES_PER_BLCK; + } } - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - ResponseByteCount += 1; + ResponseByteCount += 1; return ResponseByteCount; } @@ -435,9 +446,8 @@ uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) } */ - bool UidEquals = ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid); + bool UidEquals = ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid); - uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; if (!FrameInfo.Addressed || FrameInfo.Selected) { /* tag should remain silent if Select is performed without address flag or with select flag */ return ISO15693_APP_NO_RESPONSE; @@ -467,7 +477,7 @@ uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) MemoryReadBlock(&Password, EM4233_MEM_PSW_ADDRESS, 4); if( false ){ // YES-MAN! -// if (!memcmp(Password, FrameInfo.Parameters, 4)) { /* Incorrect password */ + // if (!memcmp(Password, FrameInfo.Parameters, 4)) { /* Incorrect password */ loggedIn = false; diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h index 88b79b3..e1d370b 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.h +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -12,8 +12,8 @@ #define EM4233_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE #define EM4233_STD_MEM_SIZE 208 // Bytes -#define EM4233_BYTES_PER_BLCK 0x4 -#define EM4233_BLCKS_PER_PAGE 0x4 +#define EM4233_BYTES_PER_BLCK 0x04 +#define EM4233_BLCKS_PER_PAGE 0x04 #define EM4233_NUMBER_OF_BLCKS ( EM4233_STD_MEM_SIZE / EM4233_BYTES_PER_BLCK ) #define EM4233_NUMBER_OF_PAGES ( EM4233_STD_MEM_SIZE / (EM4233_BYTES_PER_BLCK * EM4233_BLCKS_PER_PAGE) ) From cf27a07a8d2be68e9e6bdf08a19224b5cbe135bc Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Wed, 19 Dec 2018 17:23:19 +0100 Subject: [PATCH 53/67] Indentation fixes --- Firmware/Chameleon-Mini/Application/EM4233.c | 2 +- .../Chameleon-Mini/Application/ISO15693-A.c | 2 +- Firmware/Chameleon-Mini/Codec/ISO15693.c | 26 +-- Firmware/Chameleon-Mini/Configuration.c | 170 +++++++++--------- 4 files changed, 100 insertions(+), 100 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index 18a26ac..54a20f4 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -198,7 +198,7 @@ uint16_t EM4233_Read_Multiple(uint8_t* FrameBuf, uint16_t FrameBytes) MemoryReadBlock(&LockStatusBuffer, EM4233_MEM_LSM_ADDRESS + BlockAddress, BlocksNumber); for (uint8_t block = 0; block < BlocksNumber; block++) { /* we cycle through the blocks */ - + /* add lock status */ if (LockStatusBuffer[block] & ISO15693_MASK_USER_LOCK) { /* tests if bit 0 of the status byte if set to 1 */ FrameBuf[FramePtr] = 0x01; /* return bit 0 set as 1 (user locked) */ diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 38aa01b..b271db8 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -88,7 +88,7 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM + ISO15693_GENERIC_UID_SIZE]; else FrameStruct -> Parameters = &FrameBuf[ISO15693_REQ_ADDR_PARAM]; - + if ( (*FrameStruct -> Command) >= 0xA0) { /* if command is Custom or Proprietary */ /* then between CMD and UID is placed another byte which is IC Mfg Code, but we don't need it */ FrameStruct -> Parameters += 0x01; diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index 8c84219..bab785d 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -143,7 +143,7 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) CODEC_TIMER_SAMPLING.INTCTRLB = 0; } break; - + case DEMOD_1_OUT_OF_4_STATE: if (SampleRegister == EOC_CODE) { @@ -184,7 +184,7 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) } } break; - + case DEMOD_1_OUT_OF_256_STATE: if (SampleRegister == EOC_CODE) { @@ -252,7 +252,7 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) } else { return; } - + LOADMOD_START_SINGLE_LABEL: CodecStartSubcarrier(); ShiftRegister = SOF_PATTERN; @@ -276,7 +276,7 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) StateRegister = LOADMOD_SOF_SINGLE; } return; - + LOADMOD_BIT0_SINGLE_LABEL: //Manchester encoding if (ShiftRegister & 0x01) { /* Deactivate carrier */ @@ -288,7 +288,7 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) StateRegister = LOADMOD_BIT1_SINGLE; return; - + LOADMOD_BIT1_SINGLE_LABEL: //Manchester encoding if (ShiftRegister & 0x01) { CodecSetLoadmodState(true); @@ -312,7 +312,7 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) } } return; - + LOADMOD_EOF_SINGLE_LABEL: //End of Manchester encoding /* Output EOF */ if (ShiftRegister & 0x80) { @@ -333,7 +333,7 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) return; // ------------------------------------------------------------- - + LOADMOD_START_DUAL_LABEL: CodecStartSubcarrier(); ShiftRegister = SOF_PATTERN; @@ -514,11 +514,11 @@ void ISO15693CodecTask(void) { if (Flags.DemodFinished) { Flags.DemodFinished = 0; - + uint16_t DemodByteCount = ByteCount; uint16_t AppReceivedByteCount = 0; bool bDualSubcarrier = false; - + if (DemodByteCount > 0) { if (CodecBuffer[0] & ISO15693_REQ_SUBCARRIER_DUAL) @@ -531,13 +531,13 @@ void ISO15693CodecTask(void) } else { ApplicationReset(); } - + //This is only reached when we've received a valid frame if (AppReceivedByteCount > 0) { LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount); CodecBufferPtr = CodecBuffer; ByteCount = AppReceivedByteCount; - + CodecStartSubcarrier(); /* Start loadmodulating */ @@ -548,7 +548,7 @@ void ISO15693CodecTask(void) StateRegister = LOADMOD_START_SINGLE; CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_1); } - + } else { /* No data to be processed. Disable T1 waiting and * start listening again */ @@ -557,7 +557,7 @@ void ISO15693CodecTask(void) StartISO15693Demod(); } } - + if (Flags.LoadmodFinished) { Flags.LoadmodFinished = 0; /* Load modulation has been finished. Stop it and start to listen diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c index 35b0de5..df5a1ff 100644 --- a/Firmware/Chameleon-Mini/Configuration.c +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -38,19 +38,19 @@ static const MapEntryType PROGMEM ConfigurationMap[] = { { .Id = CONFIG_ISO14443A_READER, .Text = "ISO14443A_READER" }, #endif #ifdef CONFIG_VICINITY_SUPPORT - { .Id = CONFIG_VICINITY, .Text = "VICINITY" }, + { .Id = CONFIG_VICINITY, .Text = "VICINITY" }, #endif #ifdef CONFIG_ISO15693_SNIFF_SUPPORT - { .Id = CONFIG_ISO15693_SNIFF, .Text = "ISO15693_SNIFF" }, + { .Id = CONFIG_ISO15693_SNIFF, .Text = "ISO15693_SNIFF" }, #endif #ifdef CONFIG_SL2S2002_SUPPORT - { .Id = CONFIG_SL2S2002, .Text = "SL2S2002" }, + { .Id = CONFIG_SL2S2002, .Text = "SL2S2002" }, #endif #ifdef CONFIG_TITAGITSTANDARD_SUPPORT - { .Id = CONFIG_TITAGITSTANDARD, .Text = "TITAGITSTANDARD" }, + { .Id = CONFIG_TITAGITSTANDARD, .Text = "TITAGITSTANDARD" }, #endif #ifdef CONFIG_EM4233_SUPPORT - { .Id = CONFIG_EM4233, .Text = "EM4233" }, + { .Id = CONFIG_EM4233, .Text = "EM4233" }, #endif }; @@ -85,7 +85,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = 0, .MemorySize = 0, .ReadOnly = true, - .TagFamily = TAG_FAMILY_NONE + .TagFamily = TAG_FAMILY_NONE }, #ifdef CONFIG_MF_ULTRALIGHT_SUPPORT [CONFIG_MF_ULTRALIGHT] = { @@ -102,7 +102,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = MIFARE_ULTRALIGHT_UID_SIZE, .MemorySize = MIFARE_ULTRALIGHT_MEM_SIZE, .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO14443A + .TagFamily = TAG_FAMILY_ISO14443A }, [CONFIG_MF_ULTRALIGHT_EV1_80B] = { .CodecInitFunc = ISO14443ACodecInit, @@ -118,7 +118,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = MIFARE_ULTRALIGHT_UID_SIZE, .MemorySize = MIFARE_ULTRALIGHT_EV11_MEM_SIZE, .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO14443A + .TagFamily = TAG_FAMILY_ISO14443A }, [CONFIG_MF_ULTRALIGHT_EV1_164B] = { .CodecInitFunc = ISO14443ACodecInit, @@ -134,7 +134,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = MIFARE_ULTRALIGHT_UID_SIZE, .MemorySize = MIFARE_ULTRALIGHT_EV12_MEM_SIZE, .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO14443A + .TagFamily = TAG_FAMILY_ISO14443A }, #endif #ifdef CONFIG_MF_CLASSIC_1K_SUPPORT @@ -152,7 +152,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = MIFARE_CLASSIC_UID_SIZE, .MemorySize = MIFARE_CLASSIC_1K_MEM_SIZE, .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO14443A + .TagFamily = TAG_FAMILY_ISO14443A }, #endif #ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT @@ -170,7 +170,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = ISO14443A_UID_SIZE_DOUBLE, .MemorySize = MIFARE_CLASSIC_1K_MEM_SIZE, .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO14443A + .TagFamily = TAG_FAMILY_ISO14443A }, #endif #ifdef CONFIG_MF_CLASSIC_4K_SUPPORT @@ -188,7 +188,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = MIFARE_CLASSIC_UID_SIZE, .MemorySize = MIFARE_CLASSIC_4K_MEM_SIZE, .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO14443A + .TagFamily = TAG_FAMILY_ISO14443A }, #endif #ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT @@ -206,7 +206,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = ISO14443A_UID_SIZE_DOUBLE, .MemorySize = MIFARE_CLASSIC_4K_MEM_SIZE, .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO14443A + .TagFamily = TAG_FAMILY_ISO14443A }, #endif #ifdef CONFIG_ISO14443A_SNIFF_SUPPORT @@ -224,7 +224,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = 0, .MemorySize = 0, .ReadOnly = true, - .TagFamily = TAG_FAMILY_NONE + .TagFamily = TAG_FAMILY_NONE }, #endif #ifdef CONFIG_ISO14443A_READER_SUPPORT @@ -242,97 +242,97 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .UidSize = 0, .MemorySize = 0, .ReadOnly = false, - .TagFamily = TAG_FAMILY_NONE + .TagFamily = TAG_FAMILY_NONE }, #endif #ifdef CONFIG_VICINITY_SUPPORT [CONFIG_VICINITY] = { - .CodecInitFunc = ISO15693CodecInit, - .CodecDeInitFunc = ISO15693CodecDeInit, - .CodecTaskFunc = ISO15693CodecTask, - .ApplicationInitFunc = VicinityAppInit, - .ApplicationResetFunc = VicinityAppReset, - .ApplicationTaskFunc = VicinityAppTask, - .ApplicationTickFunc = VicinityAppTick, - .ApplicationProcessFunc = VicinityAppProcess, - .ApplicationGetUidFunc = VicinityGetUid, - .ApplicationSetUidFunc = VicinitySetUid, - .UidSize = ISO15693_GENERIC_UID_SIZE, - .MemorySize = ISO15693_GENERIC_MEM_SIZE, - .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO15693 + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = VicinityAppInit, + .ApplicationResetFunc = VicinityAppReset, + .ApplicationTaskFunc = VicinityAppTask, + .ApplicationTickFunc = VicinityAppTick, + .ApplicationProcessFunc = VicinityAppProcess, + .ApplicationGetUidFunc = VicinityGetUid, + .ApplicationSetUidFunc = VicinitySetUid, + .UidSize = ISO15693_GENERIC_UID_SIZE, + .MemorySize = ISO15693_GENERIC_MEM_SIZE, + .ReadOnly = false, + .TagFamily = TAG_FAMILY_ISO15693 }, #endif #ifdef CONFIG_ISO15693_SNIFF_SUPPORT [CONFIG_ISO15693_SNIFF] = { - .CodecInitFunc = ISO15693CodecInit, - .CodecDeInitFunc = ISO15693CodecDeInit, - .CodecTaskFunc = ISO15693CodecTask, - .ApplicationInitFunc = ApplicationInitDummy, - .ApplicationResetFunc = ApplicationResetDummy, - .ApplicationTaskFunc = ApplicationTaskDummy, - .ApplicationTickFunc = ApplicationTickDummy, - .ApplicationProcessFunc = ApplicationProcessDummy, - .ApplicationGetUidFunc = ApplicationGetUidDummy, - .ApplicationSetUidFunc = ApplicationSetUidDummy, - .UidSize = 0, - .MemorySize = 0, - .ReadOnly = true, - .TagFamily = TAG_FAMILY_NONE + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = ApplicationInitDummy, + .ApplicationResetFunc = ApplicationResetDummy, + .ApplicationTaskFunc = ApplicationTaskDummy, + .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationProcessFunc = ApplicationProcessDummy, + .ApplicationGetUidFunc = ApplicationGetUidDummy, + .ApplicationSetUidFunc = ApplicationSetUidDummy, + .UidSize = 0, + .MemorySize = 0, + .ReadOnly = true, + .TagFamily = TAG_FAMILY_NONE }, #endif #ifdef CONFIG_SL2S2002_SUPPORT [CONFIG_SL2S2002] = { - .CodecInitFunc = ISO15693CodecInit, - .CodecDeInitFunc = ISO15693CodecDeInit, - .CodecTaskFunc = ISO15693CodecTask, - .ApplicationInitFunc = Sl2s2002AppInit, - .ApplicationResetFunc = Sl2s2002AppReset, - .ApplicationTaskFunc = Sl2s2002AppTask, - .ApplicationTickFunc = Sl2s2002AppTick, - .ApplicationProcessFunc = Sl2s2002AppProcess, - .ApplicationGetUidFunc = Sl2s2002GetUid, - .ApplicationSetUidFunc = Sl2s2002SetUid, - .UidSize = ISO15693_GENERIC_UID_SIZE, - .MemorySize = ISO15693_GENERIC_MEM_SIZE, - .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO15693 + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = Sl2s2002AppInit, + .ApplicationResetFunc = Sl2s2002AppReset, + .ApplicationTaskFunc = Sl2s2002AppTask, + .ApplicationTickFunc = Sl2s2002AppTick, + .ApplicationProcessFunc = Sl2s2002AppProcess, + .ApplicationGetUidFunc = Sl2s2002GetUid, + .ApplicationSetUidFunc = Sl2s2002SetUid, + .UidSize = ISO15693_GENERIC_UID_SIZE, + .MemorySize = ISO15693_GENERIC_MEM_SIZE, + .ReadOnly = false, + .TagFamily = TAG_FAMILY_ISO15693 }, #endif #ifdef CONFIG_TITAGITSTANDARD_SUPPORT [CONFIG_TITAGITSTANDARD] = { - .CodecInitFunc = ISO15693CodecInit, - .CodecDeInitFunc = ISO15693CodecDeInit, - .CodecTaskFunc = ISO15693CodecTask, - .ApplicationInitFunc = TITagitstandardAppInit, - .ApplicationResetFunc = TITagitstandardAppReset, - .ApplicationTaskFunc = TITagitstandardAppTask, - .ApplicationTickFunc = TITagitstandardAppTick, - .ApplicationProcessFunc = TITagitstandardAppProcess, - .ApplicationGetUidFunc = TITagitstandardGetUid, - .ApplicationSetUidFunc = TITagitstandardSetUid, - .UidSize = TITAGIT_STD_UID_SIZE, - .MemorySize = TITAGIT_STD_MEM_SIZE, - .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO15693 + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = TITagitstandardAppInit, + .ApplicationResetFunc = TITagitstandardAppReset, + .ApplicationTaskFunc = TITagitstandardAppTask, + .ApplicationTickFunc = TITagitstandardAppTick, + .ApplicationProcessFunc = TITagitstandardAppProcess, + .ApplicationGetUidFunc = TITagitstandardGetUid, + .ApplicationSetUidFunc = TITagitstandardSetUid, + .UidSize = TITAGIT_STD_UID_SIZE, + .MemorySize = TITAGIT_STD_MEM_SIZE, + .ReadOnly = false, + .TagFamily = TAG_FAMILY_ISO15693 }, #endif #ifdef CONFIG_EM4233_SUPPORT [CONFIG_EM4233] = { - .CodecInitFunc = ISO15693CodecInit, - .CodecDeInitFunc = ISO15693CodecDeInit, - .CodecTaskFunc = ISO15693CodecTask, - .ApplicationInitFunc = EM4233AppInit, - .ApplicationResetFunc = EM4233AppReset, - .ApplicationTaskFunc = EM4233AppTask, - .ApplicationTickFunc = EM4233AppTick, - .ApplicationProcessFunc = EM4233AppProcess, - .ApplicationGetUidFunc = EM4233GetUid, - .ApplicationSetUidFunc = EM4233SetUid, - .UidSize = EM4233_STD_UID_SIZE, - .MemorySize = EM4233_STD_MEM_SIZE, - .ReadOnly = false, - .TagFamily = TAG_FAMILY_ISO15693 + .CodecInitFunc = ISO15693CodecInit, + .CodecDeInitFunc = ISO15693CodecDeInit, + .CodecTaskFunc = ISO15693CodecTask, + .ApplicationInitFunc = EM4233AppInit, + .ApplicationResetFunc = EM4233AppReset, + .ApplicationTaskFunc = EM4233AppTask, + .ApplicationTickFunc = EM4233AppTick, + .ApplicationProcessFunc = EM4233AppProcess, + .ApplicationGetUidFunc = EM4233GetUid, + .ApplicationSetUidFunc = EM4233SetUid, + .UidSize = EM4233_STD_UID_SIZE, + .MemorySize = EM4233_STD_MEM_SIZE, + .ReadOnly = false, + .TagFamily = TAG_FAMILY_ISO15693 }, #endif }; From 9ba4f75b66711d0b32bc5acefe71893876a167e4 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Tue, 25 Dec 2018 13:46:30 +0100 Subject: [PATCH 54/67] Current codec status, not working after APP_NO_RESPONSE --- .../Chameleon-Mini/Application/Vicinity.h | 3 -- Firmware/Chameleon-Mini/Codec/ISO15693.c | 44 ++++++++++--------- Firmware/Chameleon-Mini/Codec/ISO15693.h | 5 --- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/Vicinity.h b/Firmware/Chameleon-Mini/Application/Vicinity.h index 797ff01..7f19a91 100644 --- a/Firmware/Chameleon-Mini/Application/Vicinity.h +++ b/Firmware/Chameleon-Mini/Application/Vicinity.h @@ -11,9 +11,6 @@ #include "Application.h" #include "ISO15693-A.h" -#define ISO15693_GENERIC_UID_SIZE 8 //ISO15693_UID_SIZE -#define ISO15693_GENERIC_MEM_SIZE 8192 //ISO15693_MAX_MEM_SIZE - void VicinityAppInit(void); void VicinityAppReset(void); void VicinityAppTask(void); diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index bab785d..8679dc2 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -94,13 +94,13 @@ void isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void) INLINE void ISO15693_EOC(void) { - BitRate1 = 256 * 4; + BitRate1 = 256 * 4; // 256 * 4 - 1 if (CodecBuffer[0] & ISO15693_REQ_DATARATE_HIGH) BitRate1 = 256; if (CodecBuffer[0] & ISO15693_REQ_SUBCARRIER_DUAL) { - BitRate2 = 252 * 4; + BitRate2 = 252 * 4; // 252 * 4 - 3 if (CodecBuffer[0] & ISO15693_REQ_DATARATE_HIGH) BitRate2 = 252; } else { @@ -254,10 +254,10 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) } LOADMOD_START_SINGLE_LABEL: - CodecStartSubcarrier(); + /* Application produced data. With this interrupt we are aligned to the bit-grid. */ ShiftRegister = SOF_PATTERN; BitSent = 0; - // fallthrough + /* Fallthrough */ LOADMOD_SOF_SINGLE_LABEL: if (ShiftRegister & 0x80) { CodecSetLoadmodState(true); @@ -265,6 +265,8 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) CodecSetLoadmodState(false); } + CodecStartSubcarrier(); + ShiftRegister <<= 1; BitSent++; @@ -335,10 +337,10 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) // ------------------------------------------------------------- LOADMOD_START_DUAL_LABEL: - CodecStartSubcarrier(); ShiftRegister = SOF_PATTERN; BitSent = 0; CodecSetLoadmodState(true); + CodecStartSubcarrier(); // fallthrough LOADMOD_SOF_DUAL_LABEL: if (ShiftRegister & 0x80) { @@ -433,7 +435,7 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) #endif /* CONFIG_VICINITY_SUPPORT */ void StartISO15693Demod(void) { - + CodecBufferPtr = CodecBuffer; Flags.DemodFinished = 0; Flags.LoadmodFinished = 0; @@ -445,7 +447,8 @@ void StartISO15693Demod(void) { ModulationPauseCount = 0; ByteCount = 0; ShiftRegister = 0; - + + /* Activate Power for demodulator */ CodecSetDemodPower(true); /* Configure sampling-timer free running and sync to first modulation-pause. */ @@ -521,39 +524,38 @@ void ISO15693CodecTask(void) if (DemodByteCount > 0) { + LogEntry(LOG_INFO_CODEC_RX_DATA, CodecBuffer, DemodByteCount); + LEDHook(LED_CODEC_RX, LED_PULSE); + if (CodecBuffer[0] & ISO15693_REQ_SUBCARRIER_DUAL) { bDualSubcarrier = true; } - LogEntry(LOG_INFO_CODEC_RX_DATA, CodecBuffer, DemodByteCount); AppReceivedByteCount = ApplicationProcess(CodecBuffer, DemodByteCount); - - } else { - ApplicationReset(); } - //This is only reached when we've received a valid frame - if (AppReceivedByteCount > 0) { + /* 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); - CodecBufferPtr = CodecBuffer; - ByteCount = AppReceivedByteCount; + LEDHook(LED_CODEC_TX, LED_PULSE); - CodecStartSubcarrier(); + ByteCount = AppReceivedByteCount; + CodecBufferPtr = CodecBuffer; /* Start loadmodulating */ if (bDualSubcarrier) { - StateRegister = LOADMOD_START_DUAL; CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_2); + StateRegister = LOADMOD_START_DUAL; } else { - StateRegister = LOADMOD_START_SINGLE; CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_1); + StateRegister = LOADMOD_START_SINGLE; } } else { - /* No data to be processed. Disable T1 waiting and - * start listening again */ + /* No data to be processed. Disable T1 waiting and start listening again */ CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; - CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_OFF_gc; + CODEC_TIMER_LOADMOD.INTCTRLB = 0; + StartISO15693Demod(); } } diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.h b/Firmware/Chameleon-Mini/Codec/ISO15693.h index 93162d7..6c2e01b 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.h +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.h @@ -12,11 +12,6 @@ #define ISO15693_APP_NO_RESPONSE 0x0000 -/* VERY OUTDATED */ -#define TIMER_SAMPLING TCC0 -#define TIMER_T1_BITRATE TCD1 -#define TIMER_SUBCARRIER TCD0 - #define SUBCARRIER_1 32 #define SUBCARRIER_2 28 #define SUBCARRIER_OFF 0 From e92b3588e0b88f216b2d79c017f34b0fda7d024c Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Wed, 26 Dec 2018 00:53:17 +0100 Subject: [PATCH 55/67] Resetting LoadModState to avoid erratic behaviour --- Firmware/Chameleon-Mini/Codec/ISO15693.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index 8679dc2..6d1f706 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -440,6 +440,7 @@ void StartISO15693Demod(void) { Flags.DemodFinished = 0; Flags.LoadmodFinished = 0; DemodState = DEMOD_SOC_STATE; + LoadModState = LOADMOD_WAIT; DataRegister = 0; SampleRegister = 0; BitSampleCount = 0; @@ -489,6 +490,7 @@ void ISO15693CodecDeInit(void) Flags.DemodFinished = 0; Flags.LoadmodFinished = 0; DemodState = DEMOD_SOC_STATE; + LoadModState = LOADMOD_WAIT; DataRegister = 0; SampleRegister = 0; BitSampleCount = 0; From 9a0ee807aac9a271b1510d225794d8e672b448c7 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Wed, 26 Dec 2018 18:06:10 +0100 Subject: [PATCH 56/67] Added comments and fixed a bug in codec's source ISO15693 codec was undocumented and without comments in relevant parts. I decided to spend 3 days diving into XMega interrupts and Chameleon's lowest level code. Now, I hope, it should be more readable for everyone, even newbies like my old self was before I started this deep dive. Also, I fixed the bug referenced here https://github.com/geo-rg/ChameleonMini/issues/4 which locked the chameleon when no response was to be sent to the reader --- Firmware/Chameleon-Mini/Codec/ISO15693.c | 154 ++++++++++++++++++----- 1 file changed, 121 insertions(+), 33 deletions(-) diff --git a/Firmware/Chameleon-Mini/Codec/ISO15693.c b/Firmware/Chameleon-Mini/Codec/ISO15693.c index 6d1f706..e1aa507 100644 --- a/Firmware/Chameleon-Mini/Codec/ISO15693.c +++ b/Firmware/Chameleon-Mini/Codec/ISO15693.c @@ -3,6 +3,7 @@ * * Created on: 25.01.2017 * Author: Phillip Nash + * Modified by: ceres-c */ #include "ISO15693.h" @@ -81,19 +82,33 @@ static volatile uint16_t ReadCommandFromReader = 0; #ifdef CONFIG_VICINITY_SUPPORT -// Started when a single pulse has been detected -// ISR(CODEC_DEMOD_IN_INT0_VECT) +/* This function implements CODEC_DEMOD_IN_INT0_VECT interrupt vector. + * It is called when a pulse is detected in CODEC_DEMOD_IN_PORT (PORTB). + * The relevatn interrupt vector is registered to CODEC_DEMOD_IN_MASK0 (PIN1) via: + * CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; + * and unregistered writing the INT0MASK to 0 + */ +// ISR(CODEC_DEMOD_IN_INT0_VECT) void isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void) { - // Start sample timer + /* Start sample timer CODEC_TIMER_SAMPLING (TCD0). + * Set Counter Channel C (CCC) with relevant bitmask (TC0_CCCIF_bm), + * the period for clock sampling is specified in StartISO15693Demod. + */ CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm; + /* Sets register INTCTRLB to TC_CCCINTLVL_HI_gc = (0x03<<4) to enable compare/capture for high level interrupts on Channel C (CCC) */ CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_HI_gc; - /* Disable this interrupt */ + + /* Disable this interrupt as we've already sensed the relevant pulse and will use our internal clock from now on */ CODEC_DEMOD_IN_PORT.INT0MASK = 0; } +/* This function is called from isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT + * when we have 8 bits in SampleRegister and they represent an end of frame. + */ INLINE void ISO15693_EOC(void) { + /* Set bitrate required by the reader on SOF for our following response */ BitRate1 = 256 * 4; // 256 * 4 - 1 if (CodecBuffer[0] & ISO15693_REQ_DATARATE_HIGH) BitRate1 = 256; @@ -107,18 +122,35 @@ INLINE void ISO15693_EOC(void) BitRate2 = BitRate1; } - CODEC_TIMER_LOADMOD.CTRLD = 0; - CODEC_TIMER_LOADMOD.INTFLAGS = TC0_CCBIF_bm; + /* Disable event action for CODEC_TIMER_LOADMOD (TCE0) as we're done receiving data */ + CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; + /* Set Counter Channel B (CCB) with relevant bitmask (TC0_CCBIF_bm), the period for clock sampling is specified below */ + CODEC_TIMER_LOADMOD.INTFLAGS = TC0_CCBIF_bm; // TODO This might not be needed since commenting it does not break anything + /* Sets register INTCTRLB to TC_CCBINTLVL_HI_gc = (0x03<<2) to enable compare/capture for high level interrupts on channel B */ CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_HI_gc; + /* Set the period for CODEC_TIMER_LOADMOD (TCE0) to Bitrate - 1 because PERBUF is 0-based + * + * TODO Why are we using PERBUF instead of PER? + * With PERBUF the period register will occur on the next overflow. + */ CODEC_TIMER_LOADMOD.PERBUF = BitRate1 - 1; Flags.DemodFinished = 1; + /* Sets timer off for CODEC_TIMER_SAMPLING (TCD0) disabling clock source */ CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + /* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */ CODEC_TIMER_SAMPLING.INTCTRLB = 0; } +/* This function is registered to CODEC_TIMER_SAMPLING (TCD0)'s Counter Channel C (CCC). + * When the timer is enabled, this is called on counter's overflow + * + * It demodulates bits received from the reader and saves them in CodecBuffer. + * + * It disables its own interrupt when receives an EOF (calling ISO15693_EOC) or when it receives garbage + */ // ISR(CODEC_TIMER_SAMPLING_CCC_VECT) // Reading data sent from the reader -void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) +void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) { /* Shift demod data */ SampleRegister = (SampleRegister << 1) | (!(CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK) ? 0x01 : 0x00); @@ -137,9 +169,11 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) } else if (SampleRegister == SOC_1_OF_256_CODE) { DemodState = DEMOD_1_OUT_OF_256_STATE; SampleDataCount = 0; - } else { // No SOC. Restart and try again + } else { // No SOC. Restart and try again, we probably received garbage. Flags.DemodFinished = 1; + /* Sets timer off for CODEC_TIMER_SAMPLING (TCD0) disabling clock source */ CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + /* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */ CODEC_TIMER_SAMPLING.INTCTRLB = 0; } break; @@ -230,21 +264,28 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) } +/* This function is registered to CODEC_TIMER_LOADMOD (TCE0)'s Counter Channel B (CCB). + * When the timer is enabled, this is called on counter's overflow + * + * It modulates the carrier with consuming bytes in CodecBuffer until ByteCount is 0. + * + * It disables its own interrupt when all data has been sent + */ //ISR(CODEC_TIMER_LOADMOD_CCB_VECT) void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) { static void* JumpTable[] = { - [LOADMOD_START_SINGLE] = &&LOADMOD_START_SINGLE_LABEL, - [LOADMOD_SOF_SINGLE] = &&LOADMOD_SOF_SINGLE_LABEL, - [LOADMOD_BIT0_SINGLE] = &&LOADMOD_BIT0_SINGLE_LABEL, - [LOADMOD_BIT1_SINGLE] = &&LOADMOD_BIT1_SINGLE_LABEL, - [LOADMOD_EOF_SINGLE] = &&LOADMOD_EOF_SINGLE_LABEL, - [LOADMOD_START_DUAL] = &&LOADMOD_START_DUAL_LABEL, - [LOADMOD_SOF_DUAL] = &&LOADMOD_SOF_DUAL_LABEL, - [LOADMOD_BIT0_DUAL] = &&LOADMOD_BIT0_DUAL_LABEL, - [LOADMOD_BIT1_DUAL] = &&LOADMOD_BIT1_DUAL_LABEL, - [LOADMOD_EOF_DUAL] = &&LOADMOD_EOF_DUAL_LABEL, - [LOADMOD_FINISHED] = &&LOADMOD_FINISHED_LABEL + [LOADMOD_START_SINGLE] = &&LOADMOD_START_SINGLE_LABEL, + [LOADMOD_SOF_SINGLE] = &&LOADMOD_SOF_SINGLE_LABEL, + [LOADMOD_BIT0_SINGLE] = &&LOADMOD_BIT0_SINGLE_LABEL, + [LOADMOD_BIT1_SINGLE] = &&LOADMOD_BIT1_SINGLE_LABEL, + [LOADMOD_EOF_SINGLE] = &&LOADMOD_EOF_SINGLE_LABEL, + [LOADMOD_START_DUAL] = &&LOADMOD_START_DUAL_LABEL, + [LOADMOD_SOF_DUAL] = &&LOADMOD_SOF_DUAL_LABEL, + [LOADMOD_BIT0_DUAL] = &&LOADMOD_BIT0_DUAL_LABEL, + [LOADMOD_BIT1_DUAL] = &&LOADMOD_BIT1_DUAL_LABEL, + [LOADMOD_EOF_DUAL] = &&LOADMOD_EOF_DUAL_LABEL, + [LOADMOD_FINISHED] = &&LOADMOD_FINISHED_LABEL }; if ( (StateRegister >= LOADMOD_START_SINGLE) && (StateRegister <= LOADMOD_FINISHED) ) { @@ -255,7 +296,7 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) LOADMOD_START_SINGLE_LABEL: /* Application produced data. With this interrupt we are aligned to the bit-grid. */ - ShiftRegister = SOF_PATTERN; + ShiftRegister = SOF_PATTERN; BitSent = 0; /* Fallthrough */ LOADMOD_SOF_SINGLE_LABEL: @@ -425,22 +466,25 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) return; LOADMOD_FINISHED_LABEL: + /* Sets timer off for CODEC_TIMER_LOADMOD (TCE0) disabling clock source as we're done modulating */ CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + /* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */ CODEC_TIMER_LOADMOD.INTCTRLB = 0; - CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, SUBCARRIER_1); + CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, 0); Flags.LoadmodFinished = 1; return; } #endif /* CONFIG_VICINITY_SUPPORT */ +/* This functions resets all global variables used in the codec and enables interrupts to wait for reader data */ void StartISO15693Demod(void) { - + /* Reset global variables to default values */ CodecBufferPtr = CodecBuffer; Flags.DemodFinished = 0; Flags.LoadmodFinished = 0; DemodState = DEMOD_SOC_STATE; - LoadModState = LOADMOD_WAIT; + StateRegister = LOADMOD_WAIT; DataRegister = 0; SampleRegister = 0; BitSampleCount = 0; @@ -453,31 +497,66 @@ void StartISO15693Demod(void) { CodecSetDemodPower(true); /* Configure sampling-timer free running and sync to first modulation-pause. */ + /* Resets the counter to 0 */ CODEC_TIMER_SAMPLING.CNT = 0; - CODEC_TIMER_SAMPLING.PER = ISO15693_SAMPLE_PERIOD - 1; - CODEC_TIMER_SAMPLING.CCC = ISO15693_SAMPLE_PERIOD / 2 - 14 - 1; /* Half bit. ISR compensate*/ + /* Set the period for CODEC_TIMER_SAMPLING (TCD0) to ISO15693_SAMPLE_PERIOD - 1 because PER is 0-based */ + CODEC_TIMER_SAMPLING.PER = ISO15693_SAMPLE_PERIOD - 1; + /* Set Counter Channel C (CCC) register with half bit period - 1. (- 14 to compensate ISR timing overhead) */ + CODEC_TIMER_SAMPLING.CCC = ISO15693_SAMPLE_PERIOD / 2 - 14 - 1; + /* Set timer for CODEC_TIMER_SAMPLING (TCD0) to ISO15693_SAMPLE_CLK = TC_CLKSEL_DIV2_gc = System Clock / 2 + * + * TODO Why system clock / 2 and not iso period? + */ CODEC_TIMER_SAMPLING.CTRLA = ISO15693_SAMPLE_CLK; + /* Set event action for CODEC_TIMER_SAMPLING (TCD0) to restart and trigger CODEC_TIMER_MODSTART_EVSEL = TC_EVSEL_CH0_gc = Event Channel 0 */ CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL; + /* Set Counter Channel C (CCC) with relevant bitmask (TC0_CCCIF_bm), the period for clock sampling is specified above */ CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm; + /* Sets register INTCTRLB to TC_CCCINTLVL_OFF_gc = (0x00<<4) to disable compare/capture C interrupts + * + * TODO Why turn it off? + */ CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc; + /* Set event action for CODEC_TIMER_LOADMOD (TCE0) to restart and trigger CODEC_TIMER_MODSTART_EVSEL = TC_EVSEL_CH0_gc = Event Channel 0 */ CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL; - CODEC_TIMER_LOADMOD.PER = 4192 + 128 + 128 - 1; + /* Set the period for CODEC_TIMER_LOADMOD (TCE0) to... some magic numbers? + * Using PER instead of PERBUF breaks it when receiving ISO15693_APP_NO_RESPONSE from Application. + * + * TODO What are these numbers? + */ + CODEC_TIMER_LOADMOD.PERBUF = 4192 + 128 + 128 - 1; + /* Sets register INTCTRLA to 0 to disable timer error or overflow interrupts */ CODEC_TIMER_LOADMOD.INTCTRLA = 0; + /* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */ CODEC_TIMER_LOADMOD.INTCTRLB = 0; + /* Set timer for CODEC_TIMER_SAMPLING (TCD0) to TC_CLKSEL_EVCH6_gc = Event Channel 6 */ CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_EVCH6_gc; /* Start looking out for modulation pause via interrupt. */ - CODEC_DEMOD_IN_PORT.INTFLAGS = 0x03; + /* Sets register INTFLAGS to PORT_INT0LVL_HI_gc = (0x03<<0) to enable compare/capture for high level interrupts on CODEC_DEMOD_IN_PORT (PORTB) */ + CODEC_DEMOD_IN_PORT.INTFLAGS = PORT_INT0LVL_HI_gc; + /* Sets INT0MASK to CODEC_DEMOD_IN_MASK0 = PIN1_bm to use it as source for port interrupt 0 */ CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0; } void ISO15693CodecInit(void) { CodecInitCommon(); + + /* Register isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT function + * to CODEC_TIMER_SAMPLING (TCD0)'s Counter Channel C (CCC) + */ isr_func_TCD0_CCC_vect = &isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT; + /* Register isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT function + * to CODEC_DEMOD_IN_PORT (PORTB) interrupt 0 + */ isr_func_CODEC_DEMOD_IN_INT0_VECT = &isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT; + /* Register isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT function + * to CODEC_TIMER_LOADMOD (TCE0)'s Counter Channel B (CCB) + */ isr_func_CODEC_TIMER_LOADMOD_CCB_VECT = &isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT; + StartISO15693Demod(); } @@ -486,11 +565,12 @@ void ISO15693CodecDeInit(void) /* Gracefully shutdown codec */ CODEC_DEMOD_IN_PORT.INT0MASK = 0; + /* Reset global variables to default values */ CodecBufferPtr = CodecBuffer; Flags.DemodFinished = 0; Flags.LoadmodFinished = 0; DemodState = DEMOD_SOC_STATE; - LoadModState = LOADMOD_WAIT; + StateRegister = LOADMOD_WAIT; DataRegister = 0; SampleRegister = 0; BitSampleCount = 0; @@ -499,15 +579,22 @@ void ISO15693CodecDeInit(void) ByteCount = 0; ShiftRegister = 0; - //Disable sample timer + /* Disable sample timer */ + /* Sets timer off for CODEC_TIMER_SAMPLING (TCD0) disabling clock source */ CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc; + /* Disable event action for CODEC_TIMER_SAMPLING (TCD0) */ CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc; + /* Sets register INTCTRLB to TC_CCCINTLVL_OFF_gc = (0x00<<4) to disable compare/capture C interrupts */ CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc; + /* Restore Counter Channel C (CCC) interrupt mask (TC0_CCCIF_bm) */ CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm; - //Disable load modulation + /* Disable load modulation */ + /* Disable event action for CODEC_TIMER_LOADMOD (TCE0) */ CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc; + /* Sets register INTCTRLB to TC_CCBINTLVL_OFF_gc = (0x00<<2) to disable compare/capture B interrupts */ CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_OFF_gc; + /* Restore Counter Channel B (CCB) interrupt mask (TC0_CCBIF_bm) */ CODEC_TIMER_LOADMOD.INTFLAGS = TC0_CCBIF_bm; CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, 0); @@ -554,8 +641,10 @@ void ISO15693CodecTask(void) } } else { - /* No data to be processed. Disable T1 waiting and start listening again */ + /* No data to process. Disable CODEC_TIMER_LOADMOD (TCE0) counter and start listening again */ + /* Sets timer off for CODEC_TIMER_LOADMOD (TCE0) disabling clock source as we're done modulating */ CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc; + /* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */ CODEC_TIMER_LOADMOD.INTCTRLB = 0; StartISO15693Demod(); @@ -564,8 +653,7 @@ void ISO15693CodecTask(void) if (Flags.LoadmodFinished) { Flags.LoadmodFinished = 0; - /* Load modulation has been finished. Stop it and start to listen - * for incoming data again. */ + /* Load modulation has been finished. Stop it and start to listen for incoming data again. */ StartISO15693Demod(); } } From ab1fdddb16ec655733f6d831c28d359b07c265b9 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Wed, 26 Dec 2018 23:13:57 +0100 Subject: [PATCH 57/67] Removed old LockBit masks and updated a couple of commands to mimick real tag behaviour --- Firmware/Chameleon-Mini/Application/EM4233.c | 171 +++++++++--------- .../Chameleon-Mini/Application/ISO15693-A.h | 1 + 2 files changed, 82 insertions(+), 90 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index 54a20f4..7cb4ce4 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -18,9 +18,6 @@ bool loggedIn; CurrentFrame FrameInfo; -uint64_t EM4233_FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ -uint64_t EM4233_UserLockBits_Mask = 0; /* Holds lock state of blocks */ - void EM4233AppInit(void) { State = STATE_READY; @@ -61,25 +58,28 @@ void EM4233AppTick(void) uint16_t EM4233_Lock_Block(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t PageAddress = *FrameInfo.Parameters; + uint8_t BlockAddress = *FrameInfo.Parameters; + uint8_t LockStatus = 0; + + MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + BlockAddress), 1); if (FrameInfo.ParamLen != 1) - return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ - if (PageAddress > EM4233_NUMBER_OF_BLCKS) { + if (BlockAddress > EM4233_NUMBER_OF_BLCKS) { // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; /* malformed: trying to lock a non-existing block */ } - if ((EM4233_FactoryLockBits_Mask & (uint64_t)(1 << PageAddress)) || (EM4233_UserLockBits_Mask & (uint64_t)(1 << PageAddress))) { /* if already locked */ - // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_ALRD_LKD; + + if (LockStatus > ISO15693_MASK_UNLOCKED) { /* LockStatus 0x00 represent unlocked block, greater values are different kind of locks */ ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ } else { - EM4233_UserLockBits_Mask |= (uint64_t)(1 << PageAddress); /* write the lock status in mask */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + LockStatus |= ISO15693_MASK_USER_LOCK; + MemoryWriteBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + BlockAddress), 1); /* write user lock in memory */ + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ } @@ -135,7 +135,7 @@ uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) if (PageAddress >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a sector out of bound */ // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } @@ -145,11 +145,11 @@ uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + PageAddress), 1); if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { /* tests if the n-th bit of the factory bitmask if set to 1 */ - FrameBuf[FramePtr] = 0x02; /* return bit 1 set as 1 (factory locked) */ + FrameBuf[FramePtr] = ISO15693_MASK_FACTORY_LOCK; /* return bit 1 set as 1 (factory locked) */ } else if (LockStatus & ISO15693_MASK_USER_LOCK) { /* tests if the n-th bit of the user bitmask if set to 1 */ - FrameBuf[FramePtr] = 0x01; /* return bit 0 set as 1 (user locked) */ + FrameBuf[FramePtr] = ISO15693_MASK_USER_LOCK; /* return bit 0 set as 1 (user locked) */ } else - FrameBuf[FramePtr] = 0x00; /* return lock status 00 (unlocked) */ + FrameBuf[FramePtr] = ISO15693_MASK_UNLOCKED; /* return lock status 00 (unlocked) */ FramePtr += 1; /* block's data from byte 2 */ ResponseByteCount += 1; } @@ -159,7 +159,7 @@ uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ ResponseByteCount += 1; - + return ResponseByteCount; } @@ -168,14 +168,14 @@ uint16_t EM4233_Read_Multiple(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t FramePtr; /* holds the address where block's data will be put */ uint8_t BlockAddress = FrameInfo.Parameters[0]; - uint8_t BlocksNumber = FrameInfo.Parameters[1] + 0x01; /* according to ISO standard, we have to read 8 blocks if we get 0x07 in request */ + uint8_t BlocksNumber = FrameInfo.Parameters[1] + 0x01; /* according to ISO standard, we have to read 0x08 blocks if we get 0x07 in request */ if (FrameInfo.ParamLen != 2) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ if (BlockAddress > EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a starting block out of bound */ // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } else if ((BlockAddress + BlocksNumber) >= EM4233_NUMBER_OF_BLCKS) { /* last block is out of bound */ @@ -191,7 +191,7 @@ uint16_t EM4233_Read_Multiple(uint8_t* FrameBuf, uint16_t FrameBytes) } else { /* we have to slice blocks' data with lock statuses */ uint8_t DataBuffer[ BlocksNumber * EM4233_BYTES_PER_BLCK ]; /* a temporary vector with blocks' content */ - uint8_t LockStatusBuffer[ BlocksNumber ]; /* a vector with blocks' lock status */ + uint8_t LockStatusBuffer[ BlocksNumber ]; /* a temporary vector with blocks' lock status */ /* read all at once to reduce timing issues */ MemoryReadBlock(&DataBuffer, BlockAddress * EM4233_BYTES_PER_BLCK, BlocksNumber * EM4233_BYTES_PER_BLCK); @@ -200,20 +200,15 @@ uint16_t EM4233_Read_Multiple(uint8_t* FrameBuf, uint16_t FrameBytes) for (uint8_t block = 0; block < BlocksNumber; block++) { /* we cycle through the blocks */ /* add lock status */ - if (LockStatusBuffer[block] & ISO15693_MASK_USER_LOCK) { /* tests if bit 0 of the status byte if set to 1 */ - FrameBuf[FramePtr] = 0x01; /* return bit 0 set as 1 (user locked) */ - } else if (LockStatusBuffer[block] & ISO15693_MASK_FACTORY_LOCK) { /* tests if bit 1 of the status byte if set to 1 */ - FrameBuf[FramePtr] = 0x02; /* return bit 1 set as 1 (factory locked) */ - } else - FrameBuf[FramePtr] = 0x00; /* return lock status 00 (unlocked) */ + FrameBuf[FramePtr++] = LockStatusBuffer[block]; /* Byte in dump equals to the byte that has to be sent */ + /* I.E. We store 0x01 to identify user lock, which is the same as what ISO15693 enforce */ ResponseByteCount += 1; - FramePtr += 1; /* then copy block's data */ - for (uint8_t byte = 0; byte < EM4233_BYTES_PER_BLCK; byte++) { /* we cycle through the bytes in every block */ - FrameBuf[FramePtr] = DataBuffer[block * EM4233_BYTES_PER_BLCK + byte]; /* to copy them in the frame from our temporary buffer */ - FramePtr += 1; - } + FrameBuf[FramePtr++] = DataBuffer[block * EM4233_BYTES_PER_BLCK + 0]; + FrameBuf[FramePtr++] = DataBuffer[block * EM4233_BYTES_PER_BLCK + 1]; + FrameBuf[FramePtr++] = DataBuffer[block * EM4233_BYTES_PER_BLCK + 2]; + FrameBuf[FramePtr++] = DataBuffer[block * EM4233_BYTES_PER_BLCK + 3]; ResponseByteCount += EM4233_BYTES_PER_BLCK; } } @@ -227,41 +222,44 @@ uint16_t EM4233_Write_AFI(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t AFI = FrameInfo.Parameters[0]; - uint8_t LockStatus = 0; + uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 1) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ MemoryReadBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); - if (LockStatus & EM4233_MASK_AFI_STATUS ) { /* The afi is locked */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; - ResponseByteCount += 2; + if (LockStatus & EM4233_MASK_AFI_STATUS ) { /* The AFI is locked */ + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + // ResponseByteCount += 2; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } MemoryWriteBlock(&AFI, EM4233_MEM_AFI_ADDRESS, 1); /* Actually write new AFI */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - ResponseByteCount += 1; + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + // ResponseByteCount += 1; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } uint16_t EM4233_Lock_AFI(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t LockStatus = 0; + uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 0) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ MemoryReadBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); - if (LockStatus & EM4233_MASK_AFI_STATUS ) { /* The afi is already locked */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; - ResponseByteCount += 2; + if (LockStatus & EM4233_MASK_AFI_STATUS ) { /* The AFI is already locked */ + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + // ResponseByteCount += 2; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } @@ -269,8 +267,9 @@ uint16_t EM4233_Lock_AFI(uint8_t* FrameBuf, uint16_t FrameBytes) MemoryWriteBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); /* Actually write new AFI */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - ResponseByteCount += 1; + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + // ResponseByteCount += 1; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } @@ -278,50 +277,54 @@ uint16_t EM4233_Write_DSFID(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t DSFID = FrameInfo.Parameters[0]; - uint8_t LockStatus = 0; + uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 1) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ MemoryReadBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); - if (LockStatus & EM4233_MASK_DSFID_STATUS ) { /* The afi is locked */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; - ResponseByteCount += 2; + if (LockStatus & EM4233_MASK_DSFID_STATUS ) { /* The DSFID is locked */ + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + // ResponseByteCount += 2; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } - MemoryWriteBlock(&DSFID, EM4233_MEM_DSFID_ADDRESS, 1); /* Actually write new AFI */ + MemoryWriteBlock(&DSFID, EM4233_MEM_DSFID_ADDRESS, 1); /* Actually write new DSFID */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - ResponseByteCount += 1; + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + // ResponseByteCount += 1; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } uint16_t EM4233_Lock_DSFID(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t LockStatus = 0; + uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 0) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ MemoryReadBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); - if (LockStatus & EM4233_MASK_DSFID_STATUS ) { /* The afi is already locked */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; - ResponseByteCount += 2; + if (LockStatus & EM4233_MASK_DSFID_STATUS ) { /* The DSFID is already locked */ + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + // ResponseByteCount += 2; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } LockStatus |= EM4233_MASK_DSFID_STATUS; - MemoryWriteBlock(*FrameInfo.Parameters, EM4233_MEM_INF_ADDRESS, 4); /* Actually write the new PASSWORD */ + MemoryWriteBlock(*FrameInfo.Parameters, EM4233_MEM_INF_ADDRESS, 4); /* Actually write the new DSFID */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - ResponseByteCount += 1; + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ + // ResponseByteCount += 1; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; } @@ -345,7 +348,7 @@ uint8_t EM4233_Get_SysInfo(uint8_t* FrameBuf, uint16_t FrameBytes) */ /* System info flags */ - FrameBuf[FramePtr] = EM4233_SYSINFO_BYTE; /* check pdf for this */ + FrameBuf[FramePtr] = EM4233_SYSINFO_BYTE; /* check EM4233SLIC datasheet for this */ FramePtr += 1; /* Move forward the buffer data pointer */ ResponseByteCount += 1; /* Increment the response count */ @@ -389,7 +392,7 @@ uint8_t EM4233_Get_SysInfo(uint8_t* FrameBuf, uint16_t FrameBytes) } FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - ResponseByteCount += 1; + ResponseByteCount += 1; return ResponseByteCount; } @@ -398,40 +401,28 @@ uint16_t EM4233_Get_Multi_Block_Sec_Stat(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t FramePtr; /* holds the address where block's data will be put */ uint8_t BlockAddress = FrameInfo.Parameters[0]; - uint8_t BlocksNumber = 0; - uint8_t LockStatus = 0; + uint8_t BlocksNumber = FrameInfo.Parameters[1] + 0x01; if (FrameInfo.ParamLen != 2) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ - BlocksNumber = FrameInfo.Parameters[1]; - - if (BlockAddress >= EM4233_NUMBER_OF_BLCKS || (BlockAddress + BlocksNumber) >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a sector out of bound */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; /* real TiTag standard reply with this error */ - ResponseByteCount += 2; + if (BlockAddress > EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a starting block out of bound */ + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; + ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; + } else if ((BlockAddress + BlocksNumber) >= EM4233_NUMBER_OF_BLCKS) { /* last block is out of bound */ + BlocksNumber = EM4233_NUMBER_OF_BLCKS - BlockAddress; /* we read up to latest block, as real tag does */ } - FramePtr = 1; /* Start of response data */ + FramePtr = 1; /* start of response data */ - for (uint8_t blk = 0; blk <= BlocksNumber; blk++) { - - MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + (BlockAddress + blk)), 1); - - if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { /* tests if the n-th bit of the factory bitmask if set to 1 */ - FrameBuf[FramePtr] = 0x02; /* return bit 1 set as 1 (factory locked) */ - } else if (LockStatus & ISO15693_MASK_USER_LOCK) { /* tests if the n-th bit of the user bitmask if set to 1 */ - FrameBuf[FramePtr] = 0x01; /* return bit 0 set as 1 (user locked) */ - } else - FrameBuf[FramePtr] = 0x00; /* return lock status 00 (unlocked) */ - - FramePtr += 1; /* Move forward the buffer data pointer */ - ResponseByteCount += 1; /* Increment the response count */ - } + /* read all at once to reduce timing issues */ + MemoryReadBlock(&FrameBuf[FramePtr], EM4233_MEM_LSM_ADDRESS + BlockAddress, BlocksNumber); + ResponseByteCount += BlocksNumber; FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - ResponseByteCount += 1; + ResponseByteCount += 1; return ResponseByteCount; } @@ -463,13 +454,13 @@ uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) return ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ } - return ISO15693_APP_NO_RESPONSE; + return ISO15693_APP_NO_RESPONSE; /* Just because you never know... */ } uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t Password[4] = { 0 }; + uint8_t Password[4] = { 0 }; if (FrameInfo.ParamLen != 4) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ @@ -489,10 +480,10 @@ uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) loggedIn = true; - MemoryWriteBlock(Password, EM4233_MEM_PSW_ADDRESS, 4); /* Actually write new AFI */ + MemoryWriteBlock(Password, EM4233_MEM_PSW_ADDRESS, 4); /* Store password in memory for retrival */ FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ - ResponseByteCount += 1; + ResponseByteCount += 1; return ResponseByteCount; } diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index ac8fc31..afe6691 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -76,6 +76,7 @@ * The byte used for the lock status has its bits addressed as follow: * */ +#define ISO15693_MASK_UNLOCKED ( 0 << 0 ) #define ISO15693_MASK_USER_LOCK ( 1 << 0 ) #define ISO15693_MASK_FACTORY_LOCK ( 1 << 1 ) From 9b5dfc2708dc690269e6d1790d8b0ead3984d48f Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 27 Dec 2018 00:16:34 +0100 Subject: [PATCH 58/67] Updated EM4233 header and example dump We thought that the user had access to 64 blocks, while in EM4233 factsheet it's stated that only 52 blocks are available --- Dumps/EM4233_example.dmp | Bin 352 -> 292 bytes Firmware/Chameleon-Mini/Application/EM4233.h | 23 ++++++++---------- .../Chameleon-Mini/Application/ISO15693-A.h | 5 +--- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Dumps/EM4233_example.dmp b/Dumps/EM4233_example.dmp index e9f4caaa5851d6022b8c6f217498f1dc7ec28296..4387c6ee17d99fcb848b2ae1fbf8e97a322d9b3d 100644 GIT binary patch delta 13 UcmaFBw1jEGg-MJqlLHt904Cc6v;Y7A delta 65 hcmZ3&^nhu?1p_5CV2lPB(7?nCE)zfSOcr4j006ZA3{wCA diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h index e1d370b..a7efbee 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.h +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -11,25 +11,24 @@ #include "Application.h" #define EM4233_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE -#define EM4233_STD_MEM_SIZE 208 // Bytes +#define EM4233_STD_MEM_SIZE 0xD0 // Bytes #define EM4233_BYTES_PER_BLCK 0x04 #define EM4233_BLCKS_PER_PAGE 0x04 #define EM4233_NUMBER_OF_BLCKS ( EM4233_STD_MEM_SIZE / EM4233_BYTES_PER_BLCK ) #define EM4233_NUMBER_OF_PAGES ( EM4233_STD_MEM_SIZE / (EM4233_BYTES_PER_BLCK * EM4233_BLCKS_PER_PAGE) ) -#define EM4233_IC_REFERENCE 0x02 +#define EM4233_IC_REFERENCE 0x02 // From EM4233SLIC datasheet and checked against real tags -#define EM4233_USR_MEM_SIZE 64 // Bytes, guessed, not described anywere -#define EM4233_MEM_UID_ADDRESS 0x0100 // From 0x0100 to 0x0107 - UID -#define EM4233_MEM_AFI_ADDRESS 0x0108 // AFI byte address -#define EM4233_MEM_DSFID_ADDRESS 0x0109 // DSFID byte adress -#define EM4233_MEM_INF_ADDRESS 0x010C // Some status bits +#define EM4233_MEM_UID_ADDRESS 0xD0 // From 0x0100 to 0x0107 - UID +#define EM4233_MEM_AFI_ADDRESS 0xD8 // AFI byte address +#define EM4233_MEM_DSFID_ADDRESS 0xD9 // DSFID byte adress +#define EM4233_MEM_INF_ADDRESS 0xDC // Some status bits -#define EM4233_MEM_LSM_ADDRESS 0x0110 // From 0x0108 to 0x0149 - Lock status masks -#define EM4233_MEM_PSW_ADDRESS 0x0150 // From 0x0150 to 0x0153 - Password -#define EM4233_MEM_KEY_ADDRESS 0x0154 // From 0x0120 to 0x0127 - Encryption Key +#define EM4233_MEM_LSM_ADDRESS 0xE0 // From 0xE0 to 0x0113 - Lock status masks +#define EM4233_MEM_PSW_ADDRESS 0x0114 // From 0x0114 to 0x0117 - 32 bit Password +#define EM4233_MEM_KEY_ADDRESS 0x0118 // From 0x0118 to 0x0123 - 96 bit Encryption Key -#define EM4233_SYSINFO_BYTE 0x0F // DSFID - AFI - VICC mem size - IC ref are present +#define EM4233_SYSINFO_BYTE 0x0F // == DSFID - AFI - VICC mem size - IC ref are present /* Bit masks */ #define EM4233_MASK_READ_PROT ( 1 << 2 ) // For lock status byte @@ -37,8 +36,6 @@ #define EM4233_MASK_AFI_STATUS ( 1 << 0 ) #define EM4233_MASK_DSFID_STATUS ( 1 << 1 ) -#define EM4233_TOT_MEM_SIZE ( EM4233_STD_MEM_SIZE + EM4233_USR_MEM_SIZE ) - /* Custom command code */ #define EM4233_CMD_SET_EAS 0xA2 #define EM4233_CMD_RST_EAS 0xA3 diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index afe6691..2d43f6b 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -72,10 +72,7 @@ #define ISO15693_CRC16_POLYNORMAL 0x8408 #define ISO15693_CRC16_PRESET 0xFFFF -/* - * The byte used for the lock status has its bits addressed as follow: - * - */ +/* The lock status byte has bits assigned as follow */ #define ISO15693_MASK_UNLOCKED ( 0 << 0 ) #define ISO15693_MASK_USER_LOCK ( 1 << 0 ) #define ISO15693_MASK_FACTORY_LOCK ( 1 << 1 ) From f3f59beb9a11d90d5770e78c944f9c4cb6a79542 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Thu, 27 Dec 2018 01:21:07 +0100 Subject: [PATCH 59/67] Added 010 hex Editor template file To aid in quick dump modifications --- Software/EM4233_010Editor_Template.bt | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Software/EM4233_010Editor_Template.bt diff --git a/Software/EM4233_010Editor_Template.bt b/Software/EM4233_010Editor_Template.bt new file mode 100644 index 0000000..e762546 --- /dev/null +++ b/Software/EM4233_010Editor_Template.bt @@ -0,0 +1,33 @@ +//------------------------------------------------ +//--- 010 Editor v9.0.1 Binary Template +// +// File: EM4233 ChameleonMini dump format +// Authors: ceres-c +// Version: 1.0 +// Purpose: Quick edit of custom dumps +// Category: Electronics +// File Mask: +// ID Bytes: +// History: +// 1.0 2018-12-27 ceres-c: Initial release +//------------------------------------------------ + +struct FILE { + struct Card_dump { + char Data[4] ; + } block [52]; + + struct Emulation_data { + char UID[8] ; + char AFI[1] ; + char DSFID[1] ; + char RFU[2] ; + char Info_bits[4] ; + struct Lock_status_bytes { + char lsbyte ; + } lsb [52]; + char Password[4] ; + char Key[12] ; + } emudata; + +} file ; \ No newline at end of file From 5f6c35d7a690c7c9ceb83a412ccb7f3f67627362 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Fri, 28 Dec 2018 00:28:22 +0100 Subject: [PATCH 60/67] First draft of anticollision sequence Only 1 slot mode has been implemented, but it seems to work even for 16 slots mode. This needs to be checked with other readers. --- Firmware/Chameleon-Mini/Application/EM4233.c | 18 ++++-- .../Chameleon-Mini/Application/ISO15693-A.c | 58 ++++++++++++++++++- .../Chameleon-Mini/Application/ISO15693-A.h | 3 +- .../Application/TITagitstandard.c | 5 +- .../Application/TITagitstandard.h | 3 +- 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index 7cb4ce4..c94097c 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -15,6 +15,7 @@ static enum { } State; bool loggedIn; +uint8_t MyAFI; /* This variable holds current tag's AFI (is used in inventory) */ CurrentFrame FrameInfo; @@ -29,6 +30,7 @@ void EM4233AppInit(void) FrameInfo.Addressed = false; FrameInfo.Selected = false; loggedIn = false; + MemoryReadBlock(&MyAFI, EM4233_MEM_AFI_ADDRESS, 1); } @@ -238,6 +240,7 @@ uint16_t EM4233_Write_AFI(uint8_t* FrameBuf, uint16_t FrameBytes) } MemoryWriteBlock(&AFI, EM4233_MEM_AFI_ADDRESS, 1); /* Actually write new AFI */ + MyAFI = AFI; /* And update global variable */ // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ // ResponseByteCount += 1; @@ -493,15 +496,20 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t Uid[ActiveConfiguration.UidSize]; EM4233GetUid(Uid); - if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid)) + if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid, MyAFI)) return ISO15693_APP_NO_RESPONSE; if (State == STATE_READY || State == STATE_SELECTED) { if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - MemoryReadBlock(&FrameBuf[ISO15693_RES_ADDR_PARAM], EM4233_MEM_DSFID_ADDRESS, 1); - ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); - ResponseByteCount = 10; + if (FrameInfo.ParamLen == 0) + return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + + if (ISO15693AntiColl (FrameBuf, FrameBytes, &FrameInfo, Uid)) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + MemoryReadBlock(&FrameBuf[ISO15693_RES_ADDR_PARAM], EM4233_MEM_DSFID_ADDRESS, 1); + ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid); + ResponseByteCount += 10; + } } else if ( (*FrameInfo.Command == ISO15693_CMD_STAY_QUIET ) && FrameInfo.Addressed) { State = STATE_QUIET; diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index b271db8..9224606 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -65,7 +65,7 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) * * Authors: ceres-c & MrMoDDoM */ -bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid) +bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid, uint8_t MyAFI) { if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) /* malformed frame */ @@ -91,10 +91,18 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* if ( (*FrameStruct -> Command) >= 0xA0) { /* if command is Custom or Proprietary */ /* then between CMD and UID is placed another byte which is IC Mfg Code, but we don't need it */ - FrameStruct -> Parameters += 0x01; if (FrameBuf[ISO15693_REQ_ADDR_PARAM] != MyUid[1]) /* if IC Mfg Code is different from our Mfg code (2nd byte of UID), then don't respond */ return false; + FrameStruct -> Parameters += 0x01; + } + else if ( ((*FrameStruct -> Command) == ISO15693_CMD_INVENTORY) && (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_AFI)) { + /* or if it is Inventory with AFI flag set */ + /* then between CMD and UID is placed another byte which is requested AFI, but we don't need it */ + if (FrameBuf[ISO15693_REQ_ADDR_PARAM] != MyAFI) + /* if requested AFI is different from our current one, then don't respond */ + return false; + FrameStruct -> Parameters += 0x01; } FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); @@ -108,3 +116,49 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* return true; } } + +/* + * ISO15693AntiColl + * + * This function performs ISO15693 Anticollision + * + * Returns: + * - true: Inventory is addressed to us and a response is needed + * - false: Request is not addressed to us (different bitmask) + * and no response should be issued. + * + * Authors: ceres-c + * + * TODO: + * - Implement 16 slots mode (still, it seems to work as it is, even for 16 slots mode ._.) + */ +bool ISO15693AntiColl(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid) { + uint8_t CurrentUID[ ISO15693_GENERIC_UID_SIZE ]; /* Holds the UID flipped */ + ISO15693CopyUid(CurrentUID, MyUid); + + uint8_t MaskLenght = *FrameStruct -> Parameters; /* First byte of parameters is mask lenght... */ + uint8_t* MaskValue = FrameStruct -> Parameters + 1; /* ... then the mask itself begins */ + uint8_t BytesNum = MaskLenght / 8; /* Gets the number of full bytes in mask */ + uint8_t BitsNum = MaskLenght % 8; /* Gets the number of spare bits */ + + uint8_t B; /* B stands for Bytes and will be our reference point (I know, terrible name, I'm sorry) */ + /* Compare the full bytes in mask with UID */ + for (B = 0; B < BytesNum; B++ ) { + if (CurrentUID[B] != MaskValue[B]) + return false; /* UID different */ + } + /* Once we got here, B points for sure to the last byte of the mask, the one composed of spare bits */ + + /* Compare spare bits in mask with bits of UID */ + uint8_t BitsMask = ((1 << BitsNum) - 1); /* (1 << Bits) = 00010000 -> (1 << Bits) - 1 = 00001111 */ + if ((MaskValue[B] & BitsMask) != (CurrentUID[B] & BitsMask)) { + /* |-----------------------| Here we extract bits from the mask we received from the reader + * |------------------------| Here we extract bits from the UID + * The two extracted bit vectors are compared, if different then we're not the addressee. + * Only the latest byte of MaskValue and UID is considered. + */ + return false; + } + + return true; +} \ No newline at end of file diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index 2d43f6b..f99c6b6 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -88,7 +88,8 @@ typedef struct { void ISO15693AppendCRC(uint8_t* FrameBuf, uint16_t FrameBufSize); bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize); -bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid); +bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid, uint8_t MyAFI); +bool ISO15693AntiColl(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid); INLINE bool ISO15693CompareUid(uint8_t* Uid1, uint8_t* Uid2) diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 3208bf6..3e1cc5d 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -16,6 +16,7 @@ static enum { STATE_QUIET } State; +uint8_t MyAFI; /* Holds current tag's AFI (is used in inventory) */ uint16_t UserLockBits_Mask = 0; /* Holds lock state of blocks */ uint16_t FactoryLockBits_Mask = 0; /* Holds lock state of blocks */ CurrentFrame FrameInfo; @@ -33,6 +34,8 @@ void TITagitstandardAppInit(void) FrameInfo.ParamLen = 0; FrameInfo.Addressed = false; FrameInfo.Selected = false; + + MemoryReadBlock(&MyAFI, TITAGIT_MEM_AFI_ADDRESS, 1); } void TITagitstandardAppReset(void) @@ -64,7 +67,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t Uid[ActiveConfiguration.UidSize]; TITagitstandardGetUid(Uid); - if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid)) + if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid, MyAFI)) return ISO15693_APP_NO_RESPONSE; switch(State) { diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.h b/Firmware/Chameleon-Mini/Application/TITagitstandard.h index a433913..2c264c6 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.h +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.h @@ -12,10 +12,11 @@ #include "Application.h" #define TITAGIT_STD_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE -#define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE +#define TITAGIT_STD_MEM_SIZE 44 //TAG-IT STANDARD MAX MEM SIZE #define TITAGIT_BYTES_PER_PAGE 4 #define TITAGIT_NUMBER_OF_SECTORS ( TITAGIT_STD_MEM_SIZE / TITAGIT_BYTES_PER_PAGE ) #define TITAGIT_MEM_UID_ADDRESS 0x20 +#define TITAGIT_MEM_AFI_ADDRESS 0x28 // AFI byte address void TITagitstandardAppInit(void); void TITagitstandardAppReset(void); From 39c251c7d508f89d0ae9f94680d9a27dc406141f Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Fri, 28 Dec 2018 13:42:17 +0100 Subject: [PATCH 61/67] Fixed Select command and some minor bug fixes Select command did not fall back to READY state if Select was issued on another tag. PrepareFrame allowed the tag to respond to Selected requests even if we were not in SELECTED state. Also fixed Read Single and Read Multiple out of bound reads in case of addressed commands. --- Firmware/Chameleon-Mini/Application/EM4233.c | 123 +++++++++++------- .../Chameleon-Mini/Application/ISO15693-A.c | 12 +- .../Chameleon-Mini/Application/ISO15693-A.h | 2 +- .../Chameleon-Mini/Application/Sl2s2002.h | 3 - .../Application/TITagitstandard.c | 2 +- 5 files changed, 87 insertions(+), 55 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index c94097c..8fc69c7 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -3,6 +3,9 @@ * * Created on: 12-05-2018 * Author: ceres-c & MrMoDDoM + * TODO: + * - Check with real tag every command's actual response in addressed/selected State + * (Only EM4233_Read_Single and EM4233_Read_Multiple have been checked up to now) */ #include "ISO15693-A.h" @@ -91,22 +94,21 @@ uint16_t EM4233_Lock_Block(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t EM4233_Write_Single(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; - uint8_t* Dataptr; - uint8_t PageAddress = *FrameInfo.Parameters; + uint8_t BlockAddress = *FrameInfo.Parameters; + uint8_t* Dataptr = BlockAddress + 0x01; /* Data to write begins on 2nd byte of the frame received by the reader */ uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 5) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ - if (PageAddress > EM4233_NUMBER_OF_BLCKS) { + if (BlockAddress > EM4233_NUMBER_OF_BLCKS) { // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_OPT_NOT_SUPP; ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ return ResponseByteCount; /* malformed: trying to write in a non-existing block */ } - MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + PageAddress), 1); - Dataptr = PageAddress + 0x01; + MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + BlockAddress), 1); if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; @@ -117,7 +119,7 @@ uint16_t EM4233_Write_Single(uint8_t* FrameBuf, uint16_t FrameBytes) // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_CHG_LKD; ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ } else { - MemoryWriteBlock(Dataptr, PageAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); + MemoryWriteBlock(Dataptr, BlockAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; ResponseByteCount += 1; } @@ -129,23 +131,25 @@ uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t FramePtr; /* holds the address where block's data will be put */ - uint8_t PageAddress = *FrameInfo.Parameters; + uint8_t BlockAddress = FrameInfo.Parameters[0]; uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 1) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ - if (PageAddress >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a sector out of bound */ - // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; - ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ - return ResponseByteCount; + 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 */ + ResponseByteCount += 2; /* Copied this behaviour from real tag, not specified in ISO documents */ + } + return ResponseByteCount; /* If not addressed real tag does not respond */ } FramePtr = 1; if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + PageAddress), 1); + MemoryReadBlock(&LockStatus, (EM4233_MEM_LSM_ADDRESS + BlockAddress), 1); if (LockStatus & ISO15693_MASK_FACTORY_LOCK) { /* tests if the n-th bit of the factory bitmask if set to 1 */ FrameBuf[FramePtr] = ISO15693_MASK_FACTORY_LOCK; /* return bit 1 set as 1 (factory locked) */ } else if (LockStatus & ISO15693_MASK_USER_LOCK) { /* tests if the n-th bit of the user bitmask if set to 1 */ @@ -156,7 +160,7 @@ uint16_t EM4233_Read_Single(uint8_t* FrameBuf, uint16_t FrameBytes) ResponseByteCount += 1; } - MemoryReadBlock(&FrameBuf[FramePtr], PageAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); + MemoryReadBlock(&FrameBuf[FramePtr], BlockAddress * EM4233_BYTES_PER_BLCK, EM4233_BYTES_PER_BLCK); ResponseByteCount += 4; FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ @@ -175,11 +179,13 @@ uint16_t EM4233_Read_Multiple(uint8_t* FrameBuf, uint16_t FrameBytes) if (FrameInfo.ParamLen != 2) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ - if (BlockAddress > EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a starting block out of bound */ - // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_BLK_NOT_AVL; - ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ - return ResponseByteCount; + 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 */ + ResponseByteCount += 2; /* Copied this behaviour from real tag, not specified in ISO documents */ + } + return ResponseByteCount; /* If not addressed real tag does not respond */ } else if ((BlockAddress + BlocksNumber) >= EM4233_NUMBER_OF_BLCKS) { /* last block is out of bound */ BlocksNumber = EM4233_NUMBER_OF_BLCKS - BlockAddress; /* we read up to latest block, as real tag does */ } @@ -431,6 +437,7 @@ uint16_t EM4233_Get_Multi_Block_Sec_Stat(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) { + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; /* I've no idea how this request could generate errors ._. if ( ) { FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; @@ -442,22 +449,48 @@ uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) bool UidEquals = ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid); - if (!FrameInfo.Addressed || FrameInfo.Selected) { + if (!(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS) || + (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_SELECT) + ) { /* tag should remain silent if Select is performed without address flag or with select flag */ return ISO15693_APP_NO_RESPONSE; - } else if (State == STATE_SELECTED && !UidEquals) { - /* tag should remain silent if Select is performed while the tag is selected but against another tag */ + } else if (!UidEquals) { + /* tag should remain silent and reset if Select is performed against another UID, + * whether our the tag is selected or not + */ State = STATE_READY; return ISO15693_APP_NO_RESPONSE; - } else if (State != STATE_SELECTED && !UidEquals) { - /* tag should remain silent if Select is performed against another UID */ - return ISO15693_APP_NO_RESPONSE; } else if (State != STATE_SELECTED && UidEquals) { State = STATE_SELECTED; - return ISO15693_APP_NO_RESPONSE; /* real tag does not respond anyway */ + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount += 1; + return ResponseByteCount; } +} - return ISO15693_APP_NO_RESPONSE; /* Just because you never know... */ +uint16_t EM4233_Reset_To_Ready(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + /* I've no idea how this request could generate errors ._. + if ( ) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC; + ResponseByteCount += 2; + return ResponseByteCount; + } + */ + FrameInfo.Flags = NULL; + FrameInfo.Command = NULL; + FrameInfo.Parameters = NULL; + FrameInfo.ParamLen = 0; + FrameInfo.Addressed = false; + FrameInfo.Selected = false; + + State = STATE_READY; + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + ResponseByteCount += 1; + return ResponseByteCount; } uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) @@ -496,7 +529,14 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t Uid[ActiveConfiguration.UidSize]; EM4233GetUid(Uid); - if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid, MyAFI)) + if (FrameBuf[ISO15693_REQ_ADDR_CMD] == ISO15693_CMD_SELECT) { + /* Select has its own path before PrepareFrame because we have to change the variable State + * from Select to Ready if "Select" cmd is addressed to another tag. + * It felt weird to add this kind of check in ISO15693PrepareFrame, which should not + * interfere with tag specific variables, such as State in this case. + */ + ResponseByteCount = EM4233_Select(FrameBuf, FrameBytes, Uid); + } else if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, State == STATE_SELECTED, Uid, MyAFI)) return ISO15693_APP_NO_RESPONSE; if (State == STATE_READY || State == STATE_SELECTED) { @@ -543,30 +583,25 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } else if (*FrameInfo.Command == ISO15693_CMD_GET_BLOCK_SEC) { ResponseByteCount = EM4233_Get_Multi_Block_Sec_Stat(FrameBuf, FrameBytes); - - } else if (*FrameInfo.Command == ISO15693_CMD_SELECT) { - ResponseByteCount = EM4233_Select(FrameBuf, FrameBytes, Uid); + + } else if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) { + ResponseByteCount = EM4233_Reset_To_Ready (FrameBuf, FrameBytes); } else if (*FrameInfo.Command == EM4233_CMD_LOGIN) { ResponseByteCount = EM4233_Login(FrameBuf, FrameBytes, Uid); + } else if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { + /* This is just a placeholder to avoid falling in the following else */ + } else { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; - ResponseByteCount = 2; + /* EM4233 does not respond to non existing commands */ + // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; + // ResponseByteCount = 2; } } else if (State == STATE_QUIET) { if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) { - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; - State = STATE_READY; - - FrameInfo.Flags = NULL; - FrameInfo.Command = NULL; - FrameInfo.Parameters = NULL; - FrameInfo.ParamLen = 0; - FrameInfo.Addressed = false; - FrameInfo.Selected = false; + ResponseByteCount = EM4233_Reset_To_Ready (FrameBuf, FrameBytes); } } diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 9224606..a206bc8 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -65,7 +65,7 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) * * Authors: ceres-c & MrMoDDoM */ -bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid, uint8_t MyAFI) +bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t IsSelected, uint8_t* MyUid, uint8_t MyAFI) { if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) /* malformed frame */ @@ -96,8 +96,7 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* return false; FrameStruct -> Parameters += 0x01; } - else if ( ((*FrameStruct -> Command) == ISO15693_CMD_INVENTORY) && (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_AFI)) { - /* or if it is Inventory with AFI flag set */ + else if ( ((*FrameStruct -> Command) == ISO15693_CMD_INVENTORY) && (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_AFI)) { /* or if it is Inventory with AFI flag set */ /* then between CMD and UID is placed another byte which is requested AFI, but we don't need it */ if (FrameBuf[ISO15693_REQ_ADDR_PARAM] != MyAFI) /* if requested AFI is different from our current one, then don't respond */ @@ -107,11 +106,12 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); - uint8_t *uid = (FrameStruct -> Parameters) - ISO15693_GENERIC_UID_SIZE; - - if (FrameStruct -> Addressed && !ISO15693CompareUid( uid, MyUid)) { + if (FrameStruct -> Addressed && !ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], MyUid)) { /* addressed request but we're not the addressee */ return false; + } else if (FrameStruct -> Selected && !IsSelected) { + /* selected request but we're not in selected state */ + return false; } else { return true; } diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.h b/Firmware/Chameleon-Mini/Application/ISO15693-A.h index f99c6b6..42b1655 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.h +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.h @@ -88,7 +88,7 @@ typedef struct { void ISO15693AppendCRC(uint8_t* FrameBuf, uint16_t FrameBufSize); bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize); -bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid, uint8_t MyAFI); +bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t IsSelected, uint8_t* MyUid, uint8_t MyAFI); bool ISO15693AntiColl(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t* MyUid); INLINE diff --git a/Firmware/Chameleon-Mini/Application/Sl2s2002.h b/Firmware/Chameleon-Mini/Application/Sl2s2002.h index be37eb2..9f58761 100644 --- a/Firmware/Chameleon-Mini/Application/Sl2s2002.h +++ b/Firmware/Chameleon-Mini/Application/Sl2s2002.h @@ -11,9 +11,6 @@ #include "Application.h" #include "ISO15693-A.h" -#define ISO15693_GENERIC_UID_SIZE 8 //ISO15693_UID_SIZE -#define ISO15693_GENERIC_MEM_SIZE 8192 //ISO15693_MAX_MEM_SIZE - void Sl2s2002AppInit(void); void Sl2s2002AppReset(void); void Sl2s2002AppTask(void); diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 3e1cc5d..3a34177 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -67,7 +67,7 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t Uid[ActiveConfiguration.UidSize]; TITagitstandardGetUid(Uid); - if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, Uid, MyAFI)) + if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, State == STATE_SELECTED, Uid, MyAFI)) return ISO15693_APP_NO_RESPONSE; switch(State) { From 3c775c06cce7b6e7c3798cbe11b18a8b72a1480c Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Fri, 28 Dec 2018 17:10:02 +0100 Subject: [PATCH 62/67] Stupid me introduced a bug in Write_Single --- Firmware/Chameleon-Mini/Application/EM4233.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index 8fc69c7..a2379a8 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -95,7 +95,7 @@ uint16_t EM4233_Write_Single(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t BlockAddress = *FrameInfo.Parameters; - uint8_t* Dataptr = BlockAddress + 0x01; /* Data to write begins on 2nd byte of the frame received by the reader */ + uint8_t* Dataptr = FrameInfo.Parameters + 0x01; /* Data to write begins on 2nd byte of the frame received by the reader */ uint8_t LockStatus = 0; if (FrameInfo.ParamLen != 5) From 9b2dd662ad4f1771ba24fc5a754af43184c9807e Mon Sep 17 00:00:00 2001 From: Thorsten <12600404+bosb@users.noreply.github.com> Date: Sun, 30 Dec 2018 13:53:12 +0000 Subject: [PATCH 63/67] Respect the chosen UID --- Firmware/Chameleon-Mini/Terminal/Commands.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.c b/Firmware/Chameleon-Mini/Terminal/Commands.c index 6577768..80de7e3 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.c +++ b/Firmware/Chameleon-Mini/Terminal/Commands.c @@ -80,10 +80,6 @@ CommandStatusIdType CommandSetUid(char* OutMessage, const char* InParam) for (uint8_t i=0; i Date: Sun, 30 Dec 2018 14:02:18 +0000 Subject: [PATCH 64/67] Revert "Respect the chosen UID" This reverts commit 9b2dd662ad4f1771ba24fc5a754af43184c9807e. --- Firmware/Chameleon-Mini/Terminal/Commands.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Firmware/Chameleon-Mini/Terminal/Commands.c b/Firmware/Chameleon-Mini/Terminal/Commands.c index 80de7e3..6577768 100644 --- a/Firmware/Chameleon-Mini/Terminal/Commands.c +++ b/Firmware/Chameleon-Mini/Terminal/Commands.c @@ -80,6 +80,10 @@ CommandStatusIdType CommandSetUid(char* OutMessage, const char* InParam) for (uint8_t i=0; i Date: Tue, 1 Jan 2019 13:40:51 +0100 Subject: [PATCH 65/67] Fixed a bug with with addressed Custom/Proprietary commands --- Firmware/Chameleon-Mini/Application/ISO15693-A.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index 6fde0d9..b62f3e2 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -106,7 +106,8 @@ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct -> ParamLen = FrameBuf + (FrameBytes - ISO15693_CRC16_SIZE) - (FrameStruct -> Parameters); - if (FrameStruct -> Addressed && !ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], MyUid)) { + /* The UID, if present, always sits right befoore the parameters */ + if (FrameStruct -> Addressed && !ISO15693CompareUid(FrameStruct -> Parameters - ISO15693_GENERIC_UID_SIZE, MyUid)) { /* addressed request but we're not the addressee */ return false; } else if (FrameStruct -> Selected && !IsSelected) { From 9ae3aeced3622339df0ebc8358d8da991a703bf2 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Tue, 1 Jan 2019 22:54:49 +0100 Subject: [PATCH 66/67] Added stub EM mutual auth commands and fixed a couple of bugs E0 and E1 commands will be expanded as reverse engineering continues. At the moment E0 will be used to work on reader response to A1 random number. Fixed 2 different bugs in Login. Fixed Lock DSFID command Removed frame integrity checks from PrepareFrame, since it's already needed to do them before PrepareFrame should be called --- Firmware/Chameleon-Mini/Application/EM4233.c | 110 +++++++++++++++--- Firmware/Chameleon-Mini/Application/EM4233.h | 9 ++ .../Chameleon-Mini/Application/ISO15693-A.c | 9 +- 3 files changed, 102 insertions(+), 26 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index a2379a8..a7b2154 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -3,11 +3,16 @@ * * Created on: 12-05-2018 * Author: ceres-c & MrMoDDoM + * Notes: + * - In EM4233.h you can find the define EM4233_LOGIN_YES_CARD that has to be uncommnted + * to allow any login request without checking the password. + * * TODO: * - Check with real tag every command's actual response in addressed/selected State * (Only EM4233_Read_Single and EM4233_Read_Multiple have been checked up to now) */ +#include "../Random.h" #include "ISO15693-A.h" #include "EM4233.h" @@ -274,7 +279,7 @@ uint16_t EM4233_Lock_AFI(uint8_t* FrameBuf, uint16_t FrameBytes) LockStatus |= EM4233_MASK_AFI_STATUS; - MemoryWriteBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); /* Actually write new AFI */ + MemoryWriteBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); /* Write in info bits AFI lockdown */ // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ // ResponseByteCount += 1; @@ -329,7 +334,7 @@ uint16_t EM4233_Lock_DSFID(uint8_t* FrameBuf, uint16_t FrameBytes) LockStatus |= EM4233_MASK_DSFID_STATUS; - MemoryWriteBlock(*FrameInfo.Parameters, EM4233_MEM_INF_ADDRESS, 4); /* Actually write the new DSFID */ + MemoryWriteBlock(&LockStatus, EM4233_MEM_INF_ADDRESS, 1); /* Write in info bits DSFID lockdown */ // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ // ResponseByteCount += 1; @@ -450,8 +455,8 @@ uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) bool UidEquals = ISO15693CompareUid(&FrameBuf[ISO15693_REQ_ADDR_PARAM], Uid); if (!(FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_ADDRESS) || - (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_SELECT) - ) { + (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_SELECT) + ) { /* tag should remain silent if Select is performed without address flag or with select flag */ return ISO15693_APP_NO_RESPONSE; } else if (!UidEquals) { @@ -466,6 +471,10 @@ uint16_t EM4233_Select(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) ResponseByteCount += 1; return ResponseByteCount; } + + /* This should never happen (TM), I've added it to shut the compiler up */ + State = STATE_READY; + return ISO15693_APP_NO_RESPONSE; } uint16_t EM4233_Reset_To_Ready(uint8_t* FrameBuf, uint16_t FrameBytes) @@ -493,19 +502,26 @@ uint16_t EM4233_Reset_To_Ready(uint8_t* FrameBuf, uint16_t FrameBytes) return ResponseByteCount; } -uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) +uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t Password[4] = { 0 }; - if (FrameInfo.ParamLen != 4) - return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ + if (FrameInfo.ParamLen != 4 || !FrameInfo.Addressed) + /* Malformed: not enough or too much data. Also this command only works in addressed mode */ + return ISO15693_APP_NO_RESPONSE; MemoryReadBlock(&Password, EM4233_MEM_PSW_ADDRESS, 4); - if( false ){ // YES-MAN! - // if (!memcmp(Password, FrameInfo.Parameters, 4)) { /* Incorrect password */ + #ifdef EM4233_LOGIN_YES_CARD + /* Accept any password from reader as correct one */ + loggedIn = true; + MemoryWriteBlock(FrameInfo.Parameters, EM4233_MEM_PSW_ADDRESS, 4); /* Store password in memory for retrival */ + + #else + /* Check if the password is actually the right one */ + if (memcmp(Password, FrameInfo.Parameters, 4) != 0) { /* Incorrect password */ loggedIn = false; // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; @@ -514,21 +530,71 @@ uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes, uint8_t* Uid) return ResponseByteCount; } - loggedIn = true; + #endif - MemoryWriteBlock(Password, EM4233_MEM_PSW_ADDRESS, 4); /* Store password in memory for retrival */ + loggedIn = true; FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ ResponseByteCount += 1; return ResponseByteCount; } +uint16_t EM4233_Auth1(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + // uint8_t KeyNo = *FrameInfo.Parameters; /* Right now this parameter is unused, but it will be useful */ + + if (FrameInfo.ParamLen != 1 || !FrameInfo.Addressed) + /* Malformed: not enough or too much data. Also this command only works in addressed mode */ + return ISO15693_APP_NO_RESPONSE; + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + #ifdef EM4233_LOGIN_YES_CARD + /* Will be useful for testing purposes, probably removed in final version */ + FrameBuf[ISO15693_ADDR_FLAGS + 1] = 0x00; + FrameBuf[ISO15693_ADDR_FLAGS + 2] = 0x00; + FrameBuf[ISO15693_ADDR_FLAGS + 3] = 0x00; + FrameBuf[ISO15693_ADDR_FLAGS + 4] = 0x00; + FrameBuf[ISO15693_ADDR_FLAGS + 5] = 0x00; + FrameBuf[ISO15693_ADDR_FLAGS + 6] = 0x00; + FrameBuf[ISO15693_ADDR_FLAGS + 7] = 0x00; + #else + /* Respond like a real tag */ + RandomGetBuffer(FrameBuf + 0x01, 7); /* Random number A1 in EM Marin definitions */ + #endif + ResponseByteCount += 8; + return ResponseByteCount; +} + +uint16_t EM4233_Auth2(uint8_t* FrameBuf, uint16_t FrameBytes) +{ + uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; + // uint8_t A2 = FrameInfo.Parameters; + // uint8_t f = FrameInfo.Parameters + 0x08; + // uint8_t g[3] = { 0 }; /* Names according to EM Marin definitions */ + + if (FrameInfo.ParamLen != 11) /* Malformed: not enough or too much data */ + return ISO15693_APP_NO_RESPONSE; + // else if (!fFunc()) /* Actual f implementation to check if the f bytes we received are correct */ + // return ISO15693_APP_NO_RESPONSE; + + + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; + RandomGetBuffer(FrameBuf + 0x01, 3); /* This should be replaced with actual gFunc() implementation */ + ResponseByteCount += 4; + return ResponseByteCount; +} + uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) { uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t Uid[ActiveConfiguration.UidSize]; EM4233GetUid(Uid); + if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) + /* malformed frame */ + return ResponseByteCount; + if (FrameBuf[ISO15693_REQ_ADDR_CMD] == ISO15693_CMD_SELECT) { /* Select has its own path before PrepareFrame because we have to change the variable State * from Select to Ready if "Select" cmd is addressed to another tag. @@ -540,6 +606,7 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) return ISO15693_APP_NO_RESPONSE; if (State == STATE_READY || State == STATE_SELECTED) { + if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { if (FrameInfo.ParamLen == 0) return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */ @@ -588,17 +655,22 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) ResponseByteCount = EM4233_Reset_To_Ready (FrameBuf, FrameBytes); } else if (*FrameInfo.Command == EM4233_CMD_LOGIN) { - ResponseByteCount = EM4233_Login(FrameBuf, FrameBytes, Uid); + ResponseByteCount = EM4233_Login(FrameBuf, FrameBytes); - } else if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) { - /* This is just a placeholder to avoid falling in the following else */ + } else if (*FrameInfo.Command == EM4233_CMD_AUTH1) { + ResponseByteCount = EM4233_Auth1(FrameBuf, FrameBytes); + + } else if (*FrameInfo.Command == EM4233_CMD_AUTH2) { + ResponseByteCount = EM4233_Auth2(FrameBuf, FrameBytes); } else { - /* EM4233 does not respond to non existing commands */ - // FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; - // FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; - // ResponseByteCount = 2; + if (FrameInfo.Addressed) { + FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR; + FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP; + ResponseByteCount = 2; + } /* EM4233 respond with error flag only to addressed commands */ } + } else if (State == STATE_QUIET) { if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) { ResponseByteCount = EM4233_Reset_To_Ready (FrameBuf, FrameBytes); @@ -606,7 +678,7 @@ uint16_t EM4233AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } if (ResponseByteCount > 0) { - /* There is data to be sent. Append CRC */ + /* There is data to send. Append CRC */ ISO15693AppendCRC(FrameBuf, ResponseByteCount); ResponseByteCount += ISO15693_CRC16_SIZE; } diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h index a7efbee..3cb3743 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.h +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -53,8 +53,17 @@ #define EM4233_CMD_FST_READ_BLKS 0xC3 /* Proprietary command code */ +#define EM4233_CMD_AUTH1 0xE0 +#define EM4233_CMD_AUTH2 0xE1 #define EM4233_CMD_LOGIN 0xE4 +/* Compile time switch */ +/* EM4233_LOGIN_YES_CARD has to be uncommented if you want your emulated card + * to accept any given password from the reader when a Login request (E4) is issued. + * It is expecially useful when analyzing an unknown system and you want to fool a reader + * into thiking you are using the original tag without actually knowing the password. + */ +#define EM4233_LOGIN_YES_CARD void EM4233AppInit(void); void EM4233AppReset(void); diff --git a/Firmware/Chameleon-Mini/Application/ISO15693-A.c b/Firmware/Chameleon-Mini/Application/ISO15693-A.c index b62f3e2..b435393 100644 --- a/Firmware/Chameleon-Mini/Application/ISO15693-A.c +++ b/Firmware/Chameleon-Mini/Application/ISO15693-A.c @@ -54,9 +54,8 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) /* * ISO15693PrepareFrame * - * This function validates frame lenght and sets pointers in 'frame' struct - * to relevant byte(s) of 'FrameBuf'. Also sets frame.addressed as true if - * the command is addressed + * This function sets pointers in 'frame' struct to relevant byte(s) of 'FrameBuf'. + * Also sets frame.Addressed as true if the command is addressed, same goes for frame.Selected * * Returns: * - true: Frame is valid and a response is needed @@ -67,10 +66,6 @@ bool ISO15693CheckCRC(void* FrameBuf, uint16_t FrameBufSize) */ bool ISO15693PrepareFrame(uint8_t* FrameBuf, uint16_t FrameBytes, CurrentFrame* FrameStruct, uint8_t IsSelected, uint8_t* MyUid, uint8_t MyAFI) { - if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) - /* malformed frame */ - return false; - /* following declarations are not dependent on addressed/unaddressed state */ FrameStruct -> Flags = &FrameBuf[ISO15693_ADDR_FLAGS]; FrameStruct -> Command = &FrameBuf[ISO15693_REQ_ADDR_CMD]; From fc24f84a63706feb2453baa6f790b82f8595ad61 Mon Sep 17 00:00:00 2001 From: Federico Cerutti Date: Mon, 4 Mar 2019 11:58:51 +0100 Subject: [PATCH 67/67] Fixed a couple of validity checks and updated Titagitstandard.c to new PrepareFrame --- Firmware/Chameleon-Mini/Application/EM4233.c | 5 ++--- Firmware/Chameleon-Mini/Application/EM4233.h | 2 ++ Firmware/Chameleon-Mini/Application/TITagitstandard.c | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/EM4233.c b/Firmware/Chameleon-Mini/Application/EM4233.c index a7b2154..f3cd7a7 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.c +++ b/Firmware/Chameleon-Mini/Application/EM4233.c @@ -507,7 +507,7 @@ uint16_t EM4233_Login(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; uint8_t Password[4] = { 0 }; - if (FrameInfo.ParamLen != 4 || !FrameInfo.Addressed) + if (FrameInfo.ParamLen != 4 || !FrameInfo.Addressed || !(FrameInfo.Selected && State == STATE_SELECTED)) /* Malformed: not enough or too much data. Also this command only works in addressed mode */ return ISO15693_APP_NO_RESPONSE; @@ -544,8 +544,7 @@ uint16_t EM4233_Auth1(uint8_t* FrameBuf, uint16_t FrameBytes) uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE; // uint8_t KeyNo = *FrameInfo.Parameters; /* Right now this parameter is unused, but it will be useful */ - if (FrameInfo.ParamLen != 1 || !FrameInfo.Addressed) - /* Malformed: not enough or too much data. Also this command only works in addressed mode */ + if (FrameInfo.ParamLen != 1) /* Malformed: not enough or too much data */ return ISO15693_APP_NO_RESPONSE; FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; diff --git a/Firmware/Chameleon-Mini/Application/EM4233.h b/Firmware/Chameleon-Mini/Application/EM4233.h index 3cb3743..e291b6d 100644 --- a/Firmware/Chameleon-Mini/Application/EM4233.h +++ b/Firmware/Chameleon-Mini/Application/EM4233.h @@ -55,6 +55,8 @@ /* Proprietary command code */ #define EM4233_CMD_AUTH1 0xE0 #define EM4233_CMD_AUTH2 0xE1 +#define EM4233_CMD_GEN_READ 0xE2 // Implies some sort of singed CRC. Unknown at the moment +#define EM4233_CMD_GEN_WRITE 0xE3 // Same #define EM4233_CMD_LOGIN 0xE4 /* Compile time switch */ diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 3a34177..465d426 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -67,6 +67,10 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) uint8_t Uid[ActiveConfiguration.UidSize]; TITagitstandardGetUid(Uid); + if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) + /* malformed frame */ + return ResponseByteCount; + if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, State == STATE_SELECTED, Uid, MyAFI)) return ISO15693_APP_NO_RESPONSE;