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);