From 902cb3c00b49535f0de9a3b6d5ba0c54260ccac1 Mon Sep 17 00:00:00 2001
From: "roel@libnfc.org" <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Date: Tue, 4 Dec 2012 23:39:18 +0000
Subject: [PATCH] major USB update

---
 armsrc/LCD.c           |  22 ++++
 armsrc/Makefile        |   4 +-
 armsrc/appmain.c       | 171 +++++++++++++++---------------
 armsrc/apps.h          |  11 +-
 armsrc/epa.c           |  44 ++++----
 armsrc/fpgaloader.c    |   6 +-
 armsrc/iso14443a.c     |  64 +++++++-----
 armsrc/iso14443a.h     |   6 +-
 armsrc/iso15693.c      |  13 +--
 armsrc/mifaresniff.c   |   2 +-
 armsrc/util.h          |   3 +-
 bootrom/bootrom.c      |   2 +-
 client/Makefile        |   5 +-
 client/cmddata.c       |   7 +-
 client/cmdhf.c         |   1 +
 client/cmdhf14a.c      |  32 +++---
 client/cmdhf14b.c      |   1 +
 client/cmdhf15.c       | 115 +++++++++------------
 client/cmdhfepa.c      |  20 ++--
 client/cmdhficlass.c   |   1 +
 client/cmdhflegic.c    |   9 +-
 client/cmdhfmf.c       |  94 +++++++++--------
 client/cmdhw.c         |   1 +
 client/cmdlf.c         |   5 +-
 client/cmdlfem4x.c     |   1 +
 client/cmdlfhid.c      |   1 +
 client/cmdlfhitag.c    |  23 +++--
 client/cmdlfti.c       |   1 +
 client/cmdmain.c       |  66 ++++++++----
 client/cmdmain.h       |   4 +-
 client/cmdparser.c     |   1 +
 client/data.c          |  20 ++--
 client/data.h          |   3 +-
 client/flash.c         |  28 ++---
 client/hitag2.ht2      | Bin 48 -> 48 bytes
 client/mifarehost.c    |  63 +++++------
 client/proxmark3.c     | 230 +++++++++++++++++++++++++----------------
 client/proxmark3.h     |   5 +
 client/proxusb.c       |  18 ++--
 client/proxusb.h       |   6 +-
 client/util.h          |   3 +
 common/Makefile.common |   2 +-
 include/common.h       |  23 +----
 include/usb_cmd.h      |  23 +++--
 44 files changed, 648 insertions(+), 512 deletions(-)

diff --git a/armsrc/LCD.c b/armsrc/LCD.c
index f37aa894..65d64ac9 100644
--- a/armsrc/LCD.c
+++ b/armsrc/LCD.c
@@ -9,6 +9,7 @@
 #include "proxmark3.h"
 #include "apps.h"
 #include "LCD.h"
+#include "fonts.h"
 
 void LCDSend(unsigned int data)
 {
@@ -128,4 +129,25 @@ void LCDInit(void)
 	LCDSend(PRAMWR);			// Write to display
 	i=LCD_XRES*LCD_YRES;
 	while(i--) LCDSend(WHITE);
+  
+  // test text on different colored backgrounds
+	LCDString(" The quick brown fox  ",	(char *)&FONT6x8,1,1+8*0,WHITE  ,BLACK );
+	LCDString("  jumped over the     ",	(char *)&FONT6x8,1,1+8*1,BLACK  ,WHITE );
+	LCDString("     lazy dog.        ",	(char *)&FONT6x8,1,1+8*2,YELLOW ,RED   );
+	LCDString(" AaBbCcDdEeFfGgHhIiJj ",	(char *)&FONT6x8,1,1+8*3,RED    ,GREEN );
+	LCDString(" KkLlMmNnOoPpQqRrSsTt ",	(char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE  );
+	LCDString("UuVvWwXxYyZz0123456789",	(char *)&FONT6x8,1,1+8*5,BLUE   ,YELLOW);
+	LCDString("`-=[]_;',./~!@#$%^&*()",	(char *)&FONT6x8,1,1+8*6,BLACK  ,CYAN  );
+	LCDString("     _+{}|:\\\"<>?     ",(char *)&FONT6x8,1,1+8*7,BLUE  ,MAGENTA);
+  
+	// color bands
+	LCDFill(0, 1+8* 8, 132, 8, BLACK);
+	LCDFill(0, 1+8* 9, 132, 8, WHITE);
+	LCDFill(0, 1+8*10, 132, 8, RED);
+	LCDFill(0, 1+8*11, 132, 8, GREEN);
+	LCDFill(0, 1+8*12, 132, 8, BLUE);
+	LCDFill(0, 1+8*13, 132, 8, YELLOW);
+	LCDFill(0, 1+8*14, 132, 8, CYAN);
+	LCDFill(0, 1+8*15, 132, 8, MAGENTA);
+
 }
diff --git a/armsrc/Makefile b/armsrc/Makefile
index 715eba0a..813db17f 100644
--- a/armsrc/Makefile
+++ b/armsrc/Makefile
@@ -27,7 +27,9 @@ THUMBSRC = start.c \
 	appmain.c printf.c \
 	util.c \
 	string.c \
-	usb.c
+	usb.c \
+	usb_cdc.c \
+	cmd.c
 
 # These are to be compiled in ARM mode
 ARMSRC = fpgaloader.c \
diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index dac87677..e501dfdd 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -10,6 +10,9 @@
 // executes.
 //-----------------------------------------------------------------------------
 
+#include "usb_cdc.h"
+#include "cmd.h"
+
 #include "proxmark3.h"
 #include "apps.h"
 #include "util.h"
@@ -22,8 +25,7 @@
 #include <hitag2.h>
 
 #ifdef WITH_LCD
-# include "fonts.h"
-# include "LCD.h"
+ #include "LCD.h"
 #endif
 
 #define abs(x) ( ((x)<0) ? -(x) : (x) )
@@ -77,39 +79,41 @@ void ToSendStuffBit(int b)
 
 void DbpString(char *str)
 {
-	/* this holds up stuff unless we're connected to usb */
-	if (!UsbConnected())
-		return;
-
-	UsbCommand c;
-	c.cmd = CMD_DEBUG_PRINT_STRING;
-	c.arg[0] = strlen(str);
-	if(c.arg[0] > sizeof(c.d.asBytes)) {
-		c.arg[0] = sizeof(c.d.asBytes);
-	}
-	memcpy(c.d.asBytes, str, c.arg[0]);
-
-	UsbSendPacket((uint8_t *)&c, sizeof(c));
-	// TODO fix USB so stupid things like this aren't req'd
-	SpinDelay(50);
+  cmd_send(CMD_DEBUG_PRINT_STRING,strlen(str),0,0,(byte_t*)str,strlen(str));
+//	/* this holds up stuff unless we're connected to usb */
+//	if (!UsbConnected())
+//		return;
+//
+//	UsbCommand c;
+//	c.cmd = CMD_DEBUG_PRINT_STRING;
+//	c.arg[0] = strlen(str);
+//	if(c.arg[0] > sizeof(c.d.asBytes)) {
+//		c.arg[0] = sizeof(c.d.asBytes);
+//	}
+//	memcpy(c.d.asBytes, str, c.arg[0]);
+//
+//	UsbSendPacket((uint8_t *)&c, sizeof(c));
+//	// TODO fix USB so stupid things like this aren't req'd
+//	SpinDelay(50);
 }
 
 #if 0
 void DbpIntegers(int x1, int x2, int x3)
 {
-	/* this holds up stuff unless we're connected to usb */
-	if (!UsbConnected())
-		return;
-
-	UsbCommand c;
-	c.cmd = CMD_DEBUG_PRINT_INTEGERS;
-	c.arg[0] = x1;
-	c.arg[1] = x2;
-	c.arg[2] = x3;
-
-	UsbSendPacket((uint8_t *)&c, sizeof(c));
-	// XXX
-	SpinDelay(50);
+  cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
+//	/* this holds up stuff unless we're connected to usb */
+//	if (!UsbConnected())
+//		return;
+//
+//	UsbCommand c;
+//	c.cmd = CMD_DEBUG_PRINT_INTEGERS;
+//	c.arg[0] = x1;
+//	c.arg[1] = x2;
+//	c.arg[2] = x3;
+//
+//	UsbSendPacket((uint8_t *)&c, sizeof(c));
+//	// XXX
+//	SpinDelay(50);
 }
 #endif
 
@@ -194,7 +198,7 @@ void MeasureAntennaTuning(void)
 	int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0 
 	int vLf125 = 0, vLf134 = 0, vHf = 0;	// in mV
 
-	UsbCommand c;
+//	UsbCommand c;
 
   LED_B_ON();
 	DbpString("Measuring antenna characteristics, please wait...");
@@ -237,14 +241,14 @@ void MeasureAntennaTuning(void)
 	// can measure voltages up to 33000 mV
 	vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
 
-	c.cmd = CMD_MEASURED_ANTENNA_TUNING;
-	c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
-	c.arg[1] = vHf;
-	c.arg[2] = peakf | (peakv << 16);
+//	c.cmd = CMD_MEASURED_ANTENNA_TUNING;
+//	c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
+//	c.arg[1] = vHf;
+//	c.arg[2] = peakf | (peakv << 16);
 
   DbpString("Measuring complete, sending report back to host");
-
-	UsbSendPacket((uint8_t *)&c, sizeof(c));
+  cmd_send(CMD_MEASURED_ANTENNA_TUNING,vLf125|(vLf134<<16),vHf,peakf|(peakv<<16),0,0);
+//	UsbSendPacket((uint8_t *)&c, sizeof(c));
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
   LED_A_OFF();
   LED_B_OFF();
@@ -613,14 +617,14 @@ void ListenReaderField(int limit)
 void UsbPacketReceived(uint8_t *packet, int len)
 {
 	UsbCommand *c = (UsbCommand *)packet;
-	UsbCommand ack;
-	ack.cmd = CMD_ACK;
 
+//  Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]);
+  
 	switch(c->cmd) {
 #ifdef WITH_LF
 		case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
 			AcquireRawAdcSamples125k(c->arg[0]);
-			UsbSendPacket((uint8_t*)&ack, sizeof(ack));
+      cmd_send(CMD_ACK,0,0,0,0,0);
 			break;
 		case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
 			ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
@@ -736,13 +740,13 @@ void UsbPacketReceived(uint8_t *packet, int len)
 			SnoopIso14443a(c->arg[0]);
 			break;
 		case CMD_READER_ISO_14443a:
-			ReaderIso14443a(c, &ack);
+			ReaderIso14443a(c);
 			break;
 		case CMD_SIMULATE_TAG_ISO_14443a:
 			SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2]);  // ## Simulate iso14443a tag - pass tag type & UID
 			break;
 		case CMD_EPA_PACE_COLLECT_NONCE:
-			EPA_PACE_Collect_Nonce(c, &ack);
+			EPA_PACE_Collect_Nonce(c);
 			break;
 			
 		case CMD_READER_MIFARE:
@@ -838,16 +842,26 @@ void UsbPacketReceived(uint8_t *packet, int len)
 			break;
 
 		case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: {
-			UsbCommand n;
-			if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
-				n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
-			} else {
-				n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
-			}
-			n.arg[0] = c->arg[0];
-			memcpy(n.d.asDwords, BigBuf+c->arg[0], 12*sizeof(uint32_t));
-			LED_B_ON();
-			UsbSendPacket((uint8_t *)&n, sizeof(n));
+//			UsbCommand n;
+//			if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
+//				n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
+//			} else {
+//				n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
+//			}
+//			n.arg[0] = c->arg[0];
+      //			memcpy(n.d.asBytes, BigBuf+c->arg[0], 48); // 12*sizeof(uint32_t)
+      //			LED_B_ON();
+      //      usb_write((uint8_t *)&n, sizeof(n));
+      //			UsbSendPacket((uint8_t *)&n, sizeof(n));
+      //			LED_B_OFF();
+
+      LED_B_ON();
+      for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
+        size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
+        cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len);
+      }
+      // Trigger a finish downloading signal with an ACK frame
+      cmd_send(CMD_ACK,0,0,0,0,0);
 			LED_B_OFF();
 		} break;
 
