mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'fpga'
* fpga: (139 commits) readermac fix SKIPREADLINE compilation err less cpu usage, thanks @mwalker33 iclass replay params hf iclass replay textual hf iclass replay works. A bit bad in not reading AA2. Assumes a KD mac iclass sniff now works chg: trace list color in list send arguments to standalone mode simlper select textual iceclass reader attack mode to save unique files add: mem spiffs wipe dump size bugs iclass sniff, still too slow fix the config trigger remove some extras pm3other compilation error mplicit declaration of function "Csprintf" style and trying a long timeout ...
This commit is contained in:
+143
-43
@@ -22,29 +22,56 @@ extern uint8_t _stack_start, __bss_end__;
|
||||
static uint8_t *BigBuf = &__bss_end__;
|
||||
|
||||
/* BigBuf memory layout:
|
||||
Pointer to highest available memory: BigBuf_hi
|
||||
high BigBuf_size
|
||||
reserved = BigBuf_malloc() subtracts amount from BigBuf_hi,
|
||||
Pointer to highest available memory: s_bigbuf_hi
|
||||
high s_bigbuf_size
|
||||
reserved = BigBuf_malloc() subtracts amount from s_bigbuf_hi,
|
||||
low 0x00
|
||||
*/
|
||||
|
||||
static uint32_t BigBuf_size = 0;
|
||||
static uint32_t s_bigbuf_size = 0;
|
||||
|
||||
// High memory mark
|
||||
static uint32_t BigBuf_hi = 0;
|
||||
static uint32_t s_bigbuf_hi = 0;
|
||||
|
||||
// pointer to the emulator memory.
|
||||
static uint8_t *emulator_memory = NULL;
|
||||
|
||||
//=============================================================================
|
||||
// The ToSend buffer.
|
||||
// A buffer where we can queue things up to be sent through the FPGA, for
|
||||
// any purpose (fake tag, as reader, whatever). We go MSB first, since that
|
||||
// is the order in which they go out on the wire.
|
||||
//=============================================================================
|
||||
static tosend_t toSend = {
|
||||
.max = -1,
|
||||
.bit = 8,
|
||||
.buf = NULL
|
||||
};
|
||||
//=============================================================================
|
||||
// The dmaBuf 16bit buffer.
|
||||
// A buffer where we recive IQ samples sent from the FPGA, for demodulating
|
||||
//=============================================================================
|
||||
static dmabuf16_t dma_16 = {
|
||||
.size = DMA_BUFFER_SIZE,
|
||||
.buf = NULL
|
||||
};
|
||||
// dmaBuf 8bit buffer
|
||||
static dmabuf8_t dma_8 = {
|
||||
.size = DMA_BUFFER_SIZE,
|
||||
.buf = NULL
|
||||
};
|
||||
|
||||
|
||||
|
||||
// trace related variables
|
||||
static uint32_t traceLen = 0;
|
||||
static uint32_t trace_len = 0;
|
||||
static bool tracing = true;
|
||||
|
||||
// compute the available size for BigBuf
|
||||
void BigBuf_initialize(void) {
|
||||
BigBuf_size = (uint32_t)&_stack_start - (uint32_t)&__bss_end__;
|
||||
BigBuf_hi = BigBuf_size;
|
||||
traceLen = 0;
|
||||
s_bigbuf_size = (uint32_t)&_stack_start - (uint32_t)&__bss_end__;
|
||||
s_bigbuf_hi = s_bigbuf_size;
|
||||
trace_len = 0;
|
||||
}
|
||||
|
||||
// get the address of BigBuf
|
||||
@@ -53,7 +80,7 @@ uint8_t *BigBuf_get_addr(void) {
|
||||
}
|
||||
|
||||
uint32_t BigBuf_get_size(void) {
|
||||
return BigBuf_size;
|
||||
return s_bigbuf_size;
|
||||
}
|
||||
|
||||
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
||||
@@ -64,6 +91,11 @@ uint8_t *BigBuf_get_EM_addr(void) {
|
||||
|
||||
return emulator_memory;
|
||||
}
|
||||
/*
|
||||
uint32_t BigBuf_get_EM_size(void) {
|
||||
return CARD_MEMORY_SIZE;
|
||||
}
|
||||
*/
|
||||
|
||||
// clear ALL of BigBuf
|
||||
void BigBuf_Clear(void) {
|
||||
@@ -72,9 +104,9 @@ void BigBuf_Clear(void) {
|
||||
|
||||
// clear ALL of BigBuf
|
||||
void BigBuf_Clear_ext(bool verbose) {
|
||||
memset(BigBuf, 0, BigBuf_size);
|
||||
memset(BigBuf, 0, s_bigbuf_size);
|
||||
if (verbose)
|
||||
Dbprintf("Buffer cleared (%i bytes)", BigBuf_size);
|
||||
Dbprintf("Buffer cleared (%i bytes)", s_bigbuf_size);
|
||||
}
|
||||
|
||||
void BigBuf_Clear_EM(void) {
|
||||
@@ -82,57 +114,66 @@ void BigBuf_Clear_EM(void) {
|
||||
}
|
||||
|
||||
void BigBuf_Clear_keep_EM(void) {
|
||||
memset(BigBuf, 0, BigBuf_hi);
|
||||
memset(BigBuf, 0, s_bigbuf_hi);
|
||||
}
|
||||
|
||||
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
||||
// at the beginning of BigBuf is always for traces/samples
|
||||
uint8_t *BigBuf_malloc(uint16_t chunksize) {
|
||||
if (BigBuf_hi < chunksize)
|
||||
if (s_bigbuf_hi < chunksize)
|
||||
return NULL; // no memory left
|
||||
|
||||
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
||||
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
|
||||
return (uint8_t *)BigBuf + BigBuf_hi;
|
||||
s_bigbuf_hi -= chunksize; // aligned to 4 Byte boundary
|
||||
return (uint8_t *)BigBuf + s_bigbuf_hi;
|
||||
}
|
||||
|
||||
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
||||
void BigBuf_free(void) {
|
||||
BigBuf_hi = BigBuf_size;
|
||||
s_bigbuf_hi = s_bigbuf_size;
|
||||
emulator_memory = NULL;
|
||||
// shouldn't this empty BigBuf also?
|
||||
toSend.buf = NULL;
|
||||
dma_16.buf = NULL;
|
||||
dma_8.buf = NULL;
|
||||
}
|
||||
|
||||
// free allocated chunks EXCEPT the emulator memory
|
||||
void BigBuf_free_keep_EM(void) {
|
||||
if (emulator_memory != NULL)
|
||||
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||
s_bigbuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||
else
|
||||
BigBuf_hi = BigBuf_size;
|
||||
s_bigbuf_hi = s_bigbuf_size;
|
||||
|
||||
// shouldn't this empty BigBuf also?
|
||||
toSend.buf = NULL;
|
||||
dma_16.buf = NULL;
|
||||
dma_8.buf = NULL;
|
||||
}
|
||||
|
||||
void BigBuf_print_status(void) {
|
||||
DbpString(_CYAN_("Memory"));
|
||||
Dbprintf(" BigBuf_size.............%d", BigBuf_size);
|
||||
Dbprintf(" Available memory........%d", BigBuf_hi);
|
||||
Dbprintf(" BigBuf_size.............%d", s_bigbuf_size);
|
||||
Dbprintf(" Available memory........%d", s_bigbuf_hi);
|
||||
DbpString(_CYAN_("Tracing"));
|
||||
Dbprintf(" tracing ................%d", tracing);
|
||||
Dbprintf(" traceLen ...............%d", traceLen);
|
||||
Dbprintf(" traceLen ...............%d", trace_len);
|
||||
|
||||
Dbprintf(" dma8 memory.............%d", dma_8.buf - BigBuf_get_addr());
|
||||
Dbprintf(" dma16 memory............%d", (uint8_t*)dma_16.buf - BigBuf_get_addr());
|
||||
Dbprintf(" toSend memory...........%d", toSend.buf - BigBuf_get_addr() );
|
||||
}
|
||||
|
||||
// return the maximum trace length (i.e. the unallocated size of BigBuf)
|
||||
uint16_t BigBuf_max_traceLen(void) {
|
||||
return BigBuf_hi;
|
||||
return s_bigbuf_hi;
|
||||
}
|
||||
|
||||
void clear_trace(void) {
|
||||
traceLen = 0;
|
||||
trace_len = 0;
|
||||
}
|
||||
|
||||
void set_tracelen(uint32_t value) {
|
||||
traceLen = value;
|
||||
trace_len = value;
|
||||
}
|
||||
|
||||
void set_tracing(bool enable) {
|
||||
@@ -148,7 +189,7 @@ bool get_tracing(void) {
|
||||
* @return
|
||||
*/
|
||||
uint32_t BigBuf_get_traceLen(void) {
|
||||
return traceLen;
|
||||
return trace_len;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,16 +199,18 @@ uint32_t BigBuf_get_traceLen(void) {
|
||||
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;
|
||||
if (tracing == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + traceLen);
|
||||
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + trace_len);
|
||||
|
||||
uint32_t num_paritybytes = (iLen - 1) / 8 + 1; // number of valid paritybytes in *parity
|
||||
|
||||
// Return when trace is full
|
||||
if (TRACELOG_HDR_LEN + iLen + num_paritybytes >= BigBuf_max_traceLen() - traceLen) {
|
||||
tracing = false; // don't trace any more
|
||||
if (TRACELOG_HDR_LEN + iLen + num_paritybytes >= BigBuf_max_traceLen() - trace_len) {
|
||||
tracing = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -178,39 +221,48 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||
duration = (UINT32_MAX - timestamp_start) + timestamp_end;
|
||||
}
|
||||
|
||||
if (duration > 0x7FFF) {
|
||||
if (duration > 0xFFFF) {
|
||||
/*
|
||||
if (DBGLEVEL >= DBG_DEBUG) {
|
||||
Dbprintf("Error in LogTrace: duration too long for 15 bits encoding: 0x%08x start:0x%08x end:0x%08x", duration, timestamp_start, timestamp_end);
|
||||
Dbprintf("Forcing duration = 0");
|
||||
Dbprintf("Error in LogTrace: duration too long for 16 bits encoding: 0x%08x start: 0x%08x end: 0x%08x", duration, timestamp_start, timestamp_end);
|
||||
}
|
||||
*/
|
||||
duration = 0;
|
||||
}
|
||||
|
||||
|
||||
hdr->timestamp = timestamp_start;
|
||||
hdr->duration = duration;
|
||||
hdr->duration = duration & 0xFFFF;
|
||||
hdr->data_len = iLen;
|
||||
hdr->isResponse = !readerToTag;
|
||||
traceLen += TRACELOG_HDR_LEN;
|
||||
trace_len += TRACELOG_HDR_LEN;
|
||||
|
||||
// data bytes
|
||||
if (btBytes != NULL && iLen != 0) {
|
||||
memcpy(trace + traceLen, btBytes, iLen);
|
||||
memcpy(hdr->frame, btBytes, iLen);
|
||||
trace_len += iLen;
|
||||
}
|
||||
traceLen += iLen;
|
||||
|
||||
// parity bytes
|
||||
if (num_paritybytes != 0) {
|
||||
if (parity != NULL) {
|
||||
memcpy(trace + traceLen, parity, num_paritybytes);
|
||||
memcpy(trace + trace_len, parity, num_paritybytes);
|
||||
} else {
|
||||
memset(trace + traceLen, 0x00, num_paritybytes);
|
||||
memset(trace + trace_len, 0x00, num_paritybytes);
|
||||
}
|
||||
trace_len += num_paritybytes;
|
||||
}
|
||||
traceLen += num_paritybytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// specific LogTrace function for ISO15693: the duration needs to be scaled because otherwise it won't fit into a uint16_t
|
||||
bool LogTrace_ISO15693(const uint8_t *bytes, uint16_t len, uint32_t ts_start, uint32_t ts_end, uint8_t *parity, bool reader2tag) {
|
||||
uint32_t duration = ts_end - ts_start;
|
||||
duration /= 32;
|
||||
ts_end = ts_start + duration;
|
||||
return LogTrace(bytes, len, ts_start, ts_end, parity, reader2tag);
|
||||
}
|
||||
|
||||
|
||||
// Emulator memory
|
||||
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length) {
|
||||
uint8_t *mem = BigBuf_get_EM_addr();
|
||||
@@ -221,3 +273,51 @@ uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length) {
|
||||
Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset + length), CARD_MEMORY_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get the address of the ToSend buffer. Allocate part of Bigbuf for it, if not yet done
|
||||
tosend_t *get_tosend(void) {
|
||||
|
||||
if (toSend.buf == NULL)
|
||||
toSend.buf = BigBuf_malloc(TOSEND_BUFFER_SIZE);
|
||||
|
||||
return &toSend;
|
||||
}
|
||||
|
||||
void tosend_reset(void) {
|
||||
toSend.max = -1;
|
||||
toSend.bit = 8;
|
||||
}
|
||||
|
||||
void tosend_stuffbit(int b) {
|
||||
if (toSend.bit >= 8) {
|
||||
toSend.max++;
|
||||
toSend.buf[toSend.max] = 0;
|
||||
toSend.bit = 0;
|
||||
}
|
||||
|
||||
if (b)
|
||||
toSend.buf[ toSend.max] |= (1 << (7 - toSend.bit));
|
||||
|
||||
toSend.bit++;
|
||||
|
||||
if (toSend.max >= TOSEND_BUFFER_SIZE) {
|
||||
toSend.bit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
dmabuf16_t *get_dma16(void) {
|
||||
if (dma_16.buf == NULL)
|
||||
dma_16.buf = (uint16_t*)BigBuf_malloc(DMA_BUFFER_SIZE * sizeof(uint16_t));
|
||||
|
||||
return &dma_16;
|
||||
}
|
||||
|
||||
dmabuf8_t *get_dma8(void) {
|
||||
if (dma_8.buf == NULL)
|
||||
dma_8.buf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
|
||||
return &dma_8;
|
||||
}
|
||||
|
||||
|
||||
+31
-1
@@ -19,7 +19,10 @@
|
||||
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
||||
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
|
||||
#define CARD_MEMORY_SIZE 4096
|
||||
#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!?
|
||||
#define DMA_BUFFER_SIZE 256
|
||||
|
||||
// 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
|
||||
#define TOSEND_BUFFER_SIZE (9 * MAX_FRAME_SIZE + 1 + 1 + 2)
|
||||
|
||||
uint8_t *BigBuf_get_addr(void);
|
||||
uint32_t BigBuf_get_size(void);
|
||||
@@ -39,7 +42,34 @@ void clear_trace(void);
|
||||
void set_tracing(bool enable);
|
||||
void set_tracelen(uint32_t value);
|
||||
bool get_tracing(void);
|
||||
|
||||
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
|
||||
bool LogTrace_ISO15693(const uint8_t *bytes, uint16_t len, uint32_t ts_start, uint32_t ts_end, uint8_t *parity, bool reader2tag);
|
||||
|
||||
|
||||
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
|
||||
|
||||
|
||||
typedef struct {
|
||||
int max;
|
||||
int bit;
|
||||
uint8_t *buf;
|
||||
} tosend_t;
|
||||
|
||||
tosend_t *get_tosend(void);
|
||||
void tosend_reset(void);
|
||||
void tosend_stuffbit(int b);
|
||||
|
||||
typedef struct {
|
||||
uint16_t size;
|
||||
uint8_t *buf;
|
||||
} dmabuf8_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t size;
|
||||
uint16_t *buf;
|
||||
} dmabuf16_t;
|
||||
|
||||
dmabuf8_t *get_dma8(void);
|
||||
dmabuf16_t *get_dma16(void);
|
||||
#endif /* __BIGBUF_H */
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ SRC_ISO14443b = iso14443b.c
|
||||
SRC_FELICA = felica.c
|
||||
SRC_CRAPTO1 = crypto1.c des.c desfire_crypto.c mifaredesfire.c aes.c platform_util.c
|
||||
SRC_CRC = crc.c crc16.c crc32.c
|
||||
SRC_ICLASS = iclass.c optimized_cipher.c
|
||||
SRC_ICLASS = iclass.c optimized_cipherutils.c optimized_ikeys.c optimized_elite.c optimized_cipher.c
|
||||
SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c
|
||||
SRC_NFCBARCODE = thinfilm.c
|
||||
|
||||
@@ -79,7 +79,7 @@ endif
|
||||
include Standalone/Makefile.inc
|
||||
|
||||
#the FPGA bitstream files. Note: order matters!
|
||||
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
|
||||
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit fpga_felica.bit
|
||||
|
||||
#the lz4 source files required for decompressing the fpga config at run time
|
||||
SRC_LZ4 = lz4.c
|
||||
|
||||
@@ -44,6 +44,9 @@ define KNOWN_STANDALONE_DEFINITIONS
|
||||
| HF_COLIN | Mifare ultra fast sniff/sim/clone |
|
||||
| (RDV4 only) | - Colin Brigato |
|
||||
+----------------------------------------------------------+
|
||||
| HF_ICECLASS | Simulate HID iCLASS legacy ags |
|
||||
| (RDV4 only) | storing in flashmem |
|
||||
+----------------------------------------------------------+
|
||||
| HF_LEGIC | Read/simulate Legic Prime tags |
|
||||
| | storing in flashmem |
|
||||
+----------------------------------------------------------+
|
||||
@@ -59,9 +62,9 @@ define KNOWN_STANDALONE_DEFINITIONS
|
||||
endef
|
||||
|
||||
STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RWC LF_HIDBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN
|
||||
STANDALONE_MODES += HF_14ASNIFF HF_BOG HF_COLIN HF_LEGIC HF_MATTYRUN HF_MSDSAL HF_YOUNG
|
||||
STANDALONE_MODES += HF_14ASNIFF HF_BOG HF_COLIN HF_ICECLASS HF_LEGIC HF_MATTYRUN HF_MSDSAL HF_YOUNG
|
||||
STANDALONE_MODES_REQ_SMARTCARD :=
|
||||
STANDALONE_MODES_REQ_FLASH := LF_ICEHID HF_14ASNIFF HF_BOG HF_COLIN
|
||||
STANDALONE_MODES_REQ_FLASH := LF_ICEHID HF_14ASNIFF HF_BOG HF_COLIN HF_ICECLASS
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
|
||||
STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE)
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),)
|
||||
|
||||
@@ -57,7 +57,11 @@ endif
|
||||
ifneq (,$(findstring WITH_STANDALONE_HF_LEGIC,$(APP_CFLAGS)))
|
||||
SRC_STANDALONE = hf_legic.c
|
||||
endif
|
||||
# WITH_STANDALONE_LF_MSDSAL
|
||||
# WITH_STANDALONE_HF_MSDSAL
|
||||
ifneq (,$(findstring WITH_STANDALONE_HF_MSDSAL,$(APP_CFLAGS)))
|
||||
SRC_STANDALONE = hf_msdsal.c
|
||||
endif
|
||||
# WITH_STANDALONE_HF_ICECLASS
|
||||
ifneq (,$(findstring WITH_STANDALONE_HF_ICECLASS,$(APP_CFLAGS)))
|
||||
SRC_STANDALONE = hf_iceclass.c
|
||||
endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@
|
||||
#endif
|
||||
|
||||
#define MAX_IND 16 // 4 LEDs - 2^4 combinations
|
||||
#define CLOCK 64 //for 125kHz
|
||||
#define LF_CLOCK 64 // for 125kHz
|
||||
|
||||
// low & high - array for storage IDs. Its length must be equal.
|
||||
// Predefined IDs must be stored in low[].
|
||||
@@ -57,34 +57,35 @@ static uint64_t rev_quads(uint64_t bits) {
|
||||
}
|
||||
|
||||
static void fillbuff(uint8_t bit) {
|
||||
memset(bba + buflen, bit, CLOCK / 2);
|
||||
buflen += (CLOCK / 2);
|
||||
memset(bba + buflen, bit ^ 1, CLOCK / 2);
|
||||
buflen += (CLOCK / 2);
|
||||
memset(bba + buflen, bit, LF_CLOCK / 2);
|
||||
buflen += (LF_CLOCK / 2);
|
||||
memset(bba + buflen, bit ^ 1, LF_CLOCK / 2);
|
||||
buflen += (LF_CLOCK / 2);
|
||||
}
|
||||
|
||||
static void construct_EM410x_emul(uint64_t id) {
|
||||
|
||||
|
||||
int i, j;
|
||||
int binary[4] = {0};
|
||||
int parity[4] = {0};
|
||||
buflen = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 9; i++)
|
||||
for (i = 0; i < 9; i++)
|
||||
fillbuff(1);
|
||||
|
||||
for (uint8_t i = 0; i < 10; i++) {
|
||||
for (uint8_t j = 3; j > 0; j--, id /= 2)
|
||||
for (i = 0; i < 10; i++) {
|
||||
for (j = 3; j >= 0; j--, id /= 2)
|
||||
binary[j] = id % 2;
|
||||
|
||||
for (uint8_t j = 0; j < 4; j++)
|
||||
for (j = 0; j < 4; j++)
|
||||
fillbuff(binary[j]);
|
||||
|
||||
fillbuff(binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
|
||||
for (uint8_t j = 0; j < 4; j++)
|
||||
for (j = 0; j < 4; j++)
|
||||
parity[j] ^= binary[j];
|
||||
}
|
||||
|
||||
for (uint8_t j = 0; j < 4; j++)
|
||||
for (j = 0; j < 4; j++)
|
||||
fillbuff(parity[j]);
|
||||
|
||||
fillbuff(0);
|
||||
@@ -207,7 +208,7 @@ void RunMod(void) {
|
||||
state = 0;
|
||||
} else if (button_pressed == BUTTON_SINGLE_CLICK) {
|
||||
// Click - write ID to tag
|
||||
copy_em410x_to_t55xx(0, CLOCK, (uint32_t)(low[selected] >> 32), (uint32_t)(low[selected] & 0xffffffff));
|
||||
copy_em410x_to_t55xx(0, LF_CLOCK, (uint32_t)(low[selected] >> 32), (uint32_t)(low[selected] & 0xffffffff));
|
||||
led_slot(selected);
|
||||
state = 0; // Switch to select mode
|
||||
}
|
||||
|
||||
+82
-74
@@ -20,6 +20,7 @@
|
||||
#include "fpga.h"
|
||||
#include "fpgaloader.h"
|
||||
#include "string.h"
|
||||
#include "printf.h"
|
||||
#include "legicrf.h"
|
||||
#include "BigBuf.h"
|
||||
#include "iso14443a.h"
|
||||
@@ -62,20 +63,7 @@
|
||||
#include "spiffs.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// A buffer where we can queue things up to be sent through the FPGA, for
|
||||
// any purpose (fake tag, as reader, whatever). We go MSB first, since that
|
||||
// is the order in which they go out on the wire.
|
||||
//=============================================================================
|
||||
|
||||
#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
|
||||
uint8_t ToSend[TOSEND_BUFFER_SIZE];
|
||||
int ToSendMax = -1;
|
||||
|
||||
extern uint32_t _stack_start, _stack_end;
|
||||
|
||||
|
||||
static int ToSendBit;
|
||||
struct common_area common_area __attribute__((section(".commonarea")));
|
||||
static int button_status = BUTTON_NO_CLICK;
|
||||
static bool allow_send_wtx = false;
|
||||
@@ -86,29 +74,6 @@ inline void send_wtx(uint16_t wtx) {
|
||||
}
|
||||
}
|
||||
|
||||
void ToSendReset(void) {
|
||||
ToSendMax = -1;
|
||||
ToSendBit = 8;
|
||||
}
|
||||
|
||||
void ToSendStuffBit(int b) {
|
||||
if (ToSendBit >= 8) {
|
||||
ToSendMax++;
|
||||
ToSend[ToSendMax] = 0;
|
||||
ToSendBit = 0;
|
||||
}
|
||||
|
||||
if (b)
|
||||
ToSend[ToSendMax] |= (1 << (7 - ToSendBit));
|
||||
|
||||
ToSendBit++;
|
||||
|
||||
if (ToSendMax >= sizeof(ToSend)) {
|
||||
ToSendBit = 0;
|
||||
DbpString("ToSendStuffBit overflowed!");
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read an ADC channel and block till it completes, then return the result
|
||||
// in ADC units (0 to 1023). Also a routine to sum up a number of samples and
|
||||
@@ -213,7 +178,7 @@ static void MeasureAntennaTuning(void) {
|
||||
LED_A_ON();
|
||||
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
|
||||
SpinDelay(50);
|
||||
|
||||
#if defined RDV4
|
||||
@@ -328,6 +293,28 @@ static void TimingIntervalAcquisition(void) {
|
||||
StartTickCount();
|
||||
}
|
||||
|
||||
static void print_debug_level(void) {
|
||||
char dbglvlstr[20] = {0};
|
||||
switch(DBGLEVEL) {
|
||||
case DBG_NONE:
|
||||
sprintf(dbglvlstr, "NONE");
|
||||
break;
|
||||
case DBG_ERROR:
|
||||
sprintf(dbglvlstr, "ERROR");
|
||||
break;
|
||||
case DBG_INFO:
|
||||
sprintf(dbglvlstr, "INFO");
|
||||
break;
|
||||
case DBG_DEBUG:
|
||||
sprintf(dbglvlstr, "DEBUG");
|
||||
break;
|
||||
case DBG_EXTENDED:
|
||||
sprintf(dbglvlstr, "EXTENDED");
|
||||
break;
|
||||
}
|
||||
Dbprintf(" DBGLEVEL................%d ( " _YELLOW_("%s")" )", DBGLEVEL, dbglvlstr);
|
||||
}
|
||||
|
||||
// measure the Connection Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
|
||||
// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the PacketCommandNG structure included.
|
||||
static void printConnSpeed(void) {
|
||||
@@ -374,10 +361,10 @@ static void SendStatus(void) {
|
||||
DbpString(_CYAN_("Various"));
|
||||
|
||||
print_stack_usage();
|
||||
|
||||
Dbprintf(" DBGLEVEL................%d", DBGLEVEL);
|
||||
Dbprintf(" ToSendMax...............%d", ToSendMax);
|
||||
Dbprintf(" ToSendBit...............%d", ToSendBit);
|
||||
print_debug_level();
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
Dbprintf(" ToSendMax...............%d", ts->max );
|
||||
Dbprintf(" ToSend BUFFERSIZE.......%d", TOSEND_BUFFER_SIZE);
|
||||
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
|
||||
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks
|
||||
@@ -515,6 +502,7 @@ static void SendCapabilities(void) {
|
||||
|
||||
// Show some leds in a pattern to identify StandAlone mod is running
|
||||
void StandAloneMode(void) {
|
||||
DbpString("");
|
||||
DbpString("Stand-alone mode, no computer necessary");
|
||||
SpinDown(50);
|
||||
SpinDelay(50);
|
||||
@@ -735,7 +723,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
// emulator
|
||||
case CMD_SET_DBGMODE: {
|
||||
DBGLEVEL = packet->data.asBytes[0];
|
||||
Dbprintf("Debug level: %d", DBGLEVEL);
|
||||
print_debug_level();
|
||||
reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
@@ -793,7 +781,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
case CMD_LF_HID_WATCH: {
|
||||
uint32_t high, low;
|
||||
int res = lf_hid_watch(0, &high, &low);
|
||||
reply_ng(CMD_LF_HID_WATCH, res, NULL, 0);
|
||||
reply_ng(CMD_LF_HID_WATCH, res, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case CMD_LF_HID_SIMULATE: {
|
||||
@@ -974,6 +962,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
case CMD_LF_HITAG_SNIFF: { // Eavesdrop Hitag tag, args = type
|
||||
SniffHitag2();
|
||||
// SniffHitag2(packet->oldarg[0]);
|
||||
reply_ng(CMD_LF_HITAG_SNIFF, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case CMD_LF_HITAG_SIMULATE: { // Simulate Hitag tag, args = memory content
|
||||
@@ -1034,8 +1023,18 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
AcquireRawAdcSamplesIso15693();
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO15693_RAWADC: {
|
||||
RecordRawAdcSamplesIso15693();
|
||||
case CMD_HF_ISO15693_SNIFF: {
|
||||
/*
|
||||
struct p {
|
||||
uint8_t jam_search_len;
|
||||
uint8_t jam_search_string[];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
|
||||
SniffIso15693(payload->jam_search_len, payload->jam_search_string);
|
||||
*/
|
||||
SniffIso15693(0, NULL);
|
||||
reply_ng(CMD_HF_ISO15693_SNIFF, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO15693_COMMAND: {
|
||||
@@ -1051,7 +1050,11 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO15693_SIMULATE: {
|
||||
SimTagIso15693(packet->oldarg[0], packet->data.asBytes);
|
||||
struct p {
|
||||
uint8_t uid[10];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
SimTagIso15693(payload->uid);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -1094,6 +1097,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
}
|
||||
case CMD_HF_ISO14443B_SNIFF: {
|
||||
SniffIso14443b();
|
||||
reply_ng(CMD_HF_ISO14443B_SNIFF, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO14443B_SIMULATE: {
|
||||
@@ -1118,6 +1122,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
}
|
||||
case CMD_HF_FELICA_SNIFF: {
|
||||
felica_sniff(packet->oldarg[0], packet->oldarg[1]);
|
||||
reply_ng(CMD_HF_FELICA_SNIFF, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_FELICALITE_DUMP: {
|
||||
@@ -1129,6 +1134,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
#ifdef WITH_ISO14443a
|
||||
case CMD_HF_ISO14443A_SNIFF: {
|
||||
SniffIso14443a(packet->data.asBytes[0]);
|
||||
reply_ng(CMD_HF_ISO14443A_SNIFF, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO14443A_READER: {
|
||||
@@ -1379,7 +1385,13 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
#ifdef WITH_ICLASS
|
||||
// Makes use of ISO14443a FPGA Firmware
|
||||
case CMD_HF_ICLASS_SNIFF: {
|
||||
SniffIClass();
|
||||
struct p {
|
||||
uint8_t jam_search_len;
|
||||
uint8_t jam_search_string[];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
SniffIClass(payload->jam_search_len, payload->jam_search_string);
|
||||
reply_ng(CMD_HF_ICLASS_SNIFF, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_SIMULATE: {
|
||||
@@ -1391,7 +1403,12 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_REPLAY: {
|
||||
ReaderIClass_Replay(packet->oldarg[0], packet->data.asBytes);
|
||||
struct p {
|
||||
uint8_t reader[4];
|
||||
uint8_t mac[4];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
ReaderIClass_Replay(payload->reader, payload->mac);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_EML_MEMSET: {
|
||||
@@ -1401,36 +1418,14 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_WRITEBL: {
|
||||
struct p {
|
||||
uint8_t blockno;
|
||||
uint8_t data[12];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *)packet->data.asBytes;
|
||||
iClass_WriteBlock(payload->blockno, payload->data);
|
||||
break;
|
||||
}
|
||||
// iceman2019, unused?
|
||||
case CMD_HF_ICLASS_READCHECK: { // auth step 1
|
||||
iClass_ReadCheck(packet->oldarg[0], packet->oldarg[1]);
|
||||
iClass_WriteBlock(packet->data.asBytes);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_READBL: {
|
||||
/*
|
||||
struct p {
|
||||
uint8_t blockno;
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *)packet->data.asBytes;
|
||||
*/
|
||||
iClass_ReadBlk(packet->data.asBytes[0]);
|
||||
iClass_ReadBlock(packet->data.asBytes);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_AUTH: { //check
|
||||
/*
|
||||
struct p {
|
||||
uint8_t mac[4];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *)packet->data.asBytes;
|
||||
*/
|
||||
iClass_Authentication(packet->data.asBytes);
|
||||
break;
|
||||
}
|
||||
@@ -1439,7 +1434,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_DUMP: {
|
||||
iClass_Dump(packet->oldarg[0], packet->oldarg[1]);
|
||||
iClass_Dump(packet->data.asBytes);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_CLONE: {
|
||||
@@ -1452,6 +1447,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
iClass_Clone(payload->startblock, payload->endblock, payload->data);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_RESTORE: {
|
||||
iClass_Restore(packet->data.asBytes);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_HFSNIFF
|
||||
@@ -1619,7 +1618,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
case 1: // MEASURE_ANTENNA_TUNING_HF_START
|
||||
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
|
||||
reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
case 2:
|
||||
@@ -1906,6 +1905,13 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_SPIFFS_WIPE: {
|
||||
LED_B_ON();
|
||||
rdv40_spiffs_safe_wipe();
|
||||
reply_ng(CMD_SPIFFS_WIPE, PM3_SUCCESS, NULL, 0);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_FLASHMEM_SET_SPIBAUDRATE: {
|
||||
if (packet->length != sizeof(uint32_t))
|
||||
break;
|
||||
@@ -2063,6 +2069,8 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
break;
|
||||
}
|
||||
case CMD_STANDALONE: {
|
||||
uint8_t *bb = BigBuf_get_EM_addr();
|
||||
bb[0] = packet->data.asBytes[0];
|
||||
RunMod();
|
||||
break;
|
||||
}
|
||||
|
||||
+32
-41
@@ -100,7 +100,6 @@ int gLow = 0;
|
||||
static void init_tag(void) {
|
||||
|
||||
// initialize global tag structure
|
||||
|
||||
for (int i = 0; i < 34; i++)
|
||||
for (int j = 0; j < 7; j++)
|
||||
tag.sectors[i][j] = 0x00;
|
||||
@@ -109,9 +108,7 @@ static void init_tag(void) {
|
||||
static uint8_t bits2byte(uint8_t *bits, int length) {
|
||||
|
||||
// converts <length> separate bits into a single "byte"
|
||||
|
||||
uint8_t byte = 0;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
byte |= bits[i];
|
||||
@@ -124,11 +121,10 @@ static uint8_t bits2byte(uint8_t *bits, int length) {
|
||||
}
|
||||
|
||||
static void msb2lsb_word(uint8_t *word) {
|
||||
|
||||
|
||||
// reorders given <word> according to EM4x50 datasheet (msb -> lsb)
|
||||
|
||||
|
||||
uint8_t buff[4];
|
||||
|
||||
buff[0] = reflect8(word[3]);
|
||||
buff[1] = reflect8(word[2]);
|
||||
buff[2] = reflect8(word[1]);
|
||||
@@ -141,13 +137,12 @@ static void msb2lsb_word(uint8_t *word) {
|
||||
}
|
||||
|
||||
static void save_word(int pos, uint8_t bits[EM4X50_TAG_WORD]) {
|
||||
|
||||
|
||||
// split "raw" word into data, row and column parity bits and stop bit and
|
||||
// save them in global tag structure
|
||||
|
||||
uint8_t row_parity[4];
|
||||
uint8_t col_parity[8];
|
||||
|
||||
|
||||
// data and row parities
|
||||
for (int i = 0; i < 4; i++) {
|
||||
tag.sectors[pos][i] = bits2byte(&bits[9*i],8);
|
||||
@@ -161,7 +156,7 @@ static void save_word(int pos, uint8_t bits[EM4X50_TAG_WORD]) {
|
||||
col_parity[i] = bits[36+i];
|
||||
|
||||
tag.sectors[pos][5] = bits2byte(col_parity,8);
|
||||
|
||||
|
||||
// stop bit
|
||||
tag.sectors[pos][6] = bits[44];
|
||||
}
|
||||
@@ -169,7 +164,7 @@ static void save_word(int pos, uint8_t bits[EM4X50_TAG_WORD]) {
|
||||
static void wait_timer(int timer, uint32_t period) {
|
||||
|
||||
// do nothing for <period> using timer <timer>
|
||||
|
||||
|
||||
if (timer == FPGA_TIMER_0) {
|
||||
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||
@@ -184,23 +179,22 @@ static void wait_timer(int timer, uint32_t period) {
|
||||
}
|
||||
|
||||
static void em4x50_setup_read(void) {
|
||||
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// 50ms for the resonant antenna to settle.
|
||||
SpinDelay(50);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER);
|
||||
// start a 1.5ticks is 1us
|
||||
StartTicks();
|
||||
|
||||
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125);
|
||||
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
|
||||
|
||||
// Steal this pin from the SSP (SPI communication channel with fpga) and
|
||||
// use it to control the modulation
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
@@ -208,7 +202,7 @@ static void em4x50_setup_read(void) {
|
||||
|
||||
// Disable modulation at default, which means enable the field
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
|
||||
|
||||
// Enable Peripheral Clock for
|
||||
// TIMER_CLOCK0, used to measure exact timing before answering
|
||||
// TIMER_CLOCK1, used to capture edges of the tag frames
|
||||
@@ -221,17 +215,17 @@ static void em4x50_setup_read(void) {
|
||||
|
||||
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||
|
||||
|
||||
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||
|
||||
|
||||
// Enable and reset counters
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
|
||||
|
||||
// synchronized startup procedure
|
||||
while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC1 returned to zero
|
||||
|
||||
|
||||
// Watchdog hit
|
||||
WDT_HIT();
|
||||
}
|
||||
@@ -239,21 +233,21 @@ static void em4x50_setup_read(void) {
|
||||
// functions for "reader" use case
|
||||
|
||||
static bool get_signalproperties(void) {
|
||||
|
||||
|
||||
// calculate signal properties (mean amplitudes) from measured data:
|
||||
// 32 amplitudes (maximum values) -> mean amplitude value -> gHigh -> gLow
|
||||
|
||||
|
||||
bool signal_found = false;
|
||||
int no_periods = 32, pct = 75, noise = 140;
|
||||
uint8_t sample = 0, sample_ref = 127;
|
||||
uint8_t sample_ref = 127;
|
||||
uint8_t sample_max_mean = 0;
|
||||
uint8_t sample_max[no_periods];
|
||||
uint32_t sample_max_sum = 0;
|
||||
memcpy(sample_max, 0x00, sizeof(sample_max));
|
||||
|
||||
|
||||
// wait until signal/noise > 1 (max. 32 periods)
|
||||
for (int i = 0; i < T0 * no_periods; i++) {
|
||||
|
||||
|
||||
// about 2 samples per bit period
|
||||
wait_timer(0, T0 * EM4X50_T_TAG_HALF_PERIOD);
|
||||
|
||||
@@ -261,9 +255,9 @@ static bool get_signalproperties(void) {
|
||||
signal_found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!signal_found)
|
||||
return false;
|
||||
|
||||
@@ -273,39 +267,36 @@ static bool get_signalproperties(void) {
|
||||
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||
while (AT91C_BASE_TC0->TC_CV < T0 * 3 * EM4X50_T_TAG_FULL_PERIOD) {
|
||||
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
|
||||
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
if (sample > sample_max[i])
|
||||
sample_max[i] = sample;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
sample_max_sum += sample_max[i];
|
||||
}
|
||||
|
||||
|
||||
sample_max_mean = sample_max_sum / no_periods;
|
||||
|
||||
|
||||
// set global envelope variables
|
||||
gHigh = sample_ref + pct * (sample_max_mean - sample_ref) / 100;
|
||||
gLow = sample_ref - pct * (sample_max_mean - sample_ref) / 100;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int get_next_bit(void) {
|
||||
|
||||
|
||||
// returns bit value (or EM4X50_BIT_OTHER -> no bit pattern) by evaluating
|
||||
// a single sample within a bit period (given there is no LIW, ACK or NAK)
|
||||
// This function is not used for decoding, it is only used for identifying
|
||||
// a listen window (return value = EM4X50_BIT_OTHER) in functions
|
||||
// "find_double_listen_window" and "check_ack"
|
||||
|
||||
uint8_t sample;
|
||||
|
||||
// get sample at 3/4 of bit period
|
||||
wait_timer(0, T0 * EM4X50_T_TAG_THREE_QUARTER_PERIOD);
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
// wait until end of bit period
|
||||
wait_timer(0, T0 * EM4X50_T_TAG_QUARTER_PERIOD);
|
||||
@@ -315,7 +306,7 @@ static int get_next_bit(void) {
|
||||
return EM4X50_BIT_0;
|
||||
else if (sample < gLow)
|
||||
return EM4X50_BIT_1;
|
||||
|
||||
|
||||
return EM4X50_BIT_OTHER;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -336,7 +336,7 @@ static void BuildFliteRdblk(uint8_t *idm, int blocknum, uint16_t *blocks) {
|
||||
}
|
||||
|
||||
static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed) {
|
||||
uint8_t flags = FPGA_MAJOR_MODE_HF_ISO18092;
|
||||
uint16_t flags = FPGA_MAJOR_MODE_HF_ISO18092;
|
||||
if (power)
|
||||
flags |= FPGA_HF_ISO18092_FLAG_READER;
|
||||
if (highspeed)
|
||||
@@ -445,7 +445,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
|
||||
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Start iso18092_setup");
|
||||
|
||||
LEDsoff();
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF_FELICA);
|
||||
|
||||
// allocate command receive buffer
|
||||
BigBuf_free();
|
||||
@@ -464,7 +464,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Set up the synchronous serial port
|
||||
FpgaSetupSsc();
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO18092);
|
||||
|
||||
// LSB transfer. Remember to set it back to MSB with
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
|
||||
+14
-8
@@ -134,7 +134,7 @@ void SetupSpi(int mode) {
|
||||
// Set up the synchronous serial port with the set of options that fits
|
||||
// the FPGA mode. Both RX and TX are always enabled.
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaSetupSsc(void) {
|
||||
void FpgaSetupSsc(uint16_t fpga_mode) {
|
||||
// First configure the GPIOs, and get ourselves a clock.
|
||||
AT91C_BASE_PIOA->PIO_ASR =
|
||||
GPIO_SSC_FRAME |
|
||||
@@ -152,12 +152,16 @@ void FpgaSetupSsc(void) {
|
||||
// data and frame signal is sampled on falling edge of RK
|
||||
AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1);
|
||||
|
||||
// 8 bits per transfer, no loopback, MSB first, 1 transfer per sync
|
||||
// 8, 16 or 32 bits per transfer, no loopback, MSB first, 1 transfer per sync
|
||||
// pulse, no output sync
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
if ((fpga_mode & FPGA_MAJOR_MODE_MASK) == FPGA_MAJOR_MODE_HF_READER && FpgaGetCurrent() == FPGA_BITSTREAM_HF) {
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
} else {
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
}
|
||||
|
||||
// TX clock comes from TK pin, no clock output, outputs change on falling
|
||||
// edge of TK, frame sync is sampled on rising edge of TK, start TX on rising edge of TF
|
||||
// TX clock comes from TK pin, no clock output, outputs change on rising edge of TK,
|
||||
// TF (frame sync) is sampled on falling edge of TK, start TX on rising edge of TF
|
||||
AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5);
|
||||
|
||||
// tx framing is the same as the rx framing
|
||||
@@ -171,7 +175,7 @@ void FpgaSetupSsc(void) {
|
||||
// a single buffer as a circular buffer (so that we just chain back to
|
||||
// ourselves, not to another buffer).
|
||||
//-----------------------------------------------------------------------------
|
||||
bool FpgaSetupSscDma(uint8_t *buf, int len) {
|
||||
bool FpgaSetupSscDma(uint8_t *buf, uint16_t len) {
|
||||
if (buf == NULL) return false;
|
||||
|
||||
FpgaDisableSscDma();
|
||||
@@ -347,8 +351,10 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp co
|
||||
* length.
|
||||
*/
|
||||
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||
int result = 0;
|
||||
|
||||
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
||||
|
||||
int result = 0;
|
||||
uint16_t numbytes = 0;
|
||||
while (numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
|
||||
char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
@@ -439,7 +445,7 @@ void FpgaDownloadAndGo(int bitstream_version) {
|
||||
// The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
|
||||
// where C is the 4 bit command and D is the 12 bit data
|
||||
//
|
||||
// @params cmd and v gets or over eachother. Take careful note of overlapping bits.
|
||||
// @params cmd and v gets OR:ED over each other. Take careful note of overlapping bits.
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaSendCommand(uint16_t cmd, uint16_t v) {
|
||||
SetupSpi(SPI_FPGA_MODE);
|
||||
|
||||
+31
-20
@@ -20,6 +20,7 @@
|
||||
// definitions for multiple FPGA config files support
|
||||
#define FPGA_BITSTREAM_LF 1
|
||||
#define FPGA_BITSTREAM_HF 2
|
||||
#define FPGA_BITSTREAM_HF_FELICA 3
|
||||
|
||||
/*
|
||||
Communication between ARM / FPGA is done inside armsrc/fpgaloader.c (function FpgaSendCommand)
|
||||
@@ -52,23 +53,26 @@ thres| x x x x x x x x
|
||||
#define FPGA_CMD_TRACE_ENABLE (2<<12) // C
|
||||
|
||||
// Definitions for the FPGA configuration word.
|
||||
#define FPGA_MAJOR_MODE_MASK 0x01C0
|
||||
#define FPGA_MINOR_MODE_MASK 0x003F
|
||||
|
||||
// LF
|
||||
#define FPGA_MAJOR_MODE_LF_READER (0<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_ADC (3<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_READER (0<<6)
|
||||
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<6)
|
||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<6)
|
||||
#define FPGA_MAJOR_MODE_LF_ADC (3<<6)
|
||||
|
||||
// HF
|
||||
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5) // D
|
||||
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5) // D
|
||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5) // D
|
||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5) // D
|
||||
#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5) // D
|
||||
#define FPGA_MAJOR_MODE_HF_ISO18092 (5<<5) // D
|
||||
#define FPGA_MAJOR_MODE_HF_GET_TRACE (6<<5) // D
|
||||
#define FPGA_MAJOR_MODE_HF_READER (0<<6) // D
|
||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (1<<6) // D
|
||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (2<<6) // D
|
||||
#define FPGA_MAJOR_MODE_HF_SNIFF (3<<6) // D
|
||||
#define FPGA_MAJOR_MODE_HF_ISO18092 (4<<6) // D
|
||||
#define FPGA_MAJOR_MODE_HF_GET_TRACE (5<<6) // D
|
||||
|
||||
// BOTH HF / LF
|
||||
#define FPGA_MAJOR_MODE_OFF (7<<5) // D
|
||||
#define FPGA_MAJOR_MODE_OFF (7<<6) // D
|
||||
|
||||
|
||||
// Options for LF_READER
|
||||
#define FPGA_LF_ADC_READER_FIELD 0x1
|
||||
@@ -78,13 +82,20 @@ thres| x x x x x x x x
|
||||
#define FPGA_LF_EDGE_DETECT_READER_FIELD 0x1
|
||||
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE 0x2
|
||||
|
||||
// Options for the HF reader, tx to tag
|
||||
#define FPGA_HF_READER_TX_SHALLOW_MOD 0x1
|
||||
// Options for the HF reader
|
||||
#define FPGA_HF_READER_MODE_RECEIVE_IQ (0<<0)
|
||||
#define FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE (1<<0)
|
||||
#define FPGA_HF_READER_MODE_RECEIVE_PHASE (2<<0)
|
||||
#define FPGA_HF_READER_MODE_SEND_FULL_MOD (3<<0)
|
||||
#define FPGA_HF_READER_MODE_SEND_SHALLOW_MOD (4<<0)
|
||||
#define FPGA_HF_READER_MODE_SNIFF_IQ (5<<0)
|
||||
#define FPGA_HF_READER_MODE_SNIFF_AMPLITUDE (6<<0)
|
||||
#define FPGA_HF_READER_MODE_SNIFF_PHASE (7<<0)
|
||||
#define FPGA_HF_READER_MODE_SEND_JAM (8<<0)
|
||||
|
||||
// Options for the HF reader, correlating against rx from tag
|
||||
#define FPGA_HF_READER_RX_XCORR_848_KHZ 0x1
|
||||
#define FPGA_HF_READER_RX_XCORR_SNOOP 0x2
|
||||
#define FPGA_HF_READER_RX_XCORR_QUARTER 0x4
|
||||
#define FPGA_HF_READER_SUBCARRIER_848_KHZ (0<<4)
|
||||
#define FPGA_HF_READER_SUBCARRIER_424_KHZ (1<<4)
|
||||
#define FPGA_HF_READER_SUBCARRIER_212_KHZ (2<<4)
|
||||
|
||||
// Options for the HF simulated tag, how to modulate
|
||||
#define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000
|
||||
@@ -112,9 +123,9 @@ void FpgaEnableTracing(void);
|
||||
void FpgaDisableTracing(void);
|
||||
void FpgaDownloadAndGo(int bitstream_version);
|
||||
// void FpgaGatherVersion(int bitstream_version, char *dst, int len);
|
||||
void FpgaSetupSsc(void);
|
||||
void FpgaSetupSsc(uint16_t fpga_mode);
|
||||
void SetupSpi(int mode);
|
||||
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
||||
bool FpgaSetupSscDma(uint8_t *buf, uint16_t len);
|
||||
void Fpga_print_status(void);
|
||||
int FpgaGetCurrent(void);
|
||||
void SetAdcMuxFor(uint32_t whichGpio);
|
||||
|
||||
+8
-7
@@ -41,12 +41,12 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len) {
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Set up the synchronous serial port
|
||||
FpgaSetupSsc();
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SNIFF);
|
||||
|
||||
// Setting Frame Mode For better performance on high speed data transfer.
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNIFF);
|
||||
SpinDelay(100);
|
||||
|
||||
*len = (BigBuf_max_traceLen() & 0xFFFE);
|
||||
@@ -114,17 +114,18 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len) {
|
||||
}
|
||||
|
||||
void HfPlotDownload(void) {
|
||||
uint8_t *buf = ToSend;
|
||||
uint8_t *this_buf = buf;
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
uint8_t *this_buf = ts->buf;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
FpgaSetupSsc();
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_GET_TRACE);
|
||||
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) this_buf; // start transfer to this memory address
|
||||
AT91C_BASE_PDC_SSC->PDC_RCR = PM3_CMD_DATA_SIZE; // transfer this many samples
|
||||
buf[0] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // clear receive register
|
||||
ts->buf[0] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // clear receive register
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // Start DMA transfer
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_GET_TRACE); // let FPGA transfer its internal Block-RAM
|
||||
@@ -132,7 +133,7 @@ void HfPlotDownload(void) {
|
||||
LED_B_ON();
|
||||
for (size_t i = 0; i < FPGA_TRACE_SIZE; i += PM3_CMD_DATA_SIZE) {
|
||||
// prepare next DMA transfer:
|
||||
uint8_t *next_buf = buf + ((i + PM3_CMD_DATA_SIZE) % (2 * PM3_CMD_DATA_SIZE));
|
||||
uint8_t *next_buf = ts->buf + ((i + PM3_CMD_DATA_SIZE) % (2 * PM3_CMD_DATA_SIZE));
|
||||
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)next_buf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = PM3_CMD_DATA_SIZE;
|
||||
|
||||
+17
-13
@@ -225,7 +225,7 @@ static bool I2C_WaitForSim(void) {
|
||||
// 8051 speaks with smart card.
|
||||
// 1000*50*3.07 = 153.5ms
|
||||
// 1byte transfer == 1ms with max frame being 256bytes
|
||||
if (!WaitSCL_H_delay(20 * 1000 * 50))
|
||||
if (!WaitSCL_H_delay(30 * 1000 * 50))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -631,7 +631,7 @@ int I2C_get_version(uint8_t *maj, uint8_t *min) {
|
||||
}
|
||||
|
||||
// Will read response from smart card module, retries 3 times to get the data.
|
||||
static bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) {
|
||||
bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) {
|
||||
|
||||
uint8_t i = 3;
|
||||
int16_t len = 0;
|
||||
@@ -658,7 +658,7 @@ static bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetATR(smart_card_atr_t *card_ptr) {
|
||||
bool GetATR(smart_card_atr_t *card_ptr, bool verbose) {
|
||||
|
||||
if (!card_ptr)
|
||||
return false;
|
||||
@@ -666,19 +666,18 @@ bool GetATR(smart_card_atr_t *card_ptr) {
|
||||
card_ptr->atr_len = 0;
|
||||
memset(card_ptr->atr, 0, sizeof(card_ptr->atr));
|
||||
|
||||
|
||||
// Send ATR
|
||||
// start [C0 01] stop start C1 len aa bb cc stop]
|
||||
I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN);
|
||||
|
||||
//wait for sim card to answer.
|
||||
// 1byte = 1ms , max frame 256bytes. SHould wait 256ms atleast just in case.
|
||||
if (!I2C_WaitForSim())
|
||||
// 1byte = 1ms , max frame 256bytes. Should wait 256ms atleast just in case.
|
||||
if (I2C_WaitForSim() == false)
|
||||
return false;
|
||||
|
||||
// read bytes from module
|
||||
uint8_t len = sizeof(card_ptr->atr);
|
||||
if (!sc_rx_bytes(card_ptr->atr, &len))
|
||||
if (sc_rx_bytes(card_ptr->atr, &len) == false)
|
||||
return false;
|
||||
|
||||
uint8_t pos_td = 1;
|
||||
@@ -706,17 +705,19 @@ bool GetATR(smart_card_atr_t *card_ptr) {
|
||||
}
|
||||
|
||||
card_ptr->atr_len = len;
|
||||
LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false);
|
||||
if (verbose) {
|
||||
LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SmartCardAtr(void) {
|
||||
smart_card_atr_t card;
|
||||
LED_D_ON();
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
I2C_Reset_EnterMainProgram();
|
||||
bool isOK = GetATR(&card);
|
||||
bool isOK = GetATR(&card, true);
|
||||
reply_mix(CMD_ACK, isOK, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t));
|
||||
set_tracing(false);
|
||||
LEDsoff();
|
||||
@@ -730,10 +731,13 @@ void SmartCardRaw(uint64_t arg0, uint64_t arg1, uint8_t *data) {
|
||||
uint8_t *resp = BigBuf_malloc(ISO7618_MAX_FRAME);
|
||||
smartcard_command_t flags = arg0;
|
||||
|
||||
if ((flags & SC_CONNECT))
|
||||
if ((flags & SC_CLEARLOG) == SC_CLEARLOG)
|
||||
clear_trace();
|
||||
|
||||
set_tracing(true);
|
||||
if ((flags & SC_LOG) == SC_LOG)
|
||||
set_tracing(true);
|
||||
else
|
||||
set_tracing(false);
|
||||
|
||||
if ((flags & SC_CONNECT)) {
|
||||
|
||||
@@ -741,7 +745,7 @@ void SmartCardRaw(uint64_t arg0, uint64_t arg1, uint8_t *data) {
|
||||
|
||||
if ((flags & SC_SELECT)) {
|
||||
smart_card_atr_t card;
|
||||
bool gotATR = GetATR(&card);
|
||||
bool gotATR = GetATR(&card, true);
|
||||
//reply_old(CMD_ACK, gotATR, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t));
|
||||
if (!gotATR)
|
||||
goto OUT;
|
||||
|
||||
+2
-1
@@ -33,8 +33,9 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
|
||||
int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address);
|
||||
bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address);
|
||||
|
||||
bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen);
|
||||
//
|
||||
bool GetATR(smart_card_atr_t *card_ptr);
|
||||
bool GetATR(smart_card_atr_t *card_ptr, bool verbose);
|
||||
|
||||
// generice functions
|
||||
void SmartCardAtr(void);
|
||||
|
||||
+1546
-2034
File diff suppressed because it is too large
Load Diff
+24
-11
@@ -1,6 +1,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Jonathan Westhues, Aug 2005
|
||||
// Gerhard de Koning Gans, April 2008, May 2011
|
||||
// Iceman, August 2020
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
@@ -12,18 +13,30 @@
|
||||
#define __ICLASS_H
|
||||
|
||||
#include "common.h"
|
||||
#include "pm3_cmd.h"
|
||||
|
||||
void RAMFUNC SniffIClass(void);
|
||||
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||
void SniffIClass(uint8_t jam_search_len, uint8_t *jam_search_string);
|
||||
void ReaderIClass(uint8_t arg0);
|
||||
void ReaderIClass_Replay(uint8_t arg0, uint8_t *mac);
|
||||
void iClass_Authentication(uint8_t *mac);
|
||||
void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain);
|
||||
void iClass_WriteBlock(uint8_t blockno, uint8_t *data);
|
||||
void iClass_ReadBlk(uint8_t blockno);
|
||||
bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len);
|
||||
void iClass_Dump(uint8_t blockno, uint8_t numblks);
|
||||
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
|
||||
void iClass_ReadCheck(uint8_t blockno, uint8_t keytype);
|
||||
void ReaderIClass_Replay(uint8_t *rnr, uint8_t *mac);
|
||||
|
||||
void iClass_WriteBlock(uint8_t *msg);
|
||||
void iClass_Dump(uint8_t *msg);
|
||||
|
||||
void iClass_Restore(uint8_t *msg);
|
||||
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
|
||||
|
||||
int do_iclass_simulation_nonsec(void);
|
||||
int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf);
|
||||
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||
void iclass_simulate(uint8_t sim_type, uint8_t num_csns, bool send_reply, uint8_t *datain, uint8_t *dataout, uint16_t *dataoutlen);
|
||||
|
||||
void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain);
|
||||
void iClass_Authentication(uint8_t *bytes);
|
||||
bool iclass_auth(iclass_auth_req_t *payload, uint8_t *out);
|
||||
|
||||
void iClass_ReadBlock(uint8_t *msg);
|
||||
bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time);
|
||||
|
||||
bool select_iclass_tag(uint8_t *card_data, bool use_credit_key, uint32_t *eof_time);
|
||||
bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr *hdr, uint32_t *start_time, uint32_t *eof_time, uint8_t *mac_out);
|
||||
#endif
|
||||
|
||||
+104
-91
@@ -585,10 +585,6 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||
uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
uint8_t *data = dmaBuf;
|
||||
|
||||
uint8_t previous_data = 0;
|
||||
int maxDataLen = 0, dataLen;
|
||||
bool TagIsActive = false;
|
||||
@@ -600,10 +596,14 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||
// Set up the demodulator for the reader -> tag commands
|
||||
Uart14aInit(receivedCmd, receivedCmdPar);
|
||||
|
||||
DbpString("Starting to sniff");
|
||||
Dbprintf("Starting to sniff. Press PM3 Button to stop.");
|
||||
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
dmabuf8_t *dma = get_dma8();
|
||||
uint8_t *data = dma->buf;
|
||||
|
||||
// Setup and start DMA.
|
||||
if (!FpgaSetupSscDma((uint8_t *) dmaBuf, DMA_BUFFER_SIZE)) {
|
||||
if (!FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE)) {
|
||||
if (DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting");
|
||||
return;
|
||||
}
|
||||
@@ -621,7 +621,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||
WDT_HIT();
|
||||
LED_A_ON();
|
||||
|
||||
int register readBufDataP = data - dmaBuf;
|
||||
int register readBufDataP = data - dma->buf;
|
||||
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
|
||||
if (readBufDataP <= dmaBufDataP)
|
||||
dataLen = dmaBufDataP - readBufDataP;
|
||||
@@ -640,13 +640,13 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||
|
||||
// primary buffer was stopped( <-- we lost data!
|
||||
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
|
||||
Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
|
||||
}
|
||||
// secondary buffer sets as primary, secondary buffer was stopped
|
||||
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
@@ -710,16 +710,15 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||
previous_data = *data;
|
||||
rx_samples++;
|
||||
data++;
|
||||
if (data == dmaBuf + DMA_BUFFER_SIZE) {
|
||||
data = dmaBuf;
|
||||
if (data == dma->buf + DMA_BUFFER_SIZE) {
|
||||
data = dma->buf;
|
||||
}
|
||||
} // end main loop
|
||||
|
||||
FpgaDisableTracing();
|
||||
|
||||
if (DBGLEVEL >= DBG_ERROR) {
|
||||
Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len);
|
||||
Dbprintf("traceLen=" _YELLOW_("%d")", Uart.output[0]="_YELLOW_("%08x"), BigBuf_get_traceLen(), (uint32_t)Uart.output[0]);
|
||||
Dbprintf("trace len = " _YELLOW_("%d"), BigBuf_get_traceLen());
|
||||
}
|
||||
switch_off();
|
||||
}
|
||||
@@ -729,62 +728,61 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||
//-----------------------------------------------------------------------------
|
||||
static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par, bool collision) {
|
||||
|
||||
//uint8_t localCol = 0;
|
||||
ToSendReset();
|
||||
tosend_reset();
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
// Correction bit, might be removed when not needed
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(1); // <-----
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(1); // <-----
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
|
||||
// Send startbit
|
||||
ToSend[++ToSendMax] = SEC_D;
|
||||
LastProxToAirDuration = 8 * ToSendMax - 4;
|
||||
ts->buf[++ts->max] = SEC_D;
|
||||
LastProxToAirDuration = 8 * ts->max - 4;
|
||||
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
uint8_t b = cmd[i];
|
||||
|
||||
// Data bits
|
||||
for (uint16_t j = 0; j < 8; j++) {
|
||||
//if (collision && (localCol >= colpos)){
|
||||
if (collision) {
|
||||
ToSend[++ToSendMax] = SEC_COLL;
|
||||
//localCol++;
|
||||
ts->buf[++ts->max] = SEC_COLL;
|
||||
} else {
|
||||
if (b & 1) {
|
||||
ToSend[++ToSendMax] = SEC_D;
|
||||
ts->buf[++ts->max] = SEC_D;
|
||||
} else {
|
||||
ToSend[++ToSendMax] = SEC_E;
|
||||
ts->buf[++ts->max] = SEC_E;
|
||||
}
|
||||
b >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (collision) {
|
||||
ToSend[++ToSendMax] = SEC_COLL;
|
||||
LastProxToAirDuration = 8 * ToSendMax;
|
||||
ts->buf[++ts->max] = SEC_COLL;
|
||||
LastProxToAirDuration = 8 * ts->max;
|
||||
} else {
|
||||
// Get the parity bit
|
||||
if (par[i >> 3] & (0x80 >> (i & 0x0007))) {
|
||||
ToSend[++ToSendMax] = SEC_D;
|
||||
LastProxToAirDuration = 8 * ToSendMax - 4;
|
||||
ts->buf[++ts->max] = SEC_D;
|
||||
LastProxToAirDuration = 8 * ts->max - 4;
|
||||
} else {
|
||||
ToSend[++ToSendMax] = SEC_E;
|
||||
LastProxToAirDuration = 8 * ToSendMax;
|
||||
ts->buf[++ts->max] = SEC_E;
|
||||
LastProxToAirDuration = 8 * ts->max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send stopbit
|
||||
ToSend[++ToSendMax] = SEC_F;
|
||||
ts->buf[++ts->max] = SEC_F;
|
||||
|
||||
// Convert from last byte pos to length
|
||||
ToSendMax++;
|
||||
ts->max++;
|
||||
}
|
||||
|
||||
static void CodeIso14443aAsTagEx(const uint8_t *cmd, uint16_t len, bool collision) {
|
||||
@@ -799,37 +797,39 @@ static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len) {
|
||||
static void Code4bitAnswerAsTag(uint8_t cmd) {
|
||||
uint8_t b = cmd;
|
||||
|
||||
ToSendReset();
|
||||
tosend_reset();
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
// Correction bit, might be removed when not needed
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(1); // 1
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
ToSendStuffBit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(1); // 1
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
tosend_stuffbit(0);
|
||||
|
||||
// Send startbit
|
||||
ToSend[++ToSendMax] = SEC_D;
|
||||
ts->buf[++ts->max] = SEC_D;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (b & 1) {
|
||||
ToSend[++ToSendMax] = SEC_D;
|
||||
LastProxToAirDuration = 8 * ToSendMax - 4;
|
||||
ts->buf[++ts->max] = SEC_D;
|
||||
LastProxToAirDuration = 8 * ts->max - 4;
|
||||
} else {
|
||||
ToSend[++ToSendMax] = SEC_E;
|
||||
LastProxToAirDuration = 8 * ToSendMax;
|
||||
ts->buf[++ts->max] = SEC_E;
|
||||
LastProxToAirDuration = 8 * ts->max;
|
||||
}
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
// Send stopbit
|
||||
ToSend[++ToSendMax] = SEC_F;
|
||||
ts->buf[++ts->max] = SEC_F;
|
||||
|
||||
// Convert from last byte pos to length
|
||||
ToSendMax++;
|
||||
ts->max++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -887,32 +887,36 @@ bool prepare_tag_modulation(tag_response_info_t *response_info, size_t max_buffe
|
||||
// Prepare the tag modulation bits from the message
|
||||
CodeIso14443aAsTag(response_info->response, response_info->response_n);
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
// Make sure we do not exceed the free buffer space
|
||||
if (ToSendMax > max_buffer_size) {
|
||||
if (ts->max > max_buffer_size) {
|
||||
Dbprintf("ToSend buffer, Out-of-bound, when modulating bits for tag answer:");
|
||||
Dbhexdump(response_info->response_n, response_info->response, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the byte array, used for this modulation to the buffer position
|
||||
memcpy(response_info->modulation, ToSend, ToSendMax);
|
||||
memcpy(response_info->modulation, ts->buf, ts->max);
|
||||
|
||||
// Store the number of bytes that were used for encoding/modulation and the time needed to transfer them
|
||||
response_info->modulation_n = ToSendMax;
|
||||
response_info->modulation_n = ts->max;
|
||||
response_info->ProxToAirDuration = LastProxToAirDuration;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *max_buffer_size) {
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
// Retrieve and store the current buffer index
|
||||
response_info->modulation = *buffer;
|
||||
|
||||
// Forward the prepare tag modulation function to the inner function
|
||||
if (prepare_tag_modulation(response_info, *max_buffer_size)) {
|
||||
// Update the free buffer offset and the remaining buffer size
|
||||
*buffer += ToSendMax;
|
||||
*max_buffer_size -= ToSendMax;
|
||||
*buffer += ts->max;
|
||||
*max_buffer_size -= ts->max;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -1499,10 +1503,13 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||
uint8_t pwd[4];
|
||||
emlGetMemBt(pwd, (pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd));
|
||||
if (memcmp(receivedCmd + 1, pwd, 4) == 0) {
|
||||
uint8_t cmd[4];
|
||||
emlGetMemBt(cmd, pages * 4 + MFU_DUMP_PREFIX_LENGTH, 2);
|
||||
AddCrc14A(cmd, sizeof(cmd) - 2);
|
||||
EmSendCmd(cmd, sizeof(cmd));
|
||||
uint8_t pack[4];
|
||||
emlGetMemBt(pack, pages * 4 + MFU_DUMP_PREFIX_LENGTH, 2);
|
||||
if (memcmp(pack, "\x00\x00\x00\x00", 4) == 0) {
|
||||
memcpy(pack, "\x80\x80\x00\x00", 4);
|
||||
}
|
||||
AddCrc14A(pack, sizeof(pack) - 2);
|
||||
EmSendCmd(pack, sizeof(pack));
|
||||
} else {
|
||||
EmSend4bit(CARD_NACK_NA);
|
||||
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Auth attempt: %08x", bytes_to_num(receivedCmd + 1, 4));
|
||||
@@ -1635,12 +1642,14 @@ static void PrepareDelayedTransfer(uint16_t delay) {
|
||||
for (uint16_t i = 0; i < delay; i++)
|
||||
bitmask |= (0x01 << i);
|
||||
|
||||
ToSend[ToSendMax++] = 0x00;
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
for (uint16_t i = 0; i < ToSendMax; i++) {
|
||||
uint8_t bits_to_shift = ToSend[i] & bitmask;
|
||||
ToSend[i] = ToSend[i] >> delay;
|
||||
ToSend[i] = ToSend[i] | (bits_shifted << (8 - delay));
|
||||
ts->buf[ts->max++] = 0x00;
|
||||
|
||||
for (uint16_t i = 0; i < ts->max; i++) {
|
||||
uint8_t bits_to_shift = ts->buf[i] & bitmask;
|
||||
ts->buf[i] = ts->buf[i] >> delay;
|
||||
ts->buf[i] = ts->buf[i] | (bits_shifted << (8 - delay));
|
||||
bits_shifted = bits_to_shift;
|
||||
}
|
||||
}
|
||||
@@ -1698,11 +1707,12 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
|
||||
static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *par) {
|
||||
int last = 0;
|
||||
|
||||
ToSendReset();
|
||||
tosend_reset();
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
// Start of Communication (Seq. Z)
|
||||
ToSend[++ToSendMax] = SEC_Z;
|
||||
LastProxToAirDuration = 8 * (ToSendMax + 1) - 6;
|
||||
ts->buf[++ts->max] = SEC_Z;
|
||||
LastProxToAirDuration = 8 * (ts->max + 1) - 6;
|
||||
|
||||
size_t bytecount = nbytes(bits);
|
||||
// Generate send structure for the data bits
|
||||
@@ -1714,17 +1724,17 @@ static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, cons
|
||||
for (j = 0; j < bitsleft; j++) {
|
||||
if (b & 1) {
|
||||
// Sequence X
|
||||
ToSend[++ToSendMax] = SEC_X;
|
||||
LastProxToAirDuration = 8 * (ToSendMax + 1) - 2;
|
||||
ts->buf[++ts->max] = SEC_X;
|
||||
LastProxToAirDuration = 8 * (ts->max + 1) - 2;
|
||||
last = 1;
|
||||
} else {
|
||||
if (last == 0) {
|
||||
// Sequence Z
|
||||
ToSend[++ToSendMax] = SEC_Z;
|
||||
LastProxToAirDuration = 8 * (ToSendMax + 1) - 6;
|
||||
ts->buf[++ts->max] = SEC_Z;
|
||||
LastProxToAirDuration = 8 * (ts->max + 1) - 6;
|
||||
} else {
|
||||
// Sequence Y
|
||||
ToSend[++ToSendMax] = SEC_Y;
|
||||
ts->buf[++ts->max] = SEC_Y;
|
||||
last = 0;
|
||||
}
|
||||
}
|
||||
@@ -1736,17 +1746,17 @@ static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, cons
|
||||
// Get the parity bit
|
||||
if (par[i >> 3] & (0x80 >> (i & 0x0007))) {
|
||||
// Sequence X
|
||||
ToSend[++ToSendMax] = SEC_X;
|
||||
LastProxToAirDuration = 8 * (ToSendMax + 1) - 2;
|
||||
ts->buf[++ts->max] = SEC_X;
|
||||
LastProxToAirDuration = 8 * (ts->max + 1) - 2;
|
||||
last = 1;
|
||||
} else {
|
||||
if (last == 0) {
|
||||
// Sequence Z
|
||||
ToSend[++ToSendMax] = SEC_Z;
|
||||
LastProxToAirDuration = 8 * (ToSendMax + 1) - 6;
|
||||
ts->buf[++ts->max] = SEC_Z;
|
||||
LastProxToAirDuration = 8 * (ts->max + 1) - 6;
|
||||
} else {
|
||||
// Sequence Y
|
||||
ToSend[++ToSendMax] = SEC_Y;
|
||||
ts->buf[++ts->max] = SEC_Y;
|
||||
last = 0;
|
||||
}
|
||||
}
|
||||
@@ -1756,16 +1766,16 @@ static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, cons
|
||||
// End of Communication: Logic 0 followed by Sequence Y
|
||||
if (last == 0) {
|
||||
// Sequence Z
|
||||
ToSend[++ToSendMax] = SEC_Z;
|
||||
LastProxToAirDuration = 8 * (ToSendMax + 1) - 6;
|
||||
ts->buf[++ts->max] = SEC_Z;
|
||||
LastProxToAirDuration = 8 * (ts->max + 1) - 6;
|
||||
} else {
|
||||
// Sequence Y
|
||||
ToSend[++ToSendMax] = SEC_Y;
|
||||
ts->buf[++ts->max] = SEC_Y;
|
||||
}
|
||||
ToSend[++ToSendMax] = SEC_Y;
|
||||
ts->buf[++ts->max] = SEC_Y;
|
||||
|
||||
// Convert to length of command:
|
||||
ToSendMax++;
|
||||
ts->max++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1967,7 +1977,8 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
|
||||
|
||||
int EmSend4bit(uint8_t resp) {
|
||||
Code4bitAnswerAsTag(resp);
|
||||
int res = EmSendCmd14443aRaw(ToSend, ToSendMax);
|
||||
tosend_t *ts = get_tosend();
|
||||
int res = EmSendCmd14443aRaw(ts->buf, ts->max);
|
||||
// do the tracing for the previous reader request and this tag answer:
|
||||
uint8_t par[1] = {0x00};
|
||||
GetParity(&resp, 1, par);
|
||||
@@ -1988,7 +1999,9 @@ int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par) {
|
||||
}
|
||||
int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision) {
|
||||
CodeIso14443aAsTagPar(resp, respLen, par, collision);
|
||||
int res = EmSendCmd14443aRaw(ToSend, ToSendMax);
|
||||
tosend_t *ts = get_tosend();
|
||||
int res = EmSendCmd14443aRaw(ts->buf, ts->max);
|
||||
|
||||
// do the tracing for the previous reader request and this tag answer:
|
||||
EmLogTrace(Uart.output,
|
||||
Uart.len,
|
||||
@@ -2149,7 +2162,8 @@ void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t
|
||||
|
||||
CodeIso14443aBitsAsReaderPar(frame, bits, par);
|
||||
// Send command to tag
|
||||
TransmitFor14443a(ToSend, ToSendMax, timing);
|
||||
tosend_t *ts = get_tosend();
|
||||
TransmitFor14443a(ts->buf, ts->max, timing);
|
||||
if (g_trigger) LED_A_ON();
|
||||
|
||||
LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart << 4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration) << 4) + DELAY_ARM2AIR_AS_READER, par, true);
|
||||
@@ -2527,7 +2541,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
// Set up the synchronous serial port
|
||||
FpgaSetupSsc();
|
||||
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
|
||||
// connect Demodulated Signal to ADC:
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
@@ -2551,7 +2565,6 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
|
||||
hf_field_active = true;
|
||||
}
|
||||
|
||||
|
||||
void hf_field_off(void) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
|
||||
+445
-512
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -28,7 +28,7 @@
|
||||
|
||||
void iso14443b_setup(void);
|
||||
uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response);
|
||||
uint8_t iso14443b_select_card(iso14b_card_select_t *card);
|
||||
int iso14443b_select_card(iso14b_card_select_t *card);
|
||||
uint8_t iso14443b_select_card_srx(iso14b_card_select_t *card);
|
||||
|
||||
void SimulateIso14443bTag(uint32_t pupi);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user