]> cvs.zerfleddert.de Git - proxmark3-svn/commitdiff
Comms refactor (prerequisite of libproxmark work) (#371)
authorMichael Farrell <micolous+gh@gmail.com>
Thu, 26 Oct 2017 19:54:27 +0000 (06:54 +1100)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Thu, 26 Oct 2017 19:54:27 +0000 (21:54 +0200)
* Refactor the comms code only from PR#346, without comms_globals.h.
* OSX: Add note for example serial port

19 files changed:
client/Makefile
client/cmdlf.c
client/cmdmain.c
client/cmdmain.h
client/cmdparser.c
client/comms.c [new file with mode: 0644]
client/comms.h [new file with mode: 0644]
client/flash.c
client/flash.h
client/flasher.c
client/proxgui.cpp
client/proxgui.h
client/proxguiqt.h
client/proxmark3.c
client/proxmark3.h
client/ui.c
client/ui.h
common/iso15693tools.c
include/usb_cmd.h

index 3a96e9e928bccb59795f29f4f56b56566e52d3e7..e14939e3784bb181583030a10a142e2414c2418b 100644 (file)
@@ -21,7 +21,7 @@ LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
 LUALIB = ../liblua/liblua.a
 LDFLAGS = $(ENV_LDFLAGS)
 CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall -g -O3
 LUALIB = ../liblua/liblua.a
 LDFLAGS = $(ENV_LDFLAGS)
 CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall -g -O3
-CXXFLAGS = -I../include -Wall -O3
+CXXFLAGS = -I../include -I../uart -Wall -O3
 
 LUAPLATFORM = generic
 platform = $(shell uname)
 
 LUAPLATFORM = generic
 platform = $(shell uname)
@@ -82,7 +82,10 @@ POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d
 CORESRCS =     uart_posix.c \
                        uart_win32.c \
                        util.c \
 CORESRCS =     uart_posix.c \
                        uart_win32.c \
                        util.c \
-                       util_posix.c
+                       util_posix.c \
+                       comms.c \
+                       data.c \
+                       ui.c
 
 CMDSRCS =      crapto1/crapto1.c\
                        crapto1/crypto1.c\
 
 CMDSRCS =      crapto1/crapto1.c\
                        crapto1/crypto1.c\
@@ -102,9 +105,7 @@ CMDSRCS =   crapto1/crapto1.c\
                        crc64.c \
                        iso14443crc.c \
                        iso15693tools.c \
                        crc64.c \
                        iso14443crc.c \
                        iso15693tools.c \
-                       data.c \
                        graph.c \
                        graph.c \
-                       ui.c \
                        cmddata.c \
                        lfdemod.c \
                        cmdhf.c \
                        cmddata.c \
                        lfdemod.c \
                        cmdhf.c \
@@ -175,6 +176,7 @@ ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
 #-DDEBUG -Dverbose=1
 
 QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
 #-DDEBUG -Dverbose=1
 
 QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
+NOGUISRCS = guidummy.cpp
 
 COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
 CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
 
 COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
 CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
index eb664a111391f9b03c13106e83aadc371b78fcad..501bfaed6206129933e31afa8a965e6facda30a0 100644 (file)
@@ -335,7 +335,7 @@ int CmdLFSetConfig(const char *Cmd)
 }
 
 bool lf_read(bool silent, uint32_t samples) {
 }
 
 bool lf_read(bool silent, uint32_t samples) {
-       if (offline) return false;
+       if (IsOffline()) return false;
        UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent,samples,0}};
        clearCommandBuffer();
        //And ship it to device
        UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent,samples,0}};
        clearCommandBuffer();
        //And ship it to device
@@ -878,7 +878,7 @@ int CmdVchDemod(const char *Cmd)
 int CheckChipType(char cmdp) {
        uint32_t wordData = 0;
 
 int CheckChipType(char cmdp) {
        uint32_t wordData = 0;
 
-       if (offline || cmdp == '1') return 0;
+       if (IsOffline() || cmdp == '1') return 0;
 
        save_restoreGB(GRAPH_SAVE);
        save_restoreDB(GRAPH_SAVE);
 
        save_restoreGB(GRAPH_SAVE);
        save_restoreDB(GRAPH_SAVE);
@@ -923,7 +923,7 @@ int CmdLFfind(const char *Cmd)
                return 0;
        }
 
                return 0;
        }
 
