PrepareFrame function first draft, there might be performance issues

This commit is contained in:
Federico Cerutti
2018-12-03 23:07:50 +01:00
parent 28f647818e
commit d091e2291b
3 changed files with 202 additions and 169 deletions
@@ -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;
}
}
@@ -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)
@@ -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)