diff --git a/client/cmdhw.c b/client/cmdhw.c index 8f7243ada..230ebfa3d 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -405,11 +405,17 @@ int CmdTune(const char *Cmd) int CmdVersion(const char *Cmd) { - - clearCommandBuffer(); UsbCommand c = {CMD_VERSION}; static UsbCommand resp = {0, {0, 0, 0}}; + if(*Cmd == 'n') { + PrintAndLog("Version Cache Cleared"); + PrintAndLog(""); + memset( &resp, 0, sizeof(resp) ); + } + + clearCommandBuffer(); + if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { @@ -468,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/proxmark3.c b/client/proxmark3.c index 99ba9fbad..2625ed5af 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,52 @@ 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; 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(1); continue; } - UsbCommandReceived((UsbCommand*)rx); + + PrintAndLog("Proxmark reconnected!"); + need_reconnect = false; + offline = 0; + clearCommandBuffer(); + } + + 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); + } } + 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) { @@ -106,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 @@ -351,6 +388,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 +443,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) {