-       if (!offline && (cmdp != '1')) {
+       if (!IsOffline() && (cmdp != '1')) {
                lf_read(true, 30000);
        } else if (GraphTraceLen < minLength) {
                PrintAndLog("Data in Graphbuffer was too small.");
                lf_read(true, 30000);
        } else if (GraphTraceLen < minLength) {
                PrintAndLog("Data in Graphbuffer was too small.");
@@ -939,7 +939,7 @@ int CmdLFfind(const char *Cmd)
        // only run if graphbuffer is just noise as it should be for hitag/cotag
        if (graphJustNoise(GraphBuffer, testLen)) {
                // only run these tests if we are in online mode 
        // only run if graphbuffer is just noise as it should be for hitag/cotag
        if (graphJustNoise(GraphBuffer, testLen)) {
                // only run these tests if we are in online mode 
-               if (!offline && (cmdp != '1')) {
+               if (!IsOffline() && (cmdp != '1')) {
                        // test for em4x05 in reader talk first mode.
                        if (EM4x05Block0Test(&wordData)) {
                                PrintAndLog("\nValid EM4x05/EM4x69 Chip Found\nUse lf em 4x05readword/dump commands to read\n");
                        // test for em4x05 in reader talk first mode.
                        if (EM4x05Block0Test(&wordData)) {
                                PrintAndLog("\nValid EM4x05/EM4x69 Chip Found\nUse lf em 4x05readword/dump commands to read\n");
index 739d68e1cbc0beb609f0d858dae78a3ad1438b95..e199e127139f289c03a042ff7b2258f062d2041d 100644 (file)
@@ -36,15 +36,6 @@ static int CmdHelp(const char *Cmd);
 static int CmdQuit(const char *Cmd);
 static int CmdRev(const char *Cmd);
 
 static int CmdQuit(const char *Cmd);
 static int CmdRev(const char *Cmd);
 
-//For storing command that are received from the device
-#define CMD_BUFFER_SIZE 50
-static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
-//Points to the next empty position to write to
-static int cmd_head;//Starts as 0
-//Points to the position of the last unread command
-static int cmd_tail;//Starts as 0
-// to lock cmdBuffer operations from different threads
-static pthread_mutex_t cmdBufferMutex = PTHREAD_MUTEX_INITIALIZER;
 
 static command_t CommandTable[] = 
 {
 
 static command_t CommandTable[] = 
 {
@@ -64,6 +55,7 @@ command_t* getTopLevelCommandTable()
 {
   return CommandTable;
 }
 {
   return CommandTable;
 }
+
 int CmdHelp(const char *Cmd)
 {
   CmdsHelp(CommandTable);
 int CmdHelp(const char *Cmd)
 {
   CmdsHelp(CommandTable);
@@ -81,113 +73,6 @@ int CmdRev(const char *Cmd)
   return 0;
 }
 
   return 0;
 }
 
-/**
- * @brief This method should be called when sending a new command to the pm3. In case any old
- *  responses from previous commands are stored in the buffer, a call to this method should clear them.
- *  A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which
- *  operation. Right now we'll just have to live with this.
- */
-void clearCommandBuffer()
-{
-    //This is a very simple operation
-       pthread_mutex_lock(&cmdBufferMutex);
-    cmd_tail = cmd_head;
-       pthread_mutex_unlock(&cmdBufferMutex);
-}
-
-/**
- * @brief storeCommand stores a USB command in a circular buffer
- * @param UC
- */
-void storeCommand(UsbCommand *command)
-{
-       pthread_mutex_lock(&cmdBufferMutex);
-    if( ( cmd_head+1) % CMD_BUFFER_SIZE == cmd_tail)
-    {
-        //If these two are equal, we're about to overwrite in the
-        // circular buffer.
-        PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!");
-    }
-    //Store the command at the 'head' location
-    UsbCommand* destination = &cmdBuffer[cmd_head];
-    memcpy(destination, command, sizeof(UsbCommand));
-
-    cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
-       pthread_mutex_unlock(&cmdBufferMutex);
-}
-
-
-/**
- * @brief getCommand gets a command from an internal circular buffer.
- * @param response location to write command
- * @return 1 if response was returned, 0 if nothing has been received
- */
-int getCommand(UsbCommand* response)
-{
-       pthread_mutex_lock(&cmdBufferMutex);
-    //If head == tail, there's nothing to read, or if we just got initialized
-    if(cmd_head == cmd_tail){
-               pthread_mutex_unlock(&cmdBufferMutex);
-        return 0;
-    }
-    //Pick out the next unread command
-    UsbCommand* last_unread = &cmdBuffer[cmd_tail];
-    memcpy(response, last_unread, sizeof(UsbCommand));
-    //Increment tail - this is a circular buffer, so modulo buffer size
-    cmd_tail = (cmd_tail +1 ) % CMD_BUFFER_SIZE;
-       pthread_mutex_unlock(&cmdBufferMutex);
-    return 1;
-}
-
-
-/**
- * Waits for a certain response type. This method waits for a maximum of
- * ms_timeout milliseconds for a specified response command.
- *@brief WaitForResponseTimeout
- * @param cmd command to wait for
- * @param response struct to copy received command into.
- * @param ms_timeout
- * @return true if command was returned, otherwise false
- */
-bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning) {
-  
-       UsbCommand resp;
-       
-       if (response == NULL) {
-               response = &resp;
-       }
-
-       uint64_t start_time = msclock();
-       
-       // Wait until the command is received
-       while (true) {
-               while(getCommand(response)) {
-                       if(response->cmd == cmd){
-                               return true;
-                       }
-               }
-               if (msclock() - start_time > ms_timeout) {
-                       break;
-               }
-               if (msclock() - start_time > 2000 && show_warning) {
-                       PrintAndLog("Waiting for a response from the proxmark...");
-                       PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
-                       break;
-               }
-       }
-       return false;
-}
-
-
-bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
-       return WaitForResponseTimeoutW(cmd, response, ms_timeout, true);
-}
-
-bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
-       return WaitForResponseTimeoutW(cmd, response, -1, true);
-}
-
-
 //-----------------------------------------------------------------------------
 // Entry point into our code: called whenever the user types a command and
 // then presses Enter, which the full command line that they typed.
 //-----------------------------------------------------------------------------
 // Entry point into our code: called whenever the user types a command and
 // then presses Enter, which the full command line that they typed.
@@ -196,38 +81,3 @@ int CommandReceived(char *Cmd) {
        return CmdsParse(CommandTable, Cmd);
 }
 
        return CmdsParse(CommandTable, Cmd);
 }
 
-
-//-----------------------------------------------------------------------------
-// Entry point into our code: called whenever we received a packet over USB
-// that we weren't necessarily expecting, for example a debug print.
-//-----------------------------------------------------------------------------
-void UsbCommandReceived(UsbCommand *UC)
-{
-       switch(UC->cmd) {
-               // First check if we are handling a debug message
-               case CMD_DEBUG_PRINT_STRING: {
-                       char s[USB_CMD_DATA_SIZE+1];
-                       memset(s, 0x00, sizeof(s));
-                       size_t len = MIN(UC->arg[0],USB_CMD_DATA_SIZE);
-                       memcpy(s,UC->d.asBytes,len);
-                       PrintAndLog("#db# %s", s);
-                       return;
-               } break;
-
-               case CMD_DEBUG_PRINT_INTEGERS: {
-                       PrintAndLog("#db# %08x, %08x, %08x       \r\n", UC->arg[0], UC->arg[1], UC->arg[2]);
-                       return;
-               } break;
-
-               case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
-                       memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
-                       return;
-               } break;
-
-               default:
-                       storeCommand(UC);
-                       break;
-       }
-
-}
-
index d39bc114a107a3f3beb1939abf11322ee7e9ec61..a833b41ebf2a03d2f3bb6ba9edb801c7106c02a2 100644 (file)
 #include <stddef.h>
 #include "usb_cmd.h"
 #include "cmdparser.h"
 #include <stddef.h>
 #include "usb_cmd.h"
 #include "cmdparser.h"
+#include "comms.h"
+
 
 
-extern void UsbCommandReceived(UsbCommand *UC);
 extern int CommandReceived(char *Cmd);
 extern int CommandReceived(char *Cmd);
-extern bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
-extern bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
-extern bool WaitForResponse(uint32_t cmd, UsbCommand* response);
-extern void clearCommandBuffer();
 extern command_t* getTopLevelCommandTable();
 
 #endif
 extern command_t* getTopLevelCommandTable();
 
 #endif
index 3250899795d92fd47c1b0af1ebcebb7644cc43fd..28ca2196798fe4b71a578a9824deb9b34f212255 100644 (file)
@@ -14,6 +14,7 @@
 #include "ui.h"
 #include "cmdparser.h"
 #include "proxmark3.h"
 #include "ui.h"
 #include "cmdparser.h"
 #include "proxmark3.h"
+#include "comms.h"
 
 
 void CmdsHelp(const command_t Commands[])
 
 
 void CmdsHelp(const command_t Commands[])
@@ -23,7 +24,7 @@ void CmdsHelp(const command_t Commands[])
   int i = 0;
   while (Commands[i].Name)
   {
   int i = 0;
   while (Commands[i].Name)
   {
-    if (!offline || Commands[i].Offline)
+    if (!IsOffline() || Commands[i].Offline)
        PrintAndLog("%-16s %s", Commands[i].Name, Commands[i].Help);
     ++i;
   }
        PrintAndLog("%-16s %s", Commands[i].Name, Commands[i].Help);
     ++i;
   }
diff --git a/client/comms.c b/client/comms.c
new file mode 100644 (file)
index 0000000..abbae38
--- /dev/null
@@ -0,0 +1,325 @@
+//-----------------------------------------------------------------------------
+// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
+// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// Code for communicating with the proxmark3 hardware.
+//-----------------------------------------------------------------------------
+
+#include <pthread.h>
+
+#include "comms.h"
+#include "uart.h"
+#include "ui.h"
+#include "common.h"
+#include "data.h"
+#include "util_posix.h"
+
+// Declare globals.
+
+// Serial port that we are communicating with the PM3 on.
+static serial_port* port;
+
+// If TRUE, then there is no active connection to the PM3, and we will drop commands sent.
+static bool offline;
+
+// Transmit buffer.
+// TODO: Use locks and execute this on the main thread, rather than the receiver
+// thread.  Running on the main thread means we need to be careful in the
+// flasher, as it means SendCommand is no longer async, and can't be used as a
+// buffer for a pending command when the connection is re-established.
+static UsbCommand txcmd;
+static bool txcmd_pending;
+
+// Used by UsbReceiveCommand as a ring buffer for messages that are yet to be
+// processed by a command handler (WaitForResponse{,Timeout})
+static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
+
+// Points to the next empty position to write to
+static int cmd_head = 0;
+
+// Points to the position of the last unread command
+static int cmd_tail = 0;
+
+// to lock cmdBuffer operations from different threads
+static pthread_mutex_t cmdBufferMutex = PTHREAD_MUTEX_INITIALIZER;
+
+// These wrappers are required because it is not possible to access a static
+// global variable outside of the context of a single file.
+
+void SetSerialPort(serial_port* new_port) {
+       port = new_port;
+}
+
+serial_port* GetSerialPort() {
+       return port;
+}
+
+void SetOffline(bool new_offline) {
+       offline = new_offline;
+}
+
+bool IsOffline() {
+       return offline;
+}
+
+void SendCommand(UsbCommand *c) {
+       #ifdef COMMS_DEBUG
+       printf("Sending %04x cmd\n", c->cmd);
+       #endif
+
+       if (offline) {
+      PrintAndLog("Sending bytes to proxmark failed - offline");
+      return;
+    }
+  /**
+       The while-loop below causes hangups at times, when the pm3 unit is unresponsive
+       or disconnected. The main console thread is alive, but comm thread just spins here.
+       Not good.../holiman
+       **/
+       while(txcmd_pending);
+       txcmd = *c;
+       txcmd_pending = true;
+}
+
+/**
+ * @brief This method should be called when sending a new command to the pm3. In case any old
+ *  responses from previous commands are stored in the buffer, a call to this method should clear them.
+ *  A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which
+ *  operation. Right now we'll just have to live with this.
+ */
+void clearCommandBuffer()
+{
+       //This is a very simple operation
+       pthread_mutex_lock(&cmdBufferMutex);
+       cmd_tail = cmd_head;
+       pthread_mutex_unlock(&cmdBufferMutex);
+}
+
+/**
+ * @brief storeCommand stores a USB command in a circular buffer
+ * @param UC
+ */
+void storeCommand(UsbCommand *command)
+{
+       pthread_mutex_lock(&cmdBufferMutex);
+       if( (cmd_head+1) % CMD_BUFFER_SIZE == cmd_tail)
+       {
+               // If these two are equal, we're about to overwrite in the
+               // circular buffer.
+               PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!");
+       }
+
+       // Store the command at the 'head' location
+       UsbCommand* destination = &cmdBuffer[cmd_head];
+       memcpy(destination, command, sizeof(UsbCommand));
+
+       cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
+       pthread_mutex_unlock(&cmdBufferMutex);
+}
+
+
+/**
+ * @brief getCommand gets a command from an internal circular buffer.
+ * @param response location to write command
+ * @return 1 if response was returned, 0 if nothing has been received
+ */
+int getCommand(UsbCommand* response)
+{
+       pthread_mutex_lock(&cmdBufferMutex);
+       //If head == tail, there's nothing to read, or if we just got initialized
+       if (cmd_head == cmd_tail){
+               pthread_mutex_unlock(&cmdBufferMutex);
+               return 0;
+       }
+
+       //Pick out the next unread command
+       UsbCommand* last_unread = &cmdBuffer[cmd_tail];
+       memcpy(response, last_unread, sizeof(UsbCommand));
+       //Increment tail - this is a circular buffer, so modulo buffer size
+       cmd_tail = (cmd_tail + 1) % CMD_BUFFER_SIZE;
+
+       pthread_mutex_unlock(&cmdBufferMutex);
+       return 1;
+}
+
+//-----------------------------------------------------------------------------
+// Entry point into our code: called whenever we received a packet over USB
+// that we weren't necessarily expecting, for example a debug print.
+//-----------------------------------------------------------------------------
+void UsbCommandReceived(UsbCommand *UC)
+{
+       switch(UC->cmd) {
+
+       // First check if we are handling a debug message
+       case CMD_DEBUG_PRINT_STRING: {
+               char s[USB_CMD_DATA_SIZE+1];
+               memset(s, 0x00, sizeof(s));
+               size_t len = MIN(UC->arg[0],USB_CMD_DATA_SIZE);
+               memcpy(s,UC->d.asBytes,len);
+               PrintAndLog("#db# %s", s);
+               return;
+       }
+
+       case CMD_DEBUG_PRINT_INTEGERS: {
+               PrintAndLog("#db# %08x, %08x, %08x       \r\n", UC->arg[0], UC->arg[1], UC->arg[2]);
+               return;
+       }
+
+       case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
+               // FIXME: This does unsanitised copies into memory when we don't know
+               // the size of the buffer.
+               if (sample_buf) {
+                       memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
+               }
+               return;
+       }
+
+       default: {
+               storeCommand(UC);
+               return;
+       }
+       }
+}
+
+// Gets a single command from a proxmark3 device. This should never be used
+// with the full client.
+//
+// @param conn A receiver_arg structure.
+// @param command A buffer to store the received command.
+bool ReceiveCommand(receiver_arg* conn, UsbCommand* command) {
+       // Local recieve buffer
+       size_t rxlen;
+       byte_t rx[sizeof(UsbCommand)];
+       byte_t* prx = rx;
+
+       while (conn->run) {
+               rxlen = 0;
+               if (uart_receive(port, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) {
+                       prx += rxlen;
+                       if (prx-rx < sizeof(UsbCommand)) {
+                               // Keep reading until we have a completed response.
+                               continue;
+                       }
+
+                       // We have a completed response.
+                       memcpy(command, rx, sizeof(UsbCommand));
+                       return true;
+               }
+
+               if (prx == rx) {
+                       // We got no complete command while waiting, give up control
+                       return false;
+               }
+       }
+
+       // did not get a complete command before being cancelled.
+       return false;
+}
+
+// Worker thread for processing incoming events from the PM3
+void *uart_receiver(void *targ) {
+       receiver_arg *conn = (receiver_arg*)targ;
+       UsbCommand rx;
+
+       while (conn->run) {
+               #ifdef COMMS_DEBUG
+               printf("uart_receiver: get lock\n");
+               #endif
+               // Lock up receives, in case they try to take it away from us.
+               pthread_mutex_lock(&conn->recv_lock);
+               #ifdef COMMS_DEBUG
+               printf("uart_receiver: lock acquired\n");
+               #endif
+
+               if (port == NULL) {
+                       #ifdef COMMS_DEBUG
+                       printf("uart_receiver: port disappeared\n");
+                       #endif
+                       // Our port disappeared, stall. This code path matters for the flasher,
+                       // where it is fiddling with the serial port under us.
+                       pthread_mutex_unlock(&conn->recv_lock);
+                       msleep(10);
+                       continue;
+               }
+
+               bool got_command = ReceiveCommand(conn, &rx);
+               #ifdef COMMS_DEBUG
+               printf("uart_receiver: got command\n");
+               #endif
+               pthread_mutex_unlock(&conn->recv_lock);
+
+               if (got_command) {
+                       UsbCommandReceived(&rx);
+               }
+
+               // We aren't normally trying to transmit in the flasher when the port would
+               // be reset, so we can just keep going at this point.
+               if (txcmd_pending) {
+                       if (!uart_send(port, (byte_t*) &txcmd, sizeof(UsbCommand))) {
+                               PrintAndLog("Sending bytes to proxmark failed");
+                       }
+                       txcmd_pending = false;
+               }
+       }
+
+       pthread_exit(NULL);
+       return NULL;
+}
+
+/**
+ * Waits for a certain response type. This method waits for a maximum of
+ * ms_timeout milliseconds for a specified response command.
+ *@brief WaitForResponseTimeout
+ * @param cmd command to wait for, or CMD_ANY to take any command.
+ * @param response struct to copy received command into.
+ * @param ms_timeout
+ * @param show_warning
+ * @return true if command was returned, otherwise false
+ */
+bool WaitForResponseTimeoutW(uint64_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning) {
+       UsbCommand resp;
+
+       #ifdef COMMS_DEBUG
+       printf("Waiting for %04x cmd\n", cmd);
+       #endif
+       
+       if (response == NULL) {
+               response = &resp;
+       }
+
+       uint64_t start_time = msclock();
+
+       // Wait until the command is received
+       for (;;) {
+               while(getCommand(response)) {
+                       if (cmd == CMD_ANY || response->cmd == cmd) {
+                               return true;
+                       }
+               }
+               
+               if (msclock() - start_time > ms_timeout) {
+                       // We timed out.
+                       break;
+               }
+               
+               if (msclock() - start_time > 2000 && show_warning) {
+                       // 2 seconds elapsed (but this doesn't mean the timeout was exceeded)
+                       PrintAndLog("Waiting for a response from the proxmark...");
+                       PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
+                       break;
+               }
+       }
+       return false;
+}
+
+bool WaitForResponseTimeout(uint64_t cmd, UsbCommand* response, size_t ms_timeout) {
+       return WaitForResponseTimeoutW(cmd, response, ms_timeout, true);
+}
+
+bool WaitForResponse(uint64_t cmd, UsbCommand* response) {
+       return WaitForResponseTimeout(cmd, response, -1);
+}
diff --git a/client/comms.h b/client/comms.h
new file mode 100644 (file)
index 0000000..75adeea
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef COMMS_H_
+#define COMMS_H_
+
+#include <stdbool.h>
+#include <pthread.h>
+
+#include "usb_cmd.h"
+#include "uart.h"
+
+#ifndef CMD_BUFFER_SIZE
+#define CMD_BUFFER_SIZE 50
+#endif
+
+#ifndef MAX_DEMOD_BUF_LEN
+#define MAX_DEMOD_BUF_LEN (1024*128)
+#endif
+
+#ifndef BIGBUF_SIZE
+#define BIGBUF_SIZE 40000
+#endif
+
+typedef struct {
+       // If TRUE, continue running the uart_receiver thread.
+       bool run;
+
+       // Lock around serial port receives
+       pthread_mutex_t recv_lock;
+} receiver_arg;
+
+
+// Wrappers required as static variables can only be used in one file.
+void SetSerialPort(serial_port* new_port);
+serial_port* GetSerialPort();
+void SetOffline(bool new_offline);
+bool IsOffline();
+
+void SendCommand(UsbCommand *c);
+void *uart_receiver(void *targ);
+void UsbCommandReceived(UsbCommand *UC);
+void clearCommandBuffer();
+bool WaitForResponseTimeoutW(uint64_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
+bool WaitForResponseTimeout(uint64_t cmd, UsbCommand* response, size_t ms_timeout);
+bool WaitForResponse(uint64_t cmd, UsbCommand* response);
+
+#endif // COMMS_H_
index 7622e8a5b56553939ed805504ff28d8ecc4090a6..bf01b911f116b7d2a89cfd2a792f43dcfdde5af7 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdlib.h>
 #include <inttypes.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <inttypes.h>
 #include <unistd.h>
+
 #include "proxmark3.h"
 #include "util.h"
 #include "util_posix.h"
 #include "proxmark3.h"
 #include "util.h"
 #include "util_posix.h"
 #include "elf.h"
 #include "proxendian.h"
 #include "usb_cmd.h"
 #include "elf.h"
 #include "proxendian.h"
 #include "usb_cmd.h"
-
-void SendCommand(UsbCommand* txcmd);
-void ReceiveCommand(UsbCommand* rxcmd);
-void CloseProxmark();
-int OpenProxmark(size_t i);
+#include "comms.h"
 
 // FIXME: what the fuckity fuck
 unsigned int current_command = CMD_UNKNOWN;
 
 // FIXME: what the fuckity fuck
 unsigned int current_command = CMD_UNKNOWN;
@@ -44,6 +41,32 @@ static const uint8_t elf_ident[] = {
        EV_CURRENT
 };
 
        EV_CURRENT
 };
 
+void CloseProxmark(receiver_arg* conn, char* serial_port_name) {
+       pthread_mutex_lock(&conn->recv_lock);
+
+       // Block the port from being used by anything
+       serial_port* my_port = GetSerialPort();
+       SetSerialPort(NULL);
+
+       // Then close the port.
+       uart_close(my_port);
+       pthread_mutex_unlock(&conn->recv_lock);
+
+       // Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
+       unlink(serial_port_name);
+}
+
+bool OpenProxmark(char* serial_port_name) {
+       serial_port *new_port = uart_open(serial_port_name);
+       if (new_port == INVALID_SERIAL_PORT || new_port == CLAIMED_SERIAL_PORT) {
+               //poll once a second
+               return false;
+       }
+       
+       SetSerialPort(new_port);
+       return true;
+}
+
 // Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent
 // unaligned segments if needed
 static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, int num_phdrs)
 // Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent
 // unaligned segments if needed
 static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, int num_phdrs)
@@ -278,9 +301,12 @@ static int get_proxmark_state(uint32_t *state)
 {
        UsbCommand c;
        c.cmd = CMD_DEVICE_INFO;
 {
        UsbCommand c;
        c.cmd = CMD_DEVICE_INFO;
-  SendCommand(&c);
+       SendCommand(&c);
        UsbCommand resp;
        UsbCommand resp;
-       ReceiveCommand(&resp);
+       while (!WaitForResponse(CMD_ANY, &resp)) {
+               // Keep waiting for a response
+               msleep(100);
+       }
 
        // Three outcomes:
        // 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
 
        // Three outcomes:
        // 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
@@ -307,7 +333,7 @@ static int get_proxmark_state(uint32_t *state)
 }
 
 // Enter the bootloader to be able to start flashing
 }
 
 // Enter the bootloader to be able to start flashing
-static int enter_bootloader(char *serial_port_name)
+static int enter_bootloader(receiver_arg* conn, char *serial_port_name)
 {
        uint32_t state;
 
 {
        uint32_t state;
 
@@ -338,16 +364,17 @@ static int enter_bootloader(char *serial_port_name)
                        SendCommand(&c);
                        fprintf(stderr,"Press and hold down button NOW if your bootloader requires it.\n");
                }
                        SendCommand(&c);
                        fprintf(stderr,"Press and hold down button NOW if your bootloader requires it.\n");
                }
-    msleep(100);
-               CloseProxmark();
+               
+               msleep(100);
+               CloseProxmark(conn, serial_port_name);
 
                fprintf(stderr,"Waiting for Proxmark to reappear on %s",serial_port_name);
 
                fprintf(stderr,"Waiting for Proxmark to reappear on %s",serial_port_name);
-    do {
+               do {
                        sleep(1);
                        fprintf(stderr, ".");
                        sleep(1);
                        fprintf(stderr, ".");
-               } while (!OpenProxmark(0));
+               } while (!OpenProxmark(serial_port_name));
+               
                fprintf(stderr," Found.\n");
                fprintf(stderr," Found.\n");
-
                return 0;
        }
 
                return 0;
        }
 
@@ -355,23 +382,25 @@ static int enter_bootloader(char *serial_port_name)
        return -1;
 }
 
        return -1;
 }
 
