From 3ee3c4a649545d1f132bca61cc7484f0d5c92638 Mon Sep 17 00:00:00 2001
From: henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>
Date: Wed, 5 Mar 2008 01:59:58 +0000
Subject: Copy over the relevant changes from the sniffonly branch pending
 integration

git-svn-id: https://svn.openpcd.org:2342/trunk@442 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
---
 openpicc/application/cmd.c        |   7 +-
 openpicc/application/main.c       |  10 ++-
 openpicc/application/ssc.c        |   3 -
 openpicc/application/tc_sniffer.c | 143 ++++++++++++++++++++++++++++++++++++++
 openpicc/application/tc_sniffer.h |   7 ++
 openpicc/application/usb_print.c  |  11 ++-
 openpicc/application/usb_print.h  |   1 +
 7 files changed, 174 insertions(+), 8 deletions(-)
 create mode 100644 openpicc/application/tc_sniffer.c
 create mode 100644 openpicc/application/tc_sniffer.h

(limited to 'openpicc/application')

diff --git a/openpicc/application/cmd.c b/openpicc/application/cmd.c
index 47bbec5..50b59d3 100644
--- a/openpicc/application/cmd.c
+++ b/openpicc/application/cmd.c
@@ -21,6 +21,7 @@
 #include "ssc.h"
 #include "usb_print.h"
 #include "load_modulation.h"
+#include "tc_sniffer.h"
 
 xQueueHandle xCmdQueue;
 xTaskHandle xCmdTask;
@@ -45,7 +46,7 @@ static const portBASE_TYPE USE_COLON_FOR_LONG_COMMANDS = 0;
 /* When not USE_COLON_FOR_LONG_COMMANDS then short commands will be recognized by including
  * their character in the string SHORT_COMMANDS
  * */
-static const char *SHORT_COMMANDS = "!pc+-l?hq9fjka#i";
+static const char *SHORT_COMMANDS = "!prc+-l?hq9fjka#i";
 /* Note that the long/short command distinction only applies to the USB serial console
  * */
 
@@ -241,6 +242,9 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) {
 		case 'P':
 		    print_pio();
 		    break;
+		case 'R':
+			start_stop_sniffing();
+			break;
 		case 'C':
 		    DumpStringToUSB(
 			" *****************************************************\n\r"
@@ -442,6 +446,7 @@ void prvExecCommand(u_int32_t cmd, portCHAR *args) {
 		    " * #    - switch clock\n\r"
 			" * l    - cycle LEDs\n\r"
 			" * p    - print PIO pins\n\r"
+		    " * r    - start/stop receiving\n\r"
 			" * z 0/1- enable or disable tc_cdiv_sync\n\r"
 			" * i    - inhibit/uninhibit PLL\n\r"
 			" * !    - reset tc_cdiv_sync\n\r"
diff --git a/openpicc/application/main.c b/openpicc/application/main.c
index 2397c61..9b81aea 100644
--- a/openpicc/application/main.c
+++ b/openpicc/application/main.c
@@ -51,6 +51,7 @@
 #include "iso14443_sniffer.h"
 #include "iso14443a_pretender.h"
 #include "decoder.h"
+#include "tc_sniffer.h"
 
 static inline int detect_board(void)
 {
@@ -210,9 +211,12 @@ int main (void)
 	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,
-	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);
+
+	    
     xTaskCreate (vUSBCDCTask, (signed portCHAR *) "USB", TASK_USB_STACK,
 	NULL, TASK_USB_PRIORITY, NULL);
 	
diff --git a/openpicc/application/ssc.c b/openpicc/application/ssc.c
index 50d416b..a490d42 100644
--- a/openpicc/application/ssc.c
+++ b/openpicc/application/ssc.c
@@ -43,9 +43,6 @@
 
 #define PRINT_DEBUG 0
 
-// BROKEN Old FIQ code
-int ssc_tx_pending=0, ssc_tx_fiq_fdt_cdiv=0, ssc_tx_fiq_fdt_ssc=0;
-
 struct _ssc_handle {
 	enum ssc_mode mode;
 	const struct openpicc_hardware *openpicc;
diff --git a/openpicc/application/tc_sniffer.c b/openpicc/application/tc_sniffer.c
new file mode 100644
index 0000000..abf04c0
--- /dev/null
+++ b/openpicc/application/tc_sniffer.c
@@ -0,0 +1,143 @@
+/***************************************************************
+ *
+ * OpenPICC - T/C based dumb sniffer
+ * 
+ * TC2 will reset its value on each falling edge of SSC_DATA, we
+ * will have the FIQ store the TC2 value on each rising edge of
+ * SSC_DATA. This will give us a count of carrier cycles between
+ * modulation pauses which should be enough information to decode
+ * the modified miller encoding.
+ *
+ * Copyright 2008 Henryk Plötz <henryk@ploetzli.ch>
+ *
+ ***************************************************************
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; version 2.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*/
+
+#include <FreeRTOS.h>
+#include <openpicc.h>
+#include <task.h>
+#include <string.h>
+
+#include <USB-CDC.h>
+
+#include "tc_sniffer.h"
+#include "load_modulation.h"
+#include "pll.h"
+#include "tc_fdt.h"
+#include "usb_print.h"
+#include "cmd.h"
+#include "pio_irq.h"
+
+/* Problem: We want to receive data from the FIQ without locking (the FIQ must not be blocked ever)
+ * Strategy: Double buffering.
+ */
+
+#define BUFSIZE 1024
+#define WAIT_TICKS (20*portTICK_RATE_MS)
+typedef struct {
+	u_int32_t count;
+	u_int32_t data[BUFSIZE];
+} fiq_buffer_t;
+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;
+
+#define MIN(a, b) ((a)>(b)?(b):(a))
+void flush_buffer(fiq_buffer_t *buffer)
+{
+	/* Write all data from the given buffer out, then zero the count */
+	if(buffer->count > 0) {
+		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);
+		buffer->count = 0;
+	}
+}
+
+void start_stop_sniffing(void)
+{
+	if(currently_sniffing)
+		request_change = REQUEST_STOP;
+	else
+		request_change = REQUEST_START;
+}
+
+void tc_sniffer (void *pvParameters)
+{
+	(void)pvParameters;
+	
+	/* Disable load modulation circuitry
+	 * (Must be done explicitly, because the default state is pull-up high, leading
+	 * to a constant modulation output which prevents reception. I've been bitten by
+	 * this more than once.)
+	 */
+	load_mod_init();
+	load_mod_level(0);
+	
+	pll_init();
+	pll_inhibit(0);
+	
+	tc_fdt_init();
+	
+	memset(fiq_buffers, 0, sizeof(fiq_buffers));
+	
+	/* Wait for the USB and CMD threads to start up */
+	vTaskDelay(1000 * portTICK_RATE_MS);
+	
+	// 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);
+	
+	int current = 0;
+	while(1) {
+		/* Main loop of the sniffer */
+		
+		if(currently_sniffing) {
+			int next = (current+1)%(sizeof(fiq_buffers)/sizeof(fiq_buffers[0]));
+			flush_buffer( &fiq_buffers[next] );
+			/* The buffer designated by next is now empty, give it to the fiq,
+			 * we'll just guess that this write is atomic */ 
+			tc_sniffer_next_buffer_for_fiq = &fiq_buffers[current=next];
+
+			if(request_change == REQUEST_STOP) {
+				currently_sniffing = 0;
+				request_change = NONE;
+				
+				tc_sniffer_next_buffer_for_fiq = 0;
+				memset(fiq_buffers, 0, sizeof(fiq_buffers));
+				current = 0;
+				vUSBSendBuffer_blocking((unsigned char *)"----", 0, 4, WAIT_TICKS);
+				usb_print_set_force_silence(0);
+			} else vTaskDelay(2* portTICK_RATE_MS);
+		} else {
+			// Do nothing, wait longer
+			
+			if(request_change == REQUEST_START) {
+				// Prevent usb_print code from barging in
+				usb_print_set_force_silence(1);
+				vUSBSendBuffer_blocking((unsigned char *)"----", 0, 4, WAIT_TICKS);
+				currently_sniffing = 1;
+				request_change = NONE;
+			} else vTaskDelay(100 * portTICK_RATE_MS);
+		}
+	}
+}
diff --git a/openpicc/application/tc_sniffer.h b/openpicc/application/tc_sniffer.h
new file mode 100644
index 0000000..e3a1c29
--- /dev/null
+++ b/openpicc/application/tc_sniffer.h
@@ -0,0 +1,7 @@
+#ifndef TC_SNIFFER_H_
+#define TC_SNIFFER_H_
+
+extern void tc_sniffer (void *pvParameters);
+extern void start_stop_sniffing (void);
+
+#endif /*TC_SNIFFER_H_*/
diff --git a/openpicc/application/usb_print.c b/openpicc/application/usb_print.c
index 5ff42b8..5e4372b 100644
--- a/openpicc/application/usb_print.c
+++ b/openpicc/application/usb_print.c
@@ -29,7 +29,7 @@
 
 static char ringbuffer[BUFLEN];
 static int ringstart, ringstop;
-static int default_flush = 1;
+static int default_flush = 1, forced_silence = 0;
 static xSemaphoreHandle print_semaphore;
 
 void usb_print_buffer(const char* buffer, int start, int stop) {
@@ -92,11 +92,20 @@ int usb_print_set_default_flush(int flush)
 	return old_flush;
 }
 
+int usb_print_set_force_silence(int silence)
+{
+	int old_silence = forced_silence;
+	forced_silence = silence;
+	return old_silence;
+}
+
 
 /* Must NOT be called from ISR context */
 void usb_print_flush(void)
 {
 	int oldstop, newstart;
+	if(forced_silence) return;
+	
 	taskENTER_CRITICAL();
 	if(print_semaphore == NULL)
 		usb_print_init();
diff --git a/openpicc/application/usb_print.h b/openpicc/application/usb_print.h
index 9186dc9..0497146 100644
--- a/openpicc/application/usb_print.h
+++ b/openpicc/application/usb_print.h
@@ -10,6 +10,7 @@ extern int usb_print_char_f(const char c, int flush);
 extern void usb_print_flush(void);
 extern int usb_print_get_default_flush(void);
 extern int usb_print_set_default_flush(int flush);
+extern int usb_print_set_force_silence(int silence);
 extern void usb_print_init(void);
 
 #endif /*USB_PRINT_H_*/
-- 
cgit v1.2.3