From 96aab0688a3be310deb2b6618273203d13e5f119 Mon Sep 17 00:00:00 2001 From: LW Date: Mon, 11 Dec 2017 01:56:20 -0800 Subject: [PATCH 1/4] First try at disconnect/reconnect detection. No idea if it's going to work on WIN32. --- client/cmdhw.c | 10 +++++++- client/cmdhw.h | 1 + client/proxmark3.c | 61 +++++++++++++++++++++++++++++++++++++++++----- uart/uart_posix.c | 12 ++++----- 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 8f7243ada..2451ca776 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -405,11 +405,19 @@ int CmdTune(const char *Cmd) int CmdVersion(const char *Cmd) { + return CmdVersionC(Cmd, false); +} - clearCommandBuffer(); +int CmdVersionC(const char *Cmd, const bool no_cache) +{ UsbCommand c = {CMD_VERSION}; static UsbCommand resp = {0, {0, 0, 0}}; + if( no_cache ) + memset( &resp, 0, sizeof(resp) ); + else + clearCommandBuffer(); + if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { diff --git a/client/cmdhw.h b/client/cmdhw.h index b8e10f748..c4d6a836e 100644 --- a/client/cmdhw.h +++ b/client/cmdhw.h @@ -23,5 +23,6 @@ int CmdSetDivisor(const char *Cmd); int CmdSetMux(const char *Cmd); int CmdTune(const char *Cmd); int CmdVersion(const char *Cmd); +int CmdVersionC(const char *Cmd, const bool no_cache); #endif diff --git a/client/proxmark3.c b/client/proxmark3.c index 99ba9fbad..07485e0b5 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -38,6 +38,7 @@ pthread_mutex_t print_lock; static serial_port sp; +static char* sp_name; static UsbCommand txcmd; volatile static bool txcmd_pending = false; @@ -70,16 +71,63 @@ byte_t* prx = rx; static void *uart_receiver(void *targ) { struct receiver_arg *arg = (struct receiver_arg*)targ; size_t rxlen; + bool need_reconnect = false; + UsbCommand version_cmd = {CMD_VERSION}; + static bool request_version = false; while (arg->run) { - rxlen = 0; - if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) { - prx += rxlen; - if (prx-rx < sizeof(UsbCommand)) { + if( need_reconnect ) { + sp = uart_open(sp_name); + + if( sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT ) + { + PrintAndLog("Reconnect failed, retrying..."); + + if( txcmd_pending ) { + PrintAndLog("Cannot send bytes to offline proxmark"); + txcmd_pending = false; + } + + sleep(2); continue; } - UsbCommandReceived((UsbCommand*)rx); + + PrintAndLog("Proxmark reconnected!"); + need_reconnect = false; + offline = 0; + //CmdVersionW(NULL, true); + clearCommandBuffer(); + uart_send(sp, (byte_t*) &version_cmd, sizeof(UsbCommand)); // request it from the HW + request_version = true; + } + + rxlen = 0; + if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) ) { + if( rxlen ) { + prx += rxlen; + if (prx-rx < sizeof(UsbCommand)) { + continue; + } + + UsbCommandReceived((UsbCommand*)rx); + + if( request_version && ((UsbCommand*)rx)->cmd == CMD_ACK) + { + request_version = false; + CmdVersionW(NULL, true); + } + } } + else { + PrintAndLog("Receiving data from proxmark failed, attempting a reconnect"); + uart_close(sp); + sp = INVALID_SERIAL_PORT; + offline = 1; + txcmd_pending = false; + need_reconnect = true; + continue; + } + prx = rx; if(txcmd_pending) { @@ -351,6 +399,7 @@ int main(int argc, char* argv[]) { set_my_executable_path(); // open uart + sp_name = argv[1]; if (!waitCOMPort) { sp = uart_open(argv[1]); } else { @@ -405,7 +454,7 @@ int main(int argc, char* argv[]) { #endif // Clean up the port - if (usb_present) { + if (sp != INVALID_SERIAL_PORT && sp != CLAIMED_SERIAL_PORT) { uart_close(sp); } diff --git a/uart/uart_posix.c b/uart/uart_posix.c index 45e0d3d24..59b12956a 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -141,7 +141,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_ // Reset the output count *pszRxLen = 0; - + do { // Reset file descriptor FD_ZERO(&rfds); @@ -153,12 +153,12 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_ if (res < 0) { return false; } - + // Read time-out if (res == 0) { if (*pszRxLen == 0) { // Error, we received no data - return false; + return true; } else { // We received some data, but nothing more is available return true; @@ -168,7 +168,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_ // Retrieve the count of the incoming bytes res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount); if (res < 0) return false; - + // Cap the number of bytes, so we don't overrun the buffer if (pszMaxRxLen - (*pszRxLen) < byteCount) { byteCount = pszMaxRxLen - (*pszRxLen); @@ -178,8 +178,8 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_ res = read(((serial_port_unix*)sp)->fd, pbtRx+(*pszRxLen), byteCount); // Stop if the OS has some troubles reading the data - if (res <= 0) return false; - + if (res < 0) return false; + *pszRxLen += res; if (*pszRxLen == pszMaxRxLen) { From 2a3f94d9321b514df7ccc2e27687c764288d354b Mon Sep 17 00:00:00 2001 From: LW Date: Mon, 11 Dec 2017 02:21:37 -0800 Subject: [PATCH 2/4] Fixed function name --- client/proxmark3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 07485e0b5..961320656 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -95,7 +95,7 @@ static void *uart_receiver(void *targ) { PrintAndLog("Proxmark reconnected!"); need_reconnect = false; offline = 0; - //CmdVersionW(NULL, true); + //CmdVersionC(NULL, true); clearCommandBuffer(); uart_send(sp, (byte_t*) &version_cmd, sizeof(UsbCommand)); // request it from the HW request_version = true; @@ -114,7 +114,7 @@ static void *uart_receiver(void *targ) { if( request_version && ((UsbCommand*)rx)->cmd == CMD_ACK) { request_version = false; - CmdVersionW(NULL, true); + CmdVersionC(NULL, true); } } } From 1ab4fc9d64d3a4396457bc9f3230ce0f39fd722e Mon Sep 17 00:00:00 2001 From: LW Date: Sat, 17 Feb 2018 11:13:39 -0800 Subject: [PATCH 3/4] Removed the retrieving of version information on re-connect so we don't overwrite BigBuf --- client/cmdhw.c | 15 +++++++++++---- client/cmdhw.h | 3 ++- client/proxmark3.c | 15 +++------------ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 2451ca776..66a9f0c96 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -408,15 +408,22 @@ int CmdVersion(const char *Cmd) return CmdVersionC(Cmd, false); } -int CmdVersionC(const char *Cmd, const bool no_cache) +int CmdVersionClearCache() +{ + return CmdVersionC(NULL, true); +} + +int CmdVersionC(const char *Cmd, const bool clear_cache) { UsbCommand c = {CMD_VERSION}; static UsbCommand resp = {0, {0, 0, 0}}; - if( no_cache ) + if (clear_cache) { memset( &resp, 0, sizeof(resp) ); - else - clearCommandBuffer(); + return 0; + } + + clearCommandBuffer(); if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available SendCommand(&c); diff --git a/client/cmdhw.h b/client/cmdhw.h index c4d6a836e..334357a03 100644 --- a/client/cmdhw.h +++ b/client/cmdhw.h @@ -23,6 +23,7 @@ int CmdSetDivisor(const char *Cmd); int CmdSetMux(const char *Cmd); int CmdTune(const char *Cmd); int CmdVersion(const char *Cmd); -int CmdVersionC(const char *Cmd, const bool no_cache); +int CmdVersionClearCache(); +int CmdVersionC(const char *Cmd, const bool clear_cache); #endif diff --git a/client/proxmark3.c b/client/proxmark3.c index 961320656..cc2b334f1 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -73,7 +73,6 @@ static void *uart_receiver(void *targ) { size_t rxlen; bool need_reconnect = false; UsbCommand version_cmd = {CMD_VERSION}; - static bool request_version = false; while (arg->run) { if( need_reconnect ) { @@ -81,24 +80,22 @@ static void *uart_receiver(void *targ) { if( sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT ) { - PrintAndLog("Reconnect failed, retrying..."); + //PrintAndLog("Reconnect failed, retrying..."); if( txcmd_pending ) { PrintAndLog("Cannot send bytes to offline proxmark"); txcmd_pending = false; } - sleep(2); + sleep(1); continue; } PrintAndLog("Proxmark reconnected!"); need_reconnect = false; offline = 0; - //CmdVersionC(NULL, true); clearCommandBuffer(); - uart_send(sp, (byte_t*) &version_cmd, sizeof(UsbCommand)); // request it from the HW - request_version = true; + CmdVersionClearCache(); } rxlen = 0; @@ -110,12 +107,6 @@ static void *uart_receiver(void *targ) { } UsbCommandReceived((UsbCommand*)rx); - - if( request_version && ((UsbCommand*)rx)->cmd == CMD_ACK) - { - request_version = false; - CmdVersionC(NULL, true); - } } } else { From 6e0b2d0beb22c188d05a0c4de04eae782a7a5165 Mon Sep 17 00:00:00 2001 From: LW Date: Sat, 17 Feb 2018 16:02:13 -0800 Subject: [PATCH 4/4] Removed automatic version cache clearing, added [nocache] flag to "hw ver" to force cache clearing --- client/cmdhw.c | 17 ++++------------- client/cmdhw.h | 2 -- client/proxmark3.c | 4 +--- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/client/cmdhw.c b/client/cmdhw.c index 66a9f0c96..230ebfa3d 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -404,23 +404,14 @@ int CmdTune(const char *Cmd) } int CmdVersion(const char *Cmd) -{ - return CmdVersionC(Cmd, false); -} - -int CmdVersionClearCache() -{ - return CmdVersionC(NULL, true); -} - -int CmdVersionC(const char *Cmd, const bool clear_cache) { UsbCommand c = {CMD_VERSION}; static UsbCommand resp = {0, {0, 0, 0}}; - if (clear_cache) { + if(*Cmd == 'n') { + PrintAndLog("Version Cache Cleared"); + PrintAndLog(""); memset( &resp, 0, sizeof(resp) ); - return 0; } clearCommandBuffer(); @@ -483,7 +474,7 @@ static command_t CommandTable[] = {"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"}, {"setmux", CmdSetMux, 0, " -- Set the ADC mux to a specific value"}, {"tune", CmdTune, 0, "['l'|'h'] -- Measure antenna tuning (option 'l' or 'h' to limit to LF or HF)"}, - {"version", CmdVersion, 0, "Show version information about the connected Proxmark"}, + {"version", CmdVersion, 0, "['n'] -- Show version information about the connected Proxmark (option 'nocache' to force getting version from hardware)"}, {"status", CmdStatus, 0, "Show runtime status information about the connected Proxmark"}, {"ping", CmdPing, 0, "Test if the pm3 is responsive"}, {NULL, NULL, 0, NULL} diff --git a/client/cmdhw.h b/client/cmdhw.h index 334357a03..b8e10f748 100644 --- a/client/cmdhw.h +++ b/client/cmdhw.h @@ -23,7 +23,5 @@ int CmdSetDivisor(const char *Cmd); int CmdSetMux(const char *Cmd); int CmdTune(const char *Cmd); int CmdVersion(const char *Cmd); -int CmdVersionClearCache(); -int CmdVersionC(const char *Cmd, const bool clear_cache); #endif diff --git a/client/proxmark3.c b/client/proxmark3.c index cc2b334f1..2625ed5af 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -72,7 +72,6 @@ static void *uart_receiver(void *targ) { struct receiver_arg *arg = (struct receiver_arg*)targ; size_t rxlen; bool need_reconnect = false; - UsbCommand version_cmd = {CMD_VERSION}; while (arg->run) { if( need_reconnect ) { @@ -95,7 +94,6 @@ static void *uart_receiver(void *targ) { need_reconnect = false; offline = 0; clearCommandBuffer(); - CmdVersionClearCache(); } rxlen = 0; @@ -145,7 +143,7 @@ void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) { rarg.run = 1; pthread_create(&reader_thread, NULL, &uart_receiver, &rarg); // cache Version information now: - CmdVersion(NULL); + CmdVersion("nocache"); } // file with script