-static int wait_for_ack(void)
+static int wait_for_ack()
 {
 {
-  UsbCommand ack;
-       ReceiveCommand(&ack);
-       if (ack.cmd != CMD_ACK) {
-               printf("Error: Unexpected reply 0x%04" PRIx64 " (expected ACK)\n", ack.cmd);
+       UsbCommand resp;
+       while (!WaitForResponse(CMD_ANY, &resp)) {
+               msleep(100);
+       }
+       if (resp.cmd != CMD_ACK) {
+               printf("Error: Unexpected reply 0x%04" PRIx64 " (expected ACK)\n", resp.cmd);
                return -1;
        }
        return 0;
 }
 
 // Go into flashing mode
                return -1;
        }
        return 0;
 }
 
 // Go into flashing mode
-int flash_start_flashing(int enable_bl_writes,char *serial_port_name)
+int flash_start_flashing(receiver_arg* conn, int enable_bl_writes,char *serial_port_name)
 {
        uint32_t state;
 
 {
        uint32_t state;
 
-       if (enter_bootloader(serial_port_name) < 0)
+       if (enter_bootloader(conn, serial_port_name) < 0)
                return -1;
 
        if (get_proxmark_state(&state) < 0)
                return -1;
 
        if (get_proxmark_state(&state) < 0)
@@ -470,9 +499,9 @@ void flash_free(flash_file_t *ctx)
 }
 
 // just reset the unit
 }
 
 // just reset the unit
