From 9c37cf758bd520d779e187229ceab35301a2dbf3 Mon Sep 17 00:00:00 2001 From: chenzitai Date: Thu, 26 Jul 2018 02:28:03 +0100 Subject: [PATCH] Trace the Reader and card status in sniffing mode This will prepare for the autocalibrate of threshold If card selection fully detected, then the threshold is good, Otherwise it is not good. (cherry picked from commit f5c8485) --- .../Chameleon-Mini/Application/Sniff14443A.c | 127 ++++++++++++++++-- .../Chameleon-Mini/Codec/SniffISO14443-2A.c | 12 +- .../Chameleon-Mini/Codec/SniffISO14443-2A.h | 2 +- 3 files changed, 129 insertions(+), 12 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/Sniff14443A.c b/Firmware/Chameleon-Mini/Application/Sniff14443A.c index 68512a7..e652834 100644 --- a/Firmware/Chameleon-Mini/Application/Sniff14443A.c +++ b/Firmware/Chameleon-Mini/Application/Sniff14443A.c @@ -7,22 +7,31 @@ #include #include #include "Sniff14443A.h" -Sniff14443Command Sniff14443CurrentCommand = Sniff14443_Do_Nothing; - +#include "Codec/SniffISO14443-2A.h" extern bool checkParityBits(uint8_t * Buffer, uint16_t BitCount); - static enum { + +Sniff14443Command Sniff14443CurrentCommand = Sniff14443_Do_Nothing; +bool selected = false; +static enum { STATE_IDLE, - STATE_READER_DATA, - STATE_CARD_DATA + STATE_REQA, + STATE_ATQA, + STATE_ANTICOLLI, + STATE_SELECT, + STATE_UID, + STATE_SAK, } SniffState = STATE_IDLE; + void Sniff14443AAppInit(void){ - SniffState = STATE_IDLE; + SniffState = STATE_REQA; + selected = false; } void Sniff14443AAppReset(void){ SniffState = STATE_IDLE; Sniff14443CurrentCommand = Sniff14443_Do_Nothing; + selected = false; } // Currently APPTask and AppTick is not being used void Sniff14443AAppTask(void){/* Empty */} @@ -32,16 +41,116 @@ void Sniff14443AAppTimeout(void){ Sniff14443AAppReset(); } +void reset2REQA(void){ + SniffState = STATE_REQA; + LED_PORT.OUTCLR = LED_RED; + selected = false; + // TODO: Mark the current threshold as fail and continue + +} uint16_t Sniff14443AAppProcess(uint8_t* Buffer, uint16_t BitCount){ switch (Sniff14443CurrentCommand){ case Sniff14443_Do_Nothing: return 0; case Sniff14443_Autocalibrate: - // If received Reader WUPA - if(Buffer[0] == 0x26 || Buffer[0] == 0x54){ - LED_PORT.OUTSET = LED_RED; + switch (SniffState){ + case STATE_REQA: + // If received Reader REQA or WUPA + if (TrafficSource == TRAFFIC_READER && + (Buffer[0] == 0x26 || Buffer[0] == 0x54)) + { + SniffState = STATE_ATQA; + } else { + // Stay in this state, do noting + } + break; + case STATE_ATQA: + // ATQA: P RRRR XXXX P XXRX XXXX + if (TrafficSource == TRAFFIC_CARD && + BitCount == 2*9 && + (Buffer[0] & 0x20) == 0x00 && // Bit6 RFU shall be 0 + (Buffer[1] & 0xE0) == 0x00 && // bit13-16 RFU shall be 0 + (Buffer[2] & 0x01) == 0x00 && + checkParityBits(Buffer, BitCount)) + { + // Assume this is a good ATQA + SniffState = STATE_ANTICOLLI; + } else { + // If not ATQA, but REQA, then stay on this state, + // Reset to REQA, save the counter and reset the counter + if (TrafficSource == TRAFFIC_READER && + (Buffer[0] == 0x26 || Buffer[0] == 0x54)) { + } else { + // If not ATQA and not REQA then reset to REQA + reset2REQA(); + } + } + break; + case STATE_ANTICOLLI: + LED_PORT.OUTSET = LED_RED; + // SEL: 93/95/97 + if(TrafficSource == TRAFFIC_READER && + BitCount == 2*8 && + (Buffer[0] & 0xf0) == 0x90 && + (Buffer[0] & 0x09) == 0x01) + { + SniffState = STATE_UID; + } else{ + reset2REQA(); + } + break; + case STATE_UID: + if(TrafficSource == TRAFFIC_CARD && + BitCount == 5*9 && + checkParityBits(Buffer, BitCount)) + { + SniffState = STATE_SELECT; + } else { + reset2REQA(); + } + break; + case STATE_SELECT: + + // SELECT: 9 bytes, SEL = 93/95/97, NVB=70 + if (TrafficSource == TRAFFIC_READER && + BitCount == 9*8 && + (Buffer[0] & 0xf0) == 0x90 && + (Buffer[0] & 0x09) == 0x01 && + Buffer[1] == 0x70) + { + SniffState = STATE_SAK; + } else{ + // Not valid, reset + reset2REQA(); + } + break; + case STATE_SAK: + // SAK: 1Byte SAK + CRC + if(TrafficSource == TRAFFIC_CARD && + BitCount == 3*9 && + checkParityBits(Buffer, BitCount)) + { + if((Buffer[0] & 0x04) == 0x00){ + // UID complete, success SELECTED, + // TODO: Mark the current threshold as success and continue + // reset + SniffState = STATE_REQA; + selected = true; + LED_PORT.OUTCLR = LED_RED; + + } else { + // UID not complete, goto ANTICOLLI + SniffState = STATE_ANTICOLLI; + } + } else{ + reset2REQA(); + } + break; + default: + break; } break; + default: return 0; } diff --git a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c index fb2a51a..b58cc16 100644 --- a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c +++ b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.c @@ -513,18 +513,26 @@ void Sniff14443ACodecTask(void) PORTE.OUTSET = PIN3_bm; if(Flags.ReaderDataAvaliable){ Flags.ReaderDataAvaliable = false; + LogEntry(LOG_INFO_CODEC_SNI_READER_DATA, CodecBuffer, (ReaderBitCount+7)/8); - ApplicationProcess(CodecBuffer, (ReaderBitCount+7)/8); + // Let the Application layer know where this data comes from LEDHook(LED_CODEC_RX, LED_PULSE); + + TrafficSource = TRAFFIC_READER; + ApplicationProcess(CodecBuffer, ReaderBitCount); } if (Flags.CardDataAvaliable){ Flags.CardDataAvaliable = false; + // CardBitCount = removeParityBits(CodecBuffer2,CardBitCount ); LogEntry(LOG_INFO_CODEC_SNI_CARD_DATA_W_PARITY, CodecBuffer2, (CardBitCount + 7) / 8); LEDHook(LED_CODEC_RX, LED_PULSE); - ApplicationProcess(CodecBuffer2, (CardBitCount+7)/8); + + // Let the Application layer know where this data comes from + TrafficSource = TRAFFIC_CARD; + ApplicationProcess(CodecBuffer2, CardBitCount); } diff --git a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.h b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.h index b8616b0..0e22d46 100644 --- a/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.h +++ b/Firmware/Chameleon-Mini/Codec/SniffISO14443-2A.h @@ -9,7 +9,7 @@ #include "Codec.h" #include "Terminal/CommandLine.h" -extern enum RCTraffic {TRAFFIC_READER, TRAFFIC_CARD} TrafficSource; +enum RCTraffic {TRAFFIC_READER, TRAFFIC_CARD} TrafficSource; /* Codec Interface */ void Sniff14443ACodecInit(void); void Sniff14443ACodecDeInit(void);