mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-12-26 10:01:07 +08:00
MAJOR update, added hitag2 reader, emulation and eavesdropping, lots of new code, including FPGA tweaks, part 2
This commit is contained in:
parent
db09cb3adb
commit
d19929cbe8
18 changed files with 1355 additions and 454 deletions
|
@ -10,7 +10,7 @@ APP_INCLUDES = apps.h
|
|||
|
||||
#remove one of the following defines and comment out the relevant line
|
||||
#in the next section to remove that particular feature from compilation
|
||||
APP_CFLAGS = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF
|
||||
APP_CFLAGS = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG
|
||||
#-DWITH_LCD
|
||||
|
||||
#SRC_LCD = fonts.c LCD.c
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
#include "legicrf.h"
|
||||
#include <hitag2.h>
|
||||
|
||||
#ifdef WITH_LCD
|
||||
# include "fonts.h"
|
||||
|
@ -125,23 +126,27 @@ void Dbprintf(const char *fmt, ...) {
|
|||
}
|
||||
|
||||
// prints HEX & ASCII
|
||||
void Dbhexdump(int len, uint8_t *d) {
|
||||
void Dbhexdump(int len, uint8_t *d, bool bAsci) {
|
||||
int l=0,i;
|
||||
char ascii[9];
|
||||
|
||||
|
||||
while (len>0) {
|
||||
if (len>8) l=8;
|
||||
else l=len;
|
||||
|
||||
memcpy(ascii,d,l);
|
||||
ascii[l]=0;
|
||||
ascii[l]=0;
|
||||
|
||||
// filter safe ascii
|
||||
for (i=0;i<l;i++)
|
||||
for (i=0;i<l;i++)
|
||||
if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
|
||||
|
||||
Dbprintf("%-8s %*D",ascii,l,d," ");
|
||||
|
||||
|
||||
if (bAsci) {
|
||||
Dbprintf("%-8s %*D",ascii,l,d," ");
|
||||
} else {
|
||||
Dbprintf("%*D",l,d," ");
|
||||
}
|
||||
|
||||
len-=8;
|
||||
d+=8;
|
||||
}
|
||||
|
@ -185,14 +190,15 @@ int AvgAdc(int ch) // was static - merlok
|
|||
|
||||
void MeasureAntennaTuning(void)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
|
||||
int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0
|
||||
int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
|
||||
|
||||
UsbCommand c;
|
||||
|
||||
DbpString("Measuring antenna characteristics, please wait.");
|
||||
memset(BigBuf,0,sizeof(BigBuf));
|
||||
LED_B_ON();
|
||||
DbpString("Measuring antenna characteristics, please wait...");
|
||||
memset(dest,0,sizeof(FREE_BUFFER_SIZE));
|
||||
|
||||
/*
|
||||
* Sweeps the useful LF range of the proxmark from
|
||||
|
@ -202,8 +208,10 @@ void MeasureAntennaTuning(void)
|
|||
* the resonating frequency of your LF antenna
|
||||
* ( hopefully around 95 if it is tuned to 125kHz!)
|
||||
*/
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
|
||||
for (i=255; i>19; i--) {
|
||||
WDT_HIT();
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
||||
SpinDelay(20);
|
||||
// Vref = 3.3V, and a 10000:240 voltage divider on the input
|
||||
|
@ -221,6 +229,7 @@ void MeasureAntennaTuning(void)
|
|||
}
|
||||
}
|
||||
|
||||
LED_A_ON();
|
||||
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||
SpinDelay(20);
|
||||
|
@ -232,7 +241,14 @@ void MeasureAntennaTuning(void)
|
|||
c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
|
||||
c.arg[1] = vHf;
|
||||
c.arg[2] = peakf | (peakv << 16);
|
||||
|
||||
DbpString("Measuring complete, sending report back to host");
|
||||
|
||||
UsbSendPacket((uint8_t *)&c, sizeof(c));
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_A_OFF();
|
||||
LED_B_OFF();
|
||||
return;
|
||||
}
|
||||
|
||||
void MeasureAntennaTuningHf(void)
|
||||
|
@ -258,8 +274,7 @@ void MeasureAntennaTuningHf(void)
|
|||
|
||||
void SimulateTagHfListen(void)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
int n = sizeof(BigBuf);
|
||||
uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
|
||||
uint8_t v = 0;
|
||||
int i;
|
||||
int p = 0;
|
||||
|
@ -293,7 +308,7 @@ void SimulateTagHfListen(void)
|
|||
p = 0;
|
||||
i++;
|
||||
|
||||
if(i >= n) {
|
||||
if(i >= FREE_BUFFER_SIZE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -644,6 +659,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_HITAG
|
||||
case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type
|
||||
SnoopHitag(c->arg[0]);
|
||||
break;
|
||||
case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content
|
||||
SimulateHitagTag((bool)c->arg[0],(byte_t*)c->d.asBytes);
|
||||
break;
|
||||
case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function
|
||||
ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ISO15693
|
||||
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
|
||||
AcquireRawAdcSamplesIso15693();
|
||||
|
@ -822,16 +849,14 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
LED_B_ON();
|
||||
UsbSendPacket((uint8_t *)&n, sizeof(n));
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
|
||||
uint8_t *b = (uint8_t *)BigBuf;
|
||||
memcpy(b+c->arg[0], c->d.asBytes, 48);
|
||||
//Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
|
||||
UsbSendPacket((uint8_t*)&ack, sizeof(ack));
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CMD_READ_MEM:
|
||||
ReadMem(c->arg[0]);
|
||||
|
@ -854,10 +879,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
SendVersion();
|
||||
break;
|
||||
|
||||
#ifdef WITH_LF
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LCD
|
||||
case CMD_LCD_RESET:
|
||||
LCDReset();
|
||||
|
@ -868,7 +889,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
#endif
|
||||
case CMD_SETUP_WRITE:
|
||||
case CMD_FINISH_WRITE:
|
||||
case CMD_HARDWARE_RESET:
|
||||
case CMD_HARDWARE_RESET: {
|
||||
USB_D_PLUS_PULLUP_OFF();
|
||||
SpinDelay(1000);
|
||||
SpinDelay(1000);
|
||||
|
@ -876,16 +897,16 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
for(;;) {
|
||||
// We're going to reset, and the bootrom will take control.
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case CMD_START_FLASH:
|
||||
case CMD_START_FLASH: {
|
||||
if(common_area.flags.bootrom_present) {
|
||||
common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
|
||||
}
|
||||
USB_D_PLUS_PULLUP_OFF();
|
||||
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
|
||||
for(;;);
|
||||
break;
|
||||
} break;
|
||||
|
||||
case CMD_DEVICE_INFO: {
|
||||
UsbCommand c;
|
||||
|
@ -893,11 +914,11 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
c.arg[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
|
||||
if(common_area.flags.bootrom_present) c.arg[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
|
||||
UsbSendPacket((uint8_t*)&c, sizeof(c));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
} break;
|
||||
|
||||
default: {
|
||||
Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
typedef unsigned char byte_t;
|
||||
#include "common.h"
|
||||
#include "hitag2.h"
|
||||
|
||||
// The large multi-purpose buffer, typically used to hold A/D samples,
|
||||
// maybe processed in some way.
|
||||
|
@ -49,7 +50,7 @@ void SamyRun(void);
|
|||
//void DbpIntegers(int a, int b, int c);
|
||||
void DbpString(char *str);
|
||||
void Dbprintf(const char *fmt, ...);
|
||||
void Dbhexdump(int len, uint8_t *d);
|
||||
void Dbhexdump(int len, uint8_t *d, bool bAsci);
|
||||
|
||||
int AvgAdc(int ch);
|
||||
|
||||
|
@ -69,13 +70,9 @@ void FpgaDownloadAndGo(void);
|
|||
void FpgaGatherVersion(char *dst, int len);
|
||||
void FpgaSetupSsc(void);
|
||||
void SetupSpi(int mode);
|
||||
void FpgaSetupSscDma(uint8_t *buf, int len);
|
||||
void inline FpgaDisableSscDma(void){
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
}
|
||||
void inline FpgaEnableSscDma(void){
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
}
|
||||
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
||||
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
void SetAdcMuxFor(uint32_t whichGpio);
|
||||
|
||||
// Definitions for the FPGA commands.
|
||||
|
@ -83,19 +80,21 @@ void SetAdcMuxFor(uint32_t whichGpio);
|
|||
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
||||
// Definitions for the FPGA configuration word.
|
||||
#define FPGA_MAJOR_MODE_LF_READER (0<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_SIMULATOR (1<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_READER_TX (2<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (3<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (4<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (5<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (6<<5)
|
||||
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
||||
// Options for LF_EDGE_DETECT
|
||||
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
|
||||
// Options for the HF reader, tx to tag
|
||||
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
|
||||
// Options for the HF reader, correlating against rx from tag
|
||||
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
||||
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
||||
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
|
||||
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
|
||||
// Options for the HF simulated tag, how to modulate
|
||||
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
|
||||
|
@ -139,7 +138,7 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack);
|
|||
int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
|
||||
uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
|
||||
void iso14a_set_trigger(int enable);
|
||||
void iso14a_clear_tracelen(void);
|
||||
void iso14a_clear_trace(void);
|
||||
void iso14a_set_tracing(int enable);
|
||||
void RAMFUNC SniffMifare(uint8_t param);
|
||||
|
||||
|
@ -176,6 +175,11 @@ void RAMFUNC SnoopIClass(void);
|
|||
void SimulateIClass(uint8_t arg0, uint8_t *datain);
|
||||
void ReaderIClass(uint8_t arg0);
|
||||
|
||||
// hitag2.h
|
||||
void SnoopHitag(uint32_t type);
|
||||
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
|
||||
void ReaderHitag(hitag_function htf, hitag_data* htd);
|
||||
|
||||
/// util.h
|
||||
|
||||
#endif
|
||||
|
|
|
@ -136,18 +136,20 @@ void FpgaSetupSsc(void)
|
|||
// ourselves, not to another buffer). The stuff to manipulate those buffers
|
||||
// is in apps.h, because it should be inlined, for speed.
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaSetupSscDma(uint8_t *buf, int len)
|
||||
bool FpgaSetupSscDma(uint8_t *buf, int len)
|
||||
{
|
||||
if (buf == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RCR = len;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = len;
|
||||
|
||||
if (buf != NULL) {
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
}
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DownloadFPGA_byte(unsigned char w)
|
||||
|
|
1267
armsrc/hitag2.c
1267
armsrc/hitag2.c
File diff suppressed because it is too large
Load diff
|
@ -691,7 +691,7 @@ void RAMFUNC SnoopIClass(void)
|
|||
|
||||
// reset traceLen to 0
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_trigger(FALSE);
|
||||
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "mifareutil.h"
|
||||
|
||||
static uint32_t iso14a_timeout;
|
||||
uint8_t *trace = (uint8_t *) BigBuf;
|
||||
uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET;
|
||||
int traceLen = 0;
|
||||
int rsamples = 0;
|
||||
int tracing = TRUE;
|
||||
|
@ -68,12 +68,15 @@ void iso14a_set_trigger(int enable) {
|
|||
trigger = enable;
|
||||
}
|
||||
|
||||
void iso14a_clear_tracelen(void) {
|
||||
void iso14a_clear_trace(void) {
|
||||
memset(trace, 0x44, TRACE_SIZE);
|
||||
traceLen = 0;
|
||||
}
|
||||
|
||||
void iso14a_set_tracing(int enable) {
|
||||
tracing = enable;
|
||||
}
|
||||
|
||||
void iso14a_set_timeout(uint32_t timeout) {
|
||||
iso14a_timeout = timeout;
|
||||
}
|
||||
|
@ -580,8 +583,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
|||
|
||||
LEDsoff();
|
||||
// init trace buffer
|
||||
traceLen = 0;
|
||||
memset(trace, 0x44, TRACE_SIZE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
// We won't start recording the frames that we acquire until we trigger;
|
||||
// a good trigger condition to get started is probably when we see a
|
||||
|
@ -905,8 +907,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
|
|||
{
|
||||
// Enable and clear the trace
|
||||
tracing = TRUE;
|
||||
traceLen = 0;
|
||||
memset(trace, 0x44, TRACE_SIZE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
// This function contains the tag emulation
|
||||
uint8_t sak;
|
||||
|
@ -2379,8 +2380,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
|||
// C(red) A(yellow) B(green)
|
||||
LEDsoff();
|
||||
// init trace buffer
|
||||
traceLen = 0;
|
||||
memset(trace, 0x44, TRACE_SIZE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
|
|
|
@ -1102,7 +1102,7 @@ void ReaderIso15693(uint32_t parameter)
|
|||
|
||||
Dbprintf("%d octets read from IDENTIFY request:", answerLen1);
|
||||
DbdecodeIso15693Answer(answerLen1,answer1);
|
||||
Dbhexdump(answerLen1,answer1);
|
||||
Dbhexdump(answerLen1,answer1,true);
|
||||
|
||||
// UID is reverse
|
||||
if (answerLen1>=12)
|
||||
|
@ -1113,11 +1113,11 @@ void ReaderIso15693(uint32_t parameter)
|
|||
|
||||
Dbprintf("%d octets read from SELECT request:", answerLen2);
|
||||
DbdecodeIso15693Answer(answerLen2,answer2);
|
||||
Dbhexdump(answerLen2,answer2);
|
||||
Dbhexdump(answerLen2,answer2,true);
|
||||
|
||||
Dbprintf("%d octets read from XXX request:", answerLen3);
|
||||
DbdecodeIso15693Answer(answerLen3,answer3);
|
||||
Dbhexdump(answerLen3,answer3);
|
||||
Dbhexdump(answerLen3,answer3,true);
|
||||
|
||||
|
||||
// read all pages
|
||||
|
@ -1130,7 +1130,7 @@ void ReaderIso15693(uint32_t parameter)
|
|||
if (answerLen2>0) {
|
||||
Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
|
||||
DbdecodeIso15693Answer(answerLen2,answer2);
|
||||
Dbhexdump(answerLen2,answer2);
|
||||
Dbhexdump(answerLen2,answer2,true);
|
||||
if ( *((uint32_t*) answer2) == 0x07160101 ) break; // exit on NoPageErr
|
||||
}
|
||||
i++;
|
||||
|
@ -1264,7 +1264,7 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
|
|||
|
||||
if (DEBUG) {
|
||||
Dbprintf("SEND");
|
||||
Dbhexdump(datalen,data);
|
||||
Dbhexdump(datalen,data,true);
|
||||
}
|
||||
|
||||
recvlen=SendDataTag(data,datalen,1,speed,(recv?&recvbuf:NULL));
|
||||
|
@ -1280,7 +1280,7 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
|
|||
if (DEBUG) {
|
||||
Dbprintf("RECV");
|
||||
DbdecodeIso15693Answer(recvlen,recvbuf);
|
||||
Dbhexdump(recvlen,recvbuf);
|
||||
Dbhexdump(recvlen,recvbuf,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
210
armsrc/lfops.c
210
armsrc/lfops.c
|
@ -433,17 +433,17 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
|||
{
|
||||
int i;
|
||||
uint8_t *tab = (uint8_t *)BigBuf;
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
|
||||
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
|
||||
|
||||
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
|
||||
|
||||
|
||||
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
|
||||
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
|
||||
|
||||
i = 0;
|
||||
for(;;) {
|
||||
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
|
||||
|
@ -453,18 +453,18 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
|||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
|
||||
if (ledcontrol)
|
||||
LED_D_ON();
|
||||
|
||||
|
||||
if(tab[i])
|
||||
OPEN_COIL();
|
||||
else
|
||||
SHORT_COIL();
|
||||
|
||||
|
||||
if (ledcontrol)
|
||||
LED_D_OFF();
|
||||
|
||||
|
||||
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
|
||||
if(BUTTON_PRESS()) {
|
||||
DbpString("Stopped");
|
||||
|
@ -472,7 +472,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
|||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
|
||||
i++;
|
||||
if(i == period) {
|
||||
i = 0;
|
||||
|
@ -484,197 +484,9 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
|||
}
|
||||
}
|
||||
|
||||
/* Provides a framework for bidirectional LF tag communication
|
||||
* Encoding is currently Hitag2, but the general idea can probably
|
||||
* be transferred to other encodings.
|
||||
*
|
||||
* The new FPGA code will, for the LF simulator mode, give on SSC_FRAME
|
||||
* (PA15) a thresholded version of the signal from the ADC. Setting the
|
||||
* ADC path to the low frequency peak detection signal, will enable a
|
||||
* somewhat reasonable receiver for modulation on the carrier signal
|
||||
* that is generated by the reader. The signal is low when the reader
|
||||
* field is switched off, and high when the reader field is active. Due
|
||||
* to the way that the signal looks like, mostly only the rising edge is
|
||||
* useful, your mileage may vary.
|
||||
*
|
||||
* Neat perk: PA15 can not only be used as a bit-banging GPIO, but is also
|
||||
* TIOA1, which can be used as the capture input for timer 1. This should
|
||||
* make it possible to measure the exact edge-to-edge time, without processor
|
||||
* intervention.
|
||||
*
|
||||
* Arguments: divisor is the divisor to be sent to the FPGA (e.g. 95 for 125kHz)
|
||||
* t0 is the carrier frequency cycle duration in terms of MCK (384 for 125kHz)
|
||||
*
|
||||
* The following defines are in carrier periods:
|
||||
*/
|
||||
#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */
|
||||
#define HITAG_T_1_MIN 24 /* T[1] should be 26..30 */
|
||||
#define HITAG_T_EOF 40 /* T_EOF should be > 36 */
|
||||
#define HITAG_T_WRESP 208 /* T_wresp should be 204..212 */
|
||||
|
||||
static void hitag_handle_frame(int t0, int frame_len, char *frame);
|
||||
//#define DEBUG_RA_VALUES 1
|
||||
#define DEBUG_FRAME_CONTENTS 1
|
||||
void SimulateTagLowFrequencyBidir(int divisor, int t0)
|
||||
{
|
||||
#if DEBUG_RA_VALUES || DEBUG_FRAME_CONTENTS
|
||||
int i = 0;
|
||||
#endif
|
||||
char frame[10];
|
||||
int frame_pos=0;
|
||||
|
||||
DbpString("Starting Hitag2 emulator, press button to end");
|
||||
hitag2_init();
|
||||
|
||||
/* Set up simulator mode, frequency divisor which will drive the FPGA
|
||||
* and analog mux selection.
|
||||
*/
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
RELAY_OFF();
|
||||
|
||||
/* Set up Timer 1:
|
||||
* Capture mode, timer source MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
* external trigger rising edge, load RA on rising edge of TIOA, load RB on rising
|
||||
* edge of TIOA. Assign PA15 to TIOA1 (peripheral B)
|
||||
*/
|
||||
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK |
|
||||
AT91C_TC_ETRGEDG_RISING |
|
||||
AT91C_TC_ABETRG |
|
||||
AT91C_TC_LDRA_RISING |
|
||||
AT91C_TC_LDRB_RISING;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN |
|
||||
AT91C_TC_SWTRG;
|
||||
|
||||
/* calculate the new value for the carrier period in terms of TC1 values */
|
||||
t0 = t0/2;
|
||||
|
||||
int overflow = 0;
|
||||
while(!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
|
||||
int ra = AT91C_BASE_TC1->TC_RA;
|
||||
if((ra > t0*HITAG_T_EOF) | overflow) ra = t0*HITAG_T_EOF+1;
|
||||
#if DEBUG_RA_VALUES
|
||||
if(ra > 255 || overflow) ra = 255;
|
||||
((char*)BigBuf)[i] = ra;
|
||||
i = (i+1) % 8000;
|
||||
#endif
|
||||
|
||||
if(overflow || (ra > t0*HITAG_T_EOF) || (ra < t0*HITAG_T_0_MIN)) {
|
||||
/* Ignore */
|
||||
} else if(ra >= t0*HITAG_T_1_MIN ) {
|
||||
/* '1' bit */
|
||||
if(frame_pos < 8*sizeof(frame)) {
|
||||
frame[frame_pos / 8] |= 1<<( 7-(frame_pos%8) );
|
||||
frame_pos++;
|
||||
}
|
||||
} else if(ra >= t0*HITAG_T_0_MIN) {
|
||||
/* '0' bit */
|
||||
if(frame_pos < 8*sizeof(frame)) {
|
||||
frame[frame_pos / 8] |= 0<<( 7-(frame_pos%8) );
|
||||
frame_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
overflow = 0;
|
||||
LED_D_ON();
|
||||
} else {
|
||||
if(AT91C_BASE_TC1->TC_CV > t0*HITAG_T_EOF) {
|
||||
/* Minor nuisance: In Capture mode, the timer can not be
|
||||
* stopped by a Compare C. There's no way to stop the clock
|
||||
* in software, so we'll just have to note the fact that an
|
||||
* overflow happened and the next loaded timer value might
|
||||
* have wrapped. Also, this marks the end of frame, and the
|
||||
* still running counter can be used to determine the correct
|
||||
* time for the start of the reply.
|
||||
*/
|
||||
overflow = 1;
|
||||
|
||||
if(frame_pos > 0) {
|
||||
/* Have a frame, do something with it */
|
||||
#if DEBUG_FRAME_CONTENTS
|
||||
((char*)BigBuf)[i++] = frame_pos;
|
||||
memcpy( ((char*)BigBuf)+i, frame, 7);
|
||||
i+=7;
|
||||
i = i % sizeof(BigBuf);
|
||||
#endif
|
||||
hitag_handle_frame(t0, frame_pos, frame);
|
||||
memset(frame, 0, sizeof(frame));
|
||||
}
|
||||
frame_pos = 0;
|
||||
|
||||
}
|
||||
LED_D_OFF();
|
||||
}
|
||||
}
|
||||
DbpString("All done");
|
||||
}
|
||||
|
||||
static void hitag_send_bit(int t0, int bit) {
|
||||
if(bit == 1) {
|
||||
/* Manchester: Loaded, then unloaded */
|
||||
LED_A_ON();
|
||||
SHORT_COIL();
|
||||
while(AT91C_BASE_TC1->TC_CV < t0*15);
|
||||
OPEN_COIL();
|
||||
while(AT91C_BASE_TC1->TC_CV < t0*31);
|
||||
LED_A_OFF();
|
||||
} else if(bit == 0) {
|
||||
/* Manchester: Unloaded, then loaded */
|
||||
LED_B_ON();
|
||||
OPEN_COIL();
|
||||
while(AT91C_BASE_TC1->TC_CV < t0*15);
|
||||
SHORT_COIL();
|
||||
while(AT91C_BASE_TC1->TC_CV < t0*31);
|
||||
LED_B_OFF();
|
||||
}
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; /* Reset clock for the next bit */
|
||||
|
||||
}
|
||||
static void hitag_send_frame(int t0, int frame_len, const char const * frame, int fdt)
|
||||
{
|
||||
OPEN_COIL();
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
|
||||
/* Wait for HITAG_T_WRESP carrier periods after the last reader bit,
|
||||
* not that since the clock counts since the rising edge, but T_wresp is
|
||||
* with respect to the falling edge, we need to wait actually (T_wresp - T_g)
|
||||
* periods. The gap time T_g varies (4..10).
|
||||
*/
|
||||
while(AT91C_BASE_TC1->TC_CV < t0*(fdt-8));
|
||||
|
||||
int saved_cmr = AT91C_BASE_TC1->TC_CMR;
|
||||
AT91C_BASE_TC1->TC_CMR &= ~AT91C_TC_ETRGEDG; /* Disable external trigger for the clock */
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; /* Reset the clock and use it for response timing */
|
||||
|
||||
int i;
|
||||
for(i=0; i<5; i++)
|
||||
hitag_send_bit(t0, 1); /* Start of frame */
|
||||
|
||||
for(i=0; i<frame_len; i++) {
|
||||
hitag_send_bit(t0, !!(frame[i/ 8] & (1<<( 7-(i%8) ))) );
|
||||
}
|
||||
|
||||
OPEN_COIL();
|
||||
AT91C_BASE_TC1->TC_CMR = saved_cmr;
|
||||
}
|
||||
|
||||
/* Callback structure to cleanly separate tag emulation code from the radio layer. */
|
||||
static int hitag_cb(const char* response_data, const int response_length, const int fdt, void *cb_cookie)
|
||||
{
|
||||
hitag_send_frame(*(int*)cb_cookie, response_length, response_data, fdt);
|
||||
return 0;
|
||||
}
|
||||
/* Frame length in bits, frame contents in MSBit first format */
|
||||
static void hitag_handle_frame(int t0, int frame_len, char *frame)
|
||||
{
|
||||
hitag2_handle_command(frame, frame_len, hitag_cb, &t0);
|
||||
}
|
||||
|
||||
// compose fc/8 fc/10 waveform
|
||||
|
|
|
@ -35,7 +35,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
pcs = &mpcs;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
// iso14a_set_tracing(false);
|
||||
|
||||
iso14443a_setup();
|
||||
|
@ -115,7 +115,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
pcs = &mpcs;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
// iso14a_set_tracing(false);
|
||||
|
||||
iso14443a_setup();
|
||||
|
@ -213,7 +213,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
pcs = &mpcs;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
// iso14a_set_tracing(false);
|
||||
|
||||
iso14443a_setup();
|
||||
|
@ -311,7 +311,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
|||
for (i = 0; i < NES_MAX_INFO + 1; i++) nvectorcount[i] = 11; // 11 - empty block;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(false);
|
||||
|
||||
iso14443a_setup();
|
||||
|
@ -539,7 +539,7 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
MF_DBGLEVEL = MF_DBG_NONE;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
iso14443a_setup();
|
||||
|
@ -641,7 +641,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
uint8_t uid[8];
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(false);
|
||||
|
||||
iso14443a_setup();
|
||||
|
@ -759,7 +759,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
|
||||
if (workFlags & 0x08) {
|
||||
// clear trace
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
iso14443a_setup();
|
||||
|
@ -890,7 +890,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
|
||||
if (workFlags & 0x08) {
|
||||
// clear trace
|
||||
iso14a_clear_tracelen();
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
iso14443a_setup();
|
||||
|
|
25
common/usb.c
25
common/usb.c
|
@ -401,12 +401,15 @@ void UsbSendPacket(uint8_t *packet, int len)
|
|||
}
|
||||
AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
|
||||
|
||||
while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP))
|
||||
;
|
||||
while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)) {
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
|
||||
|
||||
while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)
|
||||
;
|
||||
while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) {
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
len -= thisTime;
|
||||
packet += thisTime;
|
||||
|
@ -426,8 +429,9 @@ static void HandleRxdData(void)
|
|||
}
|
||||
|
||||
AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK0;
|
||||
while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0)
|
||||
;
|
||||
while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
if(UsbSoFarCount >= 64) {
|
||||
UsbPacketReceived(UsbBuffer, UsbSoFarCount);
|
||||
|
@ -444,14 +448,17 @@ static void HandleRxdData(void)
|
|||
}
|
||||
|
||||
AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK1;
|
||||
while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1)
|
||||
;
|
||||
|
||||
while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
if(UsbSoFarCount >= 64) {
|
||||
UsbPacketReceived(UsbBuffer, UsbSoFarCount);
|
||||
UsbSoFarCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
void UsbStart(void)
|
||||
|
|
|
@ -6,7 +6,7 @@ clean:
|
|||
$(DELETE) fpga.map fpga.ngc fpga_ngdbuild.xrpt fpga.pcf fpga-placed_pad.csv fpga-placed.ptwx fpga.rbt xlnx_auto_0_xdb
|
||||
$(DELETE) fpga.bld fpga.mrp fpga.ngc_xst.xrpt fpga.ngm fpga-placed.ncd fpga-placed_pad.txt fpga-placed.unroutes fpga_summary.xml netlist.lst xst
|
||||
|
||||
fpga.ngc: fpga.v fpga.ucf xst.scr util.v lo_simulate.v lo_read.v lo_passthru.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
|
||||
fpga.ngc: fpga.v fpga.ucf xst.scr util.v lo_edge_detect.v lo_read.v lo_passthru.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
|
||||
$(DELETE) fpga.ngc
|
||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst.scr
|
||||
|
||||
|
|
BIN
fpga/fpga.bit
BIN
fpga/fpga.bit
Binary file not shown.
11
fpga/fpga.v
11
fpga/fpga.v
|
@ -14,7 +14,7 @@
|
|||
|
||||
`include "lo_read.v"
|
||||
`include "lo_passthru.v"
|
||||
`include "lo_simulate.v"
|
||||
`include "lo_edge_detect.v"
|
||||
`include "hi_read_tx.v"
|
||||
`include "hi_read_rx_xcorr.v"
|
||||
`include "hi_simulate.v"
|
||||
|
@ -111,6 +111,10 @@ assign hi_read_rx_xcorr_quarter = conf_word[2];
|
|||
wire [2:0] hi_simulate_mod_type;
|
||||
assign hi_simulate_mod_type = conf_word[2:0];
|
||||
|
||||
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||
wire lf_field;
|
||||
assign lf_field = conf_word[0];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// And then we instantiate the modules corresponding to each of the FPGA's
|
||||
// major modes, and use muxes to connect the outputs of the active mode to
|
||||
|
@ -136,13 +140,14 @@ lo_passthru lp(
|
|||
lp_dbg, divisor
|
||||
);
|
||||
|
||||
lo_simulate ls(
|
||||
lo_edge_detect ls(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
ls_pwr_lo, ls_pwr_hi, ls_pwr_oe1, ls_pwr_oe2, ls_pwr_oe3, ls_pwr_oe4,
|
||||
adc_d, ls_adc_clk,
|
||||
ls_ssp_frame, ls_ssp_din, ssp_dout, ls_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
ls_dbg, divisor
|
||||
ls_dbg, divisor,
|
||||
lf_field
|
||||
);
|
||||
|
||||
hi_read_tx ht(
|
||||
|
|
90
fpga/lo_edge_detect.v
Normal file
90
fpga/lo_edge_detect.v
Normal file
|
@ -0,0 +1,90 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// The way that we connect things in low-frequency simulation mode. In this
|
||||
// case just pass everything through to the ARM, which can bit-bang this
|
||||
// (because it is so slow).
|
||||
//
|
||||
// Jonathan Westhues, April 2006
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
module lo_edge_detect(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
|
||||
adc_d, adc_clk,
|
||||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg,
|
||||
divisor,
|
||||
lf_field
|
||||
);
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
input [7:0] adc_d;
|
||||
output adc_clk;
|
||||
input ssp_dout;
|
||||
output ssp_frame, ssp_din, ssp_clk;
|
||||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
input [7:0] divisor;
|
||||
input lf_field;
|
||||
|
||||
// Divide the clock to be used for the ADC
|
||||
reg [7:0] pck_divider;
|
||||
reg clk_state;
|
||||
|
||||
wire tag_modulation;
|
||||
assign tag_modulation = ssp_dout & !lf_field;
|
||||
wire reader_modulation;
|
||||
assign reader_modulation = !ssp_dout & lf_field & clk_state;
|
||||
|
||||
// No logic, straight through.
|
||||
assign pwr_oe1 = 1'b0; // not used in LF mode
|
||||
assign pwr_oe2 = tag_modulation;
|
||||
assign pwr_oe3 = tag_modulation;
|
||||
assign pwr_oe4 = tag_modulation;
|
||||
assign ssp_clk = cross_lo;
|
||||
assign pwr_lo = reader_modulation;
|
||||
assign pwr_hi = 1'b0;
|
||||
assign dbg = ssp_frame;
|
||||
|
||||
always @(posedge pck0)
|
||||
begin
|
||||
if(pck_divider == divisor[7:0])
|
||||
begin
|
||||
pck_divider <= 8'd0;
|
||||
clk_state = !clk_state;
|
||||
end
|
||||
else
|
||||
begin
|
||||
pck_divider <= pck_divider + 1;
|
||||
end
|
||||
end
|
||||
|
||||
assign adc_clk = ~clk_state;
|
||||
|
||||
// Toggle the output with hysteresis
|
||||
// Set to high if the ADC value is above 200
|
||||
// Set to low if the ADC value is below 64
|
||||
reg is_high;
|
||||
reg is_low;
|
||||
reg output_state;
|
||||
|
||||
always @(posedge pck0)
|
||||
begin
|
||||
if((pck_divider == 8'd7) && !clk_state) begin
|
||||
is_high = (adc_d >= 8'd190);
|
||||
is_low = (adc_d <= 8'd70);
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge is_high or posedge is_low)
|
||||
begin
|
||||
if(is_high)
|
||||
output_state <= 1'd1;
|
||||
else if(is_low)
|
||||
output_state <= 1'd0;
|
||||
end
|
||||
|
||||
assign ssp_frame = output_state;
|
||||
|
||||
endmodule
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
#define __COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
typedef unsigned char byte_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ISO 14443A
|
||||
|
|
|
@ -1,19 +1,33 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
|
||||
// (c) 2012 Roel Verdult
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hitag2 emulation public interface
|
||||
// Hitag2 type prototyping
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __HITAG2_H
|
||||
#define __HITAG2_H
|
||||
#ifndef _HITAG2_H_
|
||||
#define _HITAG2_H_
|
||||
|
||||
typedef int (*hitag2_response_callback_t)(const char* response_data, const int response_length, const int fdt, void *cb_cookie);
|
||||
typedef enum {
|
||||
RHT2F_PASSWORD = 21,
|
||||
RHT2F_AUTHENTICATE = 22,
|
||||
RHT2F_TEST_AUTH_ATTEMPTS = 25,
|
||||
} hitag_function;
|
||||
|
||||
extern int hitag2_init(void);
|
||||
extern int hitag2_handle_command(const char* data, const int length, hitag2_response_callback_t cb, void *cb_cookie);
|
||||
typedef struct {
|
||||
byte_t password[4];
|
||||
} PACKED rht2d_password;
|
||||
|
||||
typedef struct {
|
||||
byte_t NrAr[8];
|
||||
} PACKED rht2d_authenticate;
|
||||
|
||||
typedef union {
|
||||
rht2d_password pwd;
|
||||
rht2d_authenticate auth;
|
||||
} hitag_data;
|
||||
|
||||
#endif
|
|
@ -86,6 +86,12 @@ typedef struct {
|
|||
#define CMD_ISO_15693_COMMAND_DONE 0x0314
|
||||
#define CMD_ISO_15693_FIND_AFI 0x0315
|
||||
#define CMD_ISO_15693_DEBUG 0x0316
|
||||
|
||||
// For Hitag2 transponders
|
||||
#define CMD_SNOOP_HITAG 0x0370
|
||||
#define CMD_SIMULATE_HITAG 0x0371
|
||||
#define CMD_READER_HITAG 0x0372
|
||||
|
||||
#define CMD_SIMULATE_TAG_HF_LISTEN 0x0380
|
||||
#define CMD_SIMULATE_TAG_ISO_14443 0x0381
|
||||
#define CMD_SNOOP_ISO_14443 0x0382
|
||||
|
|
Loading…
Reference in a new issue