-int flash_stop_flashing(void) {
+int flash_stop_flashing() {
        UsbCommand c = {CMD_HARDWARE_RESET};
        UsbCommand c = {CMD_HARDWARE_RESET};
-  SendCommand(&c);
-  msleep(100);
-  return 0;
+       SendCommand(&c);
+       msleep(100);
+       return 0;
 }
 }
index 3e9f77a7aa2b5ba5a1fae6ccff2f650a432f5bd1..279062af372ac72159107e7c254c9bbb3f87b0e8 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <stdint.h>
 #include "elf.h"
 
 #include <stdint.h>
 #include "elf.h"
+#include "comms.h"
 
 typedef struct {
        void *data;
 
 typedef struct {
        void *data;
@@ -26,10 +27,12 @@ typedef struct {
 } flash_file_t;
 
 int flash_load(flash_file_t *ctx, const char *name, int can_write_bl);
 } flash_file_t;
 
 int flash_load(flash_file_t *ctx, const char *name, int can_write_bl);
-int flash_start_flashing(int enable_bl_writes,char *serial_port_name);
+int flash_start_flashing(receiver_arg* conn, int enable_bl_writes, char *serial_port_name);
 int flash_write(flash_file_t *ctx);
 void flash_free(flash_file_t *ctx);
 int flash_stop_flashing(void);
 int flash_write(flash_file_t *ctx);
 void flash_free(flash_file_t *ctx);
 int flash_stop_flashing(void);
+void CloseProxmark(receiver_arg* conn, char* serial_port_name);
+bool OpenProxmark(char* serial_port_name);
 
 #endif
 
 
 #endif
 
index f257d994517b4c6a7a5675a83c5f4f13890cfac7..40e40524e6dc8e317cce0a53ccda779b82b77445 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
+#include <pthread.h>
+
 #include "proxmark3.h"
 #include "util.h"
 #include "util_posix.h"
 #include "flash.h"
 #include "uart.h"
 #include "usb_cmd.h"
 #include "proxmark3.h"
 #include "util.h"
 #include "util_posix.h"
 #include "flash.h"
 #include "uart.h"
 #include "usb_cmd.h"
+#include "comms.h"
 
 #ifdef _WIN32
 # define unlink(x)
 
 #ifdef _WIN32
 # define unlink(x)
@@ -23,9 +26,6 @@
 # include <unistd.h>
 #endif
 
 # include <unistd.h>
 #endif
 
-static serial_port sp;
-static char* serial_port_name;
-
 void cmd_debug(UsbCommand* UC) {
   //  Debug
   printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand));
 void cmd_debug(UsbCommand* UC) {
   //  Debug
   printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand));
