Skip to content

Commit

Permalink
Merge pull request RfidResearchGroup#37 from ceres-c/rrg-iso15693-cod…
Browse files Browse the repository at this point in the history
…ec-upd

Porting ISO15693 codec and applications updates
  • Loading branch information
iceman1001 committed Sep 12, 2020
2 parents 1a41b8a + ebd6ab5 commit 1709c2f
Show file tree
Hide file tree
Showing 22 changed files with 3,921 additions and 3,836 deletions.
116 changes: 62 additions & 54 deletions Firmware/Chameleon-Mini/Application/EM4233.c
Expand Up @@ -23,9 +23,6 @@ static enum {
} State;

bool loggedIn;
uint8_t MyAFI; /* This variable holds current tag's AFI (is used in inventory) */

CurrentFrame FrameInfo;

void EM4233AppInit(void) {
State = STATE_READY;
Expand All @@ -38,7 +35,7 @@ void EM4233AppInit(void) {
FrameInfo.Selected = false;
loggedIn = false;
MemoryReadBlock(&MyAFI, EM4233_MEM_AFI_ADDRESS, 1);

MemoryReadBlock(&Uid, EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize);
}

void EM4233AppReset(void) {
Expand All @@ -51,6 +48,8 @@ void EM4233AppReset(void) {
FrameInfo.Addressed = false;
FrameInfo.Selected = false;
loggedIn = false;
MemoryReadBlock(&MyAFI, EM4233_MEM_AFI_ADDRESS, 1);
MemoryReadBlock(&Uid, EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize);
}

void EM4233AppTask(void) {
Expand All @@ -62,7 +61,7 @@ void EM4233AppTick(void) {
}

uint16_t EM4233_Lock_Block(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t BlockAddress = *FrameInfo.Parameters;
uint8_t LockStatus = 0;

Expand Down Expand Up @@ -92,7 +91,7 @@ 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;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t BlockAddress = *FrameInfo.Parameters;
uint8_t *Dataptr = FrameInfo.Parameters + 0x01; /* Data to write begins on 2nd byte of the frame received by the reader */
uint8_t LockStatus = 0;
Expand Down Expand Up @@ -127,7 +126,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;
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 LockStatus = 0;
Expand All @@ -138,7 +137,7 @@ uint16_t EM4233_Read_Single(uint8_t *FrameBuf, uint16_t FrameBytes) {
if (BlockAddress >= EM4233_NUMBER_OF_BLCKS) { /* check if the reader is requesting a sector out of bound */
if (FrameInfo.Addressed) { /* If the request is addressed */
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
FrameBuf[ISO15693_RES_ADDR_PARAM] = 0x0F; /* Magic number from real tag */
FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC;
ResponseByteCount += 2; /* Copied this behaviour from real tag, not specified in ISO documents */
}
return ResponseByteCount; /* If not addressed real tag does not respond */
Expand Down Expand Up @@ -168,7 +167,7 @@ uint16_t EM4233_Read_Single(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Read_Multiple(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
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 0x08 blocks if we get 0x07 in request */
Expand All @@ -179,7 +178,7 @@ uint16_t EM4233_Read_Multiple(uint8_t *FrameBuf, uint16_t FrameBytes) {
if (BlockAddress >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a block out of bound */
if (FrameInfo.Addressed) { /* If the request is addressed */
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
FrameBuf[ISO15693_RES_ADDR_PARAM] = 0x0F; /* Magic number from real tag */
FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC;
ResponseByteCount += 2; /* Copied this behaviour from real tag, not specified in ISO documents */
}
return ResponseByteCount; /* If not addressed real tag does not respond */
Expand Down Expand Up @@ -224,7 +223,7 @@ uint16_t EM4233_Read_Multiple(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Write_AFI(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t AFI = FrameInfo.Parameters[0];
uint8_t LockStatus = 0;

Expand All @@ -251,7 +250,7 @@ uint16_t EM4233_Write_AFI(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Lock_AFI(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t LockStatus = 0;

if (FrameInfo.ParamLen != 0)
Expand All @@ -278,7 +277,7 @@ uint16_t EM4233_Lock_AFI(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Write_DSFID(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t DSFID = FrameInfo.Parameters[0];
uint8_t LockStatus = 0;

Expand All @@ -304,7 +303,7 @@ uint16_t EM4233_Write_DSFID(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Lock_DSFID(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t LockStatus = 0;

if (FrameInfo.ParamLen != 0)
Expand All @@ -331,7 +330,7 @@ uint16_t EM4233_Lock_DSFID(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint8_t EM4233_Get_SysInfo(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t FramePtr; /* holds the address where block's data will be put */

if (FrameInfo.ParamLen != 0)
Expand All @@ -354,8 +353,6 @@ uint8_t EM4233_Get_SysInfo(uint8_t *FrameBuf, uint16_t FrameBytes) {
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 */
Expand Down Expand Up @@ -398,7 +395,7 @@ uint8_t EM4233_Get_SysInfo(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Get_Multi_Block_Sec_Stat(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
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;
Expand Down Expand Up @@ -427,7 +424,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;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
/* I've no idea how this request could generate errors ._.
if ( ) {
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
Expand Down Expand Up @@ -463,7 +460,7 @@ uint16_t EM4233_Select(uint8_t *FrameBuf, uint16_t FrameBytes, uint8_t *Uid) {
}

uint16_t EM4233_Reset_To_Ready(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
/* I've no idea how this request could generate errors ._.
if ( ) {
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
Expand All @@ -487,7 +484,7 @@ uint16_t EM4233_Reset_To_Ready(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Login(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t Password[4] = { 0 };

if (FrameInfo.ParamLen != 4 || !FrameInfo.Addressed || !(FrameInfo.Selected && State == STATE_SELECTED))
Expand Down Expand Up @@ -523,7 +520,7 @@ uint16_t EM4233_Login(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Auth1(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
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) /* Malformed: not enough or too much data */
Expand All @@ -548,7 +545,7 @@ uint16_t EM4233_Auth1(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233_Auth2(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
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 */
Expand All @@ -566,9 +563,7 @@ uint16_t EM4233_Auth2(uint8_t *FrameBuf, uint16_t FrameBytes) {
}

uint16_t EM4233AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
uint8_t Uid[ActiveConfiguration.UidSize];
EM4233GetUid(Uid);
ResponseByteCount = ISO15693_APP_NO_RESPONSE;

if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE))
/* malformed frame */
Expand All @@ -585,8 +580,8 @@ 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) {
switch (*FrameInfo.Command) {
case ISO15693_CMD_INVENTORY:
if (FrameInfo.ParamLen == 0)
return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */

Expand All @@ -596,79 +591,92 @@ uint16_t EM4233AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid);
ResponseByteCount += 10;
}
break;

} else if ((*FrameInfo.Command == ISO15693_CMD_STAY_QUIET) && FrameInfo.Addressed) {
State = STATE_QUIET;
case ISO15693_CMD_STAY_QUIET:
if (FrameInfo.Addressed)
State = STATE_QUIET;
break;

} else if (*FrameInfo.Command == ISO15693_CMD_READ_SINGLE) {
case ISO15693_CMD_READ_SINGLE:
ResponseByteCount = EM4233_Read_Single(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_WRITE_SINGLE) {
case ISO15693_CMD_WRITE_SINGLE:
ResponseByteCount = EM4233_Write_Single(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_LOCK_BLOCK) {
case ISO15693_CMD_LOCK_BLOCK:
ResponseByteCount = EM4233_Lock_Block(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_READ_MULTIPLE) {
case ISO15693_CMD_READ_MULTIPLE:
ResponseByteCount = EM4233_Read_Multiple(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_WRITE_AFI) {
case ISO15693_CMD_WRITE_AFI:
ResponseByteCount = EM4233_Write_AFI(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_LOCK_AFI) {
case ISO15693_CMD_LOCK_AFI:
ResponseByteCount = EM4233_Lock_AFI(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_WRITE_DSFID) {
case ISO15693_CMD_WRITE_DSFID:
ResponseByteCount = EM4233_Write_DSFID(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_LOCK_DSFID) {
case ISO15693_CMD_LOCK_DSFID:
ResponseByteCount = EM4233_Lock_DSFID(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_GET_SYS_INFO) {
case ISO15693_CMD_GET_SYS_INFO:
ResponseByteCount = EM4233_Get_SysInfo(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_GET_BLOCK_SEC) {
case ISO15693_CMD_GET_BLOCK_SEC:
ResponseByteCount = EM4233_Get_Multi_Block_Sec_Stat(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) {
case ISO15693_CMD_RESET_TO_READY:
ResponseByteCount = EM4233_Reset_To_Ready(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == EM4233_CMD_LOGIN) {
case EM4233_CMD_LOGIN:
ResponseByteCount = EM4233_Login(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == EM4233_CMD_AUTH1) {
case EM4233_CMD_AUTH1:
ResponseByteCount = EM4233_Auth1(FrameBuf, FrameBytes);
break;

} else if (*FrameInfo.Command == EM4233_CMD_AUTH2) {
case EM4233_CMD_AUTH2:
ResponseByteCount = EM4233_Auth2(FrameBuf, FrameBytes);
break;

} else {
default:
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 */
}
break;
}

} else if (State == STATE_QUIET) {
if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) {
ResponseByteCount = EM4233_Reset_To_Ready(FrameBuf, FrameBytes);
}
}

if (ResponseByteCount > 0) {
/* There is data to send. 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);
void EM4233SetUid(ConfigurationUidType NewUid) {
memcpy(Uid, NewUid, ActiveConfiguration.UidSize);
MemoryWriteBlock(NewUid, EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize);
}
5 changes: 5 additions & 0 deletions Firmware/Chameleon-Mini/Application/ISO15693-A.c
Expand Up @@ -2,6 +2,11 @@
#include "../Common.h"
#include <util/crc16.h>

CurrentFrame FrameInfo;
uint8_t Uid[ISO15693_GENERIC_UID_SIZE];
uint8_t MyAFI;
uint16_t ResponseByteCount;

//Refer to ISO/IEC 15693-3:2001 page 41
uint16_t calculateCRC(void *FrameBuf, uint16_t FrameBufSize) {
uint16_t reg = ISO15693_CRC16_PRESET;
Expand Down
4 changes: 4 additions & 0 deletions Firmware/Chameleon-Mini/Application/ISO15693-A.h
Expand Up @@ -85,6 +85,10 @@ typedef struct {
bool Addressed;
bool Selected;
} CurrentFrame;
extern CurrentFrame FrameInfo; /* Holds current frame information */
extern uint8_t Uid[];
extern uint8_t MyAFI; /* Holds current tag's AFI, used during inventory */
extern uint16_t ResponseByteCount; /* Length of response, used when building response frames */

void ISO15693AppendCRC(uint8_t *FrameBuf, uint16_t FrameBufSize);
bool ISO15693CheckCRC(void *FrameBuf, uint16_t FrameBufSize);
Expand Down
3 changes: 3 additions & 0 deletions Firmware/Chameleon-Mini/Application/Reader14443A.c
Expand Up @@ -19,6 +19,9 @@

// TODO replace remaining magic numbers

uint8_t ReaderSendBuffer[CODEC_BUFFER_SIZE];
uint16_t ReaderSendBitCount;

static bool Selected = false;
Reader14443Command Reader14443CurrentCommand = Reader14443_Do_Nothing;

Expand Down
4 changes: 2 additions & 2 deletions Firmware/Chameleon-Mini/Application/Reader14443A.h
Expand Up @@ -6,8 +6,8 @@

#define CRC_INIT 0x6363

uint8_t ReaderSendBuffer[CODEC_BUFFER_SIZE];
uint16_t ReaderSendBitCount;
extern uint8_t ReaderSendBuffer[];
extern uint16_t ReaderSendBitCount;

void Reader14443AAppInit(void);
void Reader14443AAppReset(void);
Expand Down
6 changes: 0 additions & 6 deletions Firmware/Chameleon-Mini/Application/Sl2s2002.c
Expand Up @@ -141,12 +141,6 @@ uint16_t Sl2s2002AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
break;
}

if (ResponseByteCount > 0) {
/* There is data to be sent. Append CRC */
ISO15693AppendCRC(FrameBuf, ResponseByteCount);
ResponseByteCount += ISO15693_CRC16_SIZE;
}

return ResponseByteCount;

} else { // Invalid CRC
Expand Down

0 comments on commit 1709c2f

Please sign in to comment.