// pointer to the emulator memory.
static uint8_t *emulator_memory = NULL;
-// trace related global variables
-// (only one left). ToDo: make this static as well?
-uint16_t traceLen = 0;
-
+// trace related variables
+static uint16_t traceLen = 0;
+int tracing = 1; //Last global one.. todo static?
// get the address of BigBuf
uint8_t *BigBuf_get_addr(void)
{
return BigBuf_hi;
}
+
+void clear_trace() {
+ uint8_t *trace = BigBuf_get_addr();
+ uint16_t max_traceLen = BigBuf_max_traceLen();
+ memset(trace, 0x44, max_traceLen);
+ traceLen = 0;
+}
+
+void set_tracing(bool enable) {
+ tracing = enable;
+}
+
+/**
+ * Get the number of bytes traced
+ * @return
+ */
+uint16_t BigBuf_get_traceLen(void)
+{
+ return traceLen;
+}
+
+/**
+ This is a function to store traces. All protocols can use this generic tracer-function.
+ The traces produced by calling this function can be fetched on the client-side
+ by 'hf list raw', alternatively 'hf list <proto>' for protocol-specific
+ annotation of commands/responses.
+
+**/
+bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
+{
+ if (!tracing) return FALSE;
+
+ uint8_t *trace = BigBuf_get_addr();
+
+ uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
+ uint16_t duration = timestamp_end - timestamp_start;
+
+ // Return when trace is full
+ uint16_t max_traceLen = BigBuf_max_traceLen();
+
+ if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
+ tracing = FALSE; // don't trace any more
+ return FALSE;
+ }
+ // Traceformat:
+ // 32 bits timestamp (little endian)
+ // 16 bits duration (little endian)
+ // 16 bits data length (little endian, Highest Bit used as readerToTag flag)
+ // y Bytes data
+ // x Bytes parity (one byte per 8 bytes data)
+
+ // timestamp (start)
+ trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
+ trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
+ trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
+ trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
+
+ // duration
+ trace[traceLen++] = ((duration >> 0) & 0xff);
+ trace[traceLen++] = ((duration >> 8) & 0xff);
+
+ // data length
+ trace[traceLen++] = ((iLen >> 0) & 0xff);
+ trace[traceLen++] = ((iLen >> 8) & 0xff);
+
+ // readerToTag flag
+ if (!readerToTag) {
+ trace[traceLen - 1] |= 0x80;
+ }
+
+ // data bytes
+ if (btBytes != NULL && iLen != 0) {
+ memcpy(trace + traceLen, btBytes, iLen);
+ }
+ traceLen += iLen;
+
+ // parity bytes
+ if (parity != NULL && iLen != 0) {
+ memcpy(trace + traceLen, parity, num_paritybytes);
+ }
+ traceLen += num_paritybytes;
+
+ if(traceLen +4 < max_traceLen)
+ { //If it hadn't been cleared, for whatever reason..
+ memset(trace+traceLen,0x44, 4);
+ }
+
+ return TRUE;
+}
+int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
+{
+ /**
+ Todo, rewrite the logger to use the generic functionality instead. It should be noted, however,
+ that this logger takes number of bits as argument, not number of bytes.
+ **/
+
+ if (!tracing) return FALSE;
+
+ uint8_t *trace = BigBuf_get_addr();
+ uint16_t iLen = nbytes(iBits);
+ // Return when trace is full
+ if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return FALSE;
+
+ //Hitag traces appear to use this traceformat:
+ // 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
+ // 32 bits parity
+ // 8 bits size (number of bits in the trace entry, not number of bytes)
+ // y Bytes data
+
+ rsamples += iSamples;
+ trace[traceLen++] = ((rsamples >> 0) & 0xff);
+ trace[traceLen++] = ((rsamples >> 8) & 0xff);
+ trace[traceLen++] = ((rsamples >> 16) & 0xff);
+ trace[traceLen++] = ((rsamples >> 24) & 0xff);
+
+ if (!readerToTag) {
+ trace[traceLen - 1] |= 0x80;
+ }
+
+ trace[traceLen++] = ((dwParity >> 0) & 0xff);
+ trace[traceLen++] = ((dwParity >> 8) & 0xff);
+ trace[traceLen++] = ((dwParity >> 16) & 0xff);
+ trace[traceLen++] = ((dwParity >> 24) & 0xff);
+ trace[traceLen++] = iBits;
+
+ memcpy(trace + traceLen, btBytes, iLen);
+ traceLen += iLen;
+
+ return TRUE;
+}
+// Emulator memory
+uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
+ uint8_t* mem = BigBuf_get_EM_addr();
+ if(offset+length < CARD_MEMORY_SIZE)
+ {
+ memcpy(mem+offset, data, length);
+ return 0;
+ }else
+ {
+ Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset+length), CARD_MEMORY_SIZE);
+ return 1;
+ }
+}
extern void BigBuf_free(void);
extern void BigBuf_free_keep_EM(void);
-extern uint16_t traceLen;
-
+uint16_t BigBuf_get_traceLen(void);
+void clear_trace();
+void set_tracing(bool enable);
+bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
+int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
+uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
#endif /* __BIGBUF_H */
#include "legicrf.h"
#include <hitag2.h>
#include "lfsampling.h"
+#include "BigBuf.h"
#ifdef WITH_LCD
#include "LCD.h"
#endif
case CMD_READER_ICLASS_REPLAY:
ReaderIClass_Replay(c->arg[0], c->d.asBytes);
break;
+ case CMD_ICLASS_EML_MEMSET:
+ emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
+ break;
#endif
case CMD_SIMULATE_TAG_HF_LISTEN:
uint8_t *BigBuf = BigBuf_get_addr();
for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
- cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,traceLen,BigBuf+c->arg[0]+i,len);
+ cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
}
// Trigger a finish downloading signal with an ACK frame
- cmd_send(CMD_ACK,1,0,traceLen,getSamplingConfig(),sizeof(sample_config));
+ cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config));
LED_B_OFF();
break;
void __attribute__((noreturn)) AppMain(void)
{
SpinDelay(100);
-
+ clear_trace();
if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
/* Initialize common area */
memset(&common_area, 0, sizeof(common_area));
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity);
void iso14a_set_trigger(bool enable);
-void iso14a_clear_trace();
-void iso14a_set_tracing(bool enable);
+
void RAMFUNC SniffMifare(uint8_t param);
/// epa.h
return;
}
- // increase the timeout (at least some cards really do need this!)
- iso14a_set_timeout(0x0002FFFF);
-
// read the CardAccess file
// this array will hold the CardAccess file
uint8_t card_access[256] = {0};
// power up the field
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
- iso14a_set_timeout(10500);
-
// select the card
return_code = iso14443a_select_card(uid, &card_select_info, NULL);
if (return_code != 1) {
#include "util.h"
#include "hitag2.h"
#include "string.h"
+#include "BigBuf.h"
static bool bQuiet;
static bool bSuccessful;
-static int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader)
-{
- static uint16_t traceLen = 0;
- uint8_t *trace = BigBuf_get_addr();
-
- // Return when trace is full
- if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE;
-
- // Trace the random, i'm curious
- rsamples += iSamples;
- trace[traceLen++] = ((rsamples >> 0) & 0xff);
- trace[traceLen++] = ((rsamples >> 8) & 0xff);
- trace[traceLen++] = ((rsamples >> 16) & 0xff);
- trace[traceLen++] = ((rsamples >> 24) & 0xff);
- if (!bReader) {
- trace[traceLen - 1] |= 0x80;
- }
- trace[traceLen++] = ((dwParity >> 0) & 0xff);
- trace[traceLen++] = ((dwParity >> 8) & 0xff);
- trace[traceLen++] = ((dwParity >> 16) & 0xff);
- trace[traceLen++] = ((dwParity >> 24) & 0xff);
- trace[traceLen++] = iBits;
- memcpy(trace + traceLen, btBytes, nbytes(iBits));
- traceLen += nbytes(iBits);
- return TRUE;
-}
struct hitag2_tag {
uint32_t uid;
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
// Clean up trace and prepare it for storing frames
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
DbpString("Starting Hitag2 snoop");
LED_D_ON();
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
// Clean up trace and prepare it for storing frames
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
DbpString("Starting Hitag2 simulation");
LED_D_ON();
bSuccessful = false;
// Clean up trace and prepare it for storing frames
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
DbpString("Starting Hitag reader family");
// The DMA buffer, used to stream samples from the FPGA
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
- // reset traceLen to 0
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
iso14a_set_trigger(FALSE);
int lastRxCounter;
DbpString("COMMAND FINISHED");
Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
- Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
+ Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
done:
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
- Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
+ Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Enable and clear the trace
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
if(simType == 0) {
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Reset trace buffer
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
// Setup SSC
FpgaSetupSsc();
int read_status= 0;
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC;
-
+ set_tracing(TRUE);
setupIclassReader();
size_t datasize = 0;
while(!BUTTON_PRESS())
{
- if(traceLen > BigBuf_max_traceLen()) {
+ if(!tracing) {
DbpString("Trace full");
break;
}
uint8_t resp[ICLASS_BUFFER_SIZE];
setupIclassReader();
-
+ set_tracing(TRUE);
while(!BUTTON_PRESS()) {
WDT_HIT();
- if(traceLen > BigBuf_max_traceLen()) {
+ if(!tracing) {
DbpString("Trace full");
break;
}
//Set card_data to all zeroes, we'll fill it with data
memset(card_data,0x0,USB_CMD_DATA_SIZE);
uint8_t failedRead =0;
- uint8_t stored_data_length =0;
+ uint32_t stored_data_length =0;
//then loop around remaining blocks
for(int block=0; block < cardsize; block++){
//Fill up the buffer
memcpy(card_data+stored_data_length,resp,8);
stored_data_length += 8;
-
if(stored_data_length +8 > USB_CMD_DATA_SIZE)
{//Time to send this off and start afresh
cmd_send(CMD_ACK,
Dbprintf("Failed to dump block %d", block);
}
}
+
//Send off any remaining data
if(stored_data_length > 0)
{
//static void GetSamplesFor14443(int weTx, int n);
-#define DEMOD_TRACE_SIZE 4096
+/*#define DEMOD_TRACE_SIZE 4096
#define READER_TAG_BUFFER_SIZE 2048
#define TAG_READER_BUFFER_SIZE 2048
#define DEMOD_DMA_BUFFER_SIZE 1024
-
+*/
//=============================================================================
// An ISO 14443 Type B tag. We listen for commands from the reader, using
// a UART kind of thing that's implemented in software. When we get a
//-----------------------------------------------------------------------------
static void CodeIso14443bAsTag(const uint8_t *cmd, int len)
{
- int i;
-
- ToSendReset();
-
- // Transmit a burst of ones, as the initial thing that lets the
- // reader get phase sync. This (TR1) must be > 80/fs, per spec,
- // but tag that I've tried (a Paypass) exceeds that by a fair bit,
- // so I will too.
- for(i = 0; i < 20; i++) {
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- }
-
- // Send SOF.
- for(i = 0; i < 10; i++) {
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- }
- for(i = 0; i < 2; i++) {
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- }
-
- for(i = 0; i < len; i++) {
- int j;
- uint8_t b = cmd[i];
-
- // Start bit
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- ToSendStuffBit(0);
-
- // Data bits
- for(j = 0; j < 8; j++) {
- if(b & 1) {
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- } else {
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- }
- b >>= 1;
- }
-
- // Stop bit
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- }
-
- // Send SOF.
- for(i = 0; i < 10; i++) {
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- ToSendStuffBit(0);
- }
- for(i = 0; i < 10; i++) {
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- }
-
- // Convert from last byte pos to length
- ToSendMax++;
-
- // Add a few more for slop
- ToSendMax += 2;
+ int i;
+
+ ToSendReset();
+
+ // Transmit a burst of ones, as the initial thing that lets the
+ // reader get phase sync. This (TR1) must be > 80/fs, per spec,
+ // but tag that I've tried (a Paypass) exceeds that by a fair bit,
+ // so I will too.
+ for(i = 0; i < 20; i++) {
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ }
+
+ // Send SOF.
+ for(i = 0; i < 10; i++) {
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ }
+ for(i = 0; i < 2; i++) {
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ }
+
+ for(i = 0; i < len; i++) {
+ int j;
+ uint8_t b = cmd[i];
+
+ // Start bit
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+
+ // Data bits
+ for(j = 0; j < 8; j++) {
+ if(b & 1) {
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ } else {
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ }
+ b >>= 1;
+ }
+
+ // Stop bit
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ }
+
+ // Send SOF.
+ for(i = 0; i < 10; i++) {
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ ToSendStuffBit(0);
+ }
+ for(i = 0; i < 10; i++) {
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ }
+
+ // Convert from last byte pos to length
+ ToSendMax++;
+
+ // Add a few more for slop
+ ToSendMax += 2;
}
//-----------------------------------------------------------------------------
// variables.
//-----------------------------------------------------------------------------
static struct {
- enum {
- STATE_UNSYNCD,
- STATE_GOT_FALLING_EDGE_OF_SOF,
- STATE_AWAITING_START_BIT,
- STATE_RECEIVING_DATA,
- STATE_ERROR_WAIT
- } state;
- uint16_t shiftReg;
- int bitCnt;
- int byteCnt;
- int byteCntMax;
- int posCnt;
- uint8_t *output;
+ enum {
+ STATE_UNSYNCD,
+ STATE_GOT_FALLING_EDGE_OF_SOF,
+ STATE_AWAITING_START_BIT,
+ STATE_RECEIVING_DATA,
+ STATE_ERROR_WAIT
+ } state;
+ uint16_t shiftReg;
+ int bitCnt;
+ int byteCnt;
+ int byteCntMax;
+ int posCnt;
+ uint8_t *output;
} Uart;
/* Receive & handle a bit coming from the reader.
*/
static int Handle14443UartBit(int bit)
{
- switch(Uart.state) {
- case STATE_UNSYNCD:
- LED_A_OFF();
- if(!bit) {
- // we went low, so this could be the beginning
- // of an SOF
- Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF;
- Uart.posCnt = 0;
- Uart.bitCnt = 0;
- }
- break;
-
- case STATE_GOT_FALLING_EDGE_OF_SOF:
- Uart.posCnt++;
- if(Uart.posCnt == 2) {
- if(bit) {
- if(Uart.bitCnt >= 10) {
- // we've seen enough consecutive
- // zeros that it's a valid SOF
- Uart.posCnt = 0;
- Uart.byteCnt = 0;
- Uart.state = STATE_AWAITING_START_BIT;
- LED_A_ON(); // Indicate we got a valid SOF
- } else {
- // didn't stay down long enough
- // before going high, error
- Uart.state = STATE_ERROR_WAIT;
- }
- } else {
- // do nothing, keep waiting
- }
- Uart.bitCnt++;
- }
- if(Uart.posCnt >= 4) Uart.posCnt = 0;
- if(Uart.bitCnt > 14) {
- // Give up if we see too many zeros without
- // a one, too.
- Uart.state = STATE_ERROR_WAIT;
- }
- break;
-
- case STATE_AWAITING_START_BIT:
- Uart.posCnt++;
- if(bit) {
- if(Uart.posCnt > 25) {
- // stayed high for too long between
- // characters, error
- Uart.state = STATE_ERROR_WAIT;
- }
- } else {
- // falling edge, this starts the data byte
- Uart.posCnt = 0;
- Uart.bitCnt = 0;
- Uart.shiftReg = 0;
- Uart.state = STATE_RECEIVING_DATA;
- LED_A_ON(); // Indicate we're receiving
- }
- break;
-
- case STATE_RECEIVING_DATA:
- Uart.posCnt++;
- if(Uart.posCnt == 2) {
- // time to sample a bit
- Uart.shiftReg >>= 1;
- if(bit) {
- Uart.shiftReg |= 0x200;
- }
- Uart.bitCnt++;
- }
- if(Uart.posCnt >= 4) {
- Uart.posCnt = 0;
- }
- if(Uart.bitCnt == 10) {
- if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001))
- {
- // this is a data byte, with correct
- // start and stop bits
- Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff;
- Uart.byteCnt++;
-
- if(Uart.byteCnt >= Uart.byteCntMax) {
- // Buffer overflowed, give up
- Uart.posCnt = 0;
- Uart.state = STATE_ERROR_WAIT;
- } else {
- // so get the next byte now
- Uart.posCnt = 0;
- Uart.state = STATE_AWAITING_START_BIT;
- }
- } else if(Uart.shiftReg == 0x000) {
- // this is an EOF byte
- LED_A_OFF(); // Finished receiving
- return TRUE;
- } else {
- // this is an error
- Uart.posCnt = 0;
- Uart.state = STATE_ERROR_WAIT;
- }
- }
- break;
-
- case STATE_ERROR_WAIT:
- // We're all screwed up, so wait a little while
- // for whatever went wrong to finish, and then
- // start over.
- Uart.posCnt++;
- if(Uart.posCnt > 10) {
- Uart.state = STATE_UNSYNCD;
- }
- break;
-
- default:
- Uart.state = STATE_UNSYNCD;
- break;
- }
-
- // This row make the error blew circular buffer in hf 14b snoop
- //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error
-
- return FALSE;
+ switch(Uart.state) {
+ case STATE_UNSYNCD:
+ LED_A_OFF();
+ if(!bit) {
+ // we went low, so this could be the beginning
+ // of an SOF
+ Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF;
+ Uart.posCnt = 0;
+ Uart.bitCnt = 0;
+ }
+ break;
+
+ case STATE_GOT_FALLING_EDGE_OF_SOF:
+ Uart.posCnt++;
+ if(Uart.posCnt == 2) {
+ if(bit) {
+ if(Uart.bitCnt >= 10) {
+ // we've seen enough consecutive
+ // zeros that it's a valid SOF
+ Uart.posCnt = 0;
+ Uart.byteCnt = 0;
+ Uart.state = STATE_AWAITING_START_BIT;
+ LED_A_ON(); // Indicate we got a valid SOF
+ } else {
+ // didn't stay down long enough
+ // before going high, error
+ Uart.state = STATE_ERROR_WAIT;
+ }
+ } else {
+ // do nothing, keep waiting
+ }
+ Uart.bitCnt++;
+ }
+ if(Uart.posCnt >= 4) Uart.posCnt = 0;
+ if(Uart.bitCnt > 14) {
+ // Give up if we see too many zeros without
+ // a one, too.
+ Uart.state = STATE_ERROR_WAIT;
+ }
+ break;
+
+ case STATE_AWAITING_START_BIT:
+ Uart.posCnt++;
+ if(bit) {
+ if(Uart.posCnt > 25) {
+ // stayed high for too long between
+ // characters, error
+ Uart.state = STATE_ERROR_WAIT;
+ }
+ } else {
+ // falling edge, this starts the data byte
+ Uart.posCnt = 0;
+ Uart.bitCnt = 0;
+ Uart.shiftReg = 0;
+ Uart.state = STATE_RECEIVING_DATA;
+ LED_A_ON(); // Indicate we're receiving
+ }
+ break;
+
+ case STATE_RECEIVING_DATA:
+ Uart.posCnt++;
+ if(Uart.posCnt == 2) {
+ // time to sample a bit
+ Uart.shiftReg >>= 1;
+ if(bit) {
+ Uart.shiftReg |= 0x200;
+ }
+ Uart.bitCnt++;
+ }
+ if(Uart.posCnt >= 4) {
+ Uart.posCnt = 0;
+ }
+ if(Uart.bitCnt == 10) {
+ if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001))
+ {
+ // this is a data byte, with correct
+ // start and stop bits
+ Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff;
+ Uart.byteCnt++;
+
+ if(Uart.byteCnt >= Uart.byteCntMax) {
+ // Buffer overflowed, give up
+ Uart.posCnt = 0;
+ Uart.state = STATE_ERROR_WAIT;
+ } else {
+ // so get the next byte now
+ Uart.posCnt = 0;
+ Uart.state = STATE_AWAITING_START_BIT;
+ }
+ } else if(Uart.shiftReg == 0x000) {
+ // this is an EOF byte
+ LED_A_OFF(); // Finished receiving
+ return TRUE;
+ } else {
+ // this is an error
+ Uart.posCnt = 0;
+ Uart.state = STATE_ERROR_WAIT;
+ }
+ }
+ break;
+
+ case STATE_ERROR_WAIT:
+ // We're all screwed up, so wait a little while
+ // for whatever went wrong to finish, and then
+ // start over.
+ Uart.posCnt++;
+ if(Uart.posCnt > 10) {
+ Uart.state = STATE_UNSYNCD;
+ }
+ break;
+
+ default:
+ Uart.state = STATE_UNSYNCD;
+ break;
+ }
+
+ // This row make the error blew circular buffer in hf 14b snoop
+ //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error
+
+ return FALSE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
static int GetIso14443CommandFromReader(uint8_t *received, int *len, int maxLen)
{
- uint8_t mask;
- int i, bit;
-
- // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
- // only, since we are receiving, not transmitting).
- // Signal field is off with the appropriate LED
- LED_D_OFF();
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
-
-
- // Now run a `software UART' on the stream of incoming samples.
- Uart.output = received;
- Uart.byteCntMax = maxLen;
- Uart.state = STATE_UNSYNCD;
-
- for(;;) {
- WDT_HIT();
-
- if(BUTTON_PRESS()) return FALSE;
-
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = 0x00;
- }
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
- uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-
- mask = 0x80;
- for(i = 0; i < 8; i++, mask >>= 1) {
- bit = (b & mask);
- if(Handle14443UartBit(bit)) {
- *len = Uart.byteCnt;
- return TRUE;
- }
- }
- }
- }
+ uint8_t mask;
+ int i, bit;
+
+ // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
+ // only, since we are receiving, not transmitting).
+ // Signal field is off with the appropriate LED
+ LED_D_OFF();
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
+
+
+ // Now run a `software UART' on the stream of incoming samples.
+ Uart.output = received;
+ Uart.byteCntMax = maxLen;
+ Uart.state = STATE_UNSYNCD;
+
+ for(;;) {
+ WDT_HIT();
+
+ if(BUTTON_PRESS()) return FALSE;
+
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ AT91C_BASE_SSC->SSC_THR = 0x00;
+ }
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+
+ mask = 0x80;
+ for(i = 0; i < 8; i++, mask >>= 1) {
+ bit = (b & mask);
+ if(Handle14443UartBit(bit)) {
+ *len = Uart.byteCnt;
+ return TRUE;
+ }
+ }
+ }
+ }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void SimulateIso14443Tag(void)
{
- static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
- static const uint8_t response1[] = {
- 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22,
- 0x00, 0x21, 0x85, 0x5e, 0xd7
- };
+ static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
+ static const uint8_t response1[] = {
+ 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22,
+ 0x00, 0x21, 0x85, 0x5e, 0xd7
+ };
- uint8_t *resp;
- int respLen;
+ uint8_t *resp;
+ int respLen;
- uint8_t *resp1 = BigBuf_get_addr() + 800;
- int resp1Len;
+ uint8_t *resp1 = BigBuf_get_addr() + 800;
+ int resp1Len;
- uint8_t *receivedCmd = BigBuf_get_addr();
- int len;
+ uint8_t *receivedCmd = BigBuf_get_addr();
+ int len;
- int i;
+ int i;
- int cmdsRecvd = 0;
+ int cmdsRecvd = 0;
- FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- memset(receivedCmd, 0x44, 400);
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+ memset(receivedCmd, 0x44, 400);
- CodeIso14443bAsTag(response1, sizeof(response1));
- memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;
+ CodeIso14443bAsTag(response1, sizeof(response1));
+ memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;
- // We need to listen to the high-frequency, peak-detected path.
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- FpgaSetupSsc();
+ // We need to listen to the high-frequency, peak-detected path.
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+ FpgaSetupSsc();
- cmdsRecvd = 0;
+ cmdsRecvd = 0;
- for(;;) {
- uint8_t b1, b2;
+ for(;;) {
+ uint8_t b1, b2;
- if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) {
+ if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) {
Dbprintf("button pressed, received %d commands", cmdsRecvd);
break;
- }
-
- // Good, look at the command now.
-
- if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) {
- resp = resp1; respLen = resp1Len;
- } else {
- Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
- // And print whether the CRC fails, just for good measure
- ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
- if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
- // Not so good, try again.
- DbpString("+++CRC fail");
- } else {
- DbpString("CRC passes");
- }
- break;
- }
-
- memset(receivedCmd, 0x44, 32);
-
- cmdsRecvd++;
-
- if(cmdsRecvd > 0x30) {
- DbpString("many commands later...");
- break;
- }
-
- if(respLen <= 0) continue;
-
- // Modulate BPSK
- // Signal field is off with the appropriate LED
- LED_D_OFF();
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
- AT91C_BASE_SSC->SSC_THR = 0xff;
- FpgaSetupSsc();
-
- // Transmit the response.
- i = 0;
- for(;;) {
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- uint8_t b = resp[i];
-
- AT91C_BASE_SSC->SSC_THR = b;
-
- i++;
- if(i > respLen) {
- break;
- }
- }
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
- volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- (void)b;
- }
- }
- }
+ }
+
+ // Good, look at the command now.
+
+ if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) {
+ resp = resp1; respLen = resp1Len;
+ } else {
+ Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
+ // And print whether the CRC fails, just for good measure
+ ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
+ if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
+ // Not so good, try again.
+ DbpString("+++CRC fail");
+ } else {
+ DbpString("CRC passes");
+ }
+ break;
+ }
+
+ memset(receivedCmd, 0x44, 32);
+
+ cmdsRecvd++;
+
+ if(cmdsRecvd > 0x30) {
+ DbpString("many commands later...");
+ break;
+ }
+
+ if(respLen <= 0) continue;
+
+ // Modulate BPSK
+ // Signal field is off with the appropriate LED
+ LED_D_OFF();
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
+ AT91C_BASE_SSC->SSC_THR = 0xff;
+ FpgaSetupSsc();
+
+ // Transmit the response.
+ i = 0;
+ for(;;) {
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ uint8_t b = resp[i];
+
+ AT91C_BASE_SSC->SSC_THR = b;
+
+ i++;
+ if(i > respLen) {
+ break;
+ }
+ }
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+ (void)b;
+ }
+ }
+ }
}
//=============================================================================
//=============================================================================
static struct {
- enum {
- DEMOD_UNSYNCD,
- DEMOD_PHASE_REF_TRAINING,
- DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
- DEMOD_GOT_FALLING_EDGE_OF_SOF,
- DEMOD_AWAITING_START_BIT,
- DEMOD_RECEIVING_DATA,
- DEMOD_ERROR_WAIT
- } state;
- int bitCount;
- int posCount;
- int thisBit;
- int metric;
- int metricN;
- uint16_t shiftReg;
- uint8_t *output;
- int len;
- int sumI;
- int sumQ;
+ enum {
+ DEMOD_UNSYNCD,
+ DEMOD_PHASE_REF_TRAINING,
+ DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
+ DEMOD_GOT_FALLING_EDGE_OF_SOF,
+ DEMOD_AWAITING_START_BIT,
+ DEMOD_RECEIVING_DATA,
+ DEMOD_ERROR_WAIT
+ } state;
+ int bitCount;
+ int posCount;
+ int thisBit;
+ int metric;
+ int metricN;
+ uint16_t shiftReg;
+ uint8_t *output;
+ int len;
+ int sumI;
+ int sumQ;
} Demod;
/*
*/
static RAMFUNC int Handle14443SamplesDemod(int ci, int cq)
{
- int v;
+ int v;
- // The soft decision on the bit uses an estimate of just the
- // quadrant of the reference angle, not the exact angle.
+ // The soft decision on the bit uses an estimate of just the
+ // quadrant of the reference angle, not the exact angle.
#define MAKE_SOFT_DECISION() { \
- if(Demod.sumI > 0) { \
- v = ci; \
- } else { \
- v = -ci; \
- } \
- if(Demod.sumQ > 0) { \
- v += cq; \
- } else { \
- v -= cq; \
- } \
- }
-
- switch(Demod.state) {
- case DEMOD_UNSYNCD:
- v = ci;
- if(v < 0) v = -v;
- if(cq > 0) {
- v += cq;
- } else {
- v -= cq;
- }
- if(v > 40) {
- Demod.posCount = 0;
- Demod.state = DEMOD_PHASE_REF_TRAINING;
- Demod.sumI = 0;
- Demod.sumQ = 0;
- }
- break;
-
- case DEMOD_PHASE_REF_TRAINING:
- if(Demod.posCount < 8) {
- Demod.sumI += ci;
- Demod.sumQ += cq;
- } else if(Demod.posCount > 100) {
- // error, waited too long
- Demod.state = DEMOD_UNSYNCD;
- } else {
- MAKE_SOFT_DECISION();
- if(v < 0) {
- Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
- Demod.posCount = 0;
- }
- }
- Demod.posCount++;
- break;
-
- case DEMOD_AWAITING_FALLING_EDGE_OF_SOF:
- MAKE_SOFT_DECISION();
- if(v < 0) {
- Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF;
- Demod.posCount = 0;
- } else {
- if(Demod.posCount > 100) {
- Demod.state = DEMOD_UNSYNCD;
- }
- }
- Demod.posCount++;
- break;
-
- case DEMOD_GOT_FALLING_EDGE_OF_SOF:
- MAKE_SOFT_DECISION();
- if(v > 0) {
- if(Demod.posCount < 12) {
- Demod.state = DEMOD_UNSYNCD;
- } else {
- LED_C_ON(); // Got SOF
- Demod.state = DEMOD_AWAITING_START_BIT;
- Demod.posCount = 0;
- Demod.len = 0;
- Demod.metricN = 0;
- Demod.metric = 0;
- }
- } else {
- if(Demod.posCount > 100) {
- Demod.state = DEMOD_UNSYNCD;
- }
- }
- Demod.posCount++;
- break;
-
- case DEMOD_AWAITING_START_BIT:
- MAKE_SOFT_DECISION();
- if(v > 0) {
- if(Demod.posCount > 10) {
- Demod.state = DEMOD_UNSYNCD;
- }
- } else {
- Demod.bitCount = 0;
- Demod.posCount = 1;
- Demod.thisBit = v;
- Demod.shiftReg = 0;
- Demod.state = DEMOD_RECEIVING_DATA;
- }
- break;
-
- case DEMOD_RECEIVING_DATA:
- MAKE_SOFT_DECISION();
- if(Demod.posCount == 0) {
- Demod.thisBit = v;
- Demod.posCount = 1;
- } else {
- Demod.thisBit += v;
-
- if(Demod.thisBit > 0) {
- Demod.metric += Demod.thisBit;
- } else {
- Demod.metric -= Demod.thisBit;
- }
- (Demod.metricN)++;
-
- Demod.shiftReg >>= 1;
- if(Demod.thisBit > 0) {
- Demod.shiftReg |= 0x200;
- }
-
- Demod.bitCount++;
- if(Demod.bitCount == 10) {
- uint16_t s = Demod.shiftReg;
- if((s & 0x200) && !(s & 0x001)) {
- uint8_t b = (s >> 1);
- Demod.output[Demod.len] = b;
- Demod.len++;
- Demod.state = DEMOD_AWAITING_START_BIT;
- } else if(s == 0x000) {
- // This is EOF
- LED_C_OFF();
- Demod.state = DEMOD_UNSYNCD;
- return TRUE;
- } else {
- Demod.state = DEMOD_UNSYNCD;
- }
- }
- Demod.posCount = 0;
- }
- break;
-
- default:
- Demod.state = DEMOD_UNSYNCD;
- break;
- }
-
- if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized...
- return FALSE;
+ if(Demod.sumI > 0) { \
+ v = ci; \
+ } else { \
+ v = -ci; \
+ } \
+ if(Demod.sumQ > 0) { \
+ v += cq; \
+ } else { \
+ v -= cq; \
+ } \
+ }
+
+ switch(Demod.state) {
+ case DEMOD_UNSYNCD:
+ v = ci;
+ if(v < 0) v = -v;
+ if(cq > 0) {
+ v += cq;
+ } else {
+ v -= cq;
+ }
+ if(v > 40) {
+ Demod.posCount = 0;
+ Demod.state = DEMOD_PHASE_REF_TRAINING;
+ Demod.sumI = 0;
+ Demod.sumQ = 0;
+ }
+ break;
+
+ case DEMOD_PHASE_REF_TRAINING:
+ if(Demod.posCount < 8) {
+ Demod.sumI += ci;
+ Demod.sumQ += cq;
+ } else if(Demod.posCount > 100) {
+ // error, waited too long
+ Demod.state = DEMOD_UNSYNCD;
+ } else {
+ MAKE_SOFT_DECISION();
+ if(v < 0) {
+ Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
+ Demod.posCount = 0;
+ }
+ }
+ Demod.posCount++;
+ break;
+
+ case DEMOD_AWAITING_FALLING_EDGE_OF_SOF:
+ MAKE_SOFT_DECISION();
+ if(v < 0) {
+ Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF;
+ Demod.posCount = 0;
+ } else {
+ if(Demod.posCount > 100) {
+ Demod.state = DEMOD_UNSYNCD;
+ }
+ }
+ Demod.posCount++;
+ break;
+
+ case DEMOD_GOT_FALLING_EDGE_OF_SOF:
+ MAKE_SOFT_DECISION();
+ if(v > 0) {
+ if(Demod.posCount < 12) {
+ Demod.state = DEMOD_UNSYNCD;
+ } else {
+ LED_C_ON(); // Got SOF
+ Demod.state = DEMOD_AWAITING_START_BIT;
+ Demod.posCount = 0;
+ Demod.len = 0;
+ Demod.metricN = 0;
+ Demod.metric = 0;
+ }
+ } else {
+ if(Demod.posCount > 100) {
+ Demod.state = DEMOD_UNSYNCD;
+ }
+ }
+ Demod.posCount++;
+ break;
+
+ case DEMOD_AWAITING_START_BIT:
+ MAKE_SOFT_DECISION();
+ if(v > 0) {
+ if(Demod.posCount > 10) {
+ Demod.state = DEMOD_UNSYNCD;
+ }
+ } else {
+ Demod.bitCount = 0;
+ Demod.posCount = 1;
+ Demod.thisBit = v;
+ Demod.shiftReg = 0;
+ Demod.state = DEMOD_RECEIVING_DATA;
+ }
+ break;
+
+ case DEMOD_RECEIVING_DATA:
+ MAKE_SOFT_DECISION();
+ if(Demod.posCount == 0) {
+ Demod.thisBit = v;
+ Demod.posCount = 1;
+ } else {
+ Demod.thisBit += v;
+
+ if(Demod.thisBit > 0) {
+ Demod.metric += Demod.thisBit;
+ } else {
+ Demod.metric -= Demod.thisBit;
+ }
+ (Demod.metricN)++;
+
+ Demod.shiftReg >>= 1;
+ if(Demod.thisBit > 0) {
+ Demod.shiftReg |= 0x200;
+ }
+
+ Demod.bitCount++;
+ if(Demod.bitCount == 10) {
+ uint16_t s = Demod.shiftReg;
+ if((s & 0x200) && !(s & 0x001)) {
+ uint8_t b = (s >> 1);
+ Demod.output[Demod.len] = b;
+ Demod.len++;
+ Demod.state = DEMOD_AWAITING_START_BIT;
+ } else if(s == 0x000) {
+ // This is EOF
+ LED_C_OFF();
+ Demod.state = DEMOD_UNSYNCD;
+ return TRUE;
+ } else {
+ Demod.state = DEMOD_UNSYNCD;
+ }
+ }
+ Demod.posCount = 0;
+ }
+ break;
+
+ default:
+ Demod.state = DEMOD_UNSYNCD;
+ break;
+ }
+
+ if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized...
+ return FALSE;
+}
+static void DemodReset()
+{
+ // Clear out the state of the "UART" that receives from the tag.
+ Demod.len = 0;
+ Demod.state = DEMOD_UNSYNCD;
+ memset(Demod.output, 0x00, MAX_FRAME_SIZE);
+}
+static void DemodInit(uint8_t *data)
+{
+ Demod.output = data;
+ DemodReset();
+}
+
+static void UartReset()
+{
+ Uart.byteCntMax = MAX_FRAME_SIZE;
+ Uart.state = STATE_UNSYNCD;
+ Uart.byteCnt = 0;
+ Uart.bitCnt = 0;
+}
+static void UartInit(uint8_t *data)
+{
+ Uart.output = data;
+ UartReset();
}
/*
- * Demodulate the samples we received from the tag
+ * Demodulate the samples we received from the tag, also log to tracebuffer
* weTx: set to 'TRUE' if we behave like a reader
* set to 'FALSE' if we behave like a snooper
* quiet: set to 'TRUE' to disable debug output
*/
static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
{
- int max = 0;
- int gotFrame = FALSE;
-
-//# define DMA_BUFFER_SIZE 8
- uint8_t *dmaBuf;
-
- int lastRxCounter;
- uint8_t *upTo;
-
- int ci, cq;
-
- int samples = 0;
-
- // Clear out the state of the "UART" that receives from the tag.
- uint8_t *BigBuf = BigBuf_get_addr();
- memset(BigBuf, 0x00, 400);
- Demod.output = BigBuf;
- Demod.len = 0;
- Demod.state = DEMOD_UNSYNCD;
-
- // And the UART that receives from the reader
- Uart.output = BigBuf + 1024;
- Uart.byteCntMax = 100;
- Uart.state = STATE_UNSYNCD;
-
- // Setup for the DMA.
- dmaBuf = BigBuf + 32;
- upTo = dmaBuf;
- lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
- FpgaSetupSscDma(dmaBuf, DEMOD_DMA_BUFFER_SIZE);
-
- // Signal field is ON with the appropriate LED:
- if (weTx) LED_D_ON(); else LED_D_OFF();
- // And put the FPGA in the appropriate mode
- FpgaWriteConfWord(
- FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
- (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
-
- for(;;) {
- int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
- if(behindBy > max) max = behindBy;
-
- while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DEMOD_DMA_BUFFER_SIZE-1))
- > 2)
- {
- ci = upTo[0];
- cq = upTo[1];
- upTo += 2;
- if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
- upTo -= DEMOD_DMA_BUFFER_SIZE;
- AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
- AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
- }
- lastRxCounter -= 2;
- if(lastRxCounter <= 0) {
- lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
- }
-
- samples += 2;
-
- Handle14443UartBit(1);
- Handle14443UartBit(1);
-
- if(Handle14443SamplesDemod(ci, cq)) {
- gotFrame = 1;
- }
- }
-
- if(samples > 2000) {
- break;
- }
- }
- AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
- if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len);
+ int max = 0;
+ int gotFrame = FALSE;
+ int lastRxCounter, ci, cq, samples = 0;
+
+ // Allocate memory from BigBuf for some buffers
+ // free all previous allocations first
+ BigBuf_free();
+
+ // The command (reader -> tag) that we're receiving.
+ uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
+
+ // The response (tag -> reader) that we're receiving.
+ uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
+
+ // The DMA buffer, used to stream samples from the FPGA
+ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
+
+ // Set up the demodulator for tag -> reader responses.
+ DemodInit(receivedResponse);
+ // Set up the demodulator for the reader -> tag commands
+ UartInit(receivedCmd);
+
+ // Setup and start DMA.
+ FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE);
+
+ uint8_t *upTo= dmaBuf;
+ lastRxCounter = DMA_BUFFER_SIZE;
+
+ // Signal field is ON with the appropriate LED:
+ if (weTx) LED_D_ON(); else LED_D_OFF();
+ // And put the FPGA in the appropriate mode
+ FpgaWriteConfWord(
+ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
+ (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
+
+ for(;;) {
+ int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
+ if(behindBy > max) max = behindBy;
+
+ while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1))
+ > 2)
+ {
+ ci = upTo[0];
+ cq = upTo[1];
+ upTo += 2;
+ if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
+ upTo -= DMA_BUFFER_SIZE;
+ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+ }
+ lastRxCounter -= 2;
+ if(lastRxCounter <= 0) {
+ lastRxCounter += DMA_BUFFER_SIZE;
+ }
+
+ samples += 2;
+
+ Handle14443UartBit(1);
+ Handle14443UartBit(1);
+
+ if(Handle14443SamplesDemod(ci, cq)) {
+ gotFrame = 1;
+ }
+ }
+
+ if(samples > 2000) {
+ break;
+ }
+ }
+ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+ if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len);
+ //Tracing
+ if (tracing && Demod.len > 0) {
+ uint8_t parity[MAX_PARITY_SIZE];
+ GetParity(Demod.output , Demod.len, parity);
+ LogTrace(Demod.output,Demod.len, 0, 0, parity, FALSE);
+ }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/*static void GetSamplesFor14443(int weTx, int n)
{
- uint8_t *dest = (uint8_t *)BigBuf;
- int c;
-
- FpgaWriteConfWord(
- FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
- (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
-
- c = 0;
- for(;;) {
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = 0x43;
- }
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
- int8_t b;
- b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
- dest[c++] = (uint8_t)b;
-
- if(c >= n) {
- break;
- }
- }
- }
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int c;
+
+ FpgaWriteConfWord(
+ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
+ (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
+
+ c = 0;
+ for(;;) {
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ AT91C_BASE_SSC->SSC_THR = 0x43;
+ }
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ int8_t b;
+ b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
+
+ dest[c++] = (uint8_t)b;
+
+ if(c >= n) {
+ break;
+ }
+ }
+ }
}*/
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
static void TransmitFor14443(void)
{
- int c;
+ int c;
- FpgaSetupSsc();
+ FpgaSetupSsc();
- while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = 0xff;
- }
+ while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ AT91C_BASE_SSC->SSC_THR = 0xff;
+ }
- // Signal field is ON with the appropriate Red LED
+ // Signal field is ON with the appropriate Red LED
LED_D_ON();
// Signal we are transmitting with the Green LED
LED_B_ON();
FpgaWriteConfWord(
- FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
-
- for(c = 0; c < 10;) {
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = 0xff;
- c++;
- }
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
- volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
- (void)r;
- }
- WDT_HIT();
- }
-
- c = 0;
- for(;;) {
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = ToSend[c];
- c++;
- if(c >= ToSendMax) {
- break;
- }
- }
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
- volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
- (void)r;
- }
- WDT_HIT();
- }
- LED_B_OFF(); // Finished sending
+ FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
+
+ for(c = 0; c < 10;) {
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ AT91C_BASE_SSC->SSC_THR = 0xff;
+ c++;
+ }
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
+ (void)r;
+ }
+ WDT_HIT();
+ }
+
+ c = 0;
+ for(;;) {
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ AT91C_BASE_SSC->SSC_THR = ToSend[c];
+ c++;
+ if(c >= ToSendMax) {
+ break;
+ }
+ }
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
+ (void)r;
+ }
+ WDT_HIT();
+ }
+ LED_B_OFF(); // Finished sending
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
{
- int i, j;
- uint8_t b;
-
- ToSendReset();
-
- // Establish initial reference level
- for(i = 0; i < 40; i++) {
- ToSendStuffBit(1);
- }
- // Send SOF
- for(i = 0; i < 10; i++) {
- ToSendStuffBit(0);
- }
-
- for(i = 0; i < len; i++) {
- // Stop bits/EGT
- ToSendStuffBit(1);
- ToSendStuffBit(1);
- // Start bit
- ToSendStuffBit(0);
- // Data bits
- b = cmd[i];
- for(j = 0; j < 8; j++) {
- if(b & 1) {
- ToSendStuffBit(1);
- } else {
- ToSendStuffBit(0);
- }
- b >>= 1;
- }
- }
- // Send EOF
- ToSendStuffBit(1);
- for(i = 0; i < 10; i++) {
- ToSendStuffBit(0);
- }
- for(i = 0; i < 8; i++) {
- ToSendStuffBit(1);
- }
-
- // And then a little more, to make sure that the last character makes
- // it out before we switch to rx mode.
- for(i = 0; i < 24; i++) {
- ToSendStuffBit(1);
- }
-
- // Convert from last character reference to length
- ToSendMax++;
+ int i, j;
+ uint8_t b;
+
+ ToSendReset();
+
+ // Establish initial reference level
+ for(i = 0; i < 40; i++) {
+ ToSendStuffBit(1);
+ }
+ // Send SOF
+ for(i = 0; i < 10; i++) {
+ ToSendStuffBit(0);
+ }
+
+ for(i = 0; i < len; i++) {
+ // Stop bits/EGT
+ ToSendStuffBit(1);
+ ToSendStuffBit(1);
+ // Start bit
+ ToSendStuffBit(0);
+ // Data bits
+ b = cmd[i];
+ for(j = 0; j < 8; j++) {
+ if(b & 1) {
+ ToSendStuffBit(1);
+ } else {
+ ToSendStuffBit(0);
+ }
+ b >>= 1;
+ }
+ }
+ // Send EOF
+ ToSendStuffBit(1);
+ for(i = 0; i < 10; i++) {
+ ToSendStuffBit(0);
+ }
+ for(i = 0; i < 8; i++) {
+ ToSendStuffBit(1);
+ }
+
+ // And then a little more, to make sure that the last character makes
+ // it out before we switch to rx mode.
+ for(i = 0; i < 24; i++) {
+ ToSendStuffBit(1);
+ }
+
+ // Convert from last character reference to length
+ ToSendMax++;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso14443(uint32_t parameter)
{
- uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
+ uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
- SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
+ SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
+}
+
+/**
+ Convenience function to encode, transmit and trace iso 14443b comms
+ **/
+static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
+{
+ CodeIso14443bAsReader(cmd, len);
+ TransmitFor14443();
+ if (tracing) {
+ uint8_t parity[MAX_PARITY_SIZE];
+ GetParity(cmd, len, parity);
+ LogTrace(cmd,len, 0, 0, parity, TRUE);
+ }
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ReadSTMemoryIso14443(uint32_t dwLast)
{
- uint8_t i = 0x00;
-
- FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- // Make sure that we start from off, since the tags are stateful;
- // confusing things will happen if we don't reset them between reads.
- LED_D_OFF();
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelay(200);
-
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- FpgaSetupSsc();
-
- // Now give it time to spin up.
- // Signal field is on with the appropriate LED
- LED_D_ON();
- FpgaWriteConfWord(
- FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
- SpinDelay(200);
-
- // First command: wake up the tag using the INITIATE command
- uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
- CodeIso14443bAsReader(cmd1, sizeof(cmd1));
- TransmitFor14443();
+ clear_trace();
+ set_tracing(TRUE);
+
+ uint8_t i = 0x00;
+
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+ // Make sure that we start from off, since the tags are stateful;
+ // confusing things will happen if we don't reset them between reads.
+ LED_D_OFF();
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelay(200);
+
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+ FpgaSetupSsc();
+
+ // Now give it time to spin up.
+ // Signal field is on with the appropriate LED
+ LED_D_ON();
+ FpgaWriteConfWord(
+ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
+ SpinDelay(200);
+
+ // First command: wake up the tag using the INITIATE command
+ uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
+
+ CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
// LED_A_ON();
- GetSamplesFor14443Demod(TRUE, 2000,TRUE);
+ GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
- if (Demod.len == 0) {
+ if (Demod.len == 0) {
DbpString("No response from tag");
return;
- } else {
+ } else {
Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %x %x %x",
Demod.output[0], Demod.output[1],Demod.output[2]);
- }
- // There is a response, SELECT the uid
- DbpString("Now SELECT tag:");
- cmd1[0] = 0x0E; // 0x0E is SELECT
- cmd1[1] = Demod.output[0];
- ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
- CodeIso14443bAsReader(cmd1, sizeof(cmd1));
- TransmitFor14443();
+ }
+ // There is a response, SELECT the uid
+ DbpString("Now SELECT tag:");
+ cmd1[0] = 0x0E; // 0x0E is SELECT
+ cmd1[1] = Demod.output[0];
+ ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
+ CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
+
// LED_A_ON();
- GetSamplesFor14443Demod(TRUE, 2000,TRUE);
+ GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
- if (Demod.len != 3) {
+ if (Demod.len != 3) {
Dbprintf("Expected 3 bytes from tag, got %d", Demod.len);
return;
- }
- // Check the CRC of the answer:
- ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]);
- if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) {
+ }
+ // Check the CRC of the answer:
+ ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]);
+ if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) {
DbpString("CRC Error reading select response.");
return;
- }
- // Check response from the tag: should be the same UID as the command we just sent:
- if (cmd1[1] != Demod.output[0]) {
+ }
+ // Check response from the tag: should be the same UID as the command we just sent:
+ if (cmd1[1] != Demod.output[0]) {
Dbprintf("Bad response to SELECT from Tag, aborting: %x %x", cmd1[1], Demod.output[0]);
return;
- }
- // Tag is now selected,
- // First get the tag's UID:
- cmd1[0] = 0x0B;
- ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
- CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one
- TransmitFor14443();
+ }
+ // Tag is now selected,
+ // First get the tag's UID:
+ cmd1[0] = 0x0B;
+ ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
+ CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one
+
// LED_A_ON();
- GetSamplesFor14443Demod(TRUE, 2000,TRUE);
+ GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
- if (Demod.len != 10) {
+ if (Demod.len != 10) {
Dbprintf("Expected 10 bytes from tag, got %d", Demod.len);
return;
- }
- // The check the CRC of the answer (use cmd1 as temporary variable):
- ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);
- if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
+ }
+ // The check the CRC of the answer (use cmd1 as temporary variable):
+ ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);
+ if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
Dbprintf("CRC Error reading block! - Below: expected, got %x %x",
(cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]);
// Do not return;, let's go on... (we should retry, maybe ?)
- }
- Dbprintf("Tag UID (64 bits): %08x %08x",
+ }
+ Dbprintf("Tag UID (64 bits): %08x %08x",
(Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4],
(Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
- // Now loop to read all 16 blocks, address from 0 to last block
- Dbprintf("Tag memory dump, block 0 to %d",dwLast);
- cmd1[0] = 0x08;
- i = 0x00;
- dwLast++;
- for (;;) {
- if (i == dwLast) {
- DbpString("System area block (0xff):");
- i = 0xff;
- }
- cmd1[1] = i;
- ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
- CodeIso14443bAsReader(cmd1, sizeof(cmd1));
- TransmitFor14443();
+ // Now loop to read all 16 blocks, address from 0 to last block
+ Dbprintf("Tag memory dump, block 0 to %d",dwLast);
+ cmd1[0] = 0x08;
+ i = 0x00;
+ dwLast++;
+ for (;;) {
+ if (i == dwLast) {
+ DbpString("System area block (0xff):");
+ i = 0xff;
+ }
+ cmd1[1] = i;
+ ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
+ CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
+
// LED_A_ON();
- GetSamplesFor14443Demod(TRUE, 2000,TRUE);
+ GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
- if (Demod.len != 6) { // Check if we got an answer from the tag
+ if (Demod.len != 6) { // Check if we got an answer from the tag
DbpString("Expected 6 bytes from tag, got less...");
return;
- }
- // The check the CRC of the answer (use cmd1 as temporary variable):
- ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
- if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
+ }
+ // The check the CRC of the answer (use cmd1 as temporary variable):
+ ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
+ if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
Dbprintf("CRC Error reading block! - Below: expected, got %x %x",
(cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]);
// Do not return;, let's go on... (we should retry, maybe ?)
- }
- // Now print out the memory location:
- Dbprintf("Address=%x, Contents=%x, CRC=%x", i,
+ }
+ // Now print out the memory location:
+ Dbprintf("Address=%x, Contents=%x, CRC=%x", i,
(Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
(Demod.output[4]<<8)+Demod.output[5]);
- if (i == 0xff) {
+ if (i == 0xff) {
break;
- }
- i++;
- }
+ }
+ i++;
+ }
}
*/
void RAMFUNC SnoopIso14443(void)
{
- // 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
- // response from the tag.
- int triggered = TRUE;
+ // 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
+ // response from the tag.
+ int triggered = TRUE;
- FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
BigBuf_free();
- // The command (reader -> tag) that we're working on receiving.
- uint8_t *receivedCmd = BigBuf_malloc(READER_TAG_BUFFER_SIZE);
- // The response (tag -> reader) that we're working on receiving.
- uint8_t *receivedResponse = BigBuf_malloc(TAG_READER_BUFFER_SIZE);
-
- // As we receive stuff, we copy it from receivedCmd or receivedResponse
- // into trace, along with its length and other annotations.
- uint8_t *trace = BigBuf_get_addr();
- traceLen = 0;
-
- // The DMA buffer, used to stream samples from the FPGA.
- uint8_t *dmaBuf = BigBuf_malloc(DEMOD_DMA_BUFFER_SIZE);
- int lastRxCounter;
- uint8_t *upTo;
- int ci, cq;
- int maxBehindBy = 0;
-
- // Count of samples received so far, so that we can include timing
- // information in the trace buffer.
- int samples = 0;
-
- // Initialize the trace buffer
- memset(trace, 0x44, BigBuf_max_traceLen());
-
- // Set up the demodulator for tag -> reader responses.
- Demod.output = receivedResponse;
- Demod.len = 0;
- Demod.state = DEMOD_UNSYNCD;
-
- // And the reader -> tag commands
- memset(&Uart, 0, sizeof(Uart));
- Uart.output = receivedCmd;
- Uart.byteCntMax = 100;
- Uart.state = STATE_UNSYNCD;
-
- // Print some debug information about the buffer sizes
- Dbprintf("Snooping buffers initialized:");
- Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
- Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
- Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
- Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
-
- // And put the FPGA in the appropriate mode
- // Signal field is off with the appropriate LED
- LED_D_OFF();
- FpgaWriteConfWord(
- FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
- FPGA_HF_READER_RX_XCORR_SNOOP);
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-
- // Setup for the DMA.
- FpgaSetupSsc();
- upTo = dmaBuf;
- lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
- FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
-
- LED_A_ON();
-
- // And now we loop, receiving samples.
- for(;;) {
- int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
- (DEMOD_DMA_BUFFER_SIZE-1);
- if(behindBy > maxBehindBy) {
- maxBehindBy = behindBy;
- if(behindBy > (9*DEMOD_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
- Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
- goto done;
- }
- }
- if(behindBy < 2) continue;
-
- ci = upTo[0];
- cq = upTo[1];
- upTo += 2;
- lastRxCounter -= 2;
- if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
- upTo -= DEMOD_DMA_BUFFER_SIZE;
- lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
- AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
- AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
- }
-
- samples += 2;
-
-#define HANDLE_BIT_IF_BODY \
- if(triggered) { \
- trace[traceLen++] = ((samples >> 0) & 0xff); \
- trace[traceLen++] = ((samples >> 8) & 0xff); \
- trace[traceLen++] = ((samples >> 16) & 0xff); \
- trace[traceLen++] = ((samples >> 24) & 0xff); \
- trace[traceLen++] = 0; \
- trace[traceLen++] = 0; \
- trace[traceLen++] = 0; \
- trace[traceLen++] = 0; \
- trace[traceLen++] = Uart.byteCnt; \
- memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \
- traceLen += Uart.byteCnt; \
- if(traceLen > 1000) break; \
- } \
- /* And ready to receive another command. */ \
- memset(&Uart, 0, sizeof(Uart)); \
- Uart.output = receivedCmd; \
- Uart.byteCntMax = 100; \
- Uart.state = STATE_UNSYNCD; \
- /* And also reset the demod code, which might have been */ \
- /* false-triggered by the commands from the reader. */ \
- memset(&Demod, 0, sizeof(Demod)); \
- Demod.output = receivedResponse; \
- Demod.state = DEMOD_UNSYNCD; \
-
- if(Handle14443UartBit(ci & 1)) {
- HANDLE_BIT_IF_BODY
- }
- if(Handle14443UartBit(cq & 1)) {
- HANDLE_BIT_IF_BODY
- }
-
- if(Handle14443SamplesDemod(ci, cq)) {
- // timestamp, as a count of samples
- trace[traceLen++] = ((samples >> 0) & 0xff);
- trace[traceLen++] = ((samples >> 8) & 0xff);
- trace[traceLen++] = ((samples >> 16) & 0xff);
- trace[traceLen++] = 0x80 | ((samples >> 24) & 0xff);
- // correlation metric (~signal strength estimate)
- if(Demod.metricN != 0) {
- Demod.metric /= Demod.metricN;
- }
- trace[traceLen++] = ((Demod.metric >> 0) & 0xff);
- trace[traceLen++] = ((Demod.metric >> 8) & 0xff);
- trace[traceLen++] = ((Demod.metric >> 16) & 0xff);
- trace[traceLen++] = ((Demod.metric >> 24) & 0xff);
- // length
- trace[traceLen++] = Demod.len;
- memcpy(trace+traceLen, receivedResponse, Demod.len);
- traceLen += Demod.len;
- if(traceLen > BigBuf_max_traceLen()) {
- DbpString("Reached trace limit");
- goto done;
- }
- triggered = TRUE;
- LED_A_OFF();
- LED_B_ON();
+ clear_trace();
+ set_tracing(TRUE);
+
+ // The DMA buffer, used to stream samples from the FPGA
+ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
+ int lastRxCounter;
+ uint8_t *upTo;
+ int ci, cq;
+ int maxBehindBy = 0;
+
+ // Count of samples received so far, so that we can include timing
+ // information in the trace buffer.
+ int samples = 0;
- // And ready to receive another response.
- memset(&Demod, 0, sizeof(Demod));
- Demod.output = receivedResponse;
- Demod.state = DEMOD_UNSYNCD;
- }
- WDT_HIT();
+ DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
+ UartInit(BigBuf_malloc(MAX_FRAME_SIZE));
- if(BUTTON_PRESS()) {
- DbpString("cancelled");
- goto done;
- }
- }
+ // Print some debug information about the buffer sizes
+ Dbprintf("Snooping buffers initialized:");
+ Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
+ Dbprintf(" Reader -> tag: %i bytes", MAX_FRAME_SIZE);
+ Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE);
+ Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE);
-done:
+ // Signal field is off with the appropriate LED
+ LED_D_OFF();
+
+ // And put the FPGA in the appropriate mode
+ FpgaWriteConfWord(
+ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
+ FPGA_HF_READER_RX_XCORR_SNOOP);
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+
+ // Setup for the DMA.
+ FpgaSetupSsc();
+ upTo = dmaBuf;
+ lastRxCounter = DMA_BUFFER_SIZE;
+ FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+ uint8_t parity[MAX_PARITY_SIZE];
+ LED_A_ON();
+
+ // And now we loop, receiving samples.
+ for(;;) {
+ int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
+ (DMA_BUFFER_SIZE-1);
+ if(behindBy > maxBehindBy) {
+ maxBehindBy = behindBy;
+ if(behindBy > (9*DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
+ Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
+ break;
+ }
+ }
+ if(behindBy < 2) continue;
+
+ ci = upTo[0];
+ cq = upTo[1];
+ upTo += 2;
+ lastRxCounter -= 2;
+ if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
+ upTo -= DMA_BUFFER_SIZE;
+ lastRxCounter += DMA_BUFFER_SIZE;
+ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+ }
+
+ samples += 2;
+
+ if(Handle14443UartBit(ci & 1)) {
+ if(triggered && tracing) {
+ GetParity(Uart.output, Uart.byteCnt, parity);
+ LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
+ }
+ if(Uart.byteCnt==0) Dbprintf("[1] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt);
+
+ /* And ready to receive another command. */
+ UartReset();
+ /* And also reset the demod code, which might have been */
+ /* false-triggered by the commands from the reader. */
+ DemodReset();
+ }
+ if(Handle14443UartBit(cq & 1)) {
+ if(triggered && tracing) {
+ GetParity(Uart.output, Uart.byteCnt, parity);
+ LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
+ }
+ if(Uart.byteCnt==0) Dbprintf("[2] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt);
+
+ /* And ready to receive another command. */
+ UartReset();
+ /* And also reset the demod code, which might have been */
+ /* false-triggered by the commands from the reader. */
+ DemodReset();
+ }
+
+ if(Handle14443SamplesDemod(ci, cq)) {
+
+ //Use samples as a time measurement
+ if(tracing)
+ {
+ uint8_t parity[MAX_PARITY_SIZE];
+ GetParity(Demod.output, Demod.len, parity);
+ LogTrace(Demod.output,Demod.len,samples, samples,parity,FALSE);
+ }
+ triggered = TRUE;
+ LED_A_OFF();
+ LED_B_ON();
+
+ // And ready to receive another response.
+ DemodReset();
+ }
+ WDT_HIT();
+
+ if(!tracing) {
+ DbpString("Reached trace limit");
+ break;
+ }
+
+ if(BUTTON_PRESS()) {
+ DbpString("cancelled");
+ break;
+ }
+ }
+ FpgaDisableSscDma();
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
Dbprintf(" Uart State: %x", Uart.state);
Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);
- Dbprintf(" Trace length: %i", traceLen);
+ Dbprintf(" Trace length: %i", BigBuf_get_traceLen());
}
/*
void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, uint8_t data[])
{
- FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- if(!powerfield)
- {
- // Make sure that we start from off, since the tags are stateful;
- // confusing things will happen if we don't reset them between reads.
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LED_D_OFF();
- SpinDelay(200);
- }
-
- if(!GETBIT(GPIO_LED_D))
- {
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- FpgaSetupSsc();
-
- // Now give it time to spin up.
- // Signal field is on with the appropriate LED
- LED_D_ON();
- FpgaWriteConfWord(
- FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
- SpinDelay(200);
- }
-
- CodeIso14443bAsReader(data, datalen);
- TransmitFor14443();
- if(recv)
- {
- uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);
- GetSamplesFor14443Demod(TRUE, 2000, TRUE);
- cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen);
- }
- if(!powerfield)
- {
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LED_D_OFF();
- }
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+ if(!powerfield)
+ {
+ // Make sure that we start from off, since the tags are stateful;
+ // confusing things will happen if we don't reset them between reads.
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LED_D_OFF();
+ SpinDelay(200);
+ }
+
+ if(!GETBIT(GPIO_LED_D))
+ {
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+ FpgaSetupSsc();
+
+ // Now give it time to spin up.
+ // Signal field is on with the appropriate LED
+ LED_D_ON();
+ FpgaWriteConfWord(
+ FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
+ SpinDelay(200);
+ }
+
+ CodeAndTransmit14443bAsReader(data, datalen);
+
+ if(recv)
+ {
+ uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);
+ GetSamplesFor14443Demod(TRUE, 2000, TRUE);
+ cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen);
+ }
+ if(!powerfield)
+ {
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LED_D_OFF();
+ }
}
#include "iso14443a.h"
#include "crapto1.h"
#include "mifareutil.h"
-
+#include "BigBuf.h"
static uint32_t iso14a_timeout;
int rsamples = 0;
-int tracing = TRUE;
uint8_t trigger = 0;
// the block number for the ISO14443-4 PCB
static uint8_t iso14_pcb_blocknum = 0;
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
+
void iso14a_set_trigger(bool enable) {
trigger = enable;
}
-void iso14a_clear_trace() {
- uint8_t *trace = BigBuf_get_addr();
- uint16_t max_traceLen = BigBuf_max_traceLen();
- memset(trace, 0x44, max_traceLen);
- traceLen = 0;
-}
-
-void iso14a_set_tracing(bool enable) {
- tracing = enable;
-}
void iso14a_set_timeout(uint32_t timeout) {
iso14a_timeout = timeout;
+ if(MF_DBGLEVEL >= 3) Dbprintf("ISO14443A Timeout set to %ld (%dms)", iso14a_timeout, iso14a_timeout / 106);
}
+
+void iso14a_set_ATS_timeout(uint8_t *ats) {
+
+ uint8_t tb1;
+ uint8_t fwi;
+ uint32_t fwt;
+
+ if (ats[0] > 1) { // there is a format byte T0
+ if ((ats[1] & 0x20) == 0x20) { // there is an interface byte TB(1)
+ if ((ats[1] & 0x10) == 0x10) { // there is an interface byte TA(1) preceding TB(1)
+ tb1 = ats[3];
+ } else {
+ tb1 = ats[2];
+ }
+ fwi = (tb1 & 0xf0) >> 4; // frame waiting indicator (FWI)
+ fwt = 256 * 16 * (1 << fwi); // frame waiting time (FWT) in 1/fc
+
+ iso14a_set_timeout(fwt/(8*16));
+ }
+ }
+}
+
+
//-----------------------------------------------------------------------------
// Generate the parity value for a byte sequence
//
ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
}
-// The function LogTrace() is also used by the iClass implementation in iClass.c
-bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
-{
- if (!tracing) return FALSE;
-
- uint8_t *trace = BigBuf_get_addr();
- uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
- uint16_t duration = timestamp_end - timestamp_start;
-
- // Return when trace is full
- uint16_t max_traceLen = BigBuf_max_traceLen();
- if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
- tracing = FALSE; // don't trace any more
- return FALSE;
- }
-
- // Traceformat:
- // 32 bits timestamp (little endian)
- // 16 bits duration (little endian)
- // 16 bits data length (little endian, Highest Bit used as readerToTag flag)
- // y Bytes data
- // x Bytes parity (one byte per 8 bytes data)
-
- // timestamp (start)
- trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
- trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
- trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
- trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
-
- // duration
- trace[traceLen++] = ((duration >> 0) & 0xff);
- trace[traceLen++] = ((duration >> 8) & 0xff);
-
- // data length
- trace[traceLen++] = ((iLen >> 0) & 0xff);
- trace[traceLen++] = ((iLen >> 8) & 0xff);
-
- // readerToTag flag
- if (!readerToTag) {
- trace[traceLen - 1] |= 0x80;
- }
-
- // data bytes
- if (btBytes != NULL && iLen != 0) {
- memcpy(trace + traceLen, btBytes, iLen);
- }
- traceLen += iLen;
-
- // parity bytes
- if (parity != NULL && iLen != 0) {
- memcpy(trace + traceLen, parity, num_paritybytes);
- }
- traceLen += num_paritybytes;
-
- return TRUE;
-}
-
//=============================================================================
// ISO 14443 Type A - Miller decoder
//=============================================================================
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
// init trace buffer
- iso14a_clear_trace();
- iso14a_set_tracing(TRUE);
+ clear_trace();
+ set_tracing(TRUE);
uint8_t *data = dmaBuf;
uint8_t previous_data = 0;
FpgaDisableSscDma();
Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len);
- Dbprintf("traceLen=%d, Uart.output[0]=%08x", traceLen, (uint32_t)Uart.output[0]);
+ Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]);
LEDsoff();
}
free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
// clear trace
- iso14a_clear_trace();
- iso14a_set_tracing(TRUE);
+ clear_trace();
+ set_tracing(TRUE);
// Prepare the responses of the anticollision phase
// there will be not enough time to do this at the moment the reader sends it REQA
if(ManchesterDecoding(b, offset, 0)) {
NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD);
return TRUE;
- } else if (c++ > iso14a_timeout) {
+ } else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) {
return FALSE;
}
}
// reset the PCB block number
iso14_pcb_blocknum = 0;
+
+ // set default timeout based on ATS
+ iso14a_set_ATS_timeout(resp);
+
return 1;
}
uint8_t par[MAX_PARITY_SIZE];
if(param & ISO14A_CONNECT) {
- iso14a_clear_trace();
+ clear_trace();
}
- iso14a_set_tracing(TRUE);
+ set_tracing(TRUE);
if(param & ISO14A_REQUEST_TRIGGER) {
iso14a_set_trigger(TRUE);
// free eventually allocated BigBuf memory. We want all for tracing.
BigBuf_free();
- iso14a_clear_trace();
- iso14a_set_tracing(TRUE);
+ clear_trace();
+ set_tracing(TRUE);
byte_t nt_diff = 0;
uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
- iso14a_set_tracing(FALSE);
+ set_tracing(FALSE);
}
/**
BigBuf_free_keep_EM();
// clear trace
- iso14a_clear_trace();
- iso14a_set_tracing(TRUE);
+ clear_trace();
+ set_tracing(TRUE);
// Authenticate response - nonce
uint32_t nonce = bytes_to_num(rAUTH_NT, 4);
}
}
}
- if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, traceLen);
+ if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen());
}
// C(red) A(yellow) B(green)
LEDsoff();
// init trace buffer
- iso14a_clear_trace();
- iso14a_set_tracing(TRUE);
+ clear_trace();
+ set_tracing(TRUE);
// The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr);
extern void iso14a_set_trigger(bool enable);
-extern void iso14a_set_timeout(uint32_t timeout);
-
-extern void iso14a_clear_trace();
-extern void iso14a_set_tracing(bool enable);
#endif /* __ISO14443A_H */
#include "lfsampling.h"
-sample_config config = { 1, 8, 1, 88, 0 } ;
+sample_config config = { 1, 8, 1, 95, 0 } ;
void printConfig()
{
pcs = &mpcs;\r
\r
// clear trace\r
- iso14a_clear_trace();\r
+ clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
LED_A_ON();\r
LED_B_OFF();\r
LED_C_OFF();\r
\r
- iso14a_clear_trace();\r
+ clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
LED_B_OFF();\r
LED_C_OFF();\r
\r
- iso14a_clear_trace();\r
+ clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
int len = iso14443a_select_card(uid, NULL, &cuid);\r
pcs = &mpcs;\r
\r
// clear trace\r
- iso14a_clear_trace();\r
+ clear_trace();\r
\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
if (MF_DBGLEVEL >= MF_DBG_ALL) \r
Dbprintf("Pages %d",Pages);\r
\r
- iso14a_clear_trace();\r
+ clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
int len = iso14443a_select_card(uid, NULL, &cuid);\r
pcs = &mpcs;\r
\r
// clear trace\r
- iso14a_clear_trace();\r
+ clear_trace();\r
\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- iso14a_clear_trace();\r
+ clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
LED_A_ON();\r
uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- iso14a_clear_trace();\r
+ clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
LED_A_ON();\r
// free eventually allocated BigBuf memory\r
BigBuf_free();\r
// clear trace\r
- iso14a_clear_trace();\r
- iso14a_set_tracing(false);\r
+ clear_trace();\r
+ set_tracing(false);\r
\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
- iso14a_set_tracing(TRUE);\r
+ set_tracing(TRUE);\r
}\r
\r
//-----------------------------------------------------------------------------\r
MF_DBGLEVEL = MF_DBG_NONE;\r
\r
// clear trace\r
- iso14a_clear_trace();\r
- iso14a_set_tracing(TRUE);\r
+ clear_trace();\r
+ set_tracing(TRUE);\r
\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
uint8_t uid[10];\r
\r
// clear trace\r
- iso14a_clear_trace();\r
- iso14a_set_tracing(false);\r
+ clear_trace();\r
+ set_tracing(false);\r
\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
LED_B_OFF();\r
LED_C_OFF();\r
\r
- iso14a_clear_trace();\r
- iso14a_set_tracing(TRUE);\r
+ clear_trace();\r
+ set_tracing(TRUE);\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
}\r
\r
LED_B_OFF();\r
LED_C_OFF();\r
\r
- iso14a_clear_trace();\r
- iso14a_set_tracing(TRUE);\r
+ clear_trace();\r
+ set_tracing(TRUE);\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
}\r
\r
uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- iso14a_clear_trace();\r
+ clear_trace();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
int len = iso14443a_select_card(uid, NULL, &cuid);\r
cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
-}
+}\r
}\r
\r
bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs) {\r
- if (traceLen && (GetTickCount() > timerData + maxTimeoutMs)) {\r
+ if (BigBuf_get_traceLen() && (GetTickCount() > timerData + maxTimeoutMs)) {\r
return intMfSniffSend();\r
}\r
return FALSE;\r
bool intMfSniffSend() {\r
\r
int pckSize = 0;\r
- int pckLen = traceLen;\r
+ int pckLen = BigBuf_get_traceLen();\r
int pckNum = 0;\r
uint8_t *trace = BigBuf_get_addr();\r
\r
while (pckLen > 0) {\r
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);\r
LED_B_ON();\r
- cmd_send(CMD_ACK, 1, traceLen, pckSize, trace + traceLen - pckLen, pckSize);\r
+ cmd_send(CMD_ACK, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);\r
LED_B_OFF();\r
\r
pckLen -= pckSize;\r
cmd_send(CMD_ACK,2,0,0,0,0);\r
LED_B_OFF();\r
\r
- iso14a_clear_trace();\r
+ clear_trace();\r
\r
return TRUE;\r
}\r
#include "util.h"
#include "string.h"
#include "apps.h"
+#include "BigBuf.h"
}
size_t nbytes(size_t nbits) {
- return (nbits/8)+((nbits%8)>0);
+ return (nbits >> 3)+((nbits % 8) > 0);
}
uint32_t SwapBits(uint32_t value, int nrbits) {
}
}
-
#define MIFARE_ULC_AUTH_1 0x1A
#define MIFARE_ULC_AUTH_2 0xAF
+/**
+06 00 = INITIATE
+0E xx = SELECT ID (xx = Chip-ID)
+0B = Get UID
+08 yy = Read Block (yy = block number)
+09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
+0C = Reset to Inventory
+0F = Completion
+0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
+**/
+
#define ISO14443B_REQB 0x05
#define ISO14443B_ATTRIB 0x1D
#define ISO14443B_HALT 0x50
+#define ISO14443B_INITIATE 0x06
+#define ISO14443B_SELECT 0x0E
+#define ISO14443B_GET_UID 0x0B
+#define ISO14443B_READ_BLK 0x08
+#define ISO14443B_WRITE_BLK 0x09
+#define ISO14443B_RESET 0x0C
+#define ISO14443B_COMPLETION 0x0F
+#define ISO14443B_AUTHENTICATE 0x0A
//First byte is 26
#define ISO15693_INVENTORY 0x01
}
}
}
+
+/**
+06 00 = INITIATE
+0E xx = SELECT ID (xx = Chip-ID)
+0B = Get UID
+08 yy = Read Block (yy = block number)
+09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
+0C = Reset to Inventory
+0F = Completion
+0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
+**/
+
void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
{
switch(cmd[0]){
case ISO14443B_REQB : snprintf(exp,size,"REQB");break;
case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break;
case ISO14443B_HALT : snprintf(exp,size,"HALT");break;
- default: snprintf(exp,size ,"?");break;
+ case ISO14443B_INITIATE : snprintf(exp,size,"INITIATE");break;
+ case ISO14443B_SELECT : snprintf(exp,size,"SELECT(%d)",cmd[1]);break;
+ case ISO14443B_GET_UID : snprintf(exp,size,"GET UID");break;
+ case ISO14443B_READ_BLK : snprintf(exp,size,"READ_BLK(%d)", cmd[1]);break;
+ case ISO14443B_WRITE_BLK : snprintf(exp,size,"WRITE_BLK(%d)",cmd[1]);break;
+ case ISO14443B_RESET : snprintf(exp,size,"RESET");break;
+ case ISO14443B_COMPLETION : snprintf(exp,size,"COMPLETION");break;
+ case ISO14443B_AUTHENTICATE : snprintf(exp,size,"AUTHENTICATE");break;
+ default : snprintf(exp,size ,"?");break;
}
}
if (tracepos + data_len + parity_len > traceLen) {
return traceLen;
}
-
uint8_t *frame = trace + tracepos;
tracepos += data_len;
uint8_t *parityBytes = trace + tracepos;
tracepos += parity_len;
+
//--- Draw the data column
+ //char line[16][110];
char line[16][110];
- for (int j = 0; j < data_len; j++) {
+
+ for (int j = 0; j < data_len && j/16 < 16; j++) {
+
int oddparity = 0x01;
int k;
}
uint8_t parityBits = parityBytes[j>>3];
-
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
- sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
+ snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
+
} else {
- sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
+ snprintf(line[j/16]+(( j % 16) * 4),110, "%02x ", frame[j]);
+ }
+ }
+ if(data_len == 0)
+ {
+ if(data_len == 0){
+ sprintf(line[0],"<empty trace - possible error>");
}
}
//--- Draw the CRC column
annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
}
- int num_lines = (data_len - 1)/16 + 1;
- for (int j = 0; j < num_lines; j++) {
+ int num_lines = MIN((data_len - 1)/16 + 1, 16);
+ for (int j = 0; j < num_lines ; j++) {
if (j == 0) {
PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
(timestamp - first_timestamp),
return 0;
}
-void iso14a_set_timeout(uint32_t timeout) {
- UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_SET_TIMEOUT, 0, timeout}};
- SendCommand(&c);
-}
-
int CmdHF14AReader(const char *Cmd)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
SendCommand(&c);
WaitForResponse(CMD_ACK,&resp);
uint8_t isOK = resp.arg[0] & 0xff;
- PrintAndLog(" Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
+ PrintAndLog("Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
// disconnect
c.cmd = CMD_READER_ISO_14443a;
uint8_t active=0;
uint8_t active_select=0;
uint16_t numbits=0;
- uint16_t timeout=0;
+ uint32_t timeout=0;
uint8_t bTimeout=0;
char buf[5]="";
int i=0;
uint8_t data[USB_CMD_DATA_SIZE];
- unsigned int datalen=0, temp;
+ uint16_t datalen=0;
+ uint32_t temp;
if (strlen(cmd)<2) {
PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] [-t] <number of bits> <0A 0B 0C ... hex>");
PrintAndLog(" -a active signal field ON without select");
PrintAndLog(" -s active signal field ON with select");
PrintAndLog(" -b number of bits to send. Useful for send partial byte");
- PrintAndLog(" -t timeout");
+ PrintAndLog(" -t timeout in ms");
return 0;
}
case 't':
bTimeout=1;
sscanf(cmd+i+2,"%d",&temp);
- timeout = temp & 0xFFFF;
+ timeout = temp;
i+=3;
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
i+=2;
c.arg[0] |= ISO14A_NO_SELECT;
}
if(bTimeout){
- #define MAX_TIMEOUT 624*105 // max timeout is 624 ms
+ #define MAX_TIMEOUT 40542464 // (2^32-1) * (8*16) / 13560000Hz * 1000ms/s =
c.arg[0] |= ISO14A_SET_TIMEOUT;
- c.arg[2] = timeout * 105; // each bit is about 9.4 us
- if(c.arg[2]>MAX_TIMEOUT) {
- c.arg[2] = MAX_TIMEOUT;
- PrintAndLog("Set timeout to 624 ms. The max we can wait for response");
+ if(timeout > MAX_TIMEOUT) {
+ timeout = MAX_TIMEOUT;
+ PrintAndLog("Set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
}
+ c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
}
if(power)
c.arg[0] |= ISO14A_NO_DISCONNECT;
int CmdHF14BList(const char *Cmd)
{
- uint8_t *got = malloc(USB_CMD_DATA_SIZE);
-
- // Query for the actual size of the trace
- UsbCommand response;
- GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
- WaitForResponse(CMD_ACK, &response);
- uint16_t traceLen = response.arg[2];
- if (traceLen > USB_CMD_DATA_SIZE) {
- uint8_t *p = realloc(got, traceLen);
- if (p == NULL) {
- PrintAndLog("Cannot allocate memory for trace");
- free(got);
- return 2;
- }
- got = p;
- GetFromBigBuf(got, traceLen, 0);
- WaitForResponse(CMD_ACK,NULL);
- }
- PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen);
- PrintAndLog(" time :rssi: who bytes");
- PrintAndLog("---------+----+----+-----------");
-
- int i = 0;
- int prev = -1;
-
- for(;;) {
-
- if(i >= traceLen) { break; }
-
- bool isResponse;
- int timestamp = *((uint32_t *)(got+i));
- if(timestamp & 0x80000000) {
- timestamp &= 0x7fffffff;
- isResponse = 1;
- } else {
- isResponse = 0;
- }
- int metric = *((uint32_t *)(got+i+4));
-
- int len = got[i+8];
+ PrintAndLog("Deprecated command, use 'hf list 14b' instead");
- if(len > 100) {
- break;
- }
- if(i + len >= traceLen) {
- break;
- }
-
- uint8_t *frame = (got+i+9);
-
- // Break and stick with current result if buffer was not completely full
- if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
-
- char line[1000] = "";
- int j;
- for(j = 0; j < len; j++) {
- sprintf(line+(j*3), "%02x ", frame[j]);
- }
-
- char *crc;
- if(len > 2) {
- uint8_t b1, b2;
- ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2);
- if(b1 != frame[len-2] || b2 != frame[len-1]) {
- crc = "**FAIL CRC**";
- } else {
- crc = "";
- }
- } else {
- crc = "(SHORT)";
- }
-
- char metricString[100];
- if(isResponse) {
- sprintf(metricString, "%3d", metric);
- } else {
- strcpy(metricString, " ");
- }
-
- PrintAndLog(" +%7d: %s: %s %s %s",
- (prev < 0 ? 0 : timestamp - prev),
- metricString,
- (isResponse ? "TAG" : " "), line, crc);
-
- prev = timestamp;
- i += (len + 9);
- }
- free(got);
- return 0;
+ return 0;
}
-
int CmdHF14BRead(const char *Cmd)
{
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};
{
{"help", CmdHelp, 1, "This help"},
{"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"},
- {"list", CmdHF14BList, 0, "List ISO 14443 history"},
+ {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
{"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"},
{"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
{"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
{ 0xE016040000000000LL, 24, "EM-Marin SA (Skidata Keycard-eco); EM4034? no 'read', just 'readmulti'" },
{ 0xE0160c0000000000LL, 24, "EM-Marin SA; EM4035?" },
{ 0xE016100000000000LL, 24, "EM-Marin SA (Skidata); EM4135; 36x64bit start page 13" },
+ { 0xE016240000000000LL, 24, "EM-Marin SA (Skidata); EM4233;" },
{ 0xE016940000000000LL, 24, "EM-Marin SA (Skidata); 51x64bit" },
{ 0xE017000000000000LL, 16, "KSW Microtec GmbH Germany" },
int xorbits_8(uint8_t val)
{
- uint8_t res = val ^ (val >> 1); //1st pass
- res = res ^ (res >> 1); // 2nd pass
- res = res ^ (res >> 2); // 3rd pass
- res = res ^ (res >> 4); // 4th pass
- return res & 1;
+ uint8_t res = val ^ (val >> 1); //1st pass
+ res = res ^ (res >> 1); // 2nd pass
+ res = res ^ (res >> 2); // 3rd pass
+ res = res ^ (res >> 4); // 4th pass
+ return res & 1;
}
int CmdHFiClassList(const char *Cmd)
int CmdHFiClassSnoop(const char *Cmd)
{
- UsbCommand c = {CMD_SNOOP_ICLASS};
- SendCommand(&c);
- return 0;
+ UsbCommand c = {CMD_SNOOP_ICLASS};
+ SendCommand(&c);
+ return 0;
}
#define NUM_CSNS 15
int CmdHFiClassSim(const char *Cmd)
{
- uint8_t simType = 0;
- uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-
- if (strlen(Cmd)<1) {
- PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
- PrintAndLog(" options");
- PrintAndLog(" 0 <CSN> simulate the given CSN");
- PrintAndLog(" 1 simulate default CSN");
- PrintAndLog(" 2 iterate CSNs, gather MACs");
- PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
- PrintAndLog(" sample: hf iclass sim 2");
- return 0;
- }
-
- simType = param_get8(Cmd, 0);
-
- if(simType == 0)
- {
- if (param_gethex(Cmd, 1, CSN, 16)) {
- PrintAndLog("A CSN should consist of 16 HEX symbols");
- return 1;
- }
- PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
-
- }
- if(simType > 2)
- {
- PrintAndLog("Undefined simptype %d", simType);
- return 1;
- }
- uint8_t numberOfCSNs=0;
+ uint8_t simType = 0;
+ uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+ if (strlen(Cmd)<1) {
+ PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
+ PrintAndLog(" options");
+ PrintAndLog(" 0 <CSN> simulate the given CSN");
+ PrintAndLog(" 1 simulate default CSN");
+ PrintAndLog(" 2 iterate CSNs, gather MACs");
+ PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
+ PrintAndLog(" sample: hf iclass sim 2");
+ return 0;
+ }
+
+ simType = param_get8(Cmd, 0);
+
+ if(simType == 0)
+ {
+ if (param_gethex(Cmd, 1, CSN, 16)) {
+ PrintAndLog("A CSN should consist of 16 HEX symbols");
+ return 1;
+ }
+ PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
+
+ }
+ if(simType > 2)
+ {
+ PrintAndLog("Undefined simptype %d", simType);
+ return 1;
+ }
+ uint8_t numberOfCSNs=0;
if(simType == 2)
{
0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 ,
0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 };
*/
-
- uint8_t csns[8*NUM_CSNS] = {
- 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
- 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
+
+ uint8_t csns[8*NUM_CSNS] = {
+ 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
+ 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
SendCommand(&c);
}
- return 0;
+ return 0;
}
int CmdHFiClassReader(const char *Cmd)
{
- UsbCommand c = {CMD_READER_ICLASS, {0}};
- SendCommand(&c);
- UsbCommand resp;
- while(!ukbhit()){
- if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
- uint8_t isOK = resp.arg[0] & 0xff;
- uint8_t * data = resp.d.asBytes;
-
- PrintAndLog("isOk:%02x", isOK);
- if( isOK == 0){
- //Aborted
- PrintAndLog("Quitting...");
- return 0;
- }
- if(isOK > 0)
- {
- PrintAndLog("CSN: %s",sprint_hex(data,8));
- }
- if(isOK >= 1)
- {
- PrintAndLog("CC: %s",sprint_hex(data+8,8));
- }else{
- PrintAndLog("No CC obtained");
- }
- } else {
- PrintAndLog("Command execute timeout");
- }
- }
-
- return 0;
+ UsbCommand c = {CMD_READER_ICLASS, {0}};
+ SendCommand(&c);
+ UsbCommand resp;
+ while(!ukbhit()){
+ if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
+ uint8_t isOK = resp.arg[0] & 0xff;
+ uint8_t * data = resp.d.asBytes;
+
+ PrintAndLog("isOk:%02x", isOK);
+ if( isOK == 0){
+ //Aborted
+ PrintAndLog("Quitting...");
+ return 0;
+ }
+ if(isOK > 0)
+ {
+ PrintAndLog("CSN: %s",sprint_hex(data,8));
+ }
+ if(isOK >= 1)
+ {
+ PrintAndLog("CC: %s",sprint_hex(data+8,8));
+ }else{
+ PrintAndLog("No CC obtained");
+ }
+ } else {
+ PrintAndLog("Command execute timeout");
+ }
+ }
+
+ return 0;
}
int CmdHFiClassReader_Replay(const char *Cmd)
{
- uint8_t readerType = 0;
- uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
+ uint8_t readerType = 0;
+ uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
- if (strlen(Cmd)<1) {
- PrintAndLog("Usage: hf iclass replay <MAC>");
- PrintAndLog(" sample: hf iclass replay 00112233");
- return 0;
- }
+ if (strlen(Cmd)<1) {
+ PrintAndLog("Usage: hf iclass replay <MAC>");
+ PrintAndLog(" sample: hf iclass replay 00112233");
+ return 0;
+ }
- if (param_gethex(Cmd, 0, MAC, 8)) {
- PrintAndLog("MAC must include 8 HEX symbols");
- return 1;
- }
+ if (param_gethex(Cmd, 0, MAC, 8)) {
+ PrintAndLog("MAC must include 8 HEX symbols");
+ return 1;
+ }
- UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
- memcpy(c.d.asBytes, MAC, 4);
- SendCommand(&c);
+ UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
+ memcpy(c.d.asBytes, MAC, 4);
+ SendCommand(&c);
- return 0;
+ return 0;
}
int CmdHFiClassReader_Dump(const char *Cmd)
{
- uint8_t readerType = 0;
- uint8_t MAC[4]={0x00,0x00,0x00,0x00};
- uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8_t keytable[128] = {0};
- int elite = 0;
- uint8_t *used_key;
- int i;
- if (strlen(Cmd)<1)
- {
- PrintAndLog("Usage: hf iclass dump <Key> [e]");
- PrintAndLog(" Key - A 16 byte master key");
- PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
- PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
- PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
- PrintAndLog(" sample: hf iclass dump 0011223344556677");
-
-
- return 0;
- }
-
- if (param_gethex(Cmd, 0, KEY, 16))
- {
- PrintAndLog("KEY must include 16 HEX symbols");
- return 1;
- }
-
- if (param_getchar(Cmd, 1) == 'e')
- {
- PrintAndLog("Elite switch on");
- elite = 1;
-
- //calc h2
- hash2(KEY, keytable);
- printarr_human_readable("keytable", keytable, 128);
-
- }
-
- UsbCommand resp;
- uint8_t key_sel[8] = {0};
- uint8_t key_sel_p[8] = { 0 };
-
- UsbCommand c = {CMD_READER_ICLASS, {0}};
- c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
- SendCommand(&c);
-
-
-
- if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
- {
- PrintAndLog("Command execute timeout");
- return 0;
- }
+ uint8_t readerType = 0;
+ uint8_t MAC[4]={0x00,0x00,0x00,0x00};
+ uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t keytable[128] = {0};
+ int elite = 0;
+ uint8_t *used_key;
+ int i;
+ if (strlen(Cmd)<1)
+ {
+ PrintAndLog("Usage: hf iclass dump <Key> [e]");
+ PrintAndLog(" Key - A 16 byte master key");
+ PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
+ PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
+ PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
+ PrintAndLog(" sample: hf iclass dump 0011223344556677");
+
+
+ return 0;
+ }
+
+ if (param_gethex(Cmd, 0, KEY, 16))
+ {
+ PrintAndLog("KEY must include 16 HEX symbols");
+ return 1;
+ }
+
+ if (param_getchar(Cmd, 1) == 'e')
+ {
+ PrintAndLog("Elite switch on");
+ elite = 1;
+
+ //calc h2
+ hash2(KEY, keytable);
+ printarr_human_readable("keytable", keytable, 128);
+
+ }
+
+ UsbCommand resp;
+ uint8_t key_sel[8] = {0};
+ uint8_t key_sel_p[8] = { 0 };
+
+ UsbCommand c = {CMD_READER_ICLASS, {0}};
+ c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
+ SendCommand(&c);
+
+
+
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
+ {
+ PrintAndLog("Command execute timeout");
+ return 0;
+ }
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t * data = resp.d.asBytes;
printvar("MAC", MAC, 4);
uint8_t iclass_data[32000] = {0};
- uint8_t iclass_datalen = 0;
- uint8_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete
+ uint32_t iclass_datalen = 0;
+ uint32_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete
UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
memcpy(d.d.asBytes, MAC, 4);
}
if(WaitForResponseTimeout(CMD_ACK,&resp,4500))
{
- uint64_t dataLength = resp.arg[0];
+ uint32_t dataLength = resp.arg[0];
iclass_blocksFailed |= resp.arg[1];
-
if(dataLength > 0)
{
+ PrintAndLog("Got %d bytes data (total so far %d)" ,dataLength,iclass_datalen);
memcpy(iclass_data, resp.d.asBytes,dataLength);
iclass_datalen += dataLength;
}else
//create a preferred filename
snprintf(filename, 100,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x",
CSN[0],CSN[1],CSN[2],CSN[3],
- CSN[4],CSN[5],CSN[6],CSN[7]);
+ CSN[4],CSN[5],CSN[6],CSN[7]);
saveFile(filename,"bin",iclass_data, iclass_datalen );
-
}
//Aaaand we're finished
return 0;
}
- return 0;
+ return 0;
+}
+
+int hf_iclass_eload_usage()
+{
+ PrintAndLog("Loads iclass tag-dump into emulator memory on device");
+ PrintAndLog("Usage: hf iclass eload f <filename>");
+ PrintAndLog("");
+ PrintAndLog("Example: hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
+ return 0;
+
}
+int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
+ UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};
+ memcpy(c.d.asBytes, data, blocksCount * 16);
+ SendCommand(&c);
+ return 0;
+}
+int CmdHFiClassELoad(const char *Cmd)
+{
+
+ char opt = param_getchar(Cmd, 0);
+ if (strlen(Cmd)<1 || opt == 'h')
+ return hf_iclass_eload_usage();
+
+ //File handling and reading
+ FILE *f;
+ char filename[FILE_PATH_SIZE];
+ if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
+ {
+ f = fopen(filename, "rb");
+ }else{
+ return hf_iclass_eload_usage();
+ }
+
+ if(!f) {
+ PrintAndLog("Failed to read from file '%s'", filename);
+ return 1;
+ }
+
+ fseek(f, 0, SEEK_END);
+ long fsize = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ uint8_t *dump = malloc(fsize);
+ size_t bytes_read = fread(dump, 1, fsize, f);
+ fclose(f);
+
+ //Validate
+
+ if (bytes_read < fsize)
+ {
+ prnlog("Error, could only read %d bytes (should be %d)",bytes_read, fsize );
+ free(dump);
+ return 1;
+ }
+ //Send to device
+ uint32_t bytes_sent = 0;
+ uint32_t bytes_remaining = bytes_read;
+
+ while(bytes_remaining > 0){
+ uint32_t bytes_in_packet = MIN(USB_CMD_DATA_SIZE, bytes_remaining);
+ UsbCommand c = {CMD_ICLASS_EML_MEMSET, {bytes_sent,bytes_in_packet,0}};
+ memcpy(c.d.asBytes, dump, bytes_in_packet);
+ SendCommand(&c);
+ bytes_remaining -= bytes_in_packet;
+ bytes_sent += bytes_in_packet;
+ }
+ free(dump);
+ PrintAndLog("Sent %d bytes of data to device emulator memory", bytes_sent);
+ return 0;
+}
+
+
int CmdHFiClass_iso14443A_write(const char *Cmd)
{
- uint8_t readerType = 0;
- uint8_t MAC[4]={0x00,0x00,0x00,0x00};
- uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-
- uint8_t blockNo=0;
- uint8_t bldata[8]={0};
-
- if (strlen(Cmd)<3)
- {
- PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
- PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
- return 0;
- }
-
- if (param_gethex(Cmd, 0, KEY, 16))
- {
- PrintAndLog("KEY must include 16 HEX symbols");
- return 1;
- }
-
- blockNo = param_get8(Cmd, 1);
- if (blockNo>32)
- {
- PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
- return 1;
- }
- if (param_gethex(Cmd, 2, bldata, 8))
- {
- PrintAndLog("Block data must include 8 HEX symbols");
- return 1;
- }
-
- UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
- SendCommand(&c);
- UsbCommand resp;
-
- if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
- uint8_t isOK = resp.arg[0] & 0xff;
- uint8_t * data = resp.d.asBytes;
-
- memcpy(CSN,data,8);
- memcpy(CCNR,data+8,8);
- PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
- PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
- PrintAndLog("isOk:%02x", isOK);
- } else {
- PrintAndLog("Command execute timeout");
- }
-
- diversifyKey(CSN,KEY, div_key);
-
- PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
- doMAC(CCNR, 12,div_key, MAC);
-
- UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
- memcpy(c2.d.asBytes, bldata, 8);
- memcpy(c2.d.asBytes+8, MAC, 4);
- SendCommand(&c2);
-
- if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
- uint8_t isOK = resp.arg[0] & 0xff;
- uint8_t * data = resp.d.asBytes;
-
- if (isOK)
- PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
- else
- PrintAndLog("isOk:%02x", isOK);
- } else {
- PrintAndLog("Command execute timeout");
- }
- return 0;
+ uint8_t readerType = 0;
+ uint8_t MAC[4]={0x00,0x00,0x00,0x00};
+ uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+ uint8_t blockNo=0;
+ uint8_t bldata[8]={0};
+
+ if (strlen(Cmd)<3)
+ {
+ PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
+ PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
+ return 0;
+ }
+
+ if (param_gethex(Cmd, 0, KEY, 16))
+ {
+ PrintAndLog("KEY must include 16 HEX symbols");
+ return 1;
+ }
+
+ blockNo = param_get8(Cmd, 1);
+ if (blockNo>32)
+ {
+ PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
+ return 1;
+ }
+ if (param_gethex(Cmd, 2, bldata, 8))
+ {
+ PrintAndLog("Block data must include 8 HEX symbols");
+ return 1;
+ }
+
+ UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
+ SendCommand(&c);
+ UsbCommand resp;
+
+ if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
+ uint8_t isOK = resp.arg[0] & 0xff;
+ uint8_t * data = resp.d.asBytes;
+
+ memcpy(CSN,data,8);
+ memcpy(CCNR,data+8,8);
+ PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
+ PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
+ PrintAndLog("isOk:%02x", isOK);
+ } else {
+ PrintAndLog("Command execute timeout");
+ }
+
+ diversifyKey(CSN,KEY, div_key);
+
+ PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
+ doMAC(CCNR, 12,div_key, MAC);
+
+ UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
+ memcpy(c2.d.asBytes, bldata, 8);
+ memcpy(c2.d.asBytes+8, MAC, 4);
+ SendCommand(&c2);
+
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+ uint8_t isOK = resp.arg[0] & 0xff;
+ uint8_t * data = resp.d.asBytes;
+
+ if (isOK)
+ PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
+ else
+ PrintAndLog("isOk:%02x", isOK);
+ } else {
+ PrintAndLog("Command execute timeout");
+ }
+ return 0;
}
int CmdHFiClass_loclass(const char *Cmd)
{
char fileName[255] = {0};
if(opt == 'f')
{
- if(param_getstr(Cmd, 1, fileName) > 0)
- {
- return bruteforceFileNoKeys(fileName);
- }else
- {
- PrintAndLog("You must specify a filename");
- }
+ if(param_getstr(Cmd, 1, fileName) > 0)
+ {
+ return bruteforceFileNoKeys(fileName);
+ }else
+ {
+ PrintAndLog("You must specify a filename");
+ }
}
else if(opt == 't')
{
{"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
{"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
{"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
- {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
+// {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
{"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"},
+ {"eload", CmdHFiClassELoad, 0, "[experimental] Load data into iclass emulator memory"},
{NULL, NULL, 0, NULL}
};
int CmdHFiClass(const char *Cmd)
{
- CmdsParse(CommandTable, Cmd);
- return 0;
+ CmdsParse(CommandTable, Cmd);
+ return 0;
}
int CmdHelp(const char *Cmd)
{
- CmdsHelp(CommandTable);
- return 0;
+ CmdsHelp(CommandTable);
+ return 0;
}
uint8_t wipeCard = 0;\r
uint8_t uid[8] = {0x00};\r
uint8_t oldUid[8] = {0x00};\r
+ uint8_t atqa[2] = {0x00};\r
+ uint8_t sak[1] = {0x00};\r
+ uint8_t atqaPresent = 1;\r
int res;\r
-\r
- if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {\r
- PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> <w>");\r
- PrintAndLog("sample: hf mf csetuid 01020304 w");\r
- PrintAndLog("Set UID for magic Chinese card (only works with!!!)");\r
- PrintAndLog("If you want wipe card then add 'w' into command line. \n");\r
+ char ctmp;\r
+ int argi=0;\r
+\r
+ if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h') {\r
+ PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols] [w]");\r
+ PrintAndLog("sample: hf mf csetuid 01020304");\r
+ PrintAndLog("sample: hf mf csetuid 01020304 0004 08 w");\r
+ PrintAndLog("Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)");\r
+ PrintAndLog("If you also want to wipe the card then add 'w' at the end of the command line.");\r
return 0;\r
- } \r
+ }\r
\r
- if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {\r
+ if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8)) {\r
PrintAndLog("UID must include 8 HEX symbols");\r
return 1;\r
}\r
+ argi++;\r
+\r
+ ctmp = param_getchar(Cmd, argi);\r
+ if (ctmp == 'w' || ctmp == 'W') {\r
+ wipeCard = 1;\r
+ atqaPresent = 0;\r
+ }\r
+\r
+ if (atqaPresent) {\r
+ if (param_getchar(Cmd, argi)) {\r
+ if (param_gethex(Cmd, argi, atqa, 4)) {\r
+ PrintAndLog("ATQA must include 4 HEX symbols");\r
+ return 1;\r
+ }\r
+ argi++;\r
+ if (!param_getchar(Cmd, argi) || param_gethex(Cmd, argi, sak, 2)) {\r
+ PrintAndLog("SAK must include 2 HEX symbols");\r
+ return 1;\r
+ }\r
+ argi++;\r
+ } else\r
+ atqaPresent = 0;\r
+ }\r
+\r
+ if(!wipeCard) {\r
+ ctmp = param_getchar(Cmd, argi);\r
+ if (ctmp == 'w' || ctmp == 'W') {\r
+ wipeCard = 1;\r
+ }\r
+ }\r
\r
- char ctmp = param_getchar(Cmd, 1);\r
- if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;\r
- \r
PrintAndLog("--wipe card:%s uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4));\r
\r
- res = mfCSetUID(uid, oldUid, wipeCard);\r
+ res = mfCSetUID(uid, (atqaPresent)?atqa:NULL, (atqaPresent)?sak:NULL, oldUid, wipeCard);\r
if (res) {\r
PrintAndLog("Can't set UID. error=%d", res);\r
return 1;\r
uint8_t cmdp =0;
while(param_getchar(Cmd, cmdp) != 0x00)
{
- PrintAndLog("working %c", param_getchar(Cmd, cmdp));
switch(param_getchar(Cmd, cmdp))
{
case 'h':
\r
// "MAGIC" CARD\r
\r
-int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {\r
- \r
+int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe) {\r
uint8_t oldblock0[16] = {0x00};\r
uint8_t block0[16] = {0x00};\r
- memcpy(block0, uid, 4); \r
- block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC\r
- // mifare classic SAK(byte 5) and ATQA(byte 6 and 7)\r
- //block0[5] = 0x08;\r
- //block0[6] = 0x04;\r
- //block0[7] = 0x00;\r
- \r
- block0[5] = 0x01; //sak\r
- block0[6] = 0x01;\r
- block0[7] = 0x0f;\r
- \r
+\r
int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);\r
- if ( old == 0) {\r
- memcpy(block0+8, oldblock0+8, 8);\r
- PrintAndLog("block 0: %s", sprint_hex(block0,16));\r
+ if (old == 0) {\r
+ memcpy(block0, oldblock0, 16);\r
+ PrintAndLog("old block 0: %s", sprint_hex(block0,16));\r
} else {\r
- PrintAndLog("Couldn't get olddata. Will write over the last bytes of Block 0.");\r
+ PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0.");\r
+ }\r
+\r
+ // fill in the new values\r
+ // UID\r
+ memcpy(block0, uid, 4); \r
+ // Mifare UID BCC\r
+ block0[4] = block0[0]^block0[1]^block0[2]^block0[3];\r
+ // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)\r
+ if (sak!=NULL)\r
+ block0[5]=sak[0];\r
+ if (atqa!=NULL) {\r
+ block0[6]=atqa[1];\r
+ block0[7]=atqa[0];\r
}\r
+ PrintAndLog("new block 0: %s", sprint_hex(block0,16));\r
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);\r
}\r
\r
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);\r
\r
-int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe);\r
+int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe);\r
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params);\r
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);\r
\r
uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination)
{
uint8_t val = param_get8ex(line, paramnum, 255, 10);
- printf("read %i", (int8_t ) val);
if( (int8_t) val == -1) return 1;
(*destination) = val;
return 0;
#
# proxmark3
+ACTION!="add|change", GOTO="mm_usb_device_blacklist_end"
+SUBSYSTEM!="tty", GOTO="mm_ignore"
+
+ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n"
+
+LABEL="mm_ignore"
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1"
+
+LABEL="mm_usb_device_blacklist_end"
// TAGSIM_MOD: short circuit antenna with different resistances (modulated by sub_carrier modulated by mod_sig_coil)
// for pwr_oe4 = 1 (tristate): antenna load = 10k || 33 = 32,9 Ohms
// for pwr_oe4 = 0 (active): antenna load = 10k || 33 || 33 = 16,5 Ohms
-assign pwr_oe4 = ~(mod_sig_coil & sub_carrier & (mod_type == `TAGSIM_MOD));
+assign pwr_oe4 = mod_sig_coil & sub_carrier & (mod_type == `TAGSIM_MOD);
// This is all LF, so doesn't matter.
assign pwr_oe2 = 1'b0;
#define CMD_READER_ICLASS 0x0394
#define CMD_READER_ICLASS_REPLAY 0x0395
#define CMD_ICLASS_ISO14443A_WRITE 0x0397
+#define CMD_ICLASS_EML_MEMSET 0x0398
// For measurements of the antenna tuning
#define CMD_MEASURE_ANTENNA_TUNING 0x0400