@@ -40,45 +40,6 @@ void cmd_debug(UsbCommand* UC) {
   printf("...\n");
 }
 
   printf("...\n");
 }
 
-void SendCommand(UsbCommand* txcmd) {
-//  printf("send: ");
-//  cmd_debug(txcmd);
-  if (!uart_send(sp,(byte_t*)txcmd,sizeof(UsbCommand))) {
-    printf("Sending bytes to proxmark failed\n");
-    exit(1);
-  }
-}
-
-void ReceiveCommand(UsbCommand* rxcmd) {
-  byte_t* prxcmd = (byte_t*)rxcmd;
-  byte_t* prx = prxcmd;
-  size_t rxlen;
-  while (true) {
-    if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-prxcmd), &rxlen)) {
-      prx += rxlen;
-      if ((prx-prxcmd) >= sizeof(UsbCommand)) {
-        return;
-      }
-    }
-  }
-}
-
-void CloseProxmark() {
-  // Clean up the port
-  uart_close(sp);
-  // Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
-  unlink(serial_port_name);
-}
-
-int OpenProxmark(size_t i) {
-  sp = uart_open(serial_port_name);
-  if (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT) {
-    //poll once a second
-    return 0;
-  }
-  return 1;
-}
-
 static void usage(char *argv0)
 {
        fprintf(stderr, "Usage:   %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
 static void usage(char *argv0)
 {
        fprintf(stderr, "Usage:   %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
@@ -86,9 +47,10 @@ static void usage(char *argv0)
        //Is the example below really true? /Martin
        fprintf(stderr, "Example:\n\n\t %s path/to/osimage.elf path/to/fpgaimage.elf\n", argv0);
        fprintf(stderr, "\nExample (Linux):\n\n\t %s  /dev/ttyACM0 armsrc/obj/fullimage.elf\n", argv0);
        //Is the example below really true? /Martin
        fprintf(stderr, "Example:\n\n\t %s path/to/osimage.elf path/to/fpgaimage.elf\n", argv0);
        fprintf(stderr, "\nExample (Linux):\n\n\t %s  /dev/ttyACM0 armsrc/obj/fullimage.elf\n", argv0);
-       fprintf(stderr, "\nNote (Linux): if the flasher gets stuck in 'Waiting for Proxmark to reappear on <DEVICE>',\n");
-       fprintf(stderr, "              you need to blacklist proxmark for modem-manager - see wiki for more details:\n");
-       fprintf(stderr, "              http://code.google.com/p/proxmark3/wiki/Linux\n\n");
+       fprintf(stderr, "\nNote (Linux): if the flasher gets stuck at 'Waiting for Proxmark to reappear',\n");
+       fprintf(stderr, "       you may need to blacklist proxmark for modem-manager. v1.4.14 and later\n");
+       fprintf(stderr, "       include this configuration patch already. The change can be found at:\n");
+       fprintf(stderr, "       https://cgit.freedesktop.org/ModemManager/ModemManager/commit/?id=6e7ff47\n\n");
 }
 
 #define MAX_FILES 4
 }
 
 #define MAX_FILES 4
@@ -99,7 +61,10 @@ int main(int argc, char **argv)
        int num_files = 0;
        int res;
        flash_file_t files[MAX_FILES];
        int num_files = 0;
        int res;
        flash_file_t files[MAX_FILES];
+       receiver_arg conn;
+       pthread_t reader_thread;
 
 
+       memset(&conn, 0, sizeof(receiver_arg));
        memset(files, 0, sizeof(files));
 
        if (argc < 3) {
        memset(files, 0, sizeof(files));
 
        if (argc < 3) {
@@ -126,16 +91,22 @@ int main(int argc, char **argv)
                }
        }
 
                }
        }
 
