Skip to content

Commit

Permalink
Merge pull request #121 from shinhub/mifare_classic_refactor
Browse files Browse the repository at this point in the history
Mifare classic refactor
  • Loading branch information
iceman1001 authored Aug 17, 2019
2 parents 7d7a391 + 0615995 commit 28bb0eb
Show file tree
Hide file tree
Showing 6 changed files with 517 additions and 634 deletions.
106 changes: 15 additions & 91 deletions Firmware/Chameleon-Mini/Application/ISO14443-3A.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@

#include "ISO14443-3A.h"

#define CRC_INIT 0x6363
#define CRC_INIT_R 0xC6C6 /* Bit reversed */
#define CRC_INIT 0x6363
#define CRC_INIT_R 0xC6C6 /* Bit reversed */

#define USE_HW_CRC

#ifdef USE_HW_CRC
void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount)
{
uint8_t* DataPtr = (uint8_t*) Buffer;
Expand All @@ -34,7 +31,8 @@ void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount)

CRC.CTRL = CRC_SOURCE_DISABLE_gc;
}
#else

/* Alternative implementation if hardware CRC is not available
#include <util/crc16.h>
void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount)
{
Expand All @@ -49,9 +47,8 @@ void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount)
DataPtr[0] = (Checksum >> 0) & 0x00FF;
DataPtr[1] = (Checksum >> 8) & 0x00FF;
}
#endif
*/

#ifdef USE_HW_CRC
bool ISO14443ACheckCRCA(const void* Buffer, uint16_t ByteCount)
{
const uint8_t* DataPtr = (const uint8_t*) Buffer;
Expand All @@ -74,7 +71,8 @@ bool ISO14443ACheckCRCA(const void* Buffer, uint16_t ByteCount)

return Result;
}
#else

/* Alternative implementation if hardware CRC is not available
#include <util/crc16.h>
bool ISO14443ACheckCRCA(const void* Buffer, uint16_t ByteCount)
{
Expand All @@ -89,85 +87,11 @@ bool ISO14443ACheckCRCA(const void* Buffer, uint16_t ByteCount)
return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF));
}
#endif

#if 0
bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue)
{
uint8_t* DataPtr = (uint8_t*) Buffer;
uint8_t NVB = DataPtr[1];
//uint8_t CollisionByteCount = (NVB >> 4) & 0x0F;
//uint8_t CollisionBitCount = (NVB >> 0) & 0x0F;

switch (NVB) {
case ISO14443A_NVB_AC_START:
/* Start of anticollision procedure.
* Send whole UID CLn + BCC */
DataPtr[0] = UidCL[0];
DataPtr[1] = UidCL[1];
DataPtr[2] = UidCL[2];
DataPtr[3] = UidCL[3];
DataPtr[4] = ISO14443A_CALC_BCC(DataPtr);

*BitCount = ISO14443A_CL_FRAME_SIZE;

return false;

case ISO14443A_NVB_AC_END:
/* End of anticollision procedure.
* Send SAK CLn if we are selected. */
if ( (DataPtr[2] == UidCL[0]) &&
(DataPtr[3] == UidCL[1]) &&
(DataPtr[4] == UidCL[2]) &&
(DataPtr[5] == UidCL[3]) ) {

DataPtr[0] = SAKValue;
ISO14443AAppendCRCA(Buffer, 1);

*BitCount = ISO14443A_SAK_FRAME_SIZE;
return true;
} else {
/* We have not been selected. Don't send anything. */
*BitCount = 0;
return false;
}
default:
uint8_t CollisionBitCount = NVB & 0x0f;
if (CollisionBitCount == 0) {
/* Full-byte anticollision frame supports */
uint8_t CollisionByteCount = ((NVB >> 4) & 0x0f) - 2;
/* Check for our UID is selecting */
if (memcmp(UidCL, &DataPtr[2], CollisionByteCount) != 0) {
*BitCount = 0;
return false;
}
memcpy(DataPtr, &UidCL[CollisionByteCount], 4 - CollisionByteCount);
/* Calc original BCC */
DataPtr[4 - CollisionByteCount] = ISO14443A_CALC_BCC(UidCL);
*BitCount = (5 - CollisionByteCount) * BITS_PER_BYTE;
} else {
/* Partial-byte anticollision frame not supported */
*BitCount = 0;
}
return false;
}
}

bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue, bool FromHalt)
{
uint8_t* DataPtr = (uint8_t*) Buffer;

if ( ((! FromHalt) && (DataPtr[0] == ISO14443A_CMD_REQA)) ||
(DataPtr[0] == ISO14443A_CMD_WUPA) ){
DataPtr[0] = (ATQAValue >> 0) & 0x00FF;
DataPtr[1] = (ATQAValue >> 8) & 0x00FF;

*BitCount = ISO14443A_ATQA_FRAME_SIZE;

return true;
} else {
return false;
}
}

#endif
*/

/* Coded in H to allow exportable inlining
INLINE bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue);
INLINE bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue, bool FromHalt);
INLINE bool ISO14443AIsWakeUp(uint8_t* Buffer, bool FromHalt);
INLINE void ISO14443ASetWakeUpResponse(uint8_t* Buffer, uint16_t ATQAValue);
*/
37 changes: 25 additions & 12 deletions Firmware/Chameleon-Mini/Application/ISO14443-3A.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,16 @@
void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount);
bool ISO14443ACheckCRCA(const void* Buffer, uint16_t ByteCount);

/* Coded here to allow exportable inlining */
INLINE bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue);
INLINE bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue, bool FromHalt);
INLINE bool ISO14443AIsWakeUp(uint8_t* Buffer, bool FromHalt);
INLINE void ISO14443ASetWakeUpResponse(uint8_t* Buffer, uint16_t ATQAValue);

INLINE
bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue)
{
bool ret = false;
uint8_t* DataPtr = (uint8_t*) Buffer;
uint8_t NVB = DataPtr[1];
//uint8_t CollisionByteCount = (NVB >> 4) & 0x0F;
Expand All @@ -71,7 +75,7 @@ bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t S

*BitCount = ISO14443A_CL_FRAME_SIZE;

return false;
break;

case ISO14443A_NVB_AC_END:
/* End of anticollision procedure.
Expand All @@ -85,12 +89,12 @@ bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t S
ISO14443AAppendCRCA(Buffer, 1);

*BitCount = ISO14443A_SAK_FRAME_SIZE;
return true;
ret = true;
} else {
/* We have not been selected. Don't send anything. */
*BitCount = 0;
return false;
}
break;
default:
{
uint8_t CollisionBitCount = NVB & 0x0f;
Expand All @@ -100,7 +104,6 @@ bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t S
/* Check for our UID is selecting */
if (memcmp(UidCL, &DataPtr[2], CollisionByteCount) != 0) {
*BitCount = 0;
return false;
}
memcpy(DataPtr, &UidCL[CollisionByteCount], 4 - CollisionByteCount);
/* Calc original BCC */
Expand All @@ -110,29 +113,39 @@ bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t S
/* Partial-byte anticollision frame not supported */
*BitCount = 0;
}
return false;
}
}
return ret;
}

INLINE
bool ISO14443AIsWakeUp(uint8_t* Buffer, bool FromHalt) {
return ( ((!FromHalt) && (Buffer[0] == ISO14443A_CMD_REQA))
|| (Buffer[0] == ISO14443A_CMD_WUPA) );
}

INLINE
void ISO14443ASetWakeUpResponse(uint8_t* Buffer, uint16_t ATQAValue) {
Buffer[0] = (ATQAValue >> 0) & 0x00FF;
Buffer[1] = (ATQAValue >> 8) & 0x00FF;
}

INLINE
bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue, bool FromHalt)
{
bool ret = false;
uint8_t* DataPtr = (uint8_t*) Buffer;

if ( ((! FromHalt) && (DataPtr[0] == ISO14443A_CMD_REQA)) ||
(DataPtr[0] == ISO14443A_CMD_WUPA) ){
DataPtr[0] = (ATQAValue >> 0) & 0x00FF;
DataPtr[1] = (ATQAValue >> 8) & 0x00FF;
if ( ISO14443AIsWakeUp(DataPtr, FromHalt) ) {
ISO14443ASetWakeUpResponse(DataPtr, ATQAValue);

*BitCount = ISO14443A_ATQA_FRAME_SIZE;

return true;
ret = true;
} else {
*BitCount = 0;

return false;
}
return ret;
}

#endif
Loading

0 comments on commit 28bb0eb

Please sign in to comment.