iClass support

Requires enabling in Makefile and disabling other options to fit in program space below 64k
This commit is contained in:
nvx
2022-06-28 16:57:39 +10:00
parent 17f32094d9
commit 4bb28e8617
12 changed files with 723 additions and 36 deletions
+9 -7
View File
@@ -1,8 +1,10 @@
/Chameleon-Mini.eep
/Chameleon-Mini.hex
/Chameleon-Mini.elf
/Chameleon-Mini.map
/Chameleon-Mini.bin
/Chameleon-Mini.lss
/Chameleon-Mini.sym
/Chameleon-*.eep
/Chameleon-*.hex
/Chameleon-*.elf
/Chameleon-*.map
/Chameleon-*.bin
/Chameleon-*.lss
/Chameleon-*.sym
/Bin/
dfu-programmer
dfu-programmer.exe
@@ -23,6 +23,7 @@
#include "EM4233.h"
#include "NTAG215.h"
#include "Sniff15693.h"
#include "IClass.h"
/* Function wrappers */
INLINE void ApplicationInit(void) {
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
/*
* IClass.c
*
* Created on: 17-05-2020
* Author: NVX
*/
#ifndef ICLASS_H_
#define ICLASS_H_
#include "Application.h"
#define ICLASS_BLOCK_SIZE 8
#define ICLASS_CSN_SIZE ICLASS_BLOCK_SIZE
#define ICLASS_BLOCK_NUM 32
#define ICLASS_MEM_SIZE ( ICLASS_BLOCK_SIZE * ICLASS_BLOCK_NUM )
#define ICLASS_READ4_SIZE ( ICLASS_BLOCK_SIZE * 4 )
void IClassAppInit(void);
void IClassAppReset(void);
void IClassDetectionInit(void);
uint16_t IClassAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes);
void IClassGetCsn(ConfigurationUidType Uid);
void IClassSetCsn(const ConfigurationUidType Uid);
#endif /* ICLASS_H_ */
@@ -292,7 +292,7 @@ static uint8_t AccessAddress;
static uint16_t CardATQAValue;
static uint8_t CardSAKValue;
static bool FromHalt = false;
static bool DetectionMode = false;
bool DetectionMode = false;
#define BYTE_SWAP(x) (((uint8_t)(x)>>4)|((uint8_t)(x)<<4))
#define NO_ACCESS 0x07
@@ -401,7 +401,7 @@ extern uint8_t bUidMode; // Magic card mode switch
static uint16_t DetectionLogPtr = FRAM_DETECTION_DATA_ADDR;
static uint8_t EEMEM LogDetectionValid = false;
static void DetectionLogToFlash(uint8_t Entry, const void *Data, uint8_t Length) {
void DetectionLogToFlash(uint8_t Entry, const void *Data, uint8_t Length) {
if (!DetectionMode)
return;
@@ -1025,7 +1025,7 @@ uint16_t MifareClassicAppProcess(uint8_t *Buffer, uint16_t BitCount) {
State = STATE_HALT;
Buffer[0] = NAK_NOT_AUTHED ^ Crypto1Nibble();
return ACK_NAK_FRAME_SIZE;
}
}
else {
DetectionLogToFlash(LOG_INFO_APP_CMD_WRITE, Buffer, 2);
/* Write command. Store the address and prepare for the upcoming data.
@@ -1313,4 +1313,4 @@ void MifareClassicGetSak(uint8_t * Sak) {
void MifareClassicSetSak(uint8_t Sak) {
CardSAKValue = Sak;
}
}
@@ -16,6 +16,9 @@
#define MIFARE_CLASSIC_1K_MEM_SIZE 1024
#define MIFARE_CLASSIC_4K_MEM_SIZE 4096
extern bool DetectionMode;
void DetectionLogToFlash(uint8_t Entry, const void *Data, uint8_t Length);
void DetectionInit(void);
void DetectionLogClear(void);
void MifareDetectionInit1K(void);
+45 -12
View File
@@ -121,7 +121,7 @@ ISR_SHARED isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void) {
*/
INLINE void ISO15693_EOC(void) {
/* Set bitrate required by the reader on SOF for our following response */
if (CodecBuffer[0] & REQ_DATARATE_HIGH) {
if (CodecBuffer[0] & REQ_DATARATE_HIGH || ActiveConfiguration.TagFamily == TAG_FAMILY_ISO15693_ICLASS) {
BitRate1 = 256;
BitRate2 = 252; /* If single subcarrier mode is requested, BitRate2 is useless, but setting it nevertheless was still faster than checking */
} else {
@@ -321,8 +321,12 @@ LOADMOD_SOF_SINGLE_LABEL:
if ((BitSent % 8) == 0) {
/* Last SOF bit has been put out. Start sending out data */
StateRegister = LOADMOD_BIT0_SINGLE;
ShiftRegister = (*CodecBufferPtr++);
if (ByteCount == 0) {
StateRegister = LOADMOD_FINISHED;
} else {
StateRegister = LOADMOD_BIT0_SINGLE;
ShiftRegister = (*CodecBufferPtr++);
}
} else {
StateRegister = LOADMOD_SOF_SINGLE;
}
@@ -403,8 +407,12 @@ LOADMOD_SOF_DUAL_LABEL:
if ((BitSent % 8) == 0) {
/* Last SOF bit has been put out. Start sending out data */
StateRegister = LOADMOD_BIT0_DUAL;
ShiftRegister = (*CodecBufferPtr++);
if (ByteCount == 0) {
StateRegister = LOADMOD_FINISHED;
} else {
StateRegister = LOADMOD_BIT0_DUAL;
ShiftRegister = (*CodecBufferPtr++);
}
} else {
StateRegister = LOADMOD_SOF_DUAL;
}
@@ -618,6 +626,23 @@ void ISO15693CodecDeInit(void) {
CodecSetLoadmodState(false);
}
void ISO15693StartEarlySend(bool bDualSubcarrier, uint16_t byteCount) {
// Buy a little more time to ready the responce (400 cycles == 14.7uS) before sending the SOF
CODEC_TIMER_LOADMOD.PER = ISO15693_T1_TIME + 200;
ByteCount = byteCount;
CodecBufferPtr = CodecBuffer;
/* Start loadmodulating */
if (bDualSubcarrier) {
CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_2);
StateRegister = LOADMOD_START_DUAL;
} else {
CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_1);
StateRegister = LOADMOD_START_SINGLE;
}
}
void ISO15693CodecTask(void) {
if (Flags.DemodFinished) {
Flags.DemodFinished = 0;
@@ -630,14 +655,19 @@ void ISO15693CodecTask(void) {
LogEntry(LOG_INFO_CODEC_RX_DATA, CodecBuffer, DemodByteCount);
LEDHook(LED_CODEC_RX, LED_PULSE);
if (CodecBuffer[0] & REQ_SUBCARRIER_DUAL) {
if (CodecBuffer[0] & REQ_SUBCARRIER_DUAL && ActiveConfiguration.TagFamily != TAG_FAMILY_ISO15693_ICLASS) {
bDualSubcarrier = true;
}
LogEntry(LOG_INFO_GENERIC, "Test1", 5);
AppReceivedByteCount = ApplicationProcess(CodecBuffer, DemodByteCount);
}
/* This is only reached when we've received a valid frame */
if (AppReceivedByteCount != ISO15693_APP_NO_RESPONSE) {
if (AppReceivedByteCount != ISO15693_APP_NO_RESPONSE && AppReceivedByteCount != ISO15693_APP_EARLY_SEND) {
if (AppReceivedByteCount == ISO15693_APP_SOF_ONLY) {
AppReceivedByteCount = 0;
}
if (AppReceivedByteCount > CODEC_BUFFER_SIZE - ISO15693_CRC16_SIZE) { /* CRC would be written outside codec buffer */
CodecBuffer[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
CodecBuffer[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP;
@@ -660,11 +690,14 @@ void ISO15693CodecTask(void) {
}
/* Calculate the CRC while modulation is already ongoing */
ISO15693AppendCRC(CodecBuffer, AppReceivedByteCount);
ByteCount += ISO15693_CRC16_SIZE; /* Increase this variable as it will be read by the codec during loadmodulation */
LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount + ISO15693_CRC16_SIZE);
} else {
if (ActiveConfiguration.TagFamily != TAG_FAMILY_ISO15693_ICLASS && AppReceivedByteCount != 0) {
ISO15693AppendCRC(CodecBuffer, AppReceivedByteCount);
ByteCount += ISO15693_CRC16_SIZE; /* Increase this variable as it will be read by the codec during loadmodulation */
LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount + ISO15693_CRC16_SIZE);
} else {
LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount);
}
} else if (AppReceivedByteCount != ISO15693_APP_EARLY_SEND) {
/* Overwrite the PERBUF register, which was configured in ISO15693_EOC, with the new appropriate value.
* This is expecially needed because, since load modulation has not been performed, we're jumping here straight after
* ISO15693_EOC. This implies that the data stored in the PERBUF register by ISO15693_EOC still has to be copied
+6
View File
@@ -8,7 +8,12 @@
#ifndef ISO15693_H_
#define ISO15693_H_
#include <stdint.h>
#include <stdbool.h>
#define ISO15693_APP_NO_RESPONSE 0x0000
#define ISO15693_APP_SOF_ONLY 0xFFFF
#define ISO15693_APP_EARLY_SEND 0xFFFE
/* Codec Interface */
void ISO15693CodecInit(void);
@@ -18,5 +23,6 @@ void ISO15693CodecTask(void);
/* Application Interface */
void ISO15693CodecStart(void);
void ISO15693CodecReset(void);
void ISO15693StartEarlySend(bool bDualSubcarrier, uint16_t byteCount);
#endif /* ISO15693_H_ */
+38
View File
@@ -69,6 +69,10 @@ static const MapEntryType PROGMEM ConfigurationMap[] = {
#ifdef CONFIG_EM4233_SUPPORT
{ .Id = CONFIG_EM4233, .Text = "EM4233" },
#endif
#ifdef CONFIG_ICLASS_SUPPORT
{ .Id = CONFIG_ICLASS, .Text = "ICLASS" },
{ .Id = CONFIG_ICLASS_DETECTION, .Text = "ICLASS_DETECTION" },
#endif
};
/* Include all Codecs and Applications */
@@ -499,6 +503,40 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.TagFamily = TAG_FAMILY_ISO14443A
},
#endif
#ifdef CONFIG_ICLASS_SUPPORT
[CONFIG_ICLASS] = {
.CodecInitFunc = ISO15693CodecInit,
.CodecDeInitFunc = ISO15693CodecDeInit,
.CodecTaskFunc = ISO15693CodecTask,
.ApplicationInitFunc = IClassAppInit,
.ApplicationResetFunc = IClassAppReset,
.ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
.ApplicationProcessFunc = IClassAppProcess,
.ApplicationGetUidFunc = IClassGetCsn,
.ApplicationSetUidFunc = IClassSetCsn,
.UidSize = ICLASS_CSN_SIZE,
.MemorySize = ICLASS_MEM_SIZE,
.ReadOnly = false,
.TagFamily = TAG_FAMILY_ISO15693_ICLASS
},
[CONFIG_ICLASS_DETECTION] = {
.CodecInitFunc = ISO15693CodecInit,
.CodecDeInitFunc = ISO15693CodecDeInit,
.CodecTaskFunc = ISO15693CodecTask,
.ApplicationInitFunc = IClassDetectionInit,
.ApplicationResetFunc = IClassAppReset,
.ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = ApplicationTickDummy,
.ApplicationProcessFunc = IClassAppProcess,
.ApplicationGetUidFunc = IClassGetCsn,
.ApplicationSetUidFunc = ApplicationSetUidDummy,
.UidSize = ICLASS_CSN_SIZE,
.MemorySize = ICLASS_MEM_SIZE,
.ReadOnly = true,
.TagFamily = TAG_FAMILY_ISO15693_ICLASS
},
#endif
};
ConfigurationType ActiveConfiguration;
+9 -4
View File
@@ -74,16 +74,21 @@ typedef enum {
#endif
#ifdef CONFIG_EM4233_SUPPORT
CONFIG_EM4233,
#endif
#ifdef CONFIG_ICLASS_SUPPORT
CONFIG_ICLASS,
CONFIG_ICLASS_DETECTION,
#endif
/* This HAS to be the last element */
CONFIG_COUNT
} ConfigurationEnum;
/** Tag Family definitions **/
#define TAG_FAMILY_NONE 0
#define TAG_FAMILY_ISO14443A 1
#define TAG_FAMILY_ISO14443B 2
#define TAG_FAMILY_ISO15693 5
#define TAG_FAMILY_NONE 0
#define TAG_FAMILY_ISO14443A 1
#define TAG_FAMILY_ISO14443B 2
#define TAG_FAMILY_ISO15693 5
#define TAG_FAMILY_ISO15693_ICLASS 6 // Disables CRC and dual subcarrier
/** With this `struct` the behavior of a configuration is defined. */
+3 -2
View File
@@ -23,6 +23,7 @@ SETTINGS += -DCONFIG_NTAG215_SUPPORT
# SETTINGS += -DCONFIG_TITAGITSTANDARD_SUPPORT
# SETTINGS += -DCONFIG_EM4233_SUPPORT
SETTINGS += -DCONFIG_ISO15693_SNIFF_SUPPORT
#SETTINGS += -DCONFIG_ICLASS_SUPPORT
#Support magic mode on mifare classic configuration
SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE
@@ -71,7 +72,7 @@ SETTINGS += -DLED_SETTING_GLOBAL
#Default logging mode
SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_OFF
#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_MEMORY
#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_TERMINAL
#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_LIVE
#Define if log settings should be global
SETTINGS += -DLOG_SETTING_GLOBAL
@@ -114,7 +115,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 Application/CryptoTDEA.S Application/NTAG215.c
SRC += Codec/ISO15693.c Codec/SniffISO15693.c
SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c Application/EM4233.c Application/Sniff15693.c
SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c Application/EM4233.c Application/Sniff15693.c Application/IClass.c
SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
LUFA_PATH = ../LUFA
CC_FLAGS = -flto -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)
+8 -7
View File
@@ -172,15 +172,16 @@ INLINE void FRAMWrite(const void *Buffer, uint16_t Address, uint16_t ByteCount)
SPIWriteBlock(Buffer, ByteCount);
FRAM_PORT.OUTSET = FRAM_CS;
if (0 == Address
#ifdef CONFIG_ISO14443A_READER_SUPPORT
if (0 == Address && GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ISO14443A_READER) {
ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration);
}
#else
if (0 == Address) {
ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration);
}
&& GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ISO14443A_READER
#endif
#ifdef CONFIG_ICLASS_SUPPORT
&& GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ICLASS_DETECTION
#endif
) {
ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration);
}
}
INLINE void FlashRead(void *Buffer, uint32_t Address, uint16_t ByteCount) {