diff --git a/Firmware/Chameleon-Mini/Application/TITagitstandard.c b/Firmware/Chameleon-Mini/Application/TITagitstandard.c index 73784fb..f334b99 100644 --- a/Firmware/Chameleon-Mini/Application/TITagitstandard.c +++ b/Firmware/Chameleon-Mini/Application/TITagitstandard.c @@ -22,6 +22,9 @@ static enum { STATE_QUIET } State; +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 @@ -30,6 +33,9 @@ static enum { void TITagitstandardAppInit(void) { State = STATE_READY; + FactoryLockBits_Mask |= (1 << 8); /* Locks block 8... */ + FactoryLockBits_Mask |= (1 << 9); /* ...and 9, which contains the UID */ + UserLockBits_Mask |= (1 << 3); /* TESTING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ } void TITagitstandardAppReset(void) @@ -92,19 +98,24 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) } if (FrameBuf[ISO15693_ADDR_FLAGS] & ISO15693_REQ_FLAG_OPTION) { /* request with option flag set */ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - /* UID is stored in blocks 8 and 9 which are blocked */ - FrameBuf[1] = ( PageAddress == 8 || PageAddress == 9) ? 0x02 : 0x00; /* block security status: when request has the 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*/ - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; /* Flags */ + } else { /* request with option flag not set */ FramePtr = FrameBuf + 1; ResponseByteCount = 5; } - MemoryReadBlock(FramePtr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); + 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) { @@ -112,6 +123,8 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) 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*/ @@ -121,17 +134,57 @@ uint16_t TITagitstandardAppProcess(uint8_t* FrameBuf, uint16_t FrameBytes) 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]; } - MemoryWriteBlock(Dataptr, PageAddress * TITAGIT_BYTES_PER_PAGE, TITAGIT_BYTES_PER_PAGE); - FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_NO_ERROR; - ResponseByteCount = 1; + 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: - /* TODO: Selected has to be impemented altogether */ + /* Selected state is not supported by Ti TagIt Standard */ break; case STATE_QUIET: