From 29a160c905b6253e70c83dc3665db7c09deb5707 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 6 May 2019 22:41:00 +0200 Subject: [PATCH] reconnect version2 yolo --- client/cmddata.c | 1 + client/comms.c | 48 ++++++++++++++++++++++++++++------------------ client/proxmark3.c | 2 -- include/pm3_cmd.h | 3 ++- uart/uart.h | 4 ++-- uart/uart_posix.c | 27 +++++++++++++------------- uart/uart_win32.c | 33 +++++++++++++++++++++++++++---- 7 files changed, 77 insertions(+), 41 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 962b537a0..f4e6594a9 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -235,6 +235,7 @@ static int usage_data_fsktonrz() { return 0; } + //set the demod buffer with given array of binary (one bit per byte) //by marshmellow void setDemodBuff(uint8_t *buff, size_t size, size_t start_idx) { diff --git a/client/comms.c b/client/comms.c index 1f3fbb30a..25636589c 100644 --- a/client/comms.c +++ b/client/comms.c @@ -319,7 +319,7 @@ __attribute__((force_align_arg_pointer)) *uart_communication(void *targ) { communication_arg_t *connection = (communication_arg_t *)targ; uint32_t rxlen; - uint8_t counter_to_offline = 0; + bool sendfailed = false; PacketResponseNG rx; PacketResponseNGRaw rx_raw; @@ -327,22 +327,25 @@ __attribute__((force_align_arg_pointer)) disableAppNap("Proxmark3 polling UART"); #endif -// is this connection->run a cross thread call? - + // is this connection->run a cross thread call? while (connection->run) { rxlen = 0; bool ACK_received = false; bool error = false; + int res; - // three failed attempts - if ( counter_to_offline >= 3 ) { + // Signal to main thread that communications seems off. + // main thread will kill and restart this thread. + if ( sendfailed ) { + PrintAndLogEx(WARNING, "sending bytes to Proxmark3 device " _RED_("failed")); __atomic_test_and_set(&comm_thread_dead, __ATOMIC_SEQ_CST); break; } pthread_mutex_lock(&spMutex); - - if (uart_receive(sp, (uint8_t *)&rx_raw.pre, sizeof(PacketResponseNGPreamble), &rxlen) && (rxlen == sizeof(PacketResponseNGPreamble))) { + + res = uart_receive(sp, (uint8_t *)&rx_raw.pre, sizeof(PacketResponseNGPreamble), &rxlen); + if ((res == PM3_SUCCESS) && (rxlen == sizeof(PacketResponseNGPreamble))) { rx.magic = rx_raw.pre.magic; uint16_t length = rx_raw.pre.length; rx.ng = rx_raw.pre.ng; @@ -354,12 +357,13 @@ __attribute__((force_align_arg_pointer)) error = true; } if ((!error) && (length > 0)) { // Get the variable length payload - if ((!uart_receive(sp, (uint8_t *)&rx_raw.data, length, &rxlen)) || (rxlen != length)) { + + res = uart_receive(sp, (uint8_t *)&rx_raw.data, length, &rxlen); + if ( (res != PM3_SUCCESS) || (rxlen != length)) { PrintAndLogEx(WARNING, "Received packet frame error variable part too short? %d/%d", rxlen, length); error = true; } else { - if (rx.ng) { // Received a valid NG frame memcpy(&rx.data, &rx_raw.data, length); rx.length = length; @@ -387,7 +391,8 @@ __attribute__((force_align_arg_pointer)) } } if (!error) { // Get the postamble - if ((!uart_receive(sp, (uint8_t *)&rx_raw.foopost, sizeof(PacketResponseNGPostamble), &rxlen)) || (rxlen != sizeof(PacketResponseNGPostamble))) { + res = uart_receive(sp, (uint8_t *)&rx_raw.foopost, sizeof(PacketResponseNGPostamble), &rxlen); + if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseNGPostamble))) { PrintAndLogEx(WARNING, "Received packet frame error fetching postamble"); error = true; } @@ -417,7 +422,9 @@ __attribute__((force_align_arg_pointer)) } else { // Old style reply PacketResponseOLD rx_old; memcpy(&rx_old, &rx_raw.pre, sizeof(PacketResponseNGPreamble)); - if ((!uart_receive(sp, ((uint8_t *)&rx_old) + sizeof(PacketResponseNGPreamble), sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble), &rxlen)) || (rxlen != sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble))) { + + res = uart_receive(sp, ((uint8_t *)&rx_old) + sizeof(PacketResponseNGPreamble), sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble), &rxlen); + if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble))) { PrintAndLogEx(WARNING, "Received packet OLD frame payload error too short? %d/%d", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble)); error = true; } @@ -476,23 +483,25 @@ __attribute__((force_align_arg_pointer)) pthread_mutex_lock(&spMutex); if (txBufferNGLen) { // NG packet - if (!uart_send(sp, (uint8_t *) &txBufferNG, txBufferNGLen)) { - counter_to_offline++; - PrintAndLogEx(WARNING, "sending bytes to Proxmark3 device " _RED_("failed")); + res = uart_send(sp, (uint8_t *) &txBufferNG, txBufferNGLen); + if (res == PM3_EIO) { + sendfailed = true; } conn.last_command = txBufferNG.pre.cmd; txBufferNGLen = 0; } else { - if (!uart_send(sp, (uint8_t *) &txBuffer, sizeof(PacketCommandOLD))) { - counter_to_offline++; - PrintAndLogEx(WARNING, "sending bytes to Proxmark3 device " _RED_("failed")); + res = uart_send(sp, (uint8_t *) &txBuffer, sizeof(PacketCommandOLD)); + if (res == PM3_EIO) { + sendfailed = true; } conn.last_command = txBuffer.cmd; } pthread_mutex_unlock(&spMutex); txBuffer_pending = false; - + + // main thread doesn't know send failed... + // tell main thread that txBuffer is empty pthread_cond_signal(&txBufferSig); } @@ -513,7 +522,8 @@ __attribute__((force_align_arg_pointer)) } bool IsCommunicationThreadDead(void) { - return comm_thread_dead; + bool ret = __atomic_load_n(&comm_thread_dead, __ATOMIC_SEQ_CST); + return ret; } bool ReConnectProxmark(void) { diff --git a/client/proxmark3.c b/client/proxmark3.c index c5bfb1cb2..c0c745f09 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -99,11 +99,9 @@ main_loop(char *script_cmds_file, char *script_cmd) { // If communications thread goes down. Device disconnected then this should hook up PM3 again. if ( IsCommunicationThreadDead() ) { - PrintAndLogEx(ERR, _RED_("ERROR:") "cannot communicate with the Proxmark, waiting for device to reconnect..."); session.pm3_present = ReConnectProxmark(); if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) { session.pm3_present = false; - continue; } } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 9f245d0e7..cba00e7f0 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -460,7 +460,8 @@ extern capabilities_t pm3_capabilities; #define PM3_EMALLOC -12 // File error client: error related to file access on host #define PM3_EFILE -13 - +// Generic TTY error +#define PM3_ENOTTY -14 // No data pm3: no data available, no host frame available (not really an error) #define PM3_ENODATA -98 // Quit program client: reserved, order to quit the program diff --git a/uart/uart.h b/uart/uart.h index fe51f0643..efd582c0b 100644 --- a/uart/uart.h +++ b/uart/uart.h @@ -89,13 +89,13 @@ void uart_close(const serial_port sp); * partial read may have completed into the buffer by the corresponding * implementation, so pszRxLen should be checked to see if any data was written. */ -bool uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen); +int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen); /* Sends a buffer to a given serial port. * pbtTx: A pointer to a buffer containing the data to send. * len: The amount of data to be sent. */ -bool uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len); +int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len); /* Sets the current speed of the serial port, in baud. */ diff --git a/uart/uart_posix.c b/uart/uart_posix.c index c80ad295b..f158cb9e8 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -235,7 +235,7 @@ void uart_close(const serial_port sp) { free(sp); } -bool uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) { +int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) { uint32_t byteCount; // FIONREAD returns size on 32b fd_set rfds; struct timeval tv; @@ -252,24 +252,24 @@ bool uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, ui // Read error if (res < 0) { - return false; + return PM3_EIO; } // Read time-out if (res == 0) { if (*pszRxLen == 0) { // We received no data - return false; + return PM3_ENODATA; } else { // We received some data, but nothing more is available - return true; + return PM3_SUCCESS; } } // Retrieve the count of the incoming bytes res = ioctl(((serial_port_unix *)sp)->fd, FIONREAD, &byteCount); // printf("UART:: RX ioctl res %d byteCount %u\n", res, byteCount); - if (res < 0) return false; + if (res < 0) return PM3_ENOTTY; // Cap the number of bytes, so we don't overrun the buffer if (pszMaxRxLen - (*pszRxLen) < byteCount) { @@ -282,21 +282,21 @@ bool uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, ui // Stop if the OS has some troubles reading the data if (res <= 0) { - return false; + return PM3_EIO; } *pszRxLen += res; if (*pszRxLen == pszMaxRxLen) { // We have all the data we wanted. - return true; + return PM3_SUCCESS; } } while (byteCount); - return true; + return PM3_SUCCESS; } -bool uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) { +int uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) { uint32_t pos = 0; fd_set rfds; struct timeval tv; @@ -311,24 +311,25 @@ bool uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) { // Write error if (res < 0) { printf("UART:: write error (%d)\n", res); - return false; + return PM3_ENOTTY; } // Write time-out if (res == 0) { printf("UART:: write time-out\n"); - return false; + return PM3_ETIMEOUT; } // Send away the bytes res = write(((serial_port_unix *)sp)->fd, pbtTx + pos, len - pos); // Stop if the OS has some troubles sending the data - if (res <= 0) return false; + if (res <= 0) + return PM3_EIO; pos += res; } - return true; + return PM3_SUCCESS; } bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { diff --git a/uart/uart_win32.c b/uart/uart_win32.c index b5f7b9302..d04a4aca1 100644 --- a/uart/uart_win32.c +++ b/uart/uart_win32.c @@ -162,13 +162,38 @@ uint32_t uart_get_speed(const serial_port sp) { return 0; } -bool uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) { - return ReadFile(((serial_port_windows *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL); +int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) { + int res = ReadFile(((serial_port_windows *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL); + if ( res ) + return PM3_SUCCESS; + + int errorcode = GetLastError(); + + // disconnected device + if (res == 0 && errorcode == 2) { + return PM3_EIO; + } + + printf("[!]res %d | rx errorcode == %d \n",res, errorcode); + return res; } -bool uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) { +int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) { DWORD txlen = 0; - return WriteFile(((serial_port_windows *)sp)->hPort, p_tx, len, &txlen, NULL); + int res = WriteFile(((serial_port_windows *)sp)->hPort, p_tx, len, &txlen, NULL); + int errorcode = GetLastError(); + if ( res == 0 ) { + printf("[!]res %d | send errorcode == %d \n",res, errorcode); + } + + if (res == 0 && errorcode == 2) { + return PM3_EIO; + } + if ( res ) + return PM3_SUCCESS; + + printf("[!!]res %d | send errorcode == %d \n",res, errorcode); + return PM3_ENOTTY; } #endif