summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openpicc/Makefile4
-rw-r--r--openpicc/application/iso14443.h1
-rw-r--r--openpicc/application/iso14443_layer2a.c14
-rw-r--r--openpicc/application/iso14443a_diffmiller.c16
-rw-r--r--openpicc/application/iso14443a_pretender.c63
-rw-r--r--openpicc/application/main.c6
-rw-r--r--openpicc/application/ssc.c2
7 files changed, 67 insertions, 39 deletions
diff --git a/openpicc/Makefile b/openpicc/Makefile
index b4270ab..e11eae5 100644
--- a/openpicc/Makefile
+++ b/openpicc/Makefile
@@ -110,9 +110,9 @@ ARM_SRC= \
os/core/MemMang/heap_2.c \
os/usb/USB-CDC.c \
os/usb/USBIsr.c \
- application/iso14443_sniffer.c \
+ application/iso14443a_pretender.c \
+# application/iso14443_sniffer.c \
# application/tc_sniffer.c \
-# application/iso14443a_pretender.c \
# application/iso14443_layer3a.c
#
diff --git a/openpicc/application/iso14443.h b/openpicc/application/iso14443.h
index a2d7458..e2418ca 100644
--- a/openpicc/application/iso14443.h
+++ b/openpicc/application/iso14443.h
@@ -80,6 +80,7 @@ typedef enum {
FRAME_PENDING, /* Frame is currently filled by Rx */
FRAME_FULL, /* Frame has been filled by Rx */
FRAME_PROCESSING,/* The frame is currently processed by the consumer */
+ FRAME_PREFILLED, /* The frame has been prefilled for later usage (only used for TX) */
} iso14443_frame_state_t;
diff --git a/openpicc/application/iso14443_layer2a.c b/openpicc/application/iso14443_layer2a.c
index 65d5d6a..2288eaa 100644
--- a/openpicc/application/iso14443_layer2a.c
+++ b/openpicc/application/iso14443_layer2a.c
@@ -132,7 +132,8 @@ int iso14443_transmit(ssc_dma_tx_buffer_t *buffer, unsigned int fdt, u_int8_t as
clock_switch(CLOCK_SELECT_CARRIER);
ssc_set_gate(0);
tc_fdt_set(fdt);
- tc_cdiv_set_divider(8); // FIXME Magic hardcoded number
+ // We'll keep the divider at 8
+ //tc_cdiv_set_divider(8); // FIXME Magic hardcoded number
if(!async) {
/* FIXME Implement */
@@ -184,6 +185,11 @@ u_int8_t iso14443_get_fast_receive(void)
static void iso14443_ssc_callback(ssc_callback_reason reason, void *data)
{
+ if( reason == SSC_CALLBACK_SETUP ) {
+ // We'll keep the divider at 8
+ tc_cdiv_set_divider(8); // FIXME Magic hardcoded number
+ }
+
if(reason == SSC_CALLBACK_RX_FRAME_BEGIN) {
/* Busy loop for the frame end */
int *end_asserted = data, i=0;
@@ -217,7 +223,8 @@ static void iso14443_ssc_callback(ssc_callback_reason reason, void *data)
clock_switch(CLOCK_SELECT_CARRIER);
ssc_set_gate(1);
tc_fdt_set(0xff00);
- tc_cdiv_set_divider(RX_DIVIDER);
+ // We'll keep the divider at 8
+ //tc_cdiv_set_divider(RX_DIVIDER);
tc_cdiv_sync_reset();
#if 1
int old=usb_print_set_default_flush(0);
@@ -243,7 +250,8 @@ static void iso14443_tc_recv_callback(tc_recv_callback_reason reason, void *data
clock_switch(CLOCK_SELECT_CARRIER);
ssc_set_gate(1);
tc_fdt_set(0xff00);
- tc_cdiv_set_divider(RX_DIVIDER);
+ // We'll keep the divider at 8
+ //tc_cdiv_set_divider(RX_DIVIDER);
tc_cdiv_sync_reset();
}
}
diff --git a/openpicc/application/iso14443a_diffmiller.c b/openpicc/application/iso14443a_diffmiller.c
index d73bf95..a36ea6b 100644
--- a/openpicc/application/iso14443a_diffmiller.c
+++ b/openpicc/application/iso14443a_diffmiller.c
@@ -101,6 +101,7 @@ struct diffmiller_state {
u_int32_t counter;
u_int16_t byte,crc;
u_int8_t parity;
+ u_int8_t last_data_bit;
struct {
u_int8_t in_frame:1;
u_int8_t frame_finished:1;
@@ -155,7 +156,7 @@ static inline void append_to_frame(struct diffmiller_state *const state,
}
-static inline void end_frame(struct diffmiller_state * const state, const u_int32_t counter)
+static inline void end_frame(struct diffmiller_state * const state, const u_int32_t counter, const int last_data_bit)
{
if(state->frame != NULL) {
if(counter > 0) {
@@ -167,6 +168,11 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3
else
state->frame->parameters.a.crc = CRC_ERROR;
+ if(last_data_bit)
+ state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_1;
+ else
+ state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_0;
+
state->flags.frame_finished = 1;
}
}
@@ -175,6 +181,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3
//#define PRINT_BIT(a) usb_print_string_f(a,0)
#define DO_BIT_0 { \
+ last_data_bit = 0; \
if(++counter==9) { \
append_to_frame(state, state->byte, 0, 8); \
counter=state->byte=state->parity=0; \
@@ -183,6 +190,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3
}
#define DO_BIT_1 { \
+ last_data_bit = 1; \
if(counter<8) { \
state->byte |= (1<<counter); \
state->parity ^= 1; \
@@ -218,7 +226,7 @@ static inline void end_frame(struct diffmiller_state * const state, const u_int3
in_frame = 0; \
} else { \
if(last_bit == BIT_0) { \
- end_frame(state, counter); \
+ end_frame(state, counter, last_data_bit); \
PRINT_BIT(" EOF\n"); \
last_bit = BIT_EOF; \
in_frame = 0; \
@@ -255,6 +263,7 @@ int iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_
int in_frame = state->flags.in_frame;
int error = state->flags.error;
int counter = state->counter;
+ int last_data_bit = state->last_data_bit;
for(; *offset < buflen; ) {
int delta;
@@ -324,6 +333,7 @@ int iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_
state->old_state = old_state;
state->last_bit = last_bit;
state->counter = counter;
+ state->last_data_bit = last_data_bit;
state->flags.in_frame = in_frame;
state->flags.error = error;
@@ -338,7 +348,7 @@ int iso14443a_diffmiller_assert_frame_ended(struct diffmiller_state * const stat
if(state->frame != NULL && state->frame != frame) return -EINVAL;
state->frame = frame;
- end_frame(state, state->counter);
+ end_frame(state, state->counter, state->last_data_bit);
PRINT_BIT(" EOF2\n");
state->flags.in_frame = 0;
diff --git a/openpicc/application/iso14443a_pretender.c b/openpicc/application/iso14443a_pretender.c
index 03fb12d..c6f54cc 100644
--- a/openpicc/application/iso14443a_pretender.c
+++ b/openpicc/application/iso14443a_pretender.c
@@ -42,6 +42,7 @@ extern volatile int fdt_offset;
static const iso14443_frame ATQA_FRAME = {
TYPE_A,
+ FRAME_PREFILLED,
{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
2,
0, 0,
@@ -51,6 +52,7 @@ static const iso14443_frame ATQA_FRAME = {
static const iso14443_frame UID_FRAME = {
TYPE_A,
+ FRAME_PREFILLED,
{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
5,
0, 0,
@@ -60,6 +62,7 @@ static const iso14443_frame UID_FRAME = {
static const iso14443_frame ATS_FRAME = {
TYPE_A,
+ FRAME_PREFILLED,
{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
3,
0, 0,
@@ -69,6 +72,7 @@ static const iso14443_frame ATS_FRAME = {
static const iso14443_frame NONCE_FRAME = {
TYPE_A,
+ FRAME_PREFILLED,
{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
4,
0, 0,
@@ -79,10 +83,11 @@ static const iso14443_frame NONCE_FRAME = {
#define FRAME_SIZE(bytes) (2* (1+(9*bytes)+1) )
#define SIZED_BUFFER(bytes) struct { int len; u_int8_t data[FRAME_SIZE(bytes)]; }
+#define BYTES_AND_BITS(bytes,bits) (bytes*9+bits)
static ssc_dma_tx_buffer_t ATQA_BUFFER, UID_BUFFER, ATS_BUFFER, NONCE_BUFFER;
-static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq)
+static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *frame, u_int8_t in_irq)
{
(void)buffer; (void)in_irq;
unsigned int buffy=0;
@@ -91,24 +96,30 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq)
ssc_dma_tx_buffer_t *tx_buffer=NULL;
int fdt = 0;
- switch(buffer->len_transfers) {
- case 3: case 4: /* REQA (7 bits) */
- //case 7: case 8: case 9:
- case 11:
+ switch(frame->parameters.a.last_bit) {
+ case ISO14443A_LAST_BIT_0:
+ fdt = 20;
+ break;
+ case ISO14443A_LAST_BIT_1:
+ fdt = 84;
+ break;
+ case ISO14443A_LAST_BIT_NONE:
+ fdt = 0;
+ break;
+ }
+
+ switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) {
+ case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */
tx_buffer = &ATQA_BUFFER;
- fdt = 1172;
+ fdt += 9*128;
break;
- case 6: case 7: /* ANTICOL (2 bytes) */
- case 8: case 9:
+ case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */
tx_buffer = &UID_BUFFER;
- fdt = 1172;
- case 21: case 22: /* SELECT (9 bytes) */
- tx_buffer = &ATS_BUFFER;
- fdt = 1172;
+ fdt += 9*128;
break;
- case 577:
- usb_print_string_f("f", 0);
- buffy=(unsigned int)buffer;
+ case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */
+ tx_buffer = &ATS_BUFFER;
+ fdt += 9*128;
break;
}
@@ -116,7 +127,6 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, u_int8_t in_irq)
//fdt += 3*128;
fdt += fdt_offset;
-
if(tx_buffer != NULL) {
tx_buffer->state = SSC_FULL;
if( iso14443_transmit(tx_buffer, fdt, 1, 0) < 0) {
@@ -208,28 +218,25 @@ prefill_failed:
#define DETECTED_MIFARE 4
while(true) {
- ssc_dma_rx_buffer_t *buffer = 0;
- res = iso14443_receive(fast_receive_callback, &buffer, 1000 * portTICK_RATE_MS);
+ iso14443_frame *frame = 0;
+ res = iso14443_receive(fast_receive_callback, &frame, 1000 * portTICK_RATE_MS);
if(res >= 0) {
- DumpUIntToUSB(buffer->len_transfers);
- DumpStringToUSB("\n\r");
-
- switch(buffer->len_transfers) {
- case 3: case 4: /* REQA (7 bits) */
+ switch(BYTES_AND_BITS(frame->numbytes, frame->numbits) ) {
+ case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */
current_detected |= DETECTED_14443A_3;
break;
- case 6: case 7: /* ANTICOL (2 bytes) */
- case 22: /* SELECT (9 bytes) */
+ case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */
+ case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */
current_detected |= DETECTED_14443A_3;
break;
- case 10: case 11: /* AUTH1A (or any other four byte frame) */
- case 19: case 20: /* AUTH2 (8 bytes) */
+ case BYTES_AND_BITS(4, 0): /* AUTH1A (or any other four byte frame) */
+ case BYTES_AND_BITS(8, 0): /* AUTH2 (8 bytes) */
current_detected |= DETECTED_MIFARE;
break;
}
portENTER_CRITICAL();
- buffer->state = SSC_FREE;
+ frame->state = FRAME_FREE;
portEXIT_CRITICAL();
} else {
if(res != -ETIMEDOUT) {
diff --git a/openpicc/application/main.c b/openpicc/application/main.c
index a082933..d9b0ad5 100644
--- a/openpicc/application/main.c
+++ b/openpicc/application/main.c
@@ -211,10 +211,10 @@ int main (void)
NULL, TASK_USB_PRIORITY, NULL);
/*xTaskCreate (iso14443_layer3a_state_machine, (signed portCHAR *) "ISO14443A-3", TASK_ISO_STACK,
NULL, TASK_ISO_PRIORITY, NULL);*/
- xTaskCreate (iso14443_sniffer, (signed portCHAR *) "ISO14443-SNIFF", TASK_ISO_STACK,
- NULL, TASK_ISO_PRIORITY, NULL);
- /*xTaskCreate (iso14443a_pretender, (signed portCHAR *) "ISO14443A-PRETEND", TASK_ISO_STACK,
+ /*xTaskCreate (iso14443_sniffer, (signed portCHAR *) "ISO14443-SNIFF", TASK_ISO_STACK,
NULL, TASK_ISO_PRIORITY, NULL);*/
+ xTaskCreate (iso14443a_pretender, (signed portCHAR *) "ISO14443A-PRETEND", TASK_ISO_STACK,
+ NULL, TASK_ISO_PRIORITY, NULL);
/*xTaskCreate (tc_sniffer, (signed portCHAR *) "RFID-SNIFFER", TASK_ISO_STACK,
NULL, TASK_ISO_PRIORITY, NULL);*/
diff --git a/openpicc/application/ssc.c b/openpicc/application/ssc.c
index 9f30400..78f2960 100644
--- a/openpicc/application/ssc.c
+++ b/openpicc/application/ssc.c
@@ -234,7 +234,9 @@ static int __ramfunc _ssc_tx_irq(u_int32_t sr, portBASE_TYPE task_woken)
/* Also set SSC mode to continous
* FIXME BUG: This will somehow drop some samples or something on the SSC*/
+ vLedSetGreen(0);
sh->ssc->SSC_TCMR = (sh->ssc->SSC_TCMR & ~AT91C_SSC_START) | AT91C_SSC_START_CONTINOUS;
+ vLedSetGreen(1);
if(sh->callback)
sh->callback(SSC_CALLBACK_TX_FRAME_BEGIN, NULL);
personal git repositories of Harald Welte. Your mileage may vary