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.
This commit is contained in:
Federico Cerutti
2018-12-28 00:28:22 +01:00
parent f3f59beb9a
commit 5f6c35d7a6
5 changed files with 77 additions and 10 deletions
+13 -5
View File
@@ -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;
@@ -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;
}
@@ -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)
@@ -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) {
@@ -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);