-  serial_port_name = argv[1];
-  
-  fprintf(stderr,"Waiting for Proxmark to appear on %s",serial_port_name);
-  do {
-    msleep(1000);
-    fprintf(stderr, ".");
-  } while (!OpenProxmark(0));
-  fprintf(stderr," Found.\n");
+       pthread_mutex_init(&conn.recv_lock, NULL);
+
+       char* serial_port_name = argv[1];
+
+       fprintf(stderr,"Waiting for Proxmark to appear on %s", serial_port_name);
+       do {
+               sleep(1);
+               fprintf(stderr, ".");
+       } while (!OpenProxmark(serial_port_name));
+       fprintf(stderr," Found.\n");
+
+       // Lets start up the communications thread
+       conn.run = true;
+       pthread_create(&reader_thread, NULL, &uart_receiver, &conn);
 
 
-       res = flash_start_flashing(can_write_bl,serial_port_name);
+       res = flash_start_flashing(&conn, can_write_bl, serial_port_name);
        if (res < 0)
                return -1;
 
        if (res < 0)
                return -1;
 
@@ -155,7 +126,11 @@ int main(int argc, char **argv)
        if (res < 0)
                return -1;
 
        if (res < 0)
                return -1;
 
-       CloseProxmark();
+       // Stop the command thread.
+       conn.run = false;
+       pthread_join(reader_thread, NULL);
+       CloseProxmark(&conn, serial_port_name);
+       pthread_mutex_destroy(&conn.recv_lock);
 
        fprintf(stderr, "All done.\n\n");
        fprintf(stderr, "Have a nice day!\n");
 
        fprintf(stderr, "All done.\n\n");
        fprintf(stderr, "Have a nice day!\n");
index e899174c419870e2e78014e609f0f3faa2f38f04..6e4ec98e9f6880d6fcd75ed81b035f50ea904d39 100644 (file)
 #include "proxgui.h"
 #include "proxguiqt.h"
 #include "proxmark3.h"
 #include "proxgui.h"
 #include "proxguiqt.h"
 #include "proxmark3.h"
+#include "uart.h"
 
 static ProxGuiQT *gui = NULL;
 static WorkerThread *main_loop_thread = NULL;
 
 
 static ProxGuiQT *gui = NULL;
 static WorkerThread *main_loop_thread = NULL;
 
-WorkerThread::WorkerThread(char *script_cmds_file, char *script_cmd, bool usb_present) : script_cmds_file(script_cmds_file), script_cmd(script_cmd), usb_present(usb_present)
+WorkerThread::WorkerThread(char *script_cmds_file, char *script_cmd,
+                           bool usb_present, serial_port* sp)
+       : script_cmds_file(script_cmds_file), script_cmd(script_cmd),
+         usb_present(usb_present), sp(sp)
 {
 }
 
 {
 }
 
@@ -24,7 +28,7 @@ WorkerThread::~WorkerThread()
 }
 
 void WorkerThread::run() {
 }
 
 void WorkerThread::run() {
-       main_loop(script_cmds_file, script_cmd, usb_present);
+       main_loop(script_cmds_file, script_cmd, usb_present, sp);
 }
 
 extern "C" void ShowGraphWindow(void)
 }
 
 extern "C" void ShowGraphWindow(void)
@@ -59,7 +63,9 @@ extern "C" void MainGraphics(void)
        gui->MainLoop();
 }
 
        gui->MainLoop();
 }
 
-extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool usb_present)
+extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file,
+                             char *script_cmd, bool usb_present,
+                             serial_port* sp)
 {
 #ifdef Q_WS_X11
        bool useGUI = getenv("DISPLAY") != 0;
 {
 #ifdef Q_WS_X11
        bool useGUI = getenv("DISPLAY") != 0;
@@ -69,7 +75,7 @@ extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file, char
        if (!useGUI)
                return;
 
        if (!useGUI)
                return;
 
-       main_loop_thread = new WorkerThread(script_cmds_file, script_cmd, usb_present);
+       main_loop_thread = new WorkerThread(script_cmds_file, script_cmd, usb_present, sp);
        gui = new ProxGuiQT(argc, argv, main_loop_thread);
 }
 
        gui = new ProxGuiQT(argc, argv, main_loop_thread);
 }
 
index 77bcbf011e4c0cd320043d26d96b2ab9d0372539..ea3abf32497a34f2aa95d1464f7ae67c9bc17c06 100644 (file)
@@ -14,12 +14,13 @@ extern "C" {
 
 #include <stdint.h>
 #include <string.h>
 
 #include <stdint.h>
 #include <string.h>
+#include "uart.h"
 
 void ShowGraphWindow(void);
 void HideGraphWindow(void);
 void RepaintGraphWindow(void);
 void MainGraphics(void);
 
 void ShowGraphWindow(void);
 void HideGraphWindow(void);
 void RepaintGraphWindow(void);
 void MainGraphics(void);
-void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool usb_present);
+void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool usb_present, serial_port* sp);
 void ExitGraphics(void);
 
 #define MAX_GRAPH_TRACE_LEN (40000*8)
 void ExitGraphics(void);
 
 #define MAX_GRAPH_TRACE_LEN (40000*8)
@@ -30,7 +31,6 @@ extern int s_Buff[MAX_GRAPH_TRACE_LEN];
 extern double CursorScaleFactor;
 extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
 extern int CommandFinished;
 extern double CursorScaleFactor;
 extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
 extern int CommandFinished;
