forked from emsec/ChameleonMini
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request emsec#297 from leandre84/master
Add implementation of TI Tagit Plus vicinity card
- Loading branch information
Showing
7 changed files
with
319 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,257 @@ | ||
/* | ||
* TITagitplus.c | ||
* | ||
* Created 20210409 | ||
* Author: leandre84 | ||
* Based on TI Tag-it Standard implementation, read multiple inspired by Sl2s2002 implementation | ||
*/ | ||
|
||
#ifdef CONFIG_TITAGITPLUS_SUPPORT | ||
|
||
#include "ISO15693-A.h" | ||
#include "TITagitplus.h" | ||
|
||
static enum { | ||
STATE_READY, | ||
STATE_SELECTED, | ||
STATE_QUIET | ||
} State; | ||
|
||
uint64_t UserLockBits_Mask_Tagitplus = 0; /* Holds lock state of blocks 1-64 */ | ||
uint64_t FactoryLockBits_Mask_Tagitplus = 0; /* Holds lock state of blocks 1-64 */ | ||
|
||
void TITagitplusAppInit(void) { | ||
State = STATE_READY; | ||
|
||
FrameInfo.Flags = NULL; | ||
FrameInfo.Command = NULL; | ||
FrameInfo.Parameters = NULL; | ||
FrameInfo.ParamLen = 0; | ||
FrameInfo.Addressed = false; | ||
FrameInfo.Selected = false; | ||
|
||
MemoryReadBlock(&MyAFI, TITAGIT_PLUS_MEM_AFI_ADDRESS, 1); | ||
TITagitplusGetUid(Uid); | ||
} | ||
|
||
void TITagitplusAppReset(void) { | ||
State = STATE_READY; | ||
|
||
FrameInfo.Flags = NULL; | ||
FrameInfo.Command = NULL; | ||
FrameInfo.Parameters = NULL; | ||
FrameInfo.ParamLen = 0; | ||
FrameInfo.Addressed = false; | ||
FrameInfo.Selected = false; | ||
|
||
MemoryReadBlock(&MyAFI, TITAGIT_PLUS_MEM_AFI_ADDRESS, 1); | ||
TITagitplusGetUid(Uid); | ||
} | ||
|
||
|
||
void TITagitplusAppTask(void) { | ||
|
||
} | ||
|
||
void TITagitplusAppTick(void) { | ||
|
||
} | ||
|
||
uint16_t TITagitplusAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) { | ||
ResponseByteCount = ISO15693_APP_NO_RESPONSE; | ||
|
||
if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE)) | ||
/* malformed frame */ | ||
return ResponseByteCount; | ||
|
||
if (!ISO15693PrepareFrame(FrameBuf, FrameBytes, &FrameInfo, State == STATE_SELECTED, Uid, MyAFI)) | ||
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 || *FrameInfo.Command == ISO15693_CMD_READ_MULTIPLE) { | ||
uint8_t *FramePtr; /* holds the address where block's data will be put */ | ||
uint8_t PageAddress = *FrameInfo.Parameters; | ||
uint8_t PageAddressCount = 1; | ||
|
||
if (*FrameInfo.Command == ISO15693_CMD_READ_SINGLE) { | ||
if (FrameInfo.ParamLen != 1) { | ||
break; /* malformed: not enough or too much data */ | ||
} | ||
} else { | ||
if (FrameInfo.ParamLen != 2) { | ||
break; /* malformed: not enough or too much data */ | ||
} | ||
PageAddressCount = *(FrameInfo.Parameters+1)+1; | ||
} | ||
|
||
if (PageAddress >= TITAGIT_PLUS_NUMBER_OF_USER_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; | ||
} | ||
|
||
/* position to one after flag bit and keep its value for now as we still need it to determine if option bit is set */ | ||
FramePtr = FrameBuf + 1; | ||
ResponseByteCount = 1; | ||
|
||
for (int i = 0; i < PageAddressCount; i++) { | ||
/* write additional bit with locking information */ | ||
if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set - handle extra byte in response*/ | ||
if (FactoryLockBits_Mask_Tagitplus & (1 << PageAddress)) { /* tests if the n-th bit of the factory bitmask if set to 1 */ | ||
*(FramePtr) = 0x02; /* return bit 1 set as 1 (factory locked) */ | ||
} else if (UserLockBits_Mask_Tagitplus & (1 << PageAddress)) { /* tests if the n-th bit of the user bitmask if set to 1 */ | ||
*(FramePtr) = 0x01; /* return bit 0 set as 1 (user locked) */ | ||
} else { | ||
*(FramePtr) = 0x00; /* return lock status 00 (unlocked) */ | ||
} | ||
|
||
FramePtr++; | ||
ResponseByteCount++; | ||
} | ||
|
||
/* write data page, increment response bytes and prepare pointer etc for next iteration */ | ||
MemoryReadBlock(FramePtr, PageAddress * TITAGIT_PLUS_BYTES_PER_PAGE, TITAGIT_PLUS_BYTES_PER_PAGE); | ||
FramePtr += TITAGIT_PLUS_BYTES_PER_PAGE; | ||
ResponseByteCount += TITAGIT_PLUS_BYTES_PER_PAGE; | ||
PageAddress++; | ||
} | ||
|
||
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* flags */ | ||
|
||
} 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_PLUS_NUMBER_OF_USER_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 = FrameInfo.Parameters + 1; | ||
|
||
if (FactoryLockBits_Mask_Tagitplus & (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_Tagitplus & (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_PLUS_BYTES_PER_PAGE, TITAGIT_PLUS_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_PLUS_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_Tagitplus & (1 << PageAddress)) || (UserLockBits_Mask_Tagitplus & (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_Tagitplus |= (1 << PageAddress); /* */ | ||
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; | ||
ResponseByteCount = 1; | ||
} | ||
|
||
} else if (*FrameInfo.Command == ISO15693_CMD_GET_SYS_INFO) { | ||
FrameBuf[0] = 0; /* Flags */ | ||
FrameBuf[1] = 0x0F; /* InfoFlags */ | ||
ISO15693CopyUid(&FrameBuf[2], Uid); | ||
FrameBuf[10] = 0x00; | ||
FrameBuf[11] = 0x00; | ||
FrameBuf[12] = 0x3F; | ||
FrameBuf[13] = 0x03; | ||
FrameBuf[14] = 0x8B; | ||
ResponseByteCount = 15; | ||
} 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; | ||
} | ||
|
||
return ResponseByteCount; | ||
} | ||
|
||
void TITagitplusGetUid(ConfigurationUidType Uid) { | ||
MemoryReadBlock(&Uid[0], TITAGIT_PLUS_MEM_UID_ADDRESS, ActiveConfiguration.UidSize); | ||
|
||
// Reverse UID after reading it | ||
TITagitplusFlipUid(Uid); | ||
} | ||
|
||
void TITagitplusSetUid(ConfigurationUidType NewUid) { | ||
memcpy(Uid, NewUid, ActiveConfiguration.UidSize); // Update the local variable | ||
// Reverse UID before writing it | ||
TITagitplusFlipUid(Uid); | ||
|
||
MemoryWriteBlock(Uid, TITAGIT_PLUS_MEM_UID_ADDRESS, ActiveConfiguration.UidSize); | ||
} | ||
|
||
void TITagitplusFlipUid(ConfigurationUidType Uid) { | ||
uint8_t tmp, *tail; | ||
tail = Uid + ActiveConfiguration.UidSize - 1; | ||
while (Uid < tail) { | ||
tmp = *Uid; | ||
*Uid++ = *tail; | ||
*tail-- = tmp; | ||
} | ||
} | ||
|
||
#endif /* CONFIG_TITAGITPLUS_SUPPORT */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* TITagitplus.h | ||
* | ||
* Created 20210409 | ||
* Author: leandre84 | ||
* Based on TI Tag-it Standard implementation | ||
*/ | ||
|
||
#ifndef TITAGITPLUS_H_ | ||
#define TITAGITPLUS_H_ | ||
|
||
#include "Application.h" | ||
#include "ISO15693-A.h" | ||
|
||
#define TITAGIT_PLUS_UID_SIZE ISO15693_GENERIC_UID_SIZE //ISO15693_UID_SIZE | ||
#define TITAGIT_PLUS_MEM_SIZE 0x110 //TAG-IT PLUS MAX MEM SIZE | ||
#define TITAGIT_PLUS_BYTES_PER_PAGE 4 | ||
#define TITAGIT_PLUS_NUMBER_OF_SECTORS ( TITAGIT_PLUS_MEM_SIZE / TITAGIT_PLUS_BYTES_PER_PAGE ) | ||
#define TITAGIT_PLUS_NUMBER_OF_USER_SECTORS ( TITAGIT_PLUS_NUMBER_OF_SECTORS - 4 ) | ||
#define TITAGIT_PLUS_MEM_UID_ADDRESS 0x100 // UID byte address (two pages) | ||
#define TITAGIT_PLUS_MEM_DSFID_ADDRESS 0x108 // DSFID byte address | ||
#define TITAGIT_PLUS_MEM_AFI_ADDRESS 0x10C // AFI byte address | ||
|
||
void TITagitplusAppInit(void); | ||
void TITagitplusAppReset(void); | ||
void TITagitplusAppTask(void); | ||
void TITagitplusAppTick(void); | ||
uint16_t TITagitplusAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes); | ||
void TITagitplusGetUid(ConfigurationUidType Uid); | ||
void TITagitplusSetUid(ConfigurationUidType Uid); | ||
void TITagitplusFlipUid(ConfigurationUidType Uid); | ||
|
||
#endif /* TITAGITPLUS_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters