EM4233 first draft

This commit is contained in:
MrMoDDoM
2018-12-10 19:43:43 +01:00
parent 1da44037c6
commit b28d8cb337
9 changed files with 341 additions and 7 deletions
@@ -20,7 +20,7 @@
#include "Sl2s2002.h"
#include "TITagitstandard.h"
#include "Sniff14443A.h"
#include "EM4233.h"
/* Function wrappers */
INLINE void ApplicationInit(void) {
@@ -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);
}
@@ -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_ */
@@ -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;
@@ -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;
+21 -2
View File
@@ -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;
+3
View File
@@ -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
Binary file not shown.
+2 -1
View File
@@ -16,6 +16,7 @@ SETTINGS += -DCONFIG_VICINITY_SUPPORT
SETTINGS += -DCONFIG_SL2S2002_SUPPORT
SETTINGS += -DCONFIG_TITAGITSTANDARD_SUPPORT
SETTINGS += -DCONFIG_ISO15693_SNIFF_SUPPORT
SETTINGS += -DCONFIG_EM4233_SUPPORT
#Support magic mode on mifare classic configuration
SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE
@@ -99,7 +100,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/TITagitstandard.c Application/ISO15693-A.c
SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c Application/EM4233.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)