summaryrefslogtreecommitdiff
path: root/openpicc/application/tc_sniffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'openpicc/application/tc_sniffer.c')
-rw-r--r--openpicc/application/tc_sniffer.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/openpicc/application/tc_sniffer.c b/openpicc/application/tc_sniffer.c
index abf04c0..a77d790 100644
--- a/openpicc/application/tc_sniffer.c
+++ b/openpicc/application/tc_sniffer.c
@@ -41,11 +41,18 @@
#include "usb_print.h"
#include "cmd.h"
#include "pio_irq.h"
+#include "led.h"
+#include "clock_switch.h"
+
+#include "iso14443a_diffmiller.h"
/* Problem: We want to receive data from the FIQ without locking (the FIQ must not be blocked ever)
* Strategy: Double buffering.
*/
+struct diffmiller_state *decoder;
+iso14443_frame rx_frame;
+
#define BUFSIZE 1024
#define WAIT_TICKS (20*portTICK_RATE_MS)
typedef struct {
@@ -57,18 +64,63 @@ fiq_buffer_t fiq_buffers[2];
fiq_buffer_t *tc_sniffer_next_buffer_for_fiq = 0;
portBASE_TYPE currently_sniffing = 0;
-enum { NONE, REQUEST_START, REQUEST_STOP } request_change = NONE;
+enum { NONE, REQUEST_START, REQUEST_STOP } request_change = REQUEST_START;
+
+//#define PRINT_TIMES
+//#define USE_BINARY_PROTOCOL
#define MIN(a, b) ((a)>(b)?(b):(a))
+static int overruns = 0;
void flush_buffer(fiq_buffer_t *buffer)
{
/* Write all data from the given buffer out, then zero the count */
if(buffer->count > 0) {
+ if(buffer->count >= BUFSIZE) {
+ DumpStringToUSB("Warning: Possible buffer overrun detected\n\r");
+ overruns++;
+ }
+ buffer->count = MIN(buffer->count, BUFSIZE);
+#ifdef USE_BINARY_PROTOCOL
vUSBSendBuffer_blocking((unsigned char*)(&(buffer->data[0])), 0, MIN(buffer->count,BUFSIZE)*4, WAIT_TICKS);
if(buffer->count >= BUFSIZE)
vUSBSendBuffer_blocking((unsigned char*)"////", 0, 4, WAIT_TICKS);
else
vUSBSendBuffer_blocking((unsigned char*)"____", 0, 4, WAIT_TICKS);
+#elif defined(PRINT_TIMES)
+ unsigned int i=0;
+ for(i=0; i<buffer->count; i++) {
+ DumpUIntToUSB(buffer->data[i]);
+ DumpStringToUSB(" ");
+ }
+ DumpStringToUSB("\n\r");
+#else
+ unsigned int offset = 0;
+ while(offset < buffer->count) {
+ int ret = iso14443a_decode_diffmiller(decoder, &rx_frame, buffer->data, &offset, buffer->count);
+ DumpStringToUSB("\n\r");
+ if(ret < 0) {
+ DumpStringToUSB("-");
+ DumpUIntToUSB(-ret);
+ } else {
+ DumpUIntToUSB(ret);
+ }
+ DumpStringToUSB(" ");
+ DumpUIntToUSB(offset); DumpStringToUSB(" "); DumpUIntToUSB(buffer->count); DumpStringToUSB(" "); DumpUIntToUSB(overruns);
+ DumpStringToUSB("\n\r");
+ if(ret >= 0) {
+ DumpStringToUSB("Frame finished, ");
+ DumpUIntToUSB(rx_frame.numbytes);
+ DumpStringToUSB(" bytes, ");
+ DumpUIntToUSB(rx_frame.numbits);
+ DumpStringToUSB(" bits\n\r");
+ switch(rx_frame.parameters.a.crc) {
+ case CRC_OK: DumpStringToUSB("CRC OK\n\r"); break;
+ case CRC_ERROR: DumpStringToUSB("CRC ERROR\n\r"); break;
+ case CRC_UNCALCULATED: DumpStringToUSB("CRC UNCALCULATED\n\r"); break;
+ }
+ }
+ }
+#endif
buffer->count = 0;
}
}
@@ -93,6 +145,8 @@ void tc_sniffer (void *pvParameters)
load_mod_init();
load_mod_level(0);
+ clock_switch_init();
+
pll_init();
pll_inhibit(0);
@@ -103,6 +157,22 @@ void tc_sniffer (void *pvParameters)
/* Wait for the USB and CMD threads to start up */
vTaskDelay(1000 * portTICK_RATE_MS);
+ if(OPENPICC->features.clock_switching) {
+ clock_switch(CLOCK_SELECT_CARRIER);
+ decoder = iso14443a_init_diffmiller(0);
+ } else {
+ switch(OPENPICC->default_clock) {
+ case CLOCK_SELECT_CARRIER:
+ decoder = iso14443a_init_diffmiller(0);
+ break;
+ case CLOCK_SELECT_PLL:
+ decoder = iso14443a_init_diffmiller(1);
+ break;
+ }
+ }
+
+ if(!decoder) vLedHaltBlinking(1);
+
// The change interrupt is going to be handled by the FIQ
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPICC_SSC_DATA);
pio_irq_enable(OPENPICC_SSC_DATA);
@@ -125,16 +195,20 @@ void tc_sniffer (void *pvParameters)
tc_sniffer_next_buffer_for_fiq = 0;
memset(fiq_buffers, 0, sizeof(fiq_buffers));
current = 0;
+#ifdef USE_BINARY_PROTOCOL
vUSBSendBuffer_blocking((unsigned char *)"----", 0, 4, WAIT_TICKS);
usb_print_set_force_silence(0);
+#endif
} else vTaskDelay(2* portTICK_RATE_MS);
} else {
// Do nothing, wait longer
if(request_change == REQUEST_START) {
// Prevent usb_print code from barging in
+#ifdef USE_BINARY_PROTOCOL
usb_print_set_force_silence(1);
vUSBSendBuffer_blocking((unsigned char *)"----", 0, 4, WAIT_TICKS);
+#endif
currently_sniffing = 1;
request_change = NONE;
} else vTaskDelay(100 * portTICK_RATE_MS);
personal git repositories of Harald Welte. Your mileage may vary