From: pwpiwi Date: Sun, 3 Jun 2018 12:25:20 +0000 (+0200) Subject: USB comms: part 4 towards @micolous PR #463 X-Git-Tag: v3.1.0~46 X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/ad939de5017f3451376d6f559858a30bae675964 USB comms: part 4 towards @micolous PR #463 * make uart_communication(), storeCommand() and getCommand() static in comms.c * move receiver thread creation and respective mutexes to comms.c * add mutex and signal for tx buffer * use comms.c for flasher as well * remove comm functions from client/proxmark3.h * this completes isolating all USB communication related functions in comms.c * don't assume a port to be defined by a name. Change parameter in OpenProxmark() to void* * comms.c: set sp and serial_port_name to NULL when offline --- diff --git a/client/Makefile b/client/Makefile index d4ac33b2..917dc767 100644 --- a/client/Makefile +++ b/client/Makefile @@ -82,7 +82,9 @@ POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d CORESRCS = uart_posix.c \ uart_win32.c \ util.c \ - util_posix.c + util_posix.c \ + ui.c \ + comms.c CMDSRCS = crapto1/crapto1.c\ crapto1/crypto1.c\ @@ -106,7 +108,6 @@ CMDSRCS = crapto1/crapto1.c\ iso14443crc.c \ iso15693tools.c \ graph.c \ - ui.c \ cmddata.c \ lfdemod.c \ emv/crypto_polarssl.c\ @@ -169,8 +170,7 @@ CMDSRCS = crapto1/crapto1.c\ cmdscript.c\ pm3_binlib.c\ pm3_bitlib.c\ - protocols.c\ - comms.c + protocols.c cpu_arch = $(shell uname -m) ifneq ($(findstring 86, $(cpu_arch)), ) diff --git a/client/cmddata.c b/client/cmddata.c index 471665b7..c4f0e8a3 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -8,14 +8,15 @@ // Data and Graph commands //----------------------------------------------------------------------------- +#include "cmddata.h" + #include // also included in util.h #include // also included in util.h #include #include // for CmdNorm INT_MIN && INT_MAX -#include "cmddata.h" #include "util.h" #include "cmdmain.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" // for show graph controls #include "graph.h" // for graph data #include "cmdparser.h"// already included in cmdmain.h diff --git a/client/cmdhf.c b/client/cmdhf.c index 4a672255..17c31209 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -9,17 +9,18 @@ // High frequency commands //----------------------------------------------------------------------------- +#include "cmdhf.h" + #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "util.h" #include "ui.h" #include "iso14443crc.h" #include "parity.h" #include "cmdmain.h" #include "cmdparser.h" -#include "cmdhf.h" #include "cmdhf14a.h" #include "cmdhf14b.h" #include "cmdhf15.h" diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 4684ae29..859dec2f 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -20,7 +20,7 @@ #include "util.h" #include "util_posix.h" #include "iso14443crc.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "cmdparser.h" #include "common.h" diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index bae40c09..ff0bf7c9 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -8,18 +8,19 @@ // High frequency ISO14443B commands //----------------------------------------------------------------------------- +#include "cmdhf14b.h" + #include #include #include #include #include #include "iso14443crc.h" -#include "proxmark3.h" +#include "comms.h" #include "graph.h" #include "util.h" #include "ui.h" #include "cmdparser.h" -#include "cmdhf14b.h" #include "cmdmain.h" #include "cmdhf14a.h" diff --git a/client/cmdhf14b.h b/client/cmdhf14b.h index a45b7434..4fcae927 100644 --- a/client/cmdhf14b.h +++ b/client/cmdhf14b.h @@ -11,6 +11,8 @@ #ifndef CMDHF14B_H__ #define CMDHF14B_H__ +#include + int CmdHF14B(const char *Cmd); int CmdHF14BList(const char *Cmd); int CmdHF14BInfo(const char *Cmd); diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 570a0420..08cc3b15 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -22,17 +22,18 @@ // the client. Signal Processing & decoding is done on the pc. This is the slowest // variant, but offers the possibility to analyze the waveforms directly. +#include "cmdhf15.h" + #include #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "graph.h" #include "ui.h" #include "util.h" #include "cmdparser.h" -#include "cmdhf15.h" #include "iso15693tools.h" #include "cmdmain.h" diff --git a/client/cmdhf15.h b/client/cmdhf15.h index c6264604..d0517fe5 100644 --- a/client/cmdhf15.h +++ b/client/cmdhf15.h @@ -11,6 +11,8 @@ #ifndef CMDHF15_H__ #define CMDHF15_H__ +#include + int CmdHF15(const char *Cmd); int CmdHF15Demod(const char *Cmd); diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index f3456afb..ac1f4268 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -17,7 +17,7 @@ #include #include "util.h" #include "util_posix.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "cmdparser.h" #include "common.h" diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index e99c3285..499f7aae 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -16,7 +16,7 @@ #include #include #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "cmdparser.h" #include "cmdhficlass.h" diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 9c9613ae..691e1978 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -8,15 +8,17 @@ // High frequency Legic commands //----------------------------------------------------------------------------- +#include "cmdhflegic.h" + #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "cmdparser.h" -#include "cmdhflegic.h" #include "cmdmain.h" #include "util.h" + static int CmdHelp(const char *Cmd); static command_t CommandTable[] = diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index a2da01c9..b50d6013 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -15,7 +15,7 @@ #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "cmdmain.h" #include "cmdhfmfhard.h" #include "parity.h" diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index cf19436c..be618d6e 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -25,6 +25,7 @@ #include #include #include "proxmark3.h" +#include "comms.h" #include "cmdmain.h" #include "ui.h" #include "util.h" diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index ac76c8dd..e4115d71 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -12,7 +12,7 @@ #include #include -#include "proxmark3.h" +#include "comms.h" #include "usb_cmd.h" #include "cmdmain.h" #include "ui.h" diff --git a/client/cmdhftopaz.c b/client/cmdhftopaz.c index 39ff1804..b0b8a3d2 100644 --- a/client/cmdhftopaz.c +++ b/client/cmdhftopaz.c @@ -8,17 +8,18 @@ // High frequency Topaz (NFC Type 1) commands //----------------------------------------------------------------------------- +#include "cmdhftopaz.h" + #include #include #include #include #include "cmdmain.h" #include "cmdparser.h" -#include "cmdhftopaz.h" #include "cmdhf14a.h" #include "ui.h" #include "mifare.h" -#include "proxmark3.h" +#include "comms.h" #include "iso14443crc.h" #include "protocols.h" diff --git a/client/cmdhw.c b/client/cmdhw.c index 4ede122f..bdab01eb 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -8,14 +8,15 @@ // Hardware commands //----------------------------------------------------------------------------- +#include "cmdhw.h" + #include #include #include #include #include "ui.h" -#include "proxmark3.h" +#include "comms.h" #include "cmdparser.h" -#include "cmdhw.h" #include "cmdmain.h" #include "cmddata.h" diff --git a/client/cmdlf.c b/client/cmdlf.c index 285d377a..c09a299c 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -8,14 +8,15 @@ // Low frequency commands //----------------------------------------------------------------------------- +#include "cmdlf.h" + #include #include #include #include #include #include -#include "proxmark3.h" -#include "cmdlf.h" +#include "comms.h" #include "lfdemod.h" // for psk2TOpsk1 #include "util.h" // for parsing cli command utils #include "ui.h" // for show graph controls diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 141ba172..cde94555 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -11,10 +11,11 @@ // FSK2a, RF/50, 96 bits (complete) //----------------------------------------------------------------------------- +#include "cmdlfawid.h" + #include #include // sscanf -#include "proxmark3.h" // Definitions, USB controls, etc -#include "cmdlfawid.h" +#include "comms.h" // Definitions, USB controls, etc #include "ui.h" // PrintAndLog #include "cmdparser.h" // CmdsParse, CmdsHelp #include "lfdemod.h" // parityTest + diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index ca163480..d1808c9a 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -7,13 +7,15 @@ //----------------------------------------------------------------------------- // Low frequency COTAG commands //----------------------------------------------------------------------------- + +#include "cmdlfcotag.h" + #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "cmddata.h" -#include "cmdlfcotag.h" #include "lfdemod.h" #include "usb_cmd.h" #include "cmdmain.h" diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index ff2ae5b0..cdaeb5ed 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -8,11 +8,12 @@ // Low frequency EM4x commands //----------------------------------------------------------------------------- +#include "cmdlfem4x.h" + #include #include #include -#include "cmdlfem4x.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 2e2ee9fd..20f834ce 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -13,7 +13,7 @@ #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" // for PrintAndLog #include "util.h" #include "cmdparser.h" diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 19b5a142..ca58d8ab 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -8,10 +8,11 @@ // Low frequency HID commands (known) //----------------------------------------------------------------------------- +#include "cmdlfhid.h" + #include #include -#include "cmdlfhid.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "graph.h" #include "cmdparser.h" diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 26ba9238..0fd8801b 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -8,10 +8,12 @@ // Low frequency Hitag support //----------------------------------------------------------------------------- +#include "cmdlfhitag.h" + #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "cmdparser.h" #include "common.h" diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 0a4f7834..b30231c5 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -8,10 +8,11 @@ // PSK1, rf/32, 64 or 224 bits (known) //----------------------------------------------------------------------------- +#include "cmdlfindala.h" + #include #include -#include "cmdlfindala.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "graph.h" #include "cmdparser.h" diff --git a/client/cmdlfio.c b/client/cmdlfio.c index f2f2df06..feb7d373 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -8,13 +8,14 @@ // FSK2a, rf/64, 64 bits (complete) //----------------------------------------------------------------------------- +#include "cmdlfio.h" + #include #include #include #include #include -#include "cmdlfio.h" -#include "proxmark3.h" +#include "comms.h" #include "graph.h" #include "ui.h" #include "cmdparser.h" diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 9c69099e..4756266c 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -9,10 +9,11 @@ //----------------------------------------------------------------------------- #include "cmdlfjablotron.h" + #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c index caabe835..d44c2a27 100644 --- a/client/cmdlfnexwatch.c +++ b/client/cmdlfnexwatch.c @@ -7,12 +7,14 @@ // Low frequency Honeywell NexWatch tag commands // PSK1 RF/16, RF/2, 128 bits long (known) //----------------------------------------------------------------------------- + +#include "cmdlfnexwatch.h" + #include #include #include #include -#include "cmdlfnexwatch.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 2c90fa14..52c35081 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -7,11 +7,13 @@ // Low frequency Noralsy tag commands // ASK/Manchester, STT, RF/32, 96 bits long (some bits unknown) //----------------------------------------------------------------------------- + #include "cmdlfnoralsy.h" + #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index ef6b394b..190361ec 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -7,10 +7,12 @@ // Low frequency Stanley/PAC tag commands // NRZ, RF/32, 128 bits long (unknown cs) //----------------------------------------------------------------------------- + #include "cmdlfpac.h" + #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlfpcf7931.c b/client/cmdlfpcf7931.c index ffaf946f..9c694b8d 100644 --- a/client/cmdlfpcf7931.c +++ b/client/cmdlfpcf7931.c @@ -8,9 +8,12 @@ //----------------------------------------------------------------------------- // Low frequency PCF7931 commands //----------------------------------------------------------------------------- + +#include "cmdlfpcf7931.h" + #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" @@ -18,7 +21,6 @@ #include "cmddata.h" #include "cmdmain.h" #include "cmdlf.h" -#include "cmdlfpcf7931.h" static int CmdHelp(const char *Cmd); diff --git a/client/cmdlfpcf7931.h b/client/cmdlfpcf7931.h index e093039c..8b24f03a 100644 --- a/client/cmdlfpcf7931.h +++ b/client/cmdlfpcf7931.h @@ -12,6 +12,8 @@ #ifndef CMDLFPCF7931_H__ #define CMDLFPCF7931_H__ +#include + struct pcf7931_config{ uint8_t Pwd[7]; uint16_t InitDelay; diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index 2f4bacfe..865b384b 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -7,11 +7,13 @@ // Low frequency Presco tag commands // ASK/Manchester, rf/32, 128 bits (complete) //----------------------------------------------------------------------------- + +#include "cmdlfpresco.h" + #include #include #include -#include "cmdlfpresco.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 366889f3..82367720 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -7,11 +7,13 @@ // Low frequency Farpoint / Pyramid tag commands // FSK2a, rf/50, 128 bits (complete) //----------------------------------------------------------------------------- + +#include "cmdlfpyramid.h" + #include #include #include -#include "cmdlfpyramid.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 8ae81250..44b77060 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -7,11 +7,13 @@ // Low frequency Securakey tag commands // ASK/Manchester, RF/40, 96 bits long (unknown cs) //----------------------------------------------------------------------------- + #include "cmdlfsecurakey.h" + #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index a9fbb71e..f53ff0d6 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -7,19 +7,20 @@ // Low frequency T55xx commands //----------------------------------------------------------------------------- +#include "cmdlft55xx.h" + #include #include #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "graph.h" #include "cmdmain.h" #include "cmdparser.h" #include "cmddata.h" #include "cmdlf.h" -#include "cmdlft55xx.h" #include "util.h" #include "lfdemod.h" #include "cmdhf14a.h" //for getTagInfo diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 4f0fd21d..2ae3e69b 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -10,6 +10,9 @@ #ifndef CMDLFT55XX_H__ #define CMDLFT55XX_H__ +#include +#include + typedef struct { uint32_t bl1; uint32_t bl2; diff --git a/client/cmdlfti.c b/client/cmdlfti.c index 7e0af94b..ff463971 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -14,7 +14,7 @@ #include #include #include "crc16.h" -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "graph.h" #include "cmdparser.h" diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 779156c8..73a9126a 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -7,11 +7,13 @@ // Low frequency Viking tag commands (AKA FDI Matalec Transit) // ASK/Manchester, RF/32, 64 bits (complete) //----------------------------------------------------------------------------- + +#include "cmdlfviking.h" + #include #include #include -#include "proxmark3.h" -#include "cmdlfviking.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 04589ba5..33259794 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -13,7 +13,7 @@ #include #include -#include "proxmark3.h" +#include "comms.h" #include "ui.h" #include "util.h" #include "graph.h" diff --git a/client/cmdmain.c b/client/cmdmain.c index c3b46145..01d4c9a7 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -50,13 +50,13 @@ command_t* getTopLevelCommandTable() return CommandTable; } -int CmdHelp(const char *Cmd) +static int CmdHelp(const char *Cmd) { CmdsHelp(CommandTable); return 0; } -int CmdQuit(const char *Cmd) +static int CmdQuit(const char *Cmd) { return 99; } diff --git a/client/cmdmain.h b/client/cmdmain.h index a833b41e..42b49145 100644 --- a/client/cmdmain.h +++ b/client/cmdmain.h @@ -11,12 +11,7 @@ #ifndef CMDMAIN_H__ #define CMDMAIN_H__ -#include -#include -#include "usb_cmd.h" #include "cmdparser.h" -#include "comms.h" - extern int CommandReceived(char *Cmd); extern command_t* getTopLevelCommandTable(); diff --git a/client/comms.c b/client/comms.c index b62f6fda..eeaff79c 100644 --- a/client/comms.c +++ b/client/comms.c @@ -9,33 +9,42 @@ // Code for communicating with the proxmark3 hardware. //----------------------------------------------------------------------------- -#include - #include "comms.h" + +#include +#ifdef __linux__ +#include // for unlink() +#endif #include "uart.h" #include "ui.h" #include "common.h" #include "util_posix.h" -// Declare globals. // Serial port that we are communicating with the PM3 on. -static serial_port sp; +static serial_port sp = NULL; +static char *serial_port_name = NULL; // If TRUE, then there is no active connection to the PM3, and we will drop commands sent. static bool offline; +typedef struct { + bool run; // If TRUE, continue running the uart_communication thread + bool block_after_ACK; // if true, block after receiving an ACK package +} communication_arg_t; + +static communication_arg_t conn; +static pthread_t USB_communication_thread; + // 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; -volatile static bool txcmd_pending = false; +static UsbCommand txBuffer; +static bool txBuffer_pending = false; +static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t txBufferSig = PTHREAD_COND_INITIALIZER; // 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]; +static UsbCommand rxBuffer[CMD_BUFFER_SIZE]; // Points to the next empty position to write to static int cmd_head = 0; @@ -43,8 +52,8 @@ 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; +// to lock rxBuffer operations from different threads +static pthread_mutex_t rxBufferMutex = 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. @@ -57,38 +66,6 @@ bool IsOffline() { return offline; } -bool OpenProxmark(char *portname, bool waitCOMPort, int timeout) { - if (!waitCOMPort) { - sp = uart_open(portname); - } else { - printf("Waiting for Proxmark to appear on %s ", portname); - fflush(stdout); - int openCount = 0; - do { - sp = uart_open(portname); - msleep(1000); - printf("."); - fflush(stdout); - } while(++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT)); - printf("\n"); - } - - // check result of uart opening - if (sp == INVALID_SERIAL_PORT) { - printf("ERROR: invalid serial port\n"); - return false; - } else if (sp == CLAIMED_SERIAL_PORT) { - printf("ERROR: serial port is claimed by another process\n"); - return false; - } else { - return true; - } -} - -void CloseProxmark(void) { - uart_close(sp); -} - void SendCommand(UsbCommand *c) { #ifdef COMMS_DEBUG printf("Sending %04x cmd\n", c->cmd); @@ -98,15 +75,22 @@ void SendCommand(UsbCommand *c) { PrintAndLog("Sending bytes to proxmark failed - offline"); return; } + + pthread_mutex_lock(&txBufferMutex); /** - 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 + This 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); + while (txBuffer_pending) { + pthread_cond_wait(&txBufferSig, &txBufferMutex); // wait for communication thread to complete sending a previous commmand + } + + txBuffer = *c; + txBuffer_pending = true; + pthread_cond_signal(&txBufferSig); // tell communication thread that a new command can be send + + pthread_mutex_unlock(&txBufferMutex); - txcmd = *c; - txcmd_pending = true; } @@ -119,18 +103,18 @@ void SendCommand(UsbCommand *c) { void clearCommandBuffer() { //This is a very simple operation - pthread_mutex_lock(&cmdBufferMutex); + pthread_mutex_lock(&rxBufferMutex); cmd_tail = cmd_head; - pthread_mutex_unlock(&cmdBufferMutex); + pthread_mutex_unlock(&rxBufferMutex); } /** * @brief storeCommand stores a USB command in a circular buffer * @param UC */ -void storeCommand(UsbCommand *command) +static void storeCommand(UsbCommand *command) { - pthread_mutex_lock(&cmdBufferMutex); + pthread_mutex_lock(&rxBufferMutex); if( (cmd_head+1) % CMD_BUFFER_SIZE == cmd_tail) { // If these two are equal, we're about to overwrite in the @@ -139,11 +123,11 @@ void storeCommand(UsbCommand *command) } // Store the command at the 'head' location - UsbCommand* destination = &cmdBuffer[cmd_head]; + UsbCommand* destination = &rxBuffer[cmd_head]; memcpy(destination, command, sizeof(UsbCommand)); cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap - pthread_mutex_unlock(&cmdBufferMutex); + pthread_mutex_unlock(&rxBufferMutex); } @@ -152,22 +136,22 @@ void storeCommand(UsbCommand *command) * @param response location to write command * @return 1 if response was returned, 0 if nothing has been received */ -int getCommand(UsbCommand* response) +static int getCommand(UsbCommand* response) { - pthread_mutex_lock(&cmdBufferMutex); + pthread_mutex_lock(&rxBufferMutex); //If head == tail, there's nothing to read, or if we just got initialized if (cmd_head == cmd_tail){ - pthread_mutex_unlock(&cmdBufferMutex); + pthread_mutex_unlock(&rxBufferMutex); return 0; } //Pick out the next unread command - UsbCommand* last_unread = &cmdBuffer[cmd_tail]; + UsbCommand* last_unread = &rxBuffer[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); + pthread_mutex_unlock(&rxBufferMutex); return 1; } @@ -202,35 +186,54 @@ static void UsbCommandReceived(UsbCommand *UC) } -void +static void #ifdef __has_attribute #if __has_attribute(force_align_arg_pointer) __attribute__((force_align_arg_pointer)) #endif #endif -*uart_receiver(void *targ) { - receiver_arg *conn = (receiver_arg*)targ; +*uart_communication(void *targ) { + communication_arg_t *conn = (communication_arg_t*)targ; size_t rxlen; - uint8_t rx[sizeof(UsbCommand)]; - uint8_t *prx = rx; + UsbCommand rx; + UsbCommand *prx = ℞ while (conn->run) { rxlen = 0; - if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) { + bool ACK_received = false; + if (uart_receive(sp, (uint8_t *)prx, sizeof(UsbCommand) - (prx-&rx), &rxlen) && rxlen) { prx += rxlen; - if (prx-rx < sizeof(UsbCommand)) { + if (prx-&rx < sizeof(UsbCommand)) { continue; } - UsbCommandReceived((UsbCommand*)rx); + UsbCommandReceived(&rx); + if (rx.cmd == CMD_ACK) { + ACK_received = true; + } } - prx = rx; + prx = ℞ + + + pthread_mutex_lock(&txBufferMutex); - if(txcmd_pending) { - if (!uart_send(sp, (uint8_t*) &txcmd, sizeof(UsbCommand))) { + if (conn->block_after_ACK) { + // if we just received an ACK, wait here until a new command is to be transmitted + if (ACK_received) { + while (!txBuffer_pending) { + pthread_cond_wait(&txBufferSig, &txBufferMutex); + } + } + } + + if(txBuffer_pending) { + if (!uart_send(sp, (uint8_t*) &txBuffer, sizeof(UsbCommand))) { PrintAndLog("Sending bytes to proxmark failed"); } - txcmd_pending = false; + txBuffer_pending = false; + pthread_cond_signal(&txBufferSig); // tell main thread that txBuffer is empty } + + pthread_mutex_unlock(&txBufferMutex); } pthread_exit(NULL); @@ -238,7 +241,6 @@ __attribute__((force_align_arg_pointer)) } - /** * Data transfer from Proxmark to client. This method times out after * ms_timeout milliseconds. @@ -289,6 +291,58 @@ bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *respon return false; } + +bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) { + char *portname = (char *)port; + if (!wait_for_port) { + sp = uart_open(portname); + } else { + printf("Waiting for Proxmark to appear on %s ", portname); + fflush(stdout); + int openCount = 0; + do { + sp = uart_open(portname); + msleep(1000); + printf("."); + fflush(stdout); + } while(++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT)); + printf("\n"); + } + + // check result of uart opening + if (sp == INVALID_SERIAL_PORT) { + printf("ERROR: invalid serial port\n"); + sp = NULL; + serial_port_name = NULL; + return false; + } else if (sp == CLAIMED_SERIAL_PORT) { + printf("ERROR: serial port is claimed by another process\n"); + sp = NULL; + serial_port_name = NULL; + return false; + } else { + // start the USB communication thread + serial_port_name = portname; + conn.run = true; + conn.block_after_ACK = flash_mode; + pthread_create(&USB_communication_thread, NULL, &uart_communication, &conn); + return true; + } +} + + +void CloseProxmark(void) { + conn.run = false; + pthread_join(USB_communication_thread, NULL); + uart_close(sp); +#ifdef __linux__ + // Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/* + if (serial_port_name) { + unlink(serial_port_name); + } +#endif +} + /** * Waits for a certain response type. This method waits for a maximum of diff --git a/client/comms.h b/client/comms.h index 111677ad..68981165 100644 --- a/client/comms.h +++ b/client/comms.h @@ -22,24 +22,14 @@ #define CMD_BUFFER_SIZE 50 #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; - - void SetOffline(bool new_offline); bool IsOffline(); -bool OpenProxmark(char *portname, bool waitCOMPort, int timeout); +bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode); void CloseProxmark(void); void SendCommand(UsbCommand *c); -void *uart_receiver(void *targ); void clearCommandBuffer(); bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning); bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout); diff --git a/client/flash.c b/client/flash.c index e3714185..e43ebd1b 100644 --- a/client/flash.c +++ b/client/flash.c @@ -20,12 +20,7 @@ #include "elf.h" #include "proxendian.h" #include "usb_cmd.h" -#include "uart.h" - -void SendCommand(UsbCommand* txcmd); -void ReceiveCommand(UsbCommand* rxcmd); - -serial_port sp; +#include "comms.h" #define FLASH_START 0x100000 #define FLASH_SIZE (256*1024) @@ -42,22 +37,6 @@ static const uint8_t elf_ident[] = { EV_CURRENT }; -void CloseProxmark(const char *serial_port_name) { - // 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); -} - -bool OpenProxmark(size_t i, const char *serial_port_name) { - sp = uart_open(serial_port_name); - if (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT) { - //poll once a second - return false; - } - - return true; -} // Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent // unaligned segments if needed @@ -207,7 +186,7 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) { } // Load an ELF file and prepare it for flashing -int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) +int flash_load(flash_file_t *ctx, const char *name, bool can_write_bl) { FILE *fd = NULL; Elf32_Ehdr ehdr; @@ -295,7 +274,7 @@ static int get_proxmark_state(uint32_t *state) c.cmd = CMD_DEVICE_INFO; SendCommand(&c); UsbCommand resp; - ReceiveCommand(&resp); + WaitForResponse(CMD_UNKNOWN, &resp); // wait for any response. No timeout. // Three outcomes: // 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK @@ -355,17 +334,16 @@ static int enter_bootloader(char *serial_port_name) } msleep(100); - CloseProxmark(serial_port_name); - - fprintf(stderr,"Waiting for Proxmark to reappear on %s",serial_port_name); - do { - sleep(1); - fprintf(stderr, "."); - } while (!OpenProxmark(0, serial_port_name)); - - fprintf(stderr," Found.\n"); + CloseProxmark(); - return 0; + bool opened = OpenProxmark(serial_port_name, true, 120, true); // wait for 2 minutes + if (opened) { + fprintf(stderr," Found.\n"); + return 0; + } else { + fprintf(stderr,"Error: Proxmark not found.\n"); + return -1; + } } fprintf(stderr, "Error: Unknown Proxmark mode\n"); @@ -375,7 +353,7 @@ static int enter_bootloader(char *serial_port_name) static int wait_for_ack(void) { UsbCommand ack; - ReceiveCommand(&ack); + WaitForResponse(CMD_UNKNOWN, &ack); if (ack.cmd != CMD_ACK) { printf("Error: Unexpected reply 0x%04" PRIx64 " (expected ACK)\n", ack.cmd); return -1; @@ -424,12 +402,12 @@ 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; + UsbCommand c; c.cmd = CMD_FINISH_WRITE; c.arg[0] = address; memcpy(c.d.asBytes, block_buf, length); - SendCommand(&c); - return wait_for_ack(); + SendCommand(&c); + return wait_for_ack(); } // Write a file's segments to Flash diff --git a/client/flash.h b/client/flash.h index f8ffd221..06c7c96e 100644 --- a/client/flash.h +++ b/client/flash.h @@ -10,8 +10,7 @@ #define __FLASH_H__ #include -#include "elf.h" -#include "uart.h" +#include typedef struct { void *data; @@ -26,14 +25,10 @@ typedef struct { flash_seg_t *segments; } flash_file_t; -int flash_load(flash_file_t *ctx, const char *name, int can_write_bl); +int flash_load(flash_file_t *ctx, const char *name, bool can_write_bl); int flash_start_flashing(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); -void CloseProxmark(const char *serial_port_name); -bool OpenProxmark(size_t i, const char *serial_port_name); - -extern serial_port sp; #endif diff --git a/client/flasher.c b/client/flasher.c index 2bb87df9..a008f7bc 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -10,18 +10,14 @@ #include #include #include +#include #include "proxmark3.h" #include "util.h" #include "util_posix.h" #include "flash.h" -#include "uart.h" +#include "comms.h" #include "usb_cmd.h" -#ifdef _WIN32 -# define unlink(x) -#else -# include -#endif void cmd_debug(UsbCommand* UC) { // Debug @@ -37,29 +33,6 @@ void cmd_debug(UsbCommand* UC) { printf("...\n"); } -void SendCommand(UsbCommand* txcmd) { -// printf("send: "); -// cmd_debug(txcmd); - if (!uart_send(sp,(uint8_t*)txcmd,sizeof(UsbCommand))) { - printf("Sending bytes to proxmark failed\n"); - exit(1); - } -} - -void ReceiveCommand(UsbCommand* rxcmd) { - uint8_t* prxcmd = (uint8_t*)rxcmd; - uint8_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; - } - } - } -} - static void usage(char *argv0) { fprintf(stderr, "Usage: %s [-b] image.elf [image.elf...]\n\n", argv0); @@ -77,7 +50,7 @@ static void usage(char *argv0) int main(int argc, char **argv) { - int can_write_bl = 0; + int can_write_bl = false; int num_files = 0; int res; flash_file_t files[MAX_FILES]; @@ -92,7 +65,7 @@ int main(int argc, char **argv) for (int i = 2; i < argc; i++) { if (argv[i][0] == '-') { if (!strcmp(argv[i], "-b")) { - can_write_bl = 1; + can_write_bl = true; } else { usage(argv[0]); return -1; @@ -110,12 +83,12 @@ int main(int argc, char **argv) char* 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, serial_port_name)); - fprintf(stderr," Found.\n"); + if (!OpenProxmark(serial_port_name, true, 120, true)) { // wait for 2 minutes + fprintf(stderr, "Could not find Proxmark on %s.\n\n", serial_port_name); + return -1; + } else { + fprintf(stderr," Found.\n"); + } res = flash_start_flashing(can_write_bl, serial_port_name); if (res < 0) @@ -137,7 +110,8 @@ int main(int argc, char **argv) if (res < 0) return -1; - CloseProxmark(serial_port_name); + // Stop the command thread. + CloseProxmark(); fprintf(stderr, "All done.\n\n"); fprintf(stderr, "Have a nice day!\n"); diff --git a/client/mifarehost.c b/client/mifarehost.c index e1ced176..2d69cfae 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -16,7 +16,7 @@ #include #include "crapto1/crapto1.h" -#include "proxmark3.h" +#include "comms.h" #include "usb_cmd.h" #include "cmdmain.h" #include "ui.h" diff --git a/client/proxmark3.c b/client/proxmark3.c index 88cb5fa7..40c46613 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -9,6 +9,8 @@ // Main binary //----------------------------------------------------------------------------- +#include "proxmark3.h" + #include #include #include @@ -17,7 +19,6 @@ #include #include -#include "proxmark3.h" #include "util_posix.h" #include "proxgui.h" #include "cmdmain.h" @@ -26,7 +27,7 @@ #include "cmdparser.h" #include "cmdhw.h" #include "whereami.h" - +#include "comms.h" void #ifdef __has_attribute @@ -35,18 +36,12 @@ __attribute__((force_align_arg_pointer)) #endif #endif main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) { - receiver_arg conn; char *cmd = NULL; - pthread_t reader_thread; bool execCommand = (script_cmd != NULL); bool stdinOnPipe = !isatty(STDIN_FILENO); - memset(&conn, 0, sizeof(receiver_arg)); - if (usb_present) { - conn.run = true; SetOffline(false); - pthread_create(&reader_thread, NULL, &uart_receiver, &conn); // cache Version information now: CmdVersion(NULL); } else { @@ -138,8 +133,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) { write_history(".history"); if (usb_present) { - conn.run = false; - pthread_join(reader_thread, NULL); + CloseProxmark(); } if (script_file) { @@ -294,7 +288,7 @@ int main(int argc, char* argv[]) { set_my_executable_path(); // try to open USB connection to Proxmark - usb_present = OpenProxmark(argv[1], waitCOMPort, 20); + usb_present = OpenProxmark(argv[1], waitCOMPort, 20, false); #ifdef HAVE_GUI #ifdef _WIN32 diff --git a/client/proxmark3.h b/client/proxmark3.h index c6185c43..86d09bc0 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -20,7 +20,6 @@ extern "C" { #endif -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); diff --git a/client/scripting.c b/client/scripting.c index 0c761cb2..e73c7138 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -15,6 +15,7 @@ #include #include #include "proxmark3.h" +#include "comms.h" #include "usb_cmd.h" #include "cmdmain.h" #include "util.h"