-extern int offline;
 extern bool GridLocked;
 
 //Operations defined in data_operations
 extern bool GridLocked;
 
 //Operations defined in data_operations
index 45a65b040c5702dc922644c8deb18bbbbe6206a0..4b2b2a2773054db7f24d38c7c090ea28b71b0bc8 100644 (file)
@@ -21,6 +21,7 @@
 #include <QPainter>
 #include <QtGui>
 
 #include <QPainter>
 #include <QtGui>
 
+#include "uart.h"
 #include "ui/ui_overlays.h"
 /**
  * @brief The actual plot, black area were we paint the graph
 #include "ui/ui_overlays.h"
 /**
  * @brief The actual plot, black area were we paint the graph
@@ -91,13 +92,14 @@ class ProxWidget : public QWidget
 class WorkerThread : public QThread {
                Q_OBJECT;
        public:
 class WorkerThread : public QThread {
                Q_OBJECT;
        public:
-               WorkerThread(char*, char*, bool);
+               WorkerThread(char*, char*, bool, serial_port*);
                ~WorkerThread();
                void run();
        private:
                char *script_cmds_file = NULL;
                char *script_cmd = NULL;
                bool usb_present;
                ~WorkerThread();
                void run();
        private:
                char *script_cmds_file = NULL;
                char *script_cmd = NULL;
                bool usb_present;
+               serial_port *sp = NULL;
 };
 
 class ProxGuiQT : public QObject
 };
 
 class ProxGuiQT : public QObject
index 99ba9fbad77ec9dbcea40bc0b36074ea7914b0e5..0acf34f682d23946ab8495b620de943d0af7e996 100644 (file)
 #include "cmdparser.h"
 #include "cmdhw.h"
 #include "whereami.h"
 #include "cmdparser.h"
 #include "cmdhw.h"
 #include "whereami.h"
+#include "comms.h"
 
 #ifdef _WIN32
 #define SERIAL_PORT_H  "com3"
 
 #ifdef _WIN32
 #define SERIAL_PORT_H  "com3"
+#elif __APPLE__
+#define SERIAL_PORT_H  "/dev/tty.usbmodem*"
 #else
 #define SERIAL_PORT_H  "/dev/ttyACM0"
 #endif
 
 #else
 #define SERIAL_PORT_H  "/dev/ttyACM0"
 #endif
 
-// a global mutex to prevent interlaced printing from different threads
-pthread_mutex_t print_lock;
-
-static serial_port sp;
-static UsbCommand txcmd;
-volatile static bool txcmd_pending = false;
-
-void SendCommand(UsbCommand *c) {
-       #if 0
-               printf("Sending %d bytes\n", sizeof(UsbCommand));
-       #endif
-
-       if (offline) {
-      PrintAndLog("Sending bytes to proxmark failed - offline");
-      return;
-    }
-  /**
-       The while-loop below causes hangups at times, when the pm3 unit is unresponsive
-       or disconnected. The main console thread is alive, but comm thread just spins here.
-       Not good.../holiman
-       **/
-       while(txcmd_pending);
-       txcmd = *c;
-       txcmd_pending = true;
-}
-
-struct receiver_arg {
-       int run;
-};
-
-byte_t rx[sizeof(UsbCommand)];
-byte_t* prx = rx;
-
-static void *uart_receiver(void *targ) {
-       struct receiver_arg *arg = (struct receiver_arg*)targ;
-       size_t rxlen;
-
-       while (arg->run) {
-               rxlen = 0;
-               if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) {
-                       prx += rxlen;
-                       if (prx-rx < sizeof(UsbCommand)) {
-                               continue;
-                       }
-                       UsbCommandReceived((UsbCommand*)rx);
-               }
-               prx = rx;
-
-               if(txcmd_pending) {
-                       if (!uart_send(sp, (byte_t*) &txcmd, sizeof(UsbCommand))) {
-                               PrintAndLog("Sending bytes to proxmark failed");
-                       }
-                       txcmd_pending = false;
-               }
-       }
-
-       pthread_exit(NULL);
-       return NULL;
-}
-
-
-void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
-       struct receiver_arg rarg;
+void main_loop(char *script_cmds_file, char* script_cmd, bool usb_present, serial_port* sp) {
+       receiver_arg conn;
        char *cmd = NULL;
        pthread_t reader_thread;
        bool execCommand = (script_cmd != NULL);
        bool stdinOnPipe = !isatty(STDIN_FILENO);
        char *cmd = NULL;
        pthread_t reader_thread;
        bool execCommand = (script_cmd != NULL);
        bool stdinOnPipe = !isatty(STDIN_FILENO);
-       
+
+       memset(&conn, 0, sizeof(receiver_arg));
+       pthread_mutex_init(&conn.recv_lock, NULL);
+
+
+       // TODO: Move this into comms.c
+       PlotGridXdefault = 64;
+       PlotGridYdefault = 64;
+       showDemod = true;
+       CursorScaleFactor = 1;
+
        if (usb_present) {
        if (usb_present) {
-               rarg.run = 1;
-               pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
+               conn.run = true;
+               SetSerialPort(sp);
+               SetOffline(false);
+               pthread_create(&reader_thread, NULL, &uart_receiver, &conn);
                // cache Version information now:
                CmdVersion(NULL);
                // cache Version information now:
                CmdVersion(NULL);
+       } else {
+               SetOffline(true);
        }
 
        // file with script
        }
 
        // file with script
@@ -122,7 +78,7 @@ void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
        
        read_history(".history");
 
        
        read_history(".history");
 
-       while(1)  {
+       while (1) {
                // If there is a script file
                if (script_file)
                {
                // If there is a script file
                if (script_file)
                {
@@ -194,7 +150,7 @@ void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
        write_history(".history");
   
        if (usb_present) {
        write_history(".history");
   
        if (usb_present) {
-               rarg.run = 0;
+               conn.run = false;
                pthread_join(reader_thread, NULL);
        }
        
                pthread_join(reader_thread, NULL);
        }
        
@@ -202,6 +158,8 @@ void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
                fclose(script_file);
                script_file = NULL;
        }
                fclose(script_file);
                script_file = NULL;
        }
+
+       pthread_mutex_destroy(&conn.recv_lock);
 }
 
 static void dumpAllHelp(int markdown)
 }
 
 static void dumpAllHelp(int markdown)
@@ -274,6 +232,8 @@ int main(int argc, char* argv[]) {
        bool addLuaExec = false;
        char *script_cmds_file = NULL;
        char *script_cmd = NULL;
        bool addLuaExec = false;
        char *script_cmds_file = NULL;
        char *script_cmd = NULL;
+       serial_port *sp = NULL;
+       g_debugMode = 0;
   
        if (argc < 2) {
                show_help(true, argv[0]);
   
        if (argc < 2) {
                show_help(true, argv[0]);
@@ -370,14 +330,11 @@ int main(int argc, char* argv[]) {
        if (sp == INVALID_SERIAL_PORT) {
                printf("ERROR: invalid serial port\n");
                usb_present = false;
        if (sp == INVALID_SERIAL_PORT) {
                printf("ERROR: invalid serial port\n");
                usb_present = false;
-               offline = 1;
        } else if (sp == CLAIMED_SERIAL_PORT) {
                printf("ERROR: serial port is claimed by another process\n");
                usb_present = false;
        } else if (sp == CLAIMED_SERIAL_PORT) {
                printf("ERROR: serial port is claimed by another process\n");
                usb_present = false;
-               offline = 1;
        } else {
                usb_present = true;
        } else {
                usb_present = true;
-               offline = 0;
        }
        
        // create a mutex to avoid interlacing print commands from our different threads
        }
        
        // create a mutex to avoid interlacing print commands from our different threads
@@ -385,23 +342,23 @@ int main(int argc, char* argv[]) {
 
 #ifdef HAVE_GUI
 #ifdef _WIN32
 
 #ifdef HAVE_GUI
 #ifdef _WIN32
-       InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present);
+       InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present, sp);
        MainGraphics();
 #else
        char* display = getenv("DISPLAY");
 
        if (display && strlen(display) > 1)
        {
        MainGraphics();
 #else
        char* display = getenv("DISPLAY");
 
        if (display && strlen(display) > 1)
        {
-               InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present);
+               InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present, sp);
                MainGraphics();
        }
        else
        {
                MainGraphics();
        }
        else
        {
-               main_loop(script_cmds_file, script_cmd, usb_present);
+               main_loop(script_cmds_file, script_cmd, usb_present, sp);
        }
 #endif
 #else
        }
 #endif
 #else
-       main_loop(script_cmds_file, script_cmd, usb_present);
+       main_loop(script_cmds_file, script_cmd, usb_present, sp);
 #endif 
 
        // Clean up the port
 #endif 
 
        // Clean up the port
index c6185c436457807c1adf4e9c08a8a9f2748d623b..11b8aabdfe627a678e09ae7ae7b5500beb906433 100644 (file)
@@ -13,6 +13,7 @@
 #define PROXMARK3_H__
 
 #include "usb_cmd.h"
 #define PROXMARK3_H__
 
 #include "usb_cmd.h"
+#include "uart.h"
 
 #define PROXPROMPT "proxmark3> "
 
 
 #define PROXPROMPT "proxmark3> "
 
@@ -23,7 +24,7 @@ extern "C" {
 void SendCommand(UsbCommand *c);
 const char *get_my_executable_path(void);
 const char *get_my_executable_directory(void);
 void SendCommand(UsbCommand *c);
 const char *get_my_executable_path(void);
 const char *get_my_executable_directory(void);
-void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present);
+void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present, serial_port* sp);
 
 #ifdef __cplusplus
 }
 
 #ifdef __cplusplus
 }
