mirror of
https://github.com/RfidResearchGroup/ChameleonMini.git
synced 2026-05-12 11:20:37 -07:00
Merge pull request #180 from gypsophlia/SniffBothWay14443-pr
Sniff Both Way 14443
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "MifareUltralight.h"
|
||||
#include "MifareClassic.h"
|
||||
#include "Reader14443A.h"
|
||||
#include "Sniff14443A.h"
|
||||
|
||||
/* Function wrappers */
|
||||
INLINE void ApplicationInit(void) {
|
||||
|
||||
@@ -141,6 +141,7 @@ uint16_t addParityBits(uint8_t * Buffer, uint16_t BitCount)
|
||||
|
||||
uint16_t removeParityBits(uint8_t * Buffer, uint16_t BitCount)
|
||||
{
|
||||
// Short frame, no parity bit is added
|
||||
if (BitCount == 7)
|
||||
return 7;
|
||||
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
//
|
||||
// Created by Zitai Chen on 25/07/2018.
|
||||
// Application layer for sniffing
|
||||
// Currently only support Autocalibrate
|
||||
//
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <LED.h>
|
||||
#include "Sniff14443A.h"
|
||||
#include "Codec/SniffISO14443-2A.h"
|
||||
extern bool checkParityBits(uint8_t * Buffer, uint16_t BitCount);
|
||||
|
||||
Sniff14443Command Sniff14443CurrentCommand = Sniff14443_Do_Nothing;
|
||||
//bool selected = false;
|
||||
static enum {
|
||||
STATE_IDLE,
|
||||
STATE_REQA,
|
||||
STATE_ATQA,
|
||||
STATE_ANTICOLLI,
|
||||
STATE_SELECT,
|
||||
STATE_UID,
|
||||
STATE_SAK,
|
||||
} SniffState = STATE_IDLE;
|
||||
|
||||
static uint16_t tmp_th = CODEC_THRESHOLD_CALIBRATE_MIN;
|
||||
static uint8_t Thresholds[(CODEC_THRESHOLD_CALIBRATE_MAX - CODEC_THRESHOLD_CALIBRATE_MIN) /
|
||||
CODEC_THRESHOLD_CALIBRATE_STEPS] = {0};
|
||||
|
||||
void Sniff14443AAppInit(void){
|
||||
SniffState = STATE_REQA;
|
||||
// Get current threshold and continue searching from here
|
||||
tmp_th = GlobalSettings.ActiveSettingPtr->ReaderThreshold;
|
||||
}
|
||||
|
||||
void Sniff14443AAppReset(void){
|
||||
SniffState = STATE_IDLE;
|
||||
|
||||
Sniff14443CurrentCommand = Sniff14443_Do_Nothing;
|
||||
}
|
||||
// Currently APPTask and AppTick is not being used
|
||||
void Sniff14443AAppTask(void){/* Empty */}
|
||||
void Sniff14443AAppTick(void){/* Empty */}
|
||||
|
||||
void Sniff14443AAppTimeout(void){
|
||||
Sniff14443AAppReset();
|
||||
}
|
||||
|
||||
INLINE void reset2REQA(void){
|
||||
SniffState = STATE_REQA;
|
||||
LED_PORT.OUTCLR = LED_RED;
|
||||
|
||||
// Mark the current threshold as fail and continue
|
||||
if(tmp_th < CODEC_THRESHOLD_CALIBRATE_MAX){
|
||||
Thresholds[(tmp_th - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS] = 0;
|
||||
tmp_th = CodecThresholdIncrement();
|
||||
} else{
|
||||
// mark finish
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_FALSE, NULL);
|
||||
}
|
||||
}
|
||||
uint16_t Sniff14443AAppProcess(uint8_t* Buffer, uint16_t BitCount){
|
||||
switch (Sniff14443CurrentCommand){
|
||||
case Sniff14443_Do_Nothing: {
|
||||
return 0;
|
||||
}
|
||||
case Sniff14443_Autocalibrate: {
|
||||
|
||||
switch (SniffState) {
|
||||
case STATE_REQA:
|
||||
LED_PORT.OUTCLR = LED_RED;
|
||||
// If received Reader REQA or WUPA
|
||||
if (TrafficSource == TRAFFIC_READER &&
|
||||
(Buffer[0] == 0x26 || Buffer[0] == 0x52)) {
|
||||
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] == 0x52)) {
|
||||
} else {
|
||||
// If not ATQA and not REQA then reset to REQA
|
||||
reset2REQA();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_ANTICOLLI:
|
||||
// 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,
|
||||
// Mark the current threshold as ok and finish
|
||||
// reset
|
||||
SniffState = STATE_REQA;
|
||||
LED_PORT.OUTSET = LED_RED;
|
||||
Thresholds[(tmp_th - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS] += 1;
|
||||
CommandLinePendingTaskFinished(COMMAND_INFO_OK_WITH_TEXT_ID, NULL);
|
||||
// Send this threshold to terminal
|
||||
char tmpBuf[10];
|
||||
snprintf(tmpBuf, 10, "%4" PRIu16 ": ", tmp_th);
|
||||
TerminalSendString(tmpBuf);
|
||||
|
||||
// Save value to EEPROM
|
||||
SETTING_UPDATE(GlobalSettings.ActiveSettingPtr->ReaderThreshold);
|
||||
|
||||
Sniff14443AAppReset();
|
||||
} else {
|
||||
// UID not complete, goto ANTICOLLI
|
||||
SniffState = STATE_ANTICOLLI;
|
||||
}
|
||||
} else {
|
||||
reset2REQA();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Zitai Chen on 25/07/2018.
|
||||
//
|
||||
|
||||
#ifndef CHAMELEON_MINI_SNIFF14443A_H
|
||||
#define CHAMELEON_MINI_SNIFF14443A_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void Sniff14443AAppInit(void);
|
||||
void Sniff14443AAppReset(void);
|
||||
void Sniff14443AAppTask(void);
|
||||
void Sniff14443AAppTick(void);
|
||||
void Sniff14443AAppTimeout(void);
|
||||
|
||||
uint16_t Sniff14443AAppProcess(uint8_t* Buffer, uint16_t BitCount);
|
||||
|
||||
typedef enum {
|
||||
Sniff14443_Do_Nothing,
|
||||
Sniff14443_Autocalibrate,
|
||||
} Sniff14443Command;
|
||||
|
||||
#endif //CHAMELEON_MINI_SNIFF14443A_H
|
||||
|
||||
@@ -23,7 +23,7 @@ static volatile struct {
|
||||
} ReaderFieldFlags = { false };
|
||||
|
||||
uint8_t CodecBuffer[CODEC_BUFFER_SIZE];
|
||||
|
||||
uint8_t CodecBuffer2[CODEC_BUFFER_SIZE];
|
||||
// the following three functions prevent sending data directly after turning on the reader field
|
||||
void CodecReaderFieldStart(void) // DO NOT CALL THIS FUNCTION INSIDE APPLICATION!
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "ISO14443-2A.h"
|
||||
#include "Reader14443-2A.h"
|
||||
#include "SniffISO14443-2A.h"
|
||||
|
||||
/* Timing definitions for ISO14443A */
|
||||
#define ISO14443A_SUBCARRIER_DIVIDER 16
|
||||
@@ -24,7 +25,7 @@
|
||||
#define ISO14443A_BIT_RATE_CYCLES 128
|
||||
#define ISO14443A_FRAME_DELAY_PREV1 1236
|
||||
#define ISO14443A_FRAME_DELAY_PREV0 1172
|
||||
#define ISO14443A_RX_PENDING_TIMEOUT 1 // ms
|
||||
#define ISO14443A_RX_PENDING_TIMEOUT 4 // ms
|
||||
|
||||
/* Peripheral definitions */
|
||||
#define CODEC_DEMOD_POWER_PORT PORTB
|
||||
@@ -38,6 +39,7 @@
|
||||
#define CODEC_DEMOD_IN_EVMUX0 EVSYS_CHMUX_PORTB_PIN1_gc
|
||||
#define CODEC_DEMOD_IN_EVMUX1 EVSYS_CHMUX_PORTB_PIN2_gc
|
||||
#define CODEC_DEMOD_IN_INT0_VECT PORTB_INT0_vect
|
||||
#define CODEC_DEMOD_IN_INT1_VECT PORTB_INT1_vect
|
||||
#define CODEC_LOADMOD_PORT PORTC
|
||||
#define CODEC_LOADMOD_MASK PIN6_bm
|
||||
#define CODEC_CARRIER_IN_PORT PORTC
|
||||
@@ -57,6 +59,8 @@
|
||||
#define CODEC_TIMER_SAMPLING TCD0
|
||||
#define CODEC_TIMER_SAMPLING_CCA_VECT TCD0_CCA_vect
|
||||
#define CODEC_TIMER_SAMPLING_CCB_VECT TCD0_CCB_vect
|
||||
#define CODEC_TIMER_SAMPLING_CCC_VECT TCD0_CCC_vect
|
||||
#define CODEC_TIMER_SAMPLING_CCD_VECT TCD0_CCD_vect
|
||||
#define CODEC_TIMER_LOADMOD TCE0
|
||||
#define CODEC_TIMER_LOADMOD_OVF_VECT TCE0_OVF_vect
|
||||
#define CODEC_TIMER_LOADMOD_CCA_VECT TCE0_CCA_vect
|
||||
@@ -80,6 +84,8 @@
|
||||
#define CODEC_THRESHOLD_CALIBRATE_STEPS 16
|
||||
#define CODEC_TIMER_TIMESTAMPS TCD1
|
||||
#define CODEC_TIMER_TIMESTAMPS_CCA_VECT TCD1_CCA_vect
|
||||
#define CODEC_TIMER_TIMESTAMPS_CCB_VECT TCD1_CCB_vect
|
||||
|
||||
|
||||
#define CODEC_BUFFER_SIZE 256
|
||||
|
||||
@@ -90,9 +96,11 @@
|
||||
#define Codec8Reg2 GPIOR2
|
||||
#define Codec8Reg3 GPIOR3
|
||||
#define CodecCount16Register1 (*((volatile uint16_t*) &GPIOR4)) /* GPIOR4 & GPIOR5 */
|
||||
#define CodecCount16Register2 (*((volatile uint16_t*) &GPIOR6)) /* GPIOR4 & GPIOR5 */
|
||||
#define CodecCount16Register2 (*((volatile uint16_t*) &GPIOR6)) /* GPIOR6 & GPIOR7 */
|
||||
#define CodecPtrRegister1 (*((volatile uint8_t**) &GPIOR8))
|
||||
#define CodecPtrRegister2 (*((volatile uint8_t**) &GPIORA))
|
||||
#define CodecPtrRegister3 (*((volatile uint8_t**) &GPIORC))
|
||||
|
||||
|
||||
extern uint16_t Reader_FWT;
|
||||
|
||||
@@ -104,6 +112,7 @@ typedef enum {
|
||||
} SubcarrierModType;
|
||||
|
||||
extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE];
|
||||
extern uint8_t CodecBuffer2[CODEC_BUFFER_SIZE];
|
||||
|
||||
INLINE void CodecInit(void) {
|
||||
ActiveConfiguration.CodecInitFunc();
|
||||
@@ -140,10 +149,14 @@ INLINE void CodecInitCommon(void)
|
||||
CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL0 = PORT_ISC_RISING_gc;
|
||||
CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL1 = PORT_ISC_FALLING_gc;
|
||||
CODEC_DEMOD_IN_PORT.INT0MASK = 0;
|
||||
CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc;
|
||||
CODEC_DEMOD_IN_PORT.INT1MASK = 0;
|
||||
CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc | PORT_INT1LVL_HI_gc;
|
||||
EVSYS.CH0MUX = CODEC_DEMOD_IN_EVMUX0;
|
||||
EVSYS.CH1MUX = CODEC_DEMOD_IN_EVMUX1;
|
||||
|
||||
EVSYS.CH2MUX = CODEC_DEMOD_IN_EVMUX0;
|
||||
|
||||
|
||||
/* Configure loadmod pin configuration and use a virtual port configuration
|
||||
* for single instruction cycle access */
|
||||
CODEC_LOADMOD_PORT.DIRSET = CODEC_LOADMOD_MASK;
|
||||
@@ -231,6 +244,7 @@ INLINE void CodecSetLoadmodState(bool bOnOff) {
|
||||
}
|
||||
}
|
||||
|
||||
// Turn on and off the codec Reader field
|
||||
INLINE void CodecSetReaderField(bool bOnOff) { // this is the function for turning on/off the reader field dumbly; before using this function, please consider to use CodecReaderField{Start,Stop}
|
||||
|
||||
if (bOnOff) {
|
||||
@@ -244,6 +258,7 @@ INLINE void CodecSetReaderField(bool bOnOff) { // this is the function for turni
|
||||
}
|
||||
}
|
||||
|
||||
// Get the status of the reader field
|
||||
INLINE bool CodecGetReaderField(void) {
|
||||
return (CODEC_READER_TIMER.CTRLA == TC_CLKSEL_DIV1_gc) && (AWEXC.OUTOVEN == CODEC_READER_MASK);
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ static void StartDemod(void) {
|
||||
StateRegister = DEMOD_DATA_BIT;
|
||||
|
||||
/* Configure sampling-timer free running and sync to first modulation-pause. */
|
||||
CODEC_TIMER_SAMPLING.CNT = 0;
|
||||
CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1;
|
||||
CODEC_TIMER_SAMPLING.CNT = 0; // Reset the timer count
|
||||
CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1; // Set Period regisiter
|
||||
CODEC_TIMER_SAMPLING.CCA = 0xFFFF; /* CCA Interrupt is not active! */
|
||||
CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_DIV1_gc;
|
||||
CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL;
|
||||
@@ -75,10 +75,11 @@ static void StartDemod(void) {
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCAINTLVL_HI_gc;
|
||||
|
||||
/* Start looking out for modulation pause via interrupt. */
|
||||
CODEC_DEMOD_IN_PORT.INTFLAGS = 0x03;
|
||||
CODEC_DEMOD_IN_PORT.INTFLAGS = PORT_INT0IF_bm;
|
||||
CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0;
|
||||
}
|
||||
|
||||
// Find first pause and start sampling
|
||||
ISR(CODEC_DEMOD_IN_INT0_VECT) {
|
||||
/* This is the first edge of the first modulation-pause after StartDemod.
|
||||
* Now we have time to start
|
||||
@@ -112,6 +113,7 @@ ISR(CODEC_DEMOD_IN_INT0_VECT) {
|
||||
CODEC_DEMOD_IN_PORT.INT0MASK = 0;
|
||||
}
|
||||
|
||||
// Sampling with timer and demod
|
||||
ISR(CODEC_TIMER_SAMPLING_CCA_VECT) {
|
||||
/* This interrupt gets called twice for every bit to sample it. */
|
||||
uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK;
|
||||
@@ -220,6 +222,7 @@ ISR(CODEC_TIMER_SAMPLING_CCA_VECT) {
|
||||
CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL;
|
||||
}
|
||||
|
||||
// Enumulate as a card to send card responds
|
||||
ISR(CODEC_TIMER_LOADMOD_OVF_VECT) {
|
||||
/* Bit rate timer. Output a half bit on the output. */
|
||||
|
||||
@@ -418,6 +421,7 @@ void ISO14443ACodecTask(void) {
|
||||
uint16_t AnswerBitCount = ISO14443A_APP_NO_RESPONSE;
|
||||
|
||||
if (DemodBitCount >= ISO14443A_MIN_BITS_PER_FRAME) {
|
||||
// For logging data
|
||||
LogEntry(LOG_INFO_CODEC_RX_DATA, CodecBuffer, (DemodBitCount+7)/8);
|
||||
LEDHook(LED_CODEC_RX, LED_PULSE);
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ INLINE void Insert1(void)
|
||||
*CodecBufferPtr++ = SampleRegister;
|
||||
}
|
||||
|
||||
|
||||
// End of Card-> reader communication and enter frame delay time
|
||||
INLINE void Reader14443A_EOC(void)
|
||||
{
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = 0;
|
||||
@@ -138,6 +140,7 @@ INLINE void BufferToSequence(void)
|
||||
uint8_t * Buffer = CodecBuffer + CODEC_BUFFER_SIZE / 2;
|
||||
CodecBufferPtr = CodecBuffer;
|
||||
|
||||
// Modified Miller Coding ISO14443-2 8.1.3
|
||||
Insert1(); // SOC
|
||||
Insert0();
|
||||
|
||||
@@ -175,8 +178,8 @@ INLINE void BufferToSequence(void)
|
||||
if (BitCount % 8)
|
||||
CodecBuffer[BitCount / 8] = SampleRegister >> (8 - (BitCount % 8));
|
||||
}
|
||||
|
||||
ISR (TCD0_CCC_vect)
|
||||
// Frame Delay Time PCD to PICC ends
|
||||
ISR (CODEC_TIMER_SAMPLING_CCC_VECT)
|
||||
{
|
||||
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm;
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc;
|
||||
@@ -202,6 +205,8 @@ ISR (TCD0_CCC_vect)
|
||||
PORTE.OUTTGL = PIN3_bm;
|
||||
}
|
||||
|
||||
// Reader -> card send bits finished
|
||||
// Start Frame delay time PCD to PICC
|
||||
void Reader14443AMillerEOC(void)
|
||||
{
|
||||
CODEC_TIMER_SAMPLING.PER = 5*SAMPLE_RATE_SYSTEM_CYCLES - 1;
|
||||
@@ -211,11 +216,13 @@ void Reader14443AMillerEOC(void)
|
||||
PORTE.OUTTGL = PIN3_bm;
|
||||
}
|
||||
|
||||
// EOC of Card->Reader found
|
||||
ISR(CODEC_TIMER_TIMESTAMPS_CCA_VECT) // EOC found
|
||||
{
|
||||
Reader14443A_EOC();
|
||||
}
|
||||
|
||||
// This interrupt find Card -> Reader SOC
|
||||
ISR(ACA_AC1_vect) // this interrupt either finds the SOC or gets triggered before
|
||||
{
|
||||
ACA.AC1CTRL &= ~AC_INTLVL_HI_gc; // disable this interrupt
|
||||
@@ -224,6 +231,10 @@ ISR(ACA_AC1_vect) // this interrupt either finds the SOC or gets triggered befor
|
||||
CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_DIV1_gc;
|
||||
}
|
||||
|
||||
// Decode the Card -> Reader signal
|
||||
// according to the pause and modulated period
|
||||
// if the half bit duration is modulated, then add 1 to buffer
|
||||
// if the half bit duration is not modulated, then add 0 to buffer
|
||||
ISR(CODEC_TIMER_LOADMOD_CCA_VECT) // pause found
|
||||
{
|
||||
uint8_t tmp = CODEC_TIMER_TIMESTAMPS.CNTL;
|
||||
@@ -296,6 +307,8 @@ void Reader14443ACodecTask(void)
|
||||
|
||||
bool breakflag = false;
|
||||
TmpCodecBuffer[0] >>= 2; // with this (and BitCountTmp = 2), the SOC is ignored
|
||||
|
||||
// Manchester Code ISO14443-2 8.2.5
|
||||
while (!breakflag && BitCountTmp < TotalBitCount)
|
||||
{
|
||||
uint8_t Bit = TmpCodecBuffer[BitCountTmp / 8] & 0x03;
|
||||
@@ -375,6 +388,7 @@ void Reader14443ACodecTask(void)
|
||||
LogEntry(LOG_INFO_CODEC_TX_DATA_W_PARITY, CodecBuffer, (BitCount + 7) / 8);
|
||||
|
||||
/* Set state and start timer for Miller encoding. */
|
||||
// Send bits to card using TCD0_CCB interrupt (See Reader14443-ISR.S)
|
||||
BufferToSequence();
|
||||
State = STATE_MILLER_SEND;
|
||||
CodecBufferPtr = CodecBuffer;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define AWEXC__OUTOVEN 0x088C
|
||||
#define CODEC_READER_TIMER__CTRLA 0x0800
|
||||
|
||||
; For sending reader bits to cards
|
||||
.global TCD0_CCB_vect, Reader14443AMillerEOC
|
||||
TCD0_CCB_vect:
|
||||
push Zero ; 1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by Zitai Chen on 05/07/2018.
|
||||
//
|
||||
|
||||
#ifndef CHAMELEON_MINI_SNIFFISO14443_2A_H
|
||||
#define CHAMELEON_MINI_SNIFFISO14443_2A_H
|
||||
|
||||
|
||||
#include "Codec.h"
|
||||
#include "Terminal/CommandLine.h"
|
||||
|
||||
enum RCTraffic {TRAFFIC_READER, TRAFFIC_CARD} TrafficSource;
|
||||
/* Codec Interface */
|
||||
void Sniff14443ACodecInit(void);
|
||||
void Sniff14443ACodecDeInit(void);
|
||||
void Sniff14443ACodecTask(void);
|
||||
|
||||
|
||||
|
||||
#endif //CHAMELEON_MINI_SNIFFISO14443_2A_H
|
||||
@@ -188,14 +188,14 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
|
||||
#endif
|
||||
#ifdef CONFIG_ISO14443A_SNIFF_SUPPORT
|
||||
[CONFIG_ISO14443A_SNIFF] = {
|
||||
.CodecInitFunc = ISO14443ACodecInit,
|
||||
.CodecDeInitFunc = ISO14443ACodecDeInit,
|
||||
.CodecTaskFunc = ISO14443ACodecTask,
|
||||
.ApplicationInitFunc = ApplicationInitDummy,
|
||||
.ApplicationResetFunc = ApplicationResetDummy,
|
||||
.ApplicationTaskFunc = ApplicationTaskDummy,
|
||||
.ApplicationTickFunc = ApplicationTickDummy,
|
||||
.ApplicationProcessFunc = ApplicationProcessDummy,
|
||||
.CodecInitFunc = Sniff14443ACodecInit,
|
||||
.CodecDeInitFunc = Sniff14443ACodecDeInit,
|
||||
.CodecTaskFunc = Sniff14443ACodecTask,
|
||||
.ApplicationInitFunc = Sniff14443AAppInit,
|
||||
.ApplicationResetFunc = Sniff14443AAppReset,
|
||||
.ApplicationTaskFunc = Sniff14443AAppTask,
|
||||
.ApplicationTickFunc = Sniff14443AAppTick,
|
||||
.ApplicationProcessFunc = Sniff14443AAppProcess,
|
||||
.ApplicationGetUidFunc = ApplicationGetUidDummy,
|
||||
.ApplicationSetUidFunc = ApplicationSetUidDummy,
|
||||
.UidSize = 0,
|
||||
|
||||
@@ -23,6 +23,14 @@ typedef enum {
|
||||
LOG_INFO_CODEC_RX_DATA_W_PARITY = 0x42, ///< Currently active codec received data.
|
||||
LOG_INFO_CODEC_TX_DATA_W_PARITY = 0x43, ///< Currently active codec sent data.
|
||||
|
||||
LOG_INFO_CODEC_SNI_READER_DATA = 0x44, //< Sniffing codec receive data from reader
|
||||
LOG_INFO_CODEC_SNI_READER_DATA_W_PARITY = 0x45, //< Sniffing codec receive data from reader
|
||||
|
||||
LOG_INFO_CODEC_SNI_CARD_DATA = 0x46, //< Sniffing codec receive data from card
|
||||
LOG_INFO_CODEC_SNI_CARD_DATA_W_PARITY = 0x47, //< Sniffing codec receive data from card
|
||||
|
||||
|
||||
|
||||
/* App */
|
||||
LOG_INFO_APP_CMD_READ = 0x80, ///< Application processed read command.
|
||||
LOG_INFO_APP_CMD_WRITE = 0x81, ///< Application processed write command.
|
||||
|
||||
@@ -92,8 +92,8 @@ TARGET = Chameleon-Mini
|
||||
OPTIMIZATION = s
|
||||
SRC += $(TARGET).c LUFADescriptors.c System.c Configuration.c Random.c Common.c Memory.c MemoryAsm.S Button.c Log.c Settings.c LED.c Map.c AntennaLevel.c
|
||||
SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Terminal/CommandLine.c
|
||||
SRC += Codec/Codec.c Codec/ISO14443-2A.c Codec/Reader14443-2A.c Codec/Reader14443-ISR.S
|
||||
SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c
|
||||
SRC += Codec/Codec.c Codec/ISO14443-2A.c Codec/Reader14443-2A.c Codec/SniffISO14443-2A.c Codec/Reader14443-ISR.S
|
||||
SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c Application/Sniff14443A.c
|
||||
SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||
LUFA_PATH = ../LUFA
|
||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) -DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) -DCOMMIT_ID=\"$(COMMIT_ID)\" $(SETTINGS)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Commands.h"
|
||||
#include <stdio.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <Settings.h>
|
||||
#include "XModem.h"
|
||||
#include "../Settings.h"
|
||||
#include "../Chameleon-Mini.h"
|
||||
@@ -16,6 +17,7 @@
|
||||
#include "../Codec/Codec.h"
|
||||
|
||||
extern Reader14443Command Reader14443CurrentCommand;
|
||||
extern Sniff14443Command Sniff14443CurrentCommand;
|
||||
|
||||
extern const PROGMEM CommandEntryType CommandTable[];
|
||||
|
||||
@@ -629,15 +631,27 @@ CommandStatusIdType CommandGetField(char* OutMessage)
|
||||
|
||||
CommandStatusIdType CommandExecAutocalibrate(char* OutMessage)
|
||||
{
|
||||
if (GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ISO14443A_READER)
|
||||
if (GlobalSettings.ActiveSettingPtr->Configuration == CONFIG_ISO14443A_READER){
|
||||
ApplicationReset();
|
||||
|
||||
Reader14443CurrentCommand = Reader14443_Autocalibrate;
|
||||
Reader14443AAppInit();
|
||||
Reader14443ACodecStart();
|
||||
CommandLinePendingTaskTimeout = &Reader14443AAppTimeout;
|
||||
return TIMEOUT_COMMAND;
|
||||
}
|
||||
else if (GlobalSettings.ActiveSettingPtr->Configuration == CONFIG_ISO14443A_SNIFF){
|
||||
ApplicationReset();
|
||||
|
||||
Sniff14443CurrentCommand = Sniff14443_Autocalibrate;
|
||||
Sniff14443AAppInit();
|
||||
CommandLinePendingTaskTimeout = &Sniff14443AAppTimeout;
|
||||
return TIMEOUT_COMMAND;
|
||||
}
|
||||
else {
|
||||
return COMMAND_ERR_INVALID_USAGE_ID;
|
||||
ApplicationReset();
|
||||
}
|
||||
|
||||
Reader14443CurrentCommand = Reader14443_Autocalibrate;
|
||||
Reader14443AAppInit();
|
||||
Reader14443ACodecStart();
|
||||
CommandLinePendingTaskTimeout = &Reader14443AAppTimeout;
|
||||
return TIMEOUT_COMMAND;
|
||||
}
|
||||
|
||||
CommandStatusIdType CommandExecClone(char *OutMessage)
|
||||
|
||||
@@ -25,6 +25,12 @@ eventTypes = {
|
||||
0x42: { 'name': 'CODEC RX W/PARITY', 'decoder': binaryDecoder },
|
||||
0x43: { 'name': 'CODEC TX W/PARITY', 'decoder': binaryDecoder },
|
||||
|
||||
0x44: { 'name': 'CODEC RX SNI READER', 'decoder': binaryDecoder },
|
||||
0x45: { 'name': 'CODEC RX SNI READER W/PARITY', 'decoder': binaryDecoder },
|
||||
0x46: { 'name': 'CODEC RX SNI CARD', 'decoder': binaryDecoder },
|
||||
0x47: { 'name': 'CODEC RX SNI CARD W/PARITY', 'decoder': binaryDecoder },
|
||||
|
||||
|
||||
0x80: { 'name': 'APP READ', 'decoder': binaryDecoder },
|
||||
0x81: { 'name': 'APP WRITE', 'decoder': binaryDecoder },
|
||||
0x84: { 'name': 'APP INC', 'decoder': binaryDecoder },
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ def verboseLog(text):
|
||||
|
||||
def formatText(log):
|
||||
formatString = '{timestamp:0>5d} ms <{deltaTimestamp:>+6d} ms>:'
|
||||
formatString += '{eventName:<16} ({dataLength:<3} bytes) [{data}]\n'
|
||||
formatString += '{eventName:<28} ({dataLength:<3} bytes)\t[{data}]\n'
|
||||
text = ''
|
||||
|
||||
for logEntry in log:
|
||||
|
||||
Reference in New Issue
Block a user