@@ -855,7 +869,8 @@ void UsbPacketReceived(uint8_t *packet, int len)
 			uint8_t *b = (uint8_t *)BigBuf;
 			memcpy(b+c->arg[0], c->d.asBytes, 48);
 			//Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
-			UsbSendPacket((uint8_t*)&ack, sizeof(ack));
+//			UsbSendPacket((uint8_t*)&ack, sizeof(ack));
+      cmd_send(CMD_ACK,0,0,0,0,0);
 		} break;
 
 		case CMD_READ_MEM:
@@ -909,11 +924,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
         } break;
 
 		case CMD_DEVICE_INFO: {
-			UsbCommand c;
-			c.cmd = CMD_DEVICE_INFO;
-			c.arg[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
-			if(common_area.flags.bootrom_present) c.arg[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
-			UsbSendPacket((uint8_t*)&c, sizeof(c));
+			uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
+			if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
+//			UsbSendPacket((uint8_t*)&c, sizeof(c));
+      cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
 		} break;
             
 		default: {
@@ -939,7 +953,10 @@ void  __attribute__((noreturn)) AppMain(void)
 	LED_B_OFF();
 	LED_A_OFF();
 
-	UsbStart();
+  // Init USB device
+  usb_enable();
+  UsbStart();
+//	UsbStart();
 
 	// The FPGA gets its clock from us from PCK0 output, so set that up.
 	AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
@@ -959,35 +976,23 @@ void  __attribute__((noreturn)) AppMain(void)
 	FpgaDownloadAndGo();
 
 	StartTickCount();
-	
+  	
 #ifdef WITH_LCD
-
 	LCDInit();
-
-	// test text on different colored backgrounds
-	LCDString(" The quick brown fox  ",	(char *)&FONT6x8,1,1+8*0,WHITE  ,BLACK );
-	LCDString("  jumped over the     ",	(char *)&FONT6x8,1,1+8*1,BLACK  ,WHITE );
-	LCDString("     lazy dog.        ",	(char *)&FONT6x8,1,1+8*2,YELLOW ,RED   );
-	LCDString(" AaBbCcDdEeFfGgHhIiJj ",	(char *)&FONT6x8,1,1+8*3,RED    ,GREEN );
-	LCDString(" KkLlMmNnOoPpQqRrSsTt ",	(char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE  );
-	LCDString("UuVvWwXxYyZz0123456789",	(char *)&FONT6x8,1,1+8*5,BLUE   ,YELLOW);
-	LCDString("`-=[]_;',./~!@#$%^&*()",	(char *)&FONT6x8,1,1+8*6,BLACK  ,CYAN  );
-	LCDString("     _+{}|:\\\"<>?     ",(char *)&FONT6x8,1,1+8*7,BLUE  ,MAGENTA);
-
-	// color bands
-	LCDFill(0, 1+8* 8, 132, 8, BLACK);
-	LCDFill(0, 1+8* 9, 132, 8, WHITE);
-	LCDFill(0, 1+8*10, 132, 8, RED);
-	LCDFill(0, 1+8*11, 132, 8, GREEN);
-	LCDFill(0, 1+8*12, 132, 8, BLUE);
-	LCDFill(0, 1+8*13, 132, 8, YELLOW);
-	LCDFill(0, 1+8*14, 132, 8, CYAN);
-	LCDFill(0, 1+8*15, 132, 8, MAGENTA);
-
 #endif
 
+  byte_t rx[sizeof(UsbCommand)];
+	size_t rx_len;
+  
 	for(;;) {
-		UsbPoll(FALSE);
+    if (usb_poll()) {
+      rx_len = usb_read(rx,sizeof(UsbCommand));
+      if (rx_len) {
+        UsbPacketReceived(rx,rx_len);
+      }
+    }
+//		UsbPoll(FALSE);
+
 		WDT_HIT();
 
 #ifdef WITH_LF
diff --git a/armsrc/apps.h b/armsrc/apps.h
index f3f90237..c2b24eea 100644
--- a/armsrc/apps.h
+++ b/armsrc/apps.h
@@ -16,6 +16,7 @@
 #include <stddef.h>
 #include "common.h"
 #include "hitag2.h"
+#include "mifare.h"
 
 // The large multi-purpose buffer, typically used to hold A/D samples,
 // maybe processed in some way.
@@ -133,17 +134,17 @@ void RAMFUNC SnoopIso14443(void);
 /// iso14443a.h
 void RAMFUNC SnoopIso14443a(uint8_t param);
 void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd);	// ## simulate iso14443a tag
-void ReaderIso14443a(UsbCommand * c, UsbCommand * ack);
+void ReaderIso14443a(UsbCommand * c);
 // Also used in iclass.c
 int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
 uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
-void iso14a_set_trigger(int enable);
-void iso14a_clear_trace(void);
-void iso14a_set_tracing(int enable);
+void iso14a_set_trigger(bool enable);
+void iso14a_clear_trace();
+void iso14a_set_tracing(bool enable);
 void RAMFUNC SniffMifare(uint8_t param);
 
 /// epa.h
-void EPA_PACE_Collect_Nonce(UsbCommand * c, UsbCommand * ack);
+void EPA_PACE_Collect_Nonce(UsbCommand * c);
 
 // mifarecmd.h
 void ReaderMifare(uint32_t parameter);
diff --git a/armsrc/epa.c b/armsrc/epa.c
index 0e93a056..73c3a755 100644
--- a/armsrc/epa.c
+++ b/armsrc/epa.c
@@ -12,8 +12,8 @@
 //-----------------------------------------------------------------------------
 
 #include "iso14443a.h"
-
 #include "epa.h"
+#include "cmd.h"
 
 // Protocol and Parameter Selection Request
 // use regular (1x) speed in both directions
@@ -211,24 +211,25 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
 // Abort helper function for EPA_PACE_Collect_Nonce
 // sets relevant data in ack, sends the response
 //-----------------------------------------------------------------------------
-static void EPA_PACE_Collect_Nonce_Abort(UsbCommand *ack, uint8_t step, int func_return)
+static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
 {
-	// step in which the failure occured
-	ack->arg[0] = step;
-	// last return code
-	ack->arg[1] = func_return;
+//	// step in which the failure occured
+//	ack->arg[0] = step;
+//	// last return code
+//	ack->arg[1] = func_return;
 
 	// power down the field
 	EPA_Finish();
 	
 	// send the USB packet
-	UsbSendPacket((void *)ack, sizeof(UsbCommand));
+  cmd_send(CMD_ACK,step,func_return,0,0,0);
+//UsbSendPacket((void *)ack, sizeof(UsbCommand));
 }
 
 //-----------------------------------------------------------------------------
 // Acquire one encrypted PACE nonce
 //-----------------------------------------------------------------------------
-void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
+void EPA_PACE_Collect_Nonce(UsbCommand *c)
 {
 	/*
 	 * ack layout:
@@ -244,14 +245,14 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
 	// return value of a function
 	int func_return;
 
-	// initialize ack with 0s
-	memset(ack->arg, 0, 12);
-	memset(ack->d.asBytes, 0, 48);
+//	// initialize ack with 0s
+//	memset(ack->arg, 0, 12);
+//	memset(ack->d.asBytes, 0, 48);
 	
 	// set up communication
 	func_return = EPA_Setup();
 	if (func_return != 0) {
-		EPA_PACE_Collect_Nonce_Abort(ack, 1, func_return);
+		EPA_PACE_Collect_Nonce_Abort(1, func_return);
 		return;
 	}
 
@@ -264,7 +265,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
 	int card_access_length = EPA_Read_CardAccess(card_access, 256);
 	// the response has to be at least this big to hold the OID
 	if (card_access_length < 18) {
-		EPA_PACE_Collect_Nonce_Abort(ack, 2, card_access_length);
+		EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
 		return;
 	}
 
@@ -275,7 +276,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
 	                                   card_access_length,
 	                                   &pace_version_info);
 	if (func_return != 0 || pace_version_info.version == 0) {
-		EPA_PACE_Collect_Nonce_Abort(ack, 3, func_return);
+		EPA_PACE_Collect_Nonce_Abort(3, func_return);
 		return;
 	}
 	
@@ -290,17 +291,18 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
 	// check if the command succeeded
 	if (func_return < 0)
 	{
-		EPA_PACE_Collect_Nonce_Abort(ack, 4, func_return);
+		EPA_PACE_Collect_Nonce_Abort(4, func_return);
 		return;
 	}
+  
+  // all done, return
+	EPA_Finish();
 	
 	// save received information
-	ack->arg[1] = func_return;
-	memcpy(ack->d.asBytes, nonce, func_return);
-
-	// all done, return
-	EPA_Finish();
-	UsbSendPacket((void *)ack, sizeof(UsbCommand));
+//	ack->arg[1] = func_return;
+//	memcpy(ack->d.asBytes, nonce, func_return);
+//	UsbSendPacket((void *)ack, sizeof(UsbCommand));
+  cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
 }
 
 //-----------------------------------------------------------------------------
diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c
index a719f5ed..e3784bf5 100644
--- a/armsrc/fpgaloader.c
+++ b/armsrc/fpgaloader.c
@@ -116,13 +116,11 @@ void FpgaSetupSsc(void)
 
 	// 8 bits per transfer, no loopback, MSB first, 1 transfer per sync
 	// pulse, no output sync, start on positive-going edge of sync
-	AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) |
-		AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
+	AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) |	AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
 
 	// clock comes from TK pin, no clock output, outputs change on falling
 	// edge of TK, start on rising edge of TF
-	AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) |
-		SSC_CLOCK_MODE_START(5);
+	AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) |	SSC_CLOCK_MODE_START(5);
 
 	// tx framing is the same as the rx framing
 	AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR;
diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c
index 3757043b..d2ebb0c6 100644
--- a/armsrc/iso14443a.c
+++ b/armsrc/iso14443a.c
@@ -14,6 +14,7 @@
 #include "apps.h"
 #include "util.h"
 #include "string.h"
+#include "cmd.h"
 
 #include "iso14443crc.h"
 #include "iso14443a.h"
@@ -64,16 +65,16 @@ const uint8_t OddByteParity[256] = {
 };
 
 
-void iso14a_set_trigger(int enable) {
+void iso14a_set_trigger(bool enable) {
 	trigger = enable;
 }
 
-void iso14a_clear_trace(void) {
-    memset(trace, 0x44, TRACE_SIZE);
+void iso14a_clear_trace() {
+  memset(trace, 0x44, TRACE_SIZE);
 	traceLen = 0;
 }
 
-void iso14a_set_tracing(int enable) {
+void iso14a_set_tracing(bool enable) {
 	tracing = enable;
 }
 
@@ -1641,7 +1642,7 @@ int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, u
 	uint8_t sel_uid[]    = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
 	uint8_t rats[]       = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
 
-	uint8_t* resp = (((uint8_t *)BigBuf) + 3560);	// was 3560 - tied to other size changes
+	uint8_t* resp = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);	// was 3560 - tied to other size changes
 
 	uint8_t sak = 0x04; // cascade uid
 	int cascade_level = 0;
@@ -1649,13 +1650,14 @@ int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, u
 	int len;
 	
 	// clear uid
-	memset(uid_ptr, 0, 8);
+	memset(uid_ptr, 0, 12);
 
 	// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
 	ReaderTransmitShort(wupa);
 	// Receive the ATQA
 	if(!ReaderReceive(resp)) return 0;
-
+//  Dbprintf("atqa: %02x %02x",resp[0],resp[1]);
+  
 	if(resp_data)
 		memcpy(resp_data->atqa, resp, 2);
 	
@@ -1670,6 +1672,8 @@ int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, u
 		// SELECT_ALL
 		ReaderTransmit(sel_all,sizeof(sel_all));
 		if (!ReaderReceive(resp)) return 0;
+//    Dbprintf("uid: %02x %02x %02x %02x",resp[0],resp[1],resp[2],resp[3]);
+
 		if(uid_ptr) memcpy(uid_ptr + cascade_level*4, resp, 4);
 		
 		// calculate crypto UID
@@ -1715,13 +1719,13 @@ int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, u
 }
 
 void iso14443a_setup() {
-	// Setup SSC
-	FpgaSetupSsc();
+  // Set up the synchronous serial port
+  FpgaSetupSsc();
 	// Start from off (no field generated)
 	// Signal field is off with the appropriate LED
 	LED_D_OFF();
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-	SpinDelay(200);
+	SpinDelay(50);
 
 	SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 
@@ -1729,7 +1733,7 @@ void iso14443a_setup() {
 	// Signal field is on with the appropriate LED
 	LED_D_ON();
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
-	SpinDelay(200);
+	SpinDelay(50);
 
 	iso14a_timeout = 2048; //default
 }
@@ -1765,18 +1769,24 @@ int iso14_apdu(uint8_t * cmd, size_t cmd_len, void * data) {
 // Read an ISO 14443a tag. Send out commands and store answers.
 //
 //-----------------------------------------------------------------------------
-void ReaderIso14443a(UsbCommand * c, UsbCommand * ack)
+void ReaderIso14443a(UsbCommand * c)
 {
 	iso14a_command_t param = c->arg[0];
 	uint8_t * cmd = c->d.asBytes;
 	size_t len = c->arg[1];
+  uint32_t arg0;
+  byte_t buf[48];
+  
+  iso14a_clear_trace();
+  iso14a_set_tracing(true);
 
 	if(param & ISO14A_REQUEST_TRIGGER) iso14a_set_trigger(1);
 
 	if(param & ISO14A_CONNECT) {
 		iso14443a_setup();
-		ack->arg[0] = iso14443a_select_card(ack->d.asBytes, (iso14a_card_select_t *) (ack->d.asBytes+12), NULL);
-		UsbSendPacket((void *)ack, sizeof(UsbCommand));
+		arg0 = iso14443a_select_card(buf, (iso14a_card_select_t *)(buf+12), NULL);
+		cmd_send(CMD_ACK,arg0,0,0,buf,48);
+//    UsbSendPacket((void *)ack, sizeof(UsbCommand));
 	}
 
 	if(param & ISO14A_SET_TIMEOUT) {
@@ -1788,8 +1798,9 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack)
 	}
 
 	if(param & ISO14A_APDU) {
-		ack->arg[0] = iso14_apdu(cmd, len, ack->d.asBytes);
-		UsbSendPacket((void *)ack, sizeof(UsbCommand));
+		arg0 = iso14_apdu(cmd, len, buf);
+		cmd_send(CMD_ACK,arg0,0,0,buf,48);
+//		UsbSendPacket((void *)ack, sizeof(UsbCommand));
 	}
 
 	if(param & ISO14A_RAW) {
@@ -1798,8 +1809,9 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack)
 			len += 2;
 		}
 		ReaderTransmit(cmd,len);
-		ack->arg[0] = ReaderReceive(ack->d.asBytes);
-		UsbSendPacket((void *)ack, sizeof(UsbCommand));
+		arg0 = ReaderReceive(buf);
+//		UsbSendPacket((void *)ack, sizeof(UsbCommand));
+    cmd_send(CMD_ACK,arg0,0,0,buf,48);
 	}
 
 	if(param & ISO14A_REQUEST_TRIGGER) iso14a_set_trigger(0);
@@ -1821,7 +1833,7 @@ void ReaderMifare(uint32_t parameter)
 	uint8_t mf_auth[]    = { 0x60,0x00,0xf5,0x7b };
 	uint8_t mf_nr_ar[]   = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
 
-	uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + 3560);	// was 3560 - tied to other size changes
+	uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);	// was 3560 - tied to other size changes
 	traceLen = 0;
 	tracing = false;
 
@@ -1918,14 +1930,16 @@ void ReaderMifare(uint32_t parameter)
 	LogTrace(par_list, 8, 0, GetParity(par_list, 8), TRUE);
 	LogTrace(ks_list, 8, 0, GetParity(ks_list, 8), TRUE);
 
-	UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
-	memcpy(ack.d.asBytes + 0,  uid, 4);
-	memcpy(ack.d.asBytes + 4,  nt, 4);
-	memcpy(ack.d.asBytes + 8,  par_list, 8);
-	memcpy(ack.d.asBytes + 16, ks_list, 8);
+  byte_t buf[48];
+//	UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
+	memcpy(buf + 0,  uid, 4);
+	memcpy(buf + 4,  nt, 4);
+	memcpy(buf + 8,  par_list, 8);
+	memcpy(buf + 16, ks_list, 8);
 		
 	LED_B_ON();
-	UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
+  cmd_send(CMD_ACK,isOK,0,0,buf,48);
+//	UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
 	LED_B_OFF();	
 
 	// Thats it...
diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h
index b8f56c15..8422f6cb 100644
--- a/armsrc/iso14443a.h
+++ b/armsrc/iso14443a.h
@@ -91,10 +91,10 @@ extern int ReaderReceivePar(uint8_t* receivedAnswer, uint32_t * parptr);
 extern void iso14443a_setup();
 extern int iso14_apdu(uint8_t * cmd, size_t cmd_len, void * data);
 extern int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, uint32_t * cuid_ptr);
-extern void iso14a_set_trigger(int enable);
+extern void iso14a_set_trigger(bool enable);
 extern void iso14a_set_timeout(uint32_t timeout);
 
-extern void iso14a_clear_tracelen(void);
-extern void iso14a_set_tracing(int enable);
+extern void iso14a_clear_tracelen();
+extern void iso14a_set_tracing(bool enable);
 
 #endif /* __ISO14443A_H */
diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c
index b73ee014..ace6f87c 100644
--- a/armsrc/iso15693.c
+++ b/armsrc/iso15693.c
@@ -63,7 +63,7 @@
 #include "apps.h"
 #include "string.h"
 #include "iso15693tools.h"
-
+#include "cmd.h"
 
 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
 
@@ -1260,7 +1260,7 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
 
 	int recvlen=0;
 	uint8_t *recvbuf=(uint8_t *)BigBuf;
-	UsbCommand n;
+//	UsbCommand n;
 	
 	if (DEBUG) {
 		Dbprintf("SEND");
@@ -1270,11 +1270,12 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
 	recvlen=SendDataTag(data,datalen,1,speed,(recv?&recvbuf:NULL));
 
 	if (recv) { 
-		n.cmd=/* CMD_ISO_15693_COMMAND_DONE */ CMD_ACK;
-		n.arg[0]=recvlen>48?48:recvlen;
-		memcpy(n.d.asBytes, recvbuf, 48);
+//		n.cmd=/* CMD_ISO_15693_COMMAND_DONE */ CMD_ACK;
+//		n.arg[0]=recvlen>48?48:recvlen;
+//		memcpy(n.d.asBytes, recvbuf, 48);
 		LED_B_ON();
-		UsbSendPacket((uint8_t *)&n, sizeof(n));
+    cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
+//		UsbSendPacket((uint8_t *)&n, sizeof(n));
 		LED_B_OFF();	
 		
 		if (DEBUG) {
diff --git a/armsrc/mifaresniff.c b/armsrc/mifaresniff.c
index fc5156fd..45878000 100644
--- a/armsrc/mifaresniff.c
+++ b/armsrc/mifaresniff.c
@@ -166,7 +166,7 @@ int intMfSniffSend() {
 	FpgaDisableSscDma();
 
 	while (pckLen > 0) {
-		pckSize = min(32, pckLen);
+		pckSize = MIN(32, pckLen);
 		UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};
 		memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);
 	
diff --git a/armsrc/util.h b/armsrc/util.h
index 21a9b757..b68c511c 100644
--- a/armsrc/util.h
+++ b/armsrc/util.h
@@ -17,7 +17,8 @@
 #define RAMFUNC __attribute((long_call, section(".ramfunc")))
 
 #define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
-#define min(a, b) (((a) > (b)) ? (b) : (a))
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
 
 #define LED_RED 1
 #define LED_ORANGE 2
diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c
index 6b0ff532..0359832c 100644
--- a/bootrom/bootrom.c
+++ b/bootrom/bootrom.c
@@ -300,6 +300,6 @@ void BootROM(void)
 	    flash_mode(1);
     } else {
 	    // jump to Flash address of the osimage entry point (LSBit set for thumb mode)
-	    asm("bx %0\n" : : "r" ( ((int)&_osimage_entry) | 0x1 ) );
+	    __asm("bx %0\n" : : "r" ( ((int)&_osimage_entry) | 0x1 ) );
     }
 }
diff --git a/client/Makefile b/client/Makefile
index 8ddde4bd..ef1155ec 100644
--- a/client/Makefile
+++ b/client/Makefile
@@ -67,12 +67,13 @@ CMDSRCS = \
 			cmdlfhitag.c \
 			cmdlfti.c \
 			cmdparser.c \
-			cmdmain.c
+			cmdmain.c \
+			uart.c
 
 CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
 
 RM = rm -f
-BINS = proxmark3 snooper cli flasher
+BINS = proxmark3 flasher #snooper cli
 CLEAN = cli cli.exe flasher flasher.exe proxmark3 proxmark3.exe snooper snooper.exe $(CMDOBJS) $(OBJDIR)/*.o *.o *.moc.cpp
 
 all: $(BINS)
diff --git a/client/cmddata.c b/client/cmddata.c
index 77640d9d..1c58c69b 100644
--- a/client/cmddata.c
+++ b/client/cmddata.c
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <limits.h>
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "data.h"
 #include "ui.h"
 #include "graph.h"
@@ -158,7 +159,7 @@ int CmdBitsamples(const char *Cmd)
   for (int i = 0; i < n; i += 12) {
     UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
     SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
 
     for (int j = 0; j < 48; j++) {
       for (int k = 0; k < 8; k++) {
@@ -418,7 +419,7 @@ int CmdHexsamples(const char *Cmd)
   for (int i = offset; i < n+offset; i += 12) {
     UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
     SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
     for (int j = 0; j < 48; j += 8) {
       PrintAndLog("%02x %02x %02x %02x %02x %02x %02x %02x",
         sample_buf[j+0],
@@ -475,7 +476,7 @@ int CmdSamples(const char *Cmd)
   for (int i = 0; i < n; i += 12) {
     UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
     SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
     for (int j = 0; j < 48; j++) {
       GraphBuffer[cnt++] = ((int)sample_buf[j]) - 128;
     }
diff --git a/client/cmdhf.c b/client/cmdhf.c
index 0ed3de1a..cfbd9e16 100644
--- a/client/cmdhf.c
+++ b/client/cmdhf.c
@@ -10,6 +10,7 @@
 
 #include <stdio.h>
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "graph.h"
 #include "ui.h"
 #include "cmdparser.h"
diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c
index be7afc77..a82c7e35 100644
--- a/client/cmdhf14a.c
+++ b/client/cmdhf14a.c
@@ -17,11 +17,13 @@
 #include "iso14443crc.h"
 #include "data.h"
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "ui.h"
 #include "cmdparser.h"
 #include "cmdhf14a.h"
 #include "common.h"
 #include "cmdmain.h"
+#include "mifare.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -29,6 +31,7 @@ int CmdHF14AList(const char *Cmd)
 {
   uint8_t got[1920];
   GetFromBigBuf(got,sizeof(got),0);
+  WaitForResponse(CMD_ACK,NULL);
 
   PrintAndLog("recorded activity:");
   PrintAndLog(" ETU     :rssi: who bytes");
@@ -161,18 +164,21 @@ int CmdHF14AReader(const char *Cmd)
 {
 	UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
 	SendCommand(&c);
-	UsbCommand * resp = WaitForResponse(CMD_ACK);
-	uint8_t              * uid  = resp->d.asBytes;
+
+	UsbCommand resp;
+  WaitForResponse(CMD_ACK,&resp);
+	
+  uint8_t              * uid  = resp.d.asBytes;
 	iso14a_card_select_t * card = (iso14a_card_select_t *)(uid + 12);
 
-	if(resp->arg[0] == 0) {
+	if(resp.arg[0] == 0) {
 		PrintAndLog("iso14443a card select failed");
 		return 0;
 	}
 
 	PrintAndLog("ATQA : %02x %02x", card->atqa[0], card->atqa[1]);
 	PrintAndLog(" UID : %s", sprint_hex(uid, 12));
-	PrintAndLog(" SAK : %02x [%d]", card->sak, resp->arg[0]);
+	PrintAndLog(" SAK : %02x [%d]", card->sak, resp.arg[0]);
 
 	switch (card->sak) {
 		case 0x00: PrintAndLog(" SAK : NXP MIFARE Ultralight | Ultralight C"); break;
@@ -191,7 +197,7 @@ int CmdHF14AReader(const char *Cmd)
 		case 0x98: PrintAndLog(" SAK : Gemplus MPCOS"); break;
 		default: ;
 	}
-	if(resp->arg[0] == 1) {
+	if(resp.arg[0] == 1) {
 		bool ta1 = 0, tb1 = 0, tc1 = 0;
 		int pos;
 
@@ -312,7 +318,7 @@ int CmdHF14AReader(const char *Cmd)
 	else
 		PrintAndLog("proprietary non-iso14443a card found, RATS not supported");
 
-	return resp->arg[0];
+	return resp.arg[0];
 }
 
 // Collect ISO14443 Type A UIDs
@@ -330,12 +336,15 @@ int CmdHF14ACUIDs(const char *Cmd)
 		// execute anticollision procedure
 		UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
 		SendCommand(&c);
-		UsbCommand *resp = WaitForResponse(CMD_ACK);
-		uint8_t *uid  = resp->d.asBytes;
+    
+    UsbCommand resp;
+    WaitForResponse(CMD_ACK,&resp);
+
+		uint8_t *uid  = resp.d.asBytes;
 		iso14a_card_select_t *card = (iso14a_card_select_t *)(uid + 12);
 
 		// check if command failed
-		if (resp->arg[0] == 0) {
+		if (resp.arg[0] == 0) {
 			PrintAndLog("Card select failed.");
 		} else {
 			// check if UID is 4 bytes
@@ -472,10 +481,9 @@ static command_t CommandTable[] =
   {NULL, NULL, 0, NULL}
 };
 
-int CmdHF14A(const char *Cmd)
-{
+int CmdHF14A(const char *Cmd) {
 	// flush
-	while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
+	WaitForResponseTimeout(CMD_ACK,NULL,100);
 
 	// parse
   CmdsParse(CommandTable, Cmd);
diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c
index 68c7fa68..9b2fa753 100644
--- a/client/cmdhf14b.c
+++ b/client/cmdhf14b.c
@@ -15,6 +15,7 @@
 #include <stdint.h>
 #include "iso14443crc.h"
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "data.h"
 #include "graph.h"
 #include "ui.h"
diff --git a/client/cmdhf15.c b/client/cmdhf15.c
index a13ac4d0..e1e5e02a 100644
--- a/client/cmdhf15.c
+++ b/client/cmdhf15.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <stdint.h>
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "data.h"
 #include "graph.h"
 #include "ui.h"
@@ -94,7 +95,7 @@ const productName uidmapping[] = {
 // returns 1 if suceeded
 int getUID(uint8_t *buf) 
 {
-	UsbCommand *r;	
+	UsbCommand resp;
 	uint8_t *recv;
 	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
 	uint8_t *req=c.d.asBytes;
@@ -111,11 +112,9 @@ int getUID(uint8_t *buf)
 	
 		SendCommand(&c);
 		
-		r=WaitForResponseTimeout(CMD_ACK,1000);
-		
-		if (r!=NULL) {
-			recv = r->d.asBytes;
-			if (r->arg[0]>=12 && ISO15_CRC_CHECK==Crc(recv,12)) {
+		if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+			recv = resp.d.asBytes;
+			if (resp.arg[0]>=12 && ISO15_CRC_CHECK==Crc(recv,12)) {
 			   memcpy(buf,&recv[2],8);
 			   return 1;
 			} 
@@ -292,7 +291,7 @@ int CmdHF15Afi(const char *Cmd)
 
 // Reads all memory pages
 int CmdHF15DumpMem(const char*Cmd) {
-	UsbCommand *r;	
+	UsbCommand resp;
 	uint8_t uid[8];	
 	uint8_t *recv=NULL;
 	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
@@ -321,20 +320,18 @@ int CmdHF15DumpMem(const char*Cmd) {
 	
 		SendCommand(&c);
 		
-		r=WaitForResponseTimeout(CMD_ACK,1000);
-		
-		if (r!=NULL) {
-			recv = r->d.asBytes;
-			if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+		if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+			recv = resp.d.asBytes;
+			if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
 				if (!(recv[0] & ISO15_RES_ERROR)) {
 					retry=0;
 					*output=0; // reset outputstring
 					sprintf(output, "Block %2i   ",blocknum);
-					for ( int i=1; i<r->arg[0]-2; i++) { // data in hex
+					for ( int i=1; i<resp.arg[0]-2; i++) { // data in hex
 						sprintf(output+strlen(output),"%02hX ",recv[i]);					
 					}					
 					strcat(output,"   "); 
-					for ( int i=1; i<r->arg[0]-2; i++) { // data in cleaned ascii
+					for ( int i=1; i<resp.arg[0]-2; i++) { // data in cleaned ascii
 						sprintf(output+strlen(output),"%c",(recv[i]>31 && recv[i]<127)?recv[i]:'.');					
 					}					
 					PrintAndLog("%s",output);	
@@ -346,14 +343,14 @@ int CmdHF15DumpMem(const char*Cmd) {
 				}
 			} // else PrintAndLog("crc");
 		} // else PrintAndLog("r null");
-		
 	} // retry
-	if (r && r->arg[0]<3) 
-		PrintAndLog("Lost Connection");
-	else if (r && ISO15_CRC_CHECK!=Crc(r->d.asBytes,r->arg[0]))
-		PrintAndLog("CRC Failed");
-	else 
-		PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1])); 
+  // TODO: need fix
+//	if (resp.arg[0]<3)
+//		PrintAndLog("Lost Connection");
+//	else if (ISO15_CRC_CHECK!=Crc(resp.d.asBytes,resp.arg[0]))
+//		PrintAndLog("CRC Failed");
+//	else 
+//		PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1])); 
 	return 0;
 }
 
@@ -392,7 +389,7 @@ int CmdHF15Help(const char *Cmd)
 
 int CmdHF15CmdInquiry(const char *Cmd) 
 {
-	UsbCommand *r;	
+	UsbCommand resp;
 	uint8_t *recv;
 	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
 	uint8_t *req=c.d.asBytes;
@@ -407,15 +404,13 @@ int CmdHF15CmdInquiry(const char *Cmd)
 
 	SendCommand(&c);
 	
-	r=WaitForResponseTimeout(CMD_ACK,1000);
-	
-	if (r!=NULL) {
-		if (r->arg[0]>=12) {
-		   recv = r->d.asBytes;
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+		if (resp.arg[0]>=12) {
+		   recv = resp.d.asBytes;
 		   PrintAndLog("UID=%s",sprintUID(NULL,&recv[2]));
 		   PrintAndLog("Tag Info: %s",getTagInfo(&recv[2]));	
 		} else {
-			PrintAndLog("Response to short, just %i bytes. No tag?\n",r->arg[0]);		
+			PrintAndLog("Response to short, just %i bytes. No tag?\n",resp.arg[0]);
 		}
 	} else {
 		PrintAndLog("timeout.");
@@ -440,7 +435,7 @@ int CmdHF15CmdDebug( const char *cmd) {
 
 
 int CmdHF15CmdRaw (const char *cmd) {
-	UsbCommand *r;	
+	UsbCommand resp;
 	uint8_t *recv;
 	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
 	int reply=1;
@@ -515,14 +510,12 @@ int CmdHF15CmdRaw (const char *cmd) {
 	SendCommand(&c);
 	
 	if (reply) {
-		r=WaitForResponseTimeout(CMD_ACK,1000);
-	
-		if (r!=NULL) {
-			recv = r->d.asBytes;
-			PrintAndLog("received %i octets",r->arg[0]);
-			hexout = (char *)malloc(r->arg[0] * 3 + 1);
+		if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+			recv = resp.d.asBytes;
+			PrintAndLog("received %i octets",resp.arg[0]);
+			hexout = (char *)malloc(resp.arg[0] * 3 + 1);
 			if (hexout != NULL) {
-				for (int i = 0; i < r->arg[0]; i++) { // data in hex
+				for (int i = 0; i < resp.arg[0]; i++) { // data in hex
 					sprintf(&hexout[i * 3], "%02hX ", recv[i]);
 				}
 				PrintAndLog("%s", hexout);
@@ -635,7 +628,7 @@ int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdle
  * get system information from tag/VICC
  */
 int CmdHF15CmdSysinfo(const char *Cmd) {
-	UsbCommand *r;	
+	UsbCommand resp;
 	uint8_t *recv;
 	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
 	uint8_t *req=c.d.asBytes;
@@ -670,14 +663,12 @@ int CmdHF15CmdSysinfo(const char *Cmd) {
 
 	SendCommand(&c);
 
-	r=WaitForResponseTimeout(CMD_ACK,1000);
-	
-	if (r!=NULL && r->arg[0]>2) {
-		recv = r->d.asBytes;
-		if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
+		recv = resp.d.asBytes;
+		if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
 			if (!(recv[0] & ISO15_RES_ERROR)) {
 				*output=0; // reset outputstring
-				for ( i=1; i<r->arg[0]-2; i++) {
+				for ( i=1; i<resp.arg[0]-2; i++) {
 					sprintf(output+strlen(output),"%02hX ",recv[i]);					
 				}					
 				strcat(output,"\n\r");
@@ -725,7 +716,7 @@ int CmdHF15CmdSysinfo(const char *Cmd) {
  * Read multiple blocks at once (not all tags support this)
  */
 int CmdHF15CmdReadmulti(const char *Cmd) {
-	UsbCommand *r;	
+	UsbCommand resp;
 	uint8_t *recv;
 	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
 	uint8_t *req=c.d.asBytes;
@@ -773,18 +764,16 @@ int CmdHF15CmdReadmulti(const char *Cmd) {
 
 	SendCommand(&c);
 
-	r=WaitForResponseTimeout(CMD_ACK,1000);
-	
-	if (r!=NULL && r->arg[0]>2) {
-		recv = r->d.asBytes;
-		if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
+		recv = resp.d.asBytes;
+		if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
 			if (!(recv[0] & ISO15_RES_ERROR)) {
 				*output=0; // reset outputstring
-				for ( int i=1; i<r->arg[0]-2; i++) {
+				for ( int i=1; i<resp.arg[0]-2; i++) {
 					sprintf(output+strlen(output),"%02hX ",recv[i]);					
 				}					
 				strcat(output,"   ");
-				for ( int i=1; i<r->arg[0]-2; i++) {
+				for ( int i=1; i<resp.arg[0]-2; i++) {
 					sprintf(output+strlen(output),"%c",recv[i]>31 && recv[i]<127?recv[i]:'.');					
 				}					
 				PrintAndLog("%s",output);	
@@ -806,7 +795,7 @@ int CmdHF15CmdReadmulti(const char *Cmd) {
  * Reads a single Block
  */
 int CmdHF15CmdRead(const char *Cmd) {
-	UsbCommand *r;	
+	UsbCommand resp;
 	uint8_t *recv;
 	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
 	uint8_t *req=c.d.asBytes;
@@ -848,19 +837,17 @@ int CmdHF15CmdRead(const char *Cmd) {
 
 	SendCommand(&c);
 
-	r=WaitForResponseTimeout(CMD_ACK,1000);
-	
-	if (r!=NULL && r->arg[0]>2) {
-		recv = r->d.asBytes;
-		if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
+		recv = resp.d.asBytes;
+		if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
 			if (!(recv[0] & ISO15_RES_ERROR)) {
 				*output=0; // reset outputstring
 				//sprintf(output, "Block %2i   ",blocknum);
-				for ( int i=1; i<r->arg[0]-2; i++) {
+				for ( int i=1; i<resp.arg[0]-2; i++) {
 					sprintf(output+strlen(output),"%02hX ",recv[i]);					
 				}					
 				strcat(output,"   ");
-				for ( int i=1; i<r->arg[0]-2; i++) {
+				for ( int i=1; i<resp.arg[0]-2; i++) {
 					sprintf(output+strlen(output),"%c",recv[i]>31 && recv[i]<127?recv[i]:'.');					
 				}					
 				PrintAndLog("%s",output);	
@@ -883,7 +870,7 @@ int CmdHF15CmdRead(const char *Cmd) {
  * Writes a single Block - might run into timeout, even when successful
  */
 int CmdHF15CmdWrite(const char *Cmd) {
-	UsbCommand *r;	
+	UsbCommand resp;
 	uint8_t *recv;
 	UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
 	uint8_t *req=c.d.asBytes;
@@ -943,11 +930,9 @@ int CmdHF15CmdWrite(const char *Cmd) {
 
 	SendCommand(&c);
 
-	r=WaitForResponseTimeout(CMD_ACK,2000);
-	
-	if (r!=NULL && r->arg[0]>2) {
-		recv = r->d.asBytes;
-		if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+	if (WaitForResponseTimeout(CMD_ACK,&resp,2000) && resp.arg[0]>2) {
+		recv = resp.d.asBytes;
+		if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
 			if (!(recv[0] & ISO15_RES_ERROR)) {					
 				PrintAndLog("OK");	
 			} else {
diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c
index 2787b969..62680eff 100644
--- a/client/cmdhfepa.c
+++ b/client/cmdhfepa.c
@@ -10,6 +10,7 @@
 
 #include "util.h"
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "ui.h"
 #include "cmdparser.h"
 #include "common.h"
@@ -42,22 +43,21 @@ int CmdHFEPACollectPACENonces(const char *Cmd)
 		// execute PACE
 		UsbCommand c = {CMD_EPA_PACE_COLLECT_NONCE, {(int)m, 0, 0}};
 		SendCommand(&c);
-		UsbCommand *resp = WaitForResponse(CMD_ACK);
+		UsbCommand resp;
+    
+    WaitForResponse(CMD_ACK,&resp);
 
 		// check if command failed
-		if (resp->arg[0] != 0) {
-			PrintAndLog("Error in step %d, Return code: %d",
-			            resp->arg[0],
-						(int)resp->arg[1]);
+		if (resp.arg[0] != 0) {
+			PrintAndLog("Error in step %d, Return code: %d",resp.arg[0],(int)resp.arg[1]);
 		} else {
-			size_t nonce_length = resp->arg[1];
+			size_t nonce_length = resp.arg[1];
 			char *nonce = (char *) malloc(2 * nonce_length + 1);
 			for(int j = 0; j < nonce_length; j++) {
-				snprintf(nonce + (2 * j), 3, "%02X", resp->d.asBytes[j]);
+				snprintf(nonce + (2 * j), 3, "%02X", resp.d.asBytes[j]);
 			}
 			// print nonce
-			PrintAndLog("Length: %d, Nonce: %s",
-			            resp->arg[1], nonce);
+			PrintAndLog("Length: %d, Nonce: %s",resp.arg[1], nonce);
 		}
 		if (i < n - 1) {
 			sleep(d);
@@ -87,7 +87,7 @@ int CmdHelp(const char *Cmd)
 int CmdHFEPA(const char *Cmd)
 {
 	// flush
-	while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
+	while (!WaitForResponseTimeout(CMD_ACK,NULL,500));
 
 	// parse
   CmdsParse(CommandTable, Cmd);
diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c
index 7c31dab3..944ec498 100644
--- a/client/cmdhficlass.c
+++ b/client/cmdhficlass.c
@@ -15,6 +15,7 @@
 #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
 #include "data.h"
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "ui.h"
 #include "cmdparser.h"
 #include "cmdhficlass.h"
diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c
index aad03561..7a268e92 100644
--- a/client/cmdhflegic.c
+++ b/client/cmdhflegic.c
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <string.h>
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "data.h"
 #include "ui.h"
 #include "cmdparser.h"
@@ -69,7 +70,7 @@ int CmdLegicDecode(const char *Cmd)
   for (i = 0; i < 256; i += 12, h += 48) {
     UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
     SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
     
     for (j = 0; j < 48; j += 8) {
       for (k = 0; k < 8; k++) {
@@ -253,7 +254,7 @@ int CmdLegicLoad(const char *Cmd)
             c.d.asBytes[j] = data[j];
         }
         SendCommand(&c);
-        WaitForResponse(CMD_ACK);
+        WaitForResponse(CMD_ACK, NULL);
         offset += 8;
     }
     fclose(f);
@@ -292,7 +293,7 @@ int CmdLegicSave(const char *Cmd)
   for (int i = offset; i < n+offset; i += 12) {
     UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
     SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
     for (int j = 0; j < 48; j += 8) {
       fprintf(f, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
         sample_buf[j+0],
@@ -357,7 +358,7 @@ int CmdLegicRfFill(const char *Cmd)
     for(i = 0; i < 22; i++) {
       c.arg[0] = i*48;
       SendCommand(&c);
-      WaitForResponse(CMD_ACK);
+      WaitForResponse(CMD_ACK,NULL);
     }
     SendCommand(&cmd);
     return 0;
diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c
index dff5db37..5927616b 100644
--- a/client/cmdhfmf.c
+++ b/client/cmdhfmf.c
@@ -9,7 +9,6 @@
 //-----------------------------------------------------------------------------
 
 #include "cmdhfmf.h"
-#include "proxmark3.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -50,14 +49,14 @@ start:
 			break;
 		}
 		
-		UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
-		if (resp != NULL) {
-			isOK  = resp->arg[0] & 0xff;
+		UsbCommand resp;
+		if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
+			isOK  = resp.arg[0] & 0xff;
 	
-			uid = (uint32_t)bytes_to_num(resp->d.asBytes +  0, 4);
-			nt =  (uint32_t)bytes_to_num(resp->d.asBytes +  4, 4);
-			par_list = bytes_to_num(resp->d.asBytes +  8, 8);
-			ks_list = bytes_to_num(resp->d.asBytes +  16, 8);
+			uid = (uint32_t)bytes_to_num(resp.d.asBytes +  0, 4);
+			nt =  (uint32_t)bytes_to_num(resp.d.asBytes +  4, 4);
+			par_list = bytes_to_num(resp.d.asBytes +  8, 8);
+			ks_list = bytes_to_num(resp.d.asBytes +  16, 8);
 	
 			printf("\n\n");
 			PrintAndLog("isOk:%02x", isOK);
@@ -131,11 +130,10 @@ int CmdHF14AMfWrBl(const char *Cmd)
 	memcpy(c.d.asBytes, key, 6);
 	memcpy(c.d.asBytes + 10, bldata, 16);
   SendCommand(&c);
-	UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
-
-	if (resp != NULL) {
-		uint8_t                isOK  = resp->arg[0] & 0xff;
 
+	UsbCommand resp;
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+		uint8_t isOK  = resp.arg[0] & 0xff;
 		PrintAndLog("isOk:%02x", isOK);
 	} else {
 		PrintAndLog("Command execute timeout");
@@ -175,11 +173,11 @@ int CmdHF14AMfRdBl(const char *Cmd)
   UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
 	memcpy(c.d.asBytes, key, 6);
   SendCommand(&c);
-	UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
 
-	if (resp != NULL) {
-		uint8_t                isOK  = resp->arg[0] & 0xff;
-		uint8_t              * data  = resp->d.asBytes;
+	UsbCommand resp;
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+		uint8_t                isOK  = resp.arg[0] & 0xff;
+		uint8_t              * data  = resp.d.asBytes;
 
 		if (isOK)
 			PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
@@ -230,12 +228,12 @@ int CmdHF14AMfRdSc(const char *Cmd)
   UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
 	memcpy(c.d.asBytes, key, 6);
   SendCommand(&c);
-	UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
 	PrintAndLog(" ");
 
-	if (resp != NULL) {
-		isOK  = resp->arg[0] & 0xff;
-		data  = resp->d.asBytes;
+	UsbCommand resp;
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+		isOK  = resp.arg[0] & 0xff;
+		data  = resp.d.asBytes;
 
 		PrintAndLog("isOk:%02x", isOK);
 		if (isOK) 
@@ -246,13 +244,11 @@ int CmdHF14AMfRdSc(const char *Cmd)
 		PrintAndLog("Command1 execute timeout");
 	}
 
-		// response2
-	resp = WaitForResponseTimeout(CMD_ACK, 500);
+  // response2
 	PrintAndLog(" ");
-
-	if (resp != NULL) {
-		isOK  = resp->arg[0] & 0xff;
-		data  = resp->d.asBytes;
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+		isOK  = resp.arg[0] & 0xff;
+		data  = resp.d.asBytes;
 
 		if (isOK) 
 			for (i = 0; i < 2; i++) {
@@ -276,7 +272,7 @@ int CmdHF14AMfDump(const char *Cmd)
 	FILE *fin;
 	FILE *fout;
 	
-	UsbCommand *resp;
+	UsbCommand resp;
 	
 	if ((fin = fopen("dumpkeys.bin","rb")) == NULL) {
 		PrintAndLog("Could not find file dumpkeys.bin");
@@ -307,11 +303,10 @@ int CmdHF14AMfDump(const char *Cmd)
 		UsbCommand c = {CMD_MIFARE_READBL, {4*i + 3, 0, 0}};
 		memcpy(c.d.asBytes, keyA[i], 6);
 		SendCommand(&c);
-		resp = WaitForResponseTimeout(CMD_ACK, 1500);
 
-		if (resp != NULL) {
-			uint8_t isOK  = resp->arg[0] & 0xff;
-			uint8_t *data  = resp->d.asBytes;
+    if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+			uint8_t isOK  = resp.arg[0] & 0xff;
+			uint8_t *data  = resp.d.asBytes;
 			if (isOK){
 				rights[i][0] = ((data[7] & 0x10)>>4) | ((data[8] & 0x1)<<1) | ((data[8] & 0x10)>>2);
 				rights[i][1] = ((data[7] & 0x20)>>5) | ((data[8] & 0x2)<<0) | ((data[8] & 0x20)>>3);
@@ -333,20 +328,23 @@ int CmdHF14AMfDump(const char *Cmd)
 	PrintAndLog("|----- Dumping all blocks to file... -----|");
 	PrintAndLog("|-----------------------------------------|");
 	
+  
 	for (i=0 ; i<16 ; i++) {
 		for (j=0 ; j<4 ; j++) {
-			if (j == 3){
+      bool received = false;
+      
+      if (j == 3){
 				UsbCommand c = {CMD_MIFARE_READBL, {i*4 + j, 0, 0}};
 				memcpy(c.d.asBytes, keyA[i], 6);
 				SendCommand(&c);
-				resp = WaitForResponseTimeout(CMD_ACK, 1500);
+        received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
 			}
 			else{
 				if ((rights[i][j] == 6) | (rights[i][j] == 5)) {
 					UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 1, 0}};
 					memcpy(c.d.asBytes, keyB[i], 6);
 					SendCommand(&c);
-					resp = WaitForResponseTimeout(CMD_ACK, 1500);
+          received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
 				}
 				else if (rights[i][j] == 7) {
 					PrintAndLog("Access rights do not allow reading of sector %d block %d",i,j);
@@ -355,13 +353,13 @@ int CmdHF14AMfDump(const char *Cmd)
 					UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 0, 0}};
 					memcpy(c.d.asBytes, keyA[i], 6);
 					SendCommand(&c);
-					resp = WaitForResponseTimeout(CMD_ACK, 1500);
+          received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
 				}
 			}
 
-			if (resp != NULL) {
-				uint8_t isOK  = resp->arg[0] & 0xff;
-				uint8_t *data  = resp->d.asBytes;
+			if (received) {
+				uint8_t isOK  = resp.arg[0] & 0xff;
+				uint8_t *data  = resp.d.asBytes;
 				if (j == 3) {
 					data[0]  = (keyA[i][0]);
 					data[1]  = (keyA[i][1]);
@@ -462,10 +460,10 @@ int CmdHF14AMfRestore(const char *Cmd)
 			
 			memcpy(c.d.asBytes + 10, bldata, 16);
 			SendCommand(&c);
-			UsbCommand *resp = WaitForResponseTimeout(CMD_ACK, 1500);
 
-			if (resp != NULL) {
-				uint8_t isOK  = resp->arg[0] & 0xff;
+			UsbCommand resp;
+      if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+				uint8_t isOK  = resp.arg[0] & 0xff;
 				PrintAndLog("isOk:%02x", isOK);
 			} else {
 				PrintAndLog("Command execute timeout");
@@ -1591,11 +1589,11 @@ int CmdHF14AMfSniff(const char *Cmd){
 			break;
 		}
 		
-		UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
-		if (resp != NULL) {
-			res = resp->arg[0] & 0xff;
-			len = resp->arg[1];
-			num = resp->arg[2];
+    UsbCommand resp;
+    if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
+			res = resp.arg[0] & 0xff;
+			len = resp.arg[1];
+			num = resp.arg[2];
 			
 			if (res == 0) return 0;
 			if (res == 1) {
@@ -1603,7 +1601,7 @@ int CmdHF14AMfSniff(const char *Cmd){
 					bufPtr = buf;
 					memset(buf, 0x00, 3000);
 				}
-				memcpy(bufPtr, resp->d.asBytes, len);
+				memcpy(bufPtr, resp.d.asBytes, len);
 				bufPtr += len;
 				pckNum++;
 			}
@@ -1678,7 +1676,7 @@ static command_t CommandTable[] =
 int CmdHFMF(const char *Cmd)
 {
 	// flush
-	while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
+	while (!WaitForResponseTimeout(CMD_ACK,NULL,500));
 
   CmdsParse(CommandTable, Cmd);
   return 0;
diff --git a/client/cmdhw.c b/client/cmdhw.c
index 4dd5823d..991cd532 100644
--- a/client/cmdhw.c
+++ b/client/cmdhw.c
@@ -14,6 +14,7 @@
 #include <limits.h>
 #include "ui.h"
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "cmdparser.h"
 #include "cmdhw.h"
 
diff --git a/client/cmdlf.c b/client/cmdlf.c
index 78e1f988..98a6c1f0 100644
--- a/client/cmdlf.c
+++ b/client/cmdlf.c
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <limits.h>
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "data.h"
 #include "graph.h"
 #include "ui.h"
@@ -364,7 +365,7 @@ int CmdLFRead(const char *Cmd)
     return 0;
   }
   SendCommand(&c);
-  WaitForResponse(CMD_ACK);
+  WaitForResponse(CMD_ACK,NULL);
   return 0;
 }
 
@@ -401,7 +402,7 @@ int CmdLFSim(const char *Cmd)
       c.d.asBytes[j] = GraphBuffer[i+j];
     }
     SendCommand(&c);
-    WaitForResponse(CMD_ACK);
+    WaitForResponse(CMD_ACK,NULL);
   }
 
   PrintAndLog("Starting simulator...");
diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c
index 537712f4..83ed673b 100644
--- a/client/cmdlfem4x.c
+++ b/client/cmdlfem4x.c
@@ -12,6 +12,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "ui.h"
 #include "graph.h"
 #include "cmdparser.h"
diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c
index 767ea3cc..93c351f1 100644
--- a/client/cmdlfhid.c
+++ b/client/cmdlfhid.c
@@ -10,6 +10,7 @@
 
 #include <stdio.h>
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "ui.h"
 #include "graph.h"
 #include "cmdparser.h"
diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c
index c852544c..2541ce59 100644
--- a/client/cmdlfhitag.c
+++ b/client/cmdlfhitag.c
@@ -13,11 +13,14 @@
 #include <string.h>
 #include "data.h"
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "ui.h"
 #include "cmdparser.h"
 #include "common.h"
 #include "util.h"
 #include "hitag2.h"
+#include "sleep.h"
+#include "cmdmain.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -25,16 +28,18 @@ int CmdLFHitagList(const char *Cmd)
 {
   uint8_t got[3000];
   GetFromBigBuf(got,sizeof(got),0);
+  WaitForResponse(CMD_ACK,NULL);
+
   char filename[256];
-  FILE* pf;
+  FILE* pf = NULL;
 
-  param_getstr(Cmd,0,filename);
-  
-  if (strlen(filename) > 0) {
+  if (param_getstr(Cmd,0,filename)) {
+    if (strlen(filename) > 0) {
       if ((pf = fopen(filename,"w")) == NULL) {
-	    PrintAndLog("Error: Could not open file [%s]",filename);
-	    return 1;
-	  }
+        PrintAndLog("Error: Could not open file [%s]",filename);
+        return 1;
+      }
+    }
   }
 
   PrintAndLog("recorded activity:");
@@ -114,7 +119,7 @@ int CmdLFHitagList(const char *Cmd)
       line);
 
 
-	if (strlen(filename) > 0) {
+   if (pf) {
       fprintf(pf," +%7d: %s: %s %s %s",
 					(prev < 0 ? 0 : (timestamp - prev)),
 					metricString,
@@ -127,7 +132,7 @@ int CmdLFHitagList(const char *Cmd)
     i += (len + 9);
   }
   
-  if (strlen(filename) > 0) {
+  if (pf) {
 	  PrintAndLog("Recorded activity succesfully written to file: %s", filename);
     fclose(pf);
   }
diff --git a/client/cmdlfti.c b/client/cmdlfti.c
index 59f83f08..4e8b1150 100644
--- a/client/cmdlfti.c
+++ b/client/cmdlfti.c
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include "crc16.h"
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "data.h"
 #include "ui.h"
 #include "graph.h"
diff --git a/client/cmdmain.c b/client/cmdmain.c
index c26f2eb4..edff9f8e 100644
--- a/client/cmdmain.c
+++ b/client/cmdmain.c
@@ -14,6 +14,7 @@
 #include <string.h>
 #include "sleep.h"
 #include "cmdparser.h"
+#include "proxmark3.h"
 #include "data.h"
 #include "usb_cmd.h"
 #include "ui.h"
@@ -55,37 +56,40 @@ int CmdQuit(const char *Cmd)
   return 0;
 }
 
-UsbCommand * WaitForResponseTimeout(uint32_t response_type, uint32_t ms_timeout) {
-	UsbCommand * ret =  NULL;
-	int i=0;
+bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
 
-	for(i=0; received_command != response_type && i < ms_timeout / 10; i++) {
-		msleep(10); // XXX ugh
+	// Wait until the command is received
+  for(size_t i=0; received_command != cmd && i < ms_timeout; i++) {
+		msleep(1); // XXX ugh
+    if (i == 2000) {
+      PrintAndLog("Waiting for a response from the proxmark...");
+      PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
+    }
 	}
 	
-	// There was an evil BUG
-	memcpy(&current_response_user, &current_response, sizeof(UsbCommand));
-	ret = &current_response_user;
+  // Check if timeout occured
+  if(received_command != cmd) return false;
 
-	if(received_command != response_type)
-		ret = NULL;
+	// Copy the received response (if supplied)
+  if (response) {
+    memcpy(response, &current_response, sizeof(UsbCommand));
+  }
 
-	received_command = CMD_UNKNOWN;
+	// Reset the received command
+  received_command = CMD_UNKNOWN;
 
-	return ret;
+	return true;
 }
 
-UsbCommand * WaitForResponse(uint32_t response_type)
-{
-	return WaitForResponseTimeout(response_type, -1);
+bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
+	return WaitForResponseTimeout(cmd,response,-1);
 }
 
 //-----------------------------------------------------------------------------
 // Entry point into our code: called whenever the user types a command and
 // then presses Enter, which the full command line that they typed.
 //-----------------------------------------------------------------------------
-void CommandReceived(char *Cmd)
-{
+void CommandReceived(char *Cmd) {
   CmdsParse(CommandTable, Cmd);
 }
 
@@ -138,6 +142,19 @@ void UsbCommandReceived(UsbCommand *UC)
         PrintAndLog("# Your HF antenna is marginal.");
     } break;
       
+    case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
+//      printf("received samples: ");
+//      print_hex(UC->d.asBytes,512);
+      sample_buf_len += UC->arg[1];
+//      printf("samples: %zd offset: %d\n",sample_buf_len,UC->arg[0]);
+      memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
+    } break;
+
+
+//    case CMD_ACK: {
+//      PrintAndLog("Receive ACK\n");
+//    } break;
+
     default: {
       // Maybe it's a response
       switch(current_command) {
@@ -146,19 +163,24 @@ void UsbCommandReceived(UsbCommand *UC)
             PrintAndLog("unrecognized command %08x\n", UC->cmd);
             break;
           }
-          int i;
-          for(i=0; i<48; i++) sample_buf[i] = UC->d.asBytes[i];
+//          int i;
+          PrintAndLog("received samples %d\n",UC->arg[0]);
+          memcpy(sample_buf+UC->arg[0],UC->d.asBytes,48);
+          sample_buf_len += 48;
+//          for(i=0; i<48; i++) sample_buf[i] = UC->d.asBytes[i];
           received_command = UC->cmd;
         } break;
 
         default: {
         } break;
       }
-      // Store the last received command
-      received_command = UC->cmd;
-      memcpy(&current_response, UC, sizeof(UsbCommand));
+//      // Store the last received command
+//      memcpy(&current_response, UC, sizeof(UsbCommand));
+//      received_command = UC->cmd;
     } break;
   }
+  // Store the last received command
+  memcpy(&current_response, UC, sizeof(UsbCommand));
   received_command = UC->cmd;
 /*
   // Maybe it's a response:
diff --git a/client/cmdmain.h b/client/cmdmain.h
index 3a4145c1..a745fea7 100644
--- a/client/cmdmain.h
+++ b/client/cmdmain.h
@@ -15,7 +15,7 @@
 
 void UsbCommandReceived(UsbCommand *UC);
 void CommandReceived(char *Cmd);
-UsbCommand * WaitForResponseTimeout(uint32_t response_type, uint32_t ms_timeout);
-UsbCommand * WaitForResponse(uint32_t response_type);
+bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
+bool WaitForResponse(uint32_t cmd, UsbCommand* response);
 
 #endif
diff --git a/client/cmdparser.c b/client/cmdparser.c
index 6f17e0bd..7ea1bf47 100644
--- a/client/cmdparser.c
+++ b/client/cmdparser.c
@@ -12,6 +12,7 @@
 #include <string.h>
 #include "ui.h"
 #include "cmdparser.h"
+#include "proxmark3.h"
 
 void CmdsHelp(const command_t Commands[])
 {
diff --git a/client/data.c b/client/data.c
index eeae8cc5..b6639867 100644
--- a/client/data.c
+++ b/client/data.c
@@ -13,24 +13,32 @@
 #include "data.h"
 #include "ui.h"
 #include "proxusb.h"
+#include "proxmark3.h"
 #include "cmdmain.h"
 
-uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
+uint8_t* sample_buf;
+size_t sample_buf_len;
 
 void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
 {
-	start_index = ((start_index/12)*12);
-    int n = (((bytes/4)/48)*48) + start_index;
+  sample_buf_len = 0;
+  sample_buf = dest;
+//	start_index = ((start_index/12)*12);
+//    int n = start_index + bytes;
     /*
      if (n % 48 != 0) {
      PrintAndLog("bad len in GetFromBigBuf");
      return;
      }
      */
-    for (int i = start_index; i < n; i += 12) {
+  UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
+  SendCommand(&c);
+/*
+  for (int i = start_index; i < n; i += 48) {
         UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
         SendCommand(&c);
-        WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
-        memcpy(dest+(i*4), sample_buf, 48);
+//        WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+//        memcpy(dest+(i*4), sample_buf, 48);
     }
+*/
 }
diff --git a/client/data.h b/client/data.h
index e3a4cbda..33ee9d04 100644
--- a/client/data.h
+++ b/client/data.h
@@ -15,7 +15,8 @@
 
 #define SAMPLE_BUFFER_SIZE 64
 
-extern uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
+extern uint8_t* sample_buf;
+extern size_t sample_buf_len;
 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
 
 void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);
diff --git a/client/flash.c b/client/flash.c
index 6670d637..8fe874e5 100644
--- a/client/flash.c
+++ b/client/flash.c
@@ -267,11 +267,11 @@ fail:
 // Get the state of the proxmark, backwards compatible
 static int get_proxmark_state(uint32_t *state)
 {
-	UsbCommand c;
+	HidCommand c;
 	c.cmd = CMD_DEVICE_INFO;
-	SendCommand(&c);
+	SendCommand_(&c);
 
-	UsbCommand resp;
+	HidCommand resp;
 	ReceiveCommand(&resp);
 
 	// Three outcomes:
@@ -313,7 +313,7 @@ static int enter_bootloader(void)
 
 	if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
 		fprintf(stderr,"Entering bootloader...\n");
-		UsbCommand c;
+		HidCommand c;
 		memset(&c, 0, sizeof (c));
 
 		if ((state & DEVICE_INFO_FLAG_BOOTROM_PRESENT)
@@ -322,12 +322,12 @@ static int enter_bootloader(void)
 			// New style handover: Send CMD_START_FLASH, which will reset the board
 			// and enter the bootrom on the next boot.
 			c.cmd = CMD_START_FLASH;
-			SendCommand(&c);
+			SendCommand_(&c);
 			fprintf(stderr,"(Press and release the button only to abort)\n");
 		} else {
 			// Old style handover: Ask the user to press the button, then reset the board
 			c.cmd = CMD_HARDWARE_RESET;
-			SendCommand(&c);
+			SendCommand_(&c);
 			fprintf(stderr,"Press and hold down button NOW if your bootloader requires it.\n");
 		}
 		fprintf(stderr,"Waiting for Proxmark to reappear on USB...");
@@ -349,7 +349,7 @@ static int enter_bootloader(void)
 
 static int wait_for_ack(void)
 {
-	UsbCommand ack;
+	HidCommand ack;
 	ReceiveCommand(&ack);
 	if (ack.cmd != CMD_ACK) {
 		printf("Error: Unexpected reply 0x%04x (expected ACK)\n", ack.cmd);
@@ -372,7 +372,7 @@ int flash_start_flashing(int enable_bl_writes)
 	if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
 		// This command is stupid. Why the heck does it care which area we're
 		// flashing, as long as it's not the bootloader area? The mind boggles.
-		UsbCommand c = {CMD_START_FLASH};
+		HidCommand c = {CMD_START_FLASH};
 
 		if (enable_bl_writes) {
 			c.arg[0] = FLASH_START;
@@ -383,7 +383,7 @@ int flash_start_flashing(int enable_bl_writes)
 			c.arg[1] = FLASH_END;
 			c.arg[2] = 0;
 		}
-		SendCommand(&c);
+		SendCommand_(&c);
 		return wait_for_ack();
 	} else {
 		fprintf(stderr, "Note: Your bootloader does not understand the new START_FLASH command\n");
@@ -400,11 +400,11 @@ static int write_block(uint32_t address, uint8_t *data, uint32_t length)
 	memset(block_buf, 0xFF, BLOCK_SIZE);
 	memcpy(block_buf, data, length);
 
-	UsbCommand c = {CMD_SETUP_WRITE};
+	HidCommand c = {CMD_SETUP_WRITE};
 	for (int i = 0; i < 240; i += 48) {
 		memcpy(c.d.asBytes, block_buf + i, 48);
 		c.arg[0] = i / 4;
-		SendCommand(&c);
+		SendCommand_(&c);
 		if (wait_for_ack() < 0)
 			return -1;
 	}
@@ -412,7 +412,7 @@ static int write_block(uint32_t address, uint8_t *data, uint32_t length)
 	c.cmd = CMD_FINISH_WRITE;
 	c.arg[0] = address;
 	memcpy(c.d.asBytes, block_buf+240, 16);
-	SendCommand(&c);
+	SendCommand_(&c);
 	return wait_for_ack();
 }
 
@@ -472,7 +472,7 @@ void flash_free(flash_file_t *ctx)
 
 // just reset the unit
 int flash_stop_flashing(void) {
-	UsbCommand c = {CMD_HARDWARE_RESET};
-	SendCommand(&c);
+	HidCommand c = {CMD_HARDWARE_RESET};
+	SendCommand_(&c);
 	return 0;
 }
diff --git a/client/hitag2.ht2 b/client/hitag2.ht2
index 6aa27962b20bf2cbe5e10c109d500c06d3f13991..2b6d5055b953160a9efe965a18a91088016c3468 100644
GIT binary patch
delta 10
RcmXpoU}4#)ATyCg2LKB50v7-P

delta 10
RcmXpoU}4#)AU%;q2LKB10u}%O

diff --git a/client/mifarehost.c b/client/mifarehost.c
index f34759df..22b2a328 100644
--- a/client/mifarehost.c
+++ b/client/mifarehost.c
@@ -12,6 +12,7 @@
 #include <stdlib.h> 
 #include <string.h>
 #include "mifarehost.h"
+#include "proxmark3.h"
 
 // MIFARE
 
@@ -59,12 +60,12 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
 	fnVector * vector = NULL;
 	countKeys	*ck;
 	int lenVector = 0;
-	UsbCommand * resp = NULL;
+	UsbCommand resp;
 	
 	memset(resultKeys, 0x00, 16 * 6);
 
 	// flush queue
-	while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
+	while (!WaitForResponseTimeout(CMD_ACK,NULL,500));
 	
   UsbCommand c = {CMD_MIFARE_NESTED, {blockNo, keyType, trgBlockNo + trgKeyType * 0x100}};
 	memcpy(c.d.asBytes, key, 6);
@@ -81,18 +82,16 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
 			break;
 		}
 
-		resp = WaitForResponseTimeout(CMD_ACK, 1500);
-
-		if (resp != NULL) {
-			isEOF  = resp->arg[0] & 0xff;
+		if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+			isEOF  = resp.arg[0] & 0xff;
 
 			if (isEOF) break;
 			
-			len = resp->arg[1] & 0xff;
+			len = resp.arg[1] & 0xff;
 			if (len == 0) continue;
 			
-			memcpy(&uid, resp->d.asBytes, 4); 
-			PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, resp->arg[2] & 0xff, (resp->arg[2] >> 8) & 0xff);
+			memcpy(&uid, resp.d.asBytes, 4);
+			PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, resp.arg[2] & 0xff, (resp.arg[2] >> 8) & 0xff);
 			vector = (fnVector *) realloc((void *)vector, (lenVector + len) * sizeof(fnVector) + 200);
 			if (vector == NULL) {
 				PrintAndLog("Memory allocation error for fnVector. len: %d bytes: %d", lenVector + len, (lenVector + len) * sizeof(fnVector)); 
@@ -100,12 +99,12 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
 			}
 			
 			for (i = 0; i < len; i++) {
-				vector[lenVector + i].blockNo = resp->arg[2] & 0xff;
-				vector[lenVector + i].keyType = (resp->arg[2] >> 8) & 0xff;
+				vector[lenVector + i].blockNo = resp.arg[2] & 0xff;
+				vector[lenVector + i].keyType = (resp.arg[2] >> 8) & 0xff;
 				vector[lenVector + i].uid = uid;
 
-				memcpy(&vector[lenVector + i].nt,  (void *)(resp->d.asBytes + 8 + i * 8 + 0), 4);
-				memcpy(&vector[lenVector + i].ks1, (void *)(resp->d.asBytes + 8 + i * 8 + 4), 4);
+				memcpy(&vector[lenVector + i].nt,  (void *)(resp.d.asBytes + 8 + i * 8 + 0), 4);
+				memcpy(&vector[lenVector + i].ks1, (void *)(resp.d.asBytes + 8 + i * 8 + 4), 4);
 			}
 
 			lenVector += len;
@@ -187,14 +186,12 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
 
   UsbCommand c = {CMD_MIFARE_CHKKEYS, {blockNo, keyType, keycnt}};
 	memcpy(c.d.asBytes, keyBlock, 6 * keycnt);
-
   SendCommand(&c);
 
-	UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 3000);
-
-	if (resp == NULL) return 1;
-	if ((resp->arg[0] & 0xff) != 0x01) return 2;
-	*key = bytes_to_num(resp->d.asBytes, 6);
+	UsbCommand resp;
+	if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) return 1;
+	if ((resp.arg[0] & 0xff) != 0x01) return 2;
+	*key = bytes_to_num(resp.d.asBytes, 6);
 	return 0;
 }
 
@@ -202,13 +199,11 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
 
 int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {
 	UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}};
- 
-	SendCommand(&c);
+ 	SendCommand(&c);
 
-	UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
-
-	if (resp == NULL) return 1;
-	memcpy(data, resp->d.asBytes, blocksCount * 16); 
+  UsbCommand resp;
+	if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) return 1;
+	memcpy(data, resp.d.asBytes, blocksCount * 16);
 	return 0;
 }
 
@@ -241,11 +236,10 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint
 	memcpy(c.d.asBytes, data, 16); 
 	SendCommand(&c);
 
-	UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
-
-	if (resp != NULL) {
-		isOK  = resp->arg[0] & 0xff;
-		if (uid != NULL) memcpy(uid, resp->d.asBytes, 4); 
+  UsbCommand resp;
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+		isOK  = resp.arg[0] & 0xff;
+		if (uid != NULL) memcpy(uid, resp.d.asBytes, 4);
 		if (!isOK) return 2;
 	} else {
 		PrintAndLog("Command execute timeout");
@@ -260,11 +254,10 @@ int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
 	UsbCommand c = {CMD_MIFARE_EML_CGETBLOCK, {params, 0, blockNo}};
 	SendCommand(&c);
 
-	UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
-
-	if (resp != NULL) {
-		isOK  = resp->arg[0] & 0xff;
-		memcpy(data, resp->d.asBytes, 16); 
+  UsbCommand resp;
+	if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+		isOK  = resp.arg[0] & 0xff;
+		memcpy(data, resp.d.asBytes, 16);
 		if (!isOK) return 2;
 	} else {
 		PrintAndLog("Command execute timeout");
diff --git a/client/proxmark3.c b/client/proxmark3.c
index 4b898d54..cff94903 100644
--- a/client/proxmark3.c
+++ b/client/proxmark3.c
@@ -16,98 +16,135 @@
 #include <unistd.h>
 #include <readline/readline.h>
 #include <readline/history.h>
-#include "proxusb.h"
+//#include "proxusb.h"
 #include "proxmark3.h"
 #include "proxgui.h"
 #include "cmdmain.h"
+#include "uart.h"
+#include "messages.h"
+#include "ui.h"
+
+static serial_port sp;
+
+void SendCommand(UsbCommand *c) {
+#if 0
+  printf("Sending %d bytes\n", sizeof(UsbCommand));
+#endif
+  if (!uart_send(sp,(byte_t*)c,sizeof(UsbCommand))) {
+    ERR("Sending bytes to proxmark failed");
+  }
+}
 
-struct usb_receiver_arg
-{
+struct receiver_arg {
   int run;
 };
 
-struct main_loop_arg
-{
+struct main_loop_arg {
   int usb_present;
   char *script_cmds_file;
 };
 
-static void *usb_receiver(void *targ)
-{
-  struct usb_receiver_arg *arg = (struct usb_receiver_arg*)targ;
-  UsbCommand cmdbuf;
+//static void *usb_receiver(void *targ) {
+//  struct receiver_arg *arg = (struct receiver_arg*)targ;
+//  UsbCommand cmdbuf;
+//
+//  while (arg->run) {
+//    if (ReceiveCommandPoll(&cmdbuf)) {
+//      UsbCommandReceived(&cmdbuf);
+//      fflush(NULL);
+//    }
+//  }
+//
+//  pthread_exit(NULL);
+//  return NULL;
+//}
 
+byte_t rx[0x1000000];
+
+static void *uart_receiver(void *targ) {
+  struct receiver_arg *arg = (struct receiver_arg*)targ;
+  size_t rxlen;
+  size_t cmd_count;
+  
   while (arg->run) {
-    if (ReceiveCommandPoll(&cmdbuf)) {
-      UsbCommandReceived(&cmdbuf);
-      fflush(NULL);
+    if (uart_receive(sp,rx,&rxlen)) {
+      if ((rxlen % sizeof(UsbCommand)) != 0) {
+        PrintAndLog("ERROR: received %zd bytes, which does not seem to be one or more command(s)\n",rxlen);
+        continue;
+      }
+      cmd_count = rxlen / sizeof(UsbCommand);
+//      printf("received %zd bytes, which represents %zd commands\n",rxlen, cmd_count);
+      for (size_t i=0; i<cmd_count; i++) {
+        UsbCommandReceived((UsbCommand*)(rx+(i*sizeof(UsbCommand))));
+      }
     }
   }
-
+  
   pthread_exit(NULL);
   return NULL;
 }
 
-static void *main_loop(void *targ)
-{
-    struct main_loop_arg *arg = (struct main_loop_arg*)targ;
-    struct usb_receiver_arg rarg;
-    char *cmd = NULL;
-    pthread_t reader_thread;
 
-    if (arg->usb_present == 1) {
-        rarg.run=1;
-        pthread_create(&reader_thread, NULL, &usb_receiver, &rarg);
-    }
-    
-    FILE *script_file = NULL;
-    char script_cmd_buf[256];
-    
-    if (arg->script_cmds_file)
+static void *main_loop(void *targ) {
+  struct main_loop_arg *arg = (struct main_loop_arg*)targ;
+  struct receiver_arg rarg;
+  char *cmd = NULL;
+  pthread_t reader_thread;
+  
+  if (arg->usb_present == 1) {
+    rarg.run=1;
+    // pthread_create(&reader_thread, NULL, &usb_receiver, &rarg);
+    pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
+  }
+  
+  FILE *script_file = NULL;
+  char script_cmd_buf[256];
+  
+  if (arg->script_cmds_file)
+  {
+    script_file = fopen(arg->script_cmds_file, "r");
+    if (script_file)
     {
-        script_file = fopen(arg->script_cmds_file, "r");
-        if (script_file)
-        {
-            printf("using 'scripting' commands file %s\n", arg->script_cmds_file);
-        }
+      printf("using 'scripting' commands file %s\n", arg->script_cmds_file);
     }
+  }
 
 	read_history(".history");
 	while(1)
+  {
+    // If there is a script file
+    if (script_file)
+    {
+      if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), script_file))
+      {
+        fclose(script_file);
+        script_file = NULL;
+      }
+      else
+      {
+        char *nl;
+        nl = strrchr(script_cmd_buf, '\r');
+        if (nl) *nl = '\0';
+        nl = strrchr(script_cmd_buf, '\n');
+        if (nl) *nl = '\0';
+        
+        if ((cmd = (char*) malloc(strlen(script_cmd_buf))) != NULL)
         {
-	    // If there is a script file
-	    if (script_file)
-	    {
-	        if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), script_file))
-	        {
-	            fclose(script_file);
-	            script_file = NULL;
-	        }
-	        else
-	        {
-	            char *nl;
-	            nl = strrchr(script_cmd_buf, '\r');
-                    if (nl) *nl = '\0';
-                    nl = strrchr(script_cmd_buf, '\n');
-                    if (nl) *nl = '\0';
-	            
-                    if ((cmd = (char*) malloc(strlen(script_cmd_buf))) != NULL)
-                    {
-                        memset(cmd, 0, strlen(script_cmd_buf));
-                        strcpy(cmd, script_cmd_buf);
-                        printf("%s\n", cmd);
-                    }
-	        }
-	    }
+          memset(cmd, 0, strlen(script_cmd_buf));
+          strcpy(cmd, script_cmd_buf);
+          printf("%s\n", cmd);
+        }
+      }
+    }
 		
 		if (!script_file)
 		{
-		    cmd = readline(PROXPROMPT);
+      cmd = readline(PROXPROMPT);
 		}
 		
 		if (cmd) {
 			while(cmd[strlen(cmd) - 1] == ' ')
-			cmd[strlen(cmd) - 1] = 0x00;
+        cmd[strlen(cmd) - 1] = 0x00;
 			
 			if (cmd[0] != 0x00) {
 				if (strncmp(cmd, "quit", 4) == 0) {
@@ -123,41 +160,41 @@ static void *main_loop(void *targ)
 			break;
 		}
 	}
-
+  
 	write_history(".history");
-
-    if (arg->usb_present == 1) {
-        rarg.run = 0;
-        pthread_join(reader_thread, NULL);
-    }
-    
-    if (script_file)
-    {
-        fclose(script_file);
-        script_file = NULL;
-    }
-
-    ExitGraphics();
-    pthread_exit(NULL);
-    return NULL;
+  
+  if (arg->usb_present == 1) {
+    rarg.run = 0;
+    pthread_join(reader_thread, NULL);
+  }
+  
+  if (script_file)
+  {
+    fclose(script_file);
+    script_file = NULL;
+  }
+  
+  ExitGraphics();
+  pthread_exit(NULL);
+  return NULL;
 }
 
-int main(int argc, char **argv)
-{
+int main(int argc, char* argv[]) {
+  
+  if (argc < 2) {
+    printf("syntax: %s <port>\n\n",argv[0]);
+    return 1;
+  }
+  
   // Make sure to initialize
   struct main_loop_arg marg = {
     .usb_present = 0,
     .script_cmds_file = NULL
   };
   pthread_t main_loop_t;
-  usb_init();
-
-  // If the user passed the filename of the 'script' to execute, get it
-  if (argc > 1 && argv[1])
-  {
-    marg.script_cmds_file = argv[1];
-  }
 
+/*
+  usb_init();
   if (!OpenProxmark(1)) {
     fprintf(stderr,"PROXMARK3: NOT FOUND!\n");
     marg.usb_present = 0;
@@ -166,7 +203,22 @@ int main(int argc, char **argv)
     marg.usb_present = 1;
     offline = 0;
   }
+*/
+  sp = uart_open(argv[1]);
+  if (sp == INVALID_SERIAL_PORT) {
+    printf("ERROR: invalid serial port\n");
+    marg.usb_present = 0;
+    offline = 1;
+  } else {
+    marg.usb_present = 1;
+    offline = 0;
+  }
 
+  // If the user passed the filename of the 'script' to execute, get it
+  if (argc > 2 && argv[2]) {
+    marg.script_cmds_file = argv[2];
+  }
+  
   pthread_create(&main_loop_t, NULL, &main_loop, &marg);
   InitGraphics(argc, argv);
 
@@ -174,8 +226,12 @@ int main(int argc, char **argv)
 
   pthread_join(main_loop_t, NULL);
 
-  if (marg.usb_present == 1) {
-    CloseProxmark();
-  }
+//  if (marg.usb_present == 1) {
+//    CloseProxmark();
+//  }
+
+  // Clean up the port
+  uart_close(sp);
+  
   return 0;
 }
diff --git a/client/proxmark3.h b/client/proxmark3.h
index f5dd2b7f..2875511b 100644
--- a/client/proxmark3.h
+++ b/client/proxmark3.h
@@ -12,6 +12,11 @@
 #ifndef PROXMARK3_H__
 #define PROXMARK3_H__
 
+#include <usb.h>
+#include "usb_cmd.h"
+
 #define PROXPROMPT "proxmark3> "
 
+void SendCommand(UsbCommand *c);
+
 #endif
diff --git a/client/proxusb.c b/client/proxusb.c
index 3c2b20b4..2f152ace 100644
--- a/client/proxusb.c
+++ b/client/proxusb.c
@@ -34,15 +34,15 @@ unsigned char return_on_error = 0;
 unsigned char error_occured = 0;
 extern unsigned int current_command;
 
-void SendCommand(UsbCommand *c)
+void SendCommand_(HidCommand *c)
 {
   int ret;
 
 #if 0
-  printf("Sending %d bytes\n", sizeof(UsbCommand));
+  printf("Sending %d bytes\n", sizeof(HidCommand));
 #endif
   current_command = c->cmd;
-  ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(UsbCommand), 1000);
+  ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(HidCommand), 1000);
   if (ret<0) {
     error_occured = 1;
     if (return_on_error)
@@ -63,12 +63,12 @@ void SendCommand(UsbCommand *c)
   }
 }
 
-bool ReceiveCommandPoll(UsbCommand *c)
+bool ReceiveCommandPoll(HidCommand *c)
 {
   int ret;
 
-  memset(c, 0, sizeof (UsbCommand));
-  ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(UsbCommand), 500);
+  memset(c, 0, sizeof (HidCommand));
+  ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(HidCommand), 500);
   if (ret<0) {
     if (ret != -ETIMEDOUT) {
       error_occured = 1;
@@ -89,16 +89,16 @@ bool ReceiveCommandPoll(UsbCommand *c)
       return false;
     }
   } else {
-    if (ret && (ret < sizeof(UsbCommand))) {
+    if (ret && (ret < sizeof(HidCommand))) {
       fprintf(stderr, "Read only %d instead of requested %d bytes!\n",
-        ret, (int)sizeof(UsbCommand));
+        ret, (int)sizeof(HidCommand));
     }
   }
 
   return ret > 0;
 }
 
-void ReceiveCommand(UsbCommand *c)
+void ReceiveCommand(HidCommand *c)
 {
 //  printf("%s()\n", __FUNCTION__);
   int retval = 0;
diff --git a/client/proxusb.h b/client/proxusb.h
index 5845888a..cc34fd48 100644
--- a/client/proxusb.h
+++ b/client/proxusb.h
@@ -19,9 +19,9 @@
 extern unsigned char return_on_error;
 extern unsigned char error_occured;
 
-void SendCommand(UsbCommand *c);
-bool ReceiveCommandPoll(UsbCommand *c);
-void ReceiveCommand(UsbCommand *c);
+void SendCommand_(HidCommand *c);
+bool ReceiveCommandPoll(HidCommand *c);
+void ReceiveCommand(HidCommand *c);
 struct usb_dev_handle* FindProxmark(int verbose, unsigned int *iface);
 struct usb_dev_handle* OpenProxmark(int verbose);
 void CloseProxmark(void);
diff --git a/client/util.h b/client/util.h
index 22e83471..1d410592 100644
--- a/client/util.h
+++ b/client/util.h
@@ -16,6 +16,9 @@
 #include <ctype.h>
 #include <time.h>
 
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
 int ukbhit(void);
 
 void AddLogLine(char *fileName, char *extData, char *c);
diff --git a/common/Makefile.common b/common/Makefile.common
index d8968327..9ff05c50 100644
--- a/common/Makefile.common
+++ b/common/Makefile.common
@@ -65,7 +65,7 @@ VPATH = . ../common/ ../fpga/
 
 INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES)
 
-CFLAGS =  -c $(INCLUDE) -Wall -Werror -pedantic -std=gnu99 $(APP_CFLAGS)
+CFLAGS =  -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS)
 LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n
 LIBS = -lgcc
 
diff --git a/include/common.h b/include/common.h
index cfce1b9f..13daa86e 100644
--- a/include/common.h
+++ b/include/common.h
@@ -12,27 +12,10 @@
 #ifndef __COMMON_H
 #define __COMMON_H
 
+#include <stddef.h>
 #include <stdint.h>
+#include <stdbool.h>
+#include <at91sam7s512.h>
 typedef unsigned char byte_t;
 
-//-----------------------------------------------------------------------------
-// ISO 14443A
-//-----------------------------------------------------------------------------
-typedef struct {
-	uint8_t atqa[2];
-	uint8_t  sak;
-	uint8_t  ats_len;
-	uint8_t  ats[20]; //FIXME: size?
-} __attribute__((__packed__)) iso14a_card_select_t;
-
-typedef enum ISO14A_COMMAND {
-	ISO14A_CONNECT = 1,
-	ISO14A_NO_DISCONNECT = 2,
-	ISO14A_APDU = 4,
-	ISO14A_RAW = 8,
-	ISO14A_REQUEST_TRIGGER = 0x10,
-	ISO14A_APPEND_CRC = 0x20,
-	ISO14A_SET_TIMEOUT = 0x40
-} iso14a_command_t;
-
 #endif
diff --git a/include/usb_cmd.h b/include/usb_cmd.h
index a7552b3e..b3c52d1d 100644
--- a/include/usb_cmd.h
+++ b/include/usb_cmd.h
@@ -24,12 +24,23 @@ typedef BYTE uint8_t;
 #endif
 
 typedef struct {
-	uint32_t	cmd;
-	uint32_t	arg[3];
-	union {
-		uint8_t		asBytes[48];
-		uint32_t	asDwords[12];
-	} d;
+  uint32_t	cmd;
+  uint32_t	arg[3];
+  union {
+    uint8_t		asBytes[48];
+    uint32_t	asDwords[12];
+  } d;
+} PACKED HidCommand;
+
+#define USB_CMD_DATA_SIZE 512
+
+typedef struct {
+  uint32_t cmd;
+  uint32_t arg[3];
+  union {
+    uint8_t	 asBytes[USB_CMD_DATA_SIZE];
+    uint32_t asDwords[USB_CMD_DATA_SIZE/4];
+  } d;
 } PACKED UsbCommand;
 
 // For the bootloader
-- 
2.39.5