index df2c3ce3c6a6909cb99317f34770853c40992f13..48869fd1049f2914f01c636b5d28280f1cf35f8b 100644 (file)
@@ -21,7 +21,7 @@
 double CursorScaleFactor = 1;
 int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
 int offline;
 double CursorScaleFactor = 1;
 int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
 int offline;
-int flushAfterWrite = 0;  //buzzy
+bool flushAfterWrite = false;  //buzzy
 int GridOffset = 0;
 bool GridLocked = false;
 bool showDemod = true;
 int GridOffset = 0;
 bool GridLocked = false;
 bool showDemod = true;
@@ -62,7 +62,6 @@ void PrintAndLog(char *fmt, ...)
        }
 #else
        // We are using libedit (OSX), which doesn't support this flag.
        }
 #else
        // We are using libedit (OSX), which doesn't support this flag.
-       int need_hack = 0;
 #endif
        
        va_start(argptr, fmt);
 #endif
        
        va_start(argptr, fmt);
@@ -72,6 +71,9 @@ void PrintAndLog(char *fmt, ...)
        va_end(argptr);
        printf("\n");
 
        va_end(argptr);
        printf("\n");
 
+       // This needs to be wrapped in ifdefs, as this if optimisation is disabled,
+       // this block won't be removed, and it'll fail at the linker.
+#ifdef RL_STATE_READCMD
        if (need_hack) {
                rl_restore_prompt();
                rl_replace_line(saved_line, 0);
        if (need_hack) {
                rl_restore_prompt();
                rl_replace_line(saved_line, 0);
@@ -79,6 +81,7 @@ void PrintAndLog(char *fmt, ...)
                rl_redisplay();
                free(saved_line);
        }
                rl_redisplay();
                free(saved_line);
        }
+#endif
        
        if (logging && logfile) {
                vfprintf(logfile, fmt, argptr2);
        
        if (logging && logfile) {
                vfprintf(logfile, fmt, argptr2);
@@ -100,3 +103,8 @@ void SetLogFilename(char *fn)
 {
   logfilename = fn;
 }
 {
   logfilename = fn;
 }
+
+void SetFlushAfterWrite(bool flush_after_write) {
+       flushAfterWrite = flush_after_write;
+}
+
index 4049033d60b01bac36cb1d3af191d784d00ac093..2986efafdaa12dd5052b57d0761202edb679acc6 100644 (file)
 
 #include <stdbool.h>
 #include <stdint.h>
 
 #include <stdbool.h>
 #include <stdint.h>
+#include <pthread.h>
+
+// a global mutex to prevent interlaced printing from different threads
+pthread_mutex_t print_lock;
+extern uint8_t g_debugMode;
 
 void ShowGui(void);
 void HideGraphWindow(void);
 
 void ShowGui(void);
 void HideGraphWindow(void);
@@ -23,8 +28,7 @@ void SetLogFilename(char *fn);
 
 extern double CursorScaleFactor;
 extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
 
 extern double CursorScaleFactor;
 extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
-extern int offline;
-extern int flushAfterWrite;   //buzzy
+extern bool flushAfterWrite;   //buzzy
 extern bool GridLocked;
 extern bool showDemod;
 
 extern bool GridLocked;
 extern bool showDemod;
 
index 26e636ca7b0c27d90dee14bf3f79d70168fd546c..cf7d5341cead23a1c9ad97fcffa1b5c4f290c219 100644 (file)
@@ -50,8 +50,9 @@ int Iso15693AddCrc(uint8_t *req, int n) {
        return n+2;
 }
 
        return n+2;
 }
 
-
+#ifdef ON_DEVICE
 int sprintf(char *str, const char *format, ...);
 int sprintf(char *str, const char *format, ...);
+#endif
 
 // returns a string representation of the UID
 // UID is transmitted and stored LSB first, displayed MSB first
 
 // returns a string representation of the UID
 // UID is transmitted and stored LSB first, displayed MSB first
index 194a9d53bdb5377246c5f8e15c56233caec69294..df2923a0677ddd3e509b1f5565fc781909f87848 100644 (file)
@@ -212,7 +212,7 @@ typedef struct{
 #define CMD_HF_SNIFFER                                                    0x0800
 
 #define CMD_UNKNOWN                                                       0xFFFF
 #define CMD_HF_SNIFFER                                                    0x0800
 
 #define CMD_UNKNOWN                                                       0xFFFF
-
+#define CMD_ANY                                               0xFFFFFFFFFFFFFFFF
 
 //Mifare simulation flags
 #define FLAG_INTERACTIVE      0x01
 
 //Mifare simulation flags
 #define FLAG_INTERACTIVE      0x01
Impressum, Datenschutz