reconnect version2 yolo

This commit is contained in:
iceman1001 2019-05-06 22:41:00 +02:00
commit 29a160c905
7 changed files with 77 additions and 41 deletions

View file

@ -235,6 +235,7 @@ static int usage_data_fsktonrz() {
return 0; return 0;
} }
//set the demod buffer with given array of binary (one bit per byte) //set the demod buffer with given array of binary (one bit per byte)
//by marshmellow //by marshmellow
void setDemodBuff(uint8_t *buff, size_t size, size_t start_idx) { void setDemodBuff(uint8_t *buff, size_t size, size_t start_idx) {

View file

@ -319,7 +319,7 @@ __attribute__((force_align_arg_pointer))
*uart_communication(void *targ) { *uart_communication(void *targ) {
communication_arg_t *connection = (communication_arg_t *)targ; communication_arg_t *connection = (communication_arg_t *)targ;
uint32_t rxlen; uint32_t rxlen;
uint8_t counter_to_offline = 0; bool sendfailed = false;
PacketResponseNG rx; PacketResponseNG rx;
PacketResponseNGRaw rx_raw; PacketResponseNGRaw rx_raw;
@ -327,22 +327,25 @@ __attribute__((force_align_arg_pointer))
disableAppNap("Proxmark3 polling UART"); disableAppNap("Proxmark3 polling UART");
#endif #endif
// is this connection->run a cross thread call? // is this connection->run a cross thread call?
while (connection->run) { while (connection->run) {
rxlen = 0; rxlen = 0;
bool ACK_received = false; bool ACK_received = false;
bool error = false; bool error = false;
int res;
// three failed attempts // Signal to main thread that communications seems off.
if ( counter_to_offline >= 3 ) { // 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); __atomic_test_and_set(&comm_thread_dead, __ATOMIC_SEQ_CST);
break; break;
} }
pthread_mutex_lock(&spMutex); 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; rx.magic = rx_raw.pre.magic;
uint16_t length = rx_raw.pre.length; uint16_t length = rx_raw.pre.length;
rx.ng = rx_raw.pre.ng; rx.ng = rx_raw.pre.ng;
@ -354,12 +357,13 @@ __attribute__((force_align_arg_pointer))
error = true; error = true;
} }
if ((!error) && (length > 0)) { // Get the variable length payload 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); PrintAndLogEx(WARNING, "Received packet frame error variable part too short? %d/%d", rxlen, length);
error = true; error = true;
} else { } else {
if (rx.ng) { // Received a valid NG frame if (rx.ng) { // Received a valid NG frame
memcpy(&rx.data, &rx_raw.data, length); memcpy(&rx.data, &rx_raw.data, length);
rx.length = length; rx.length = length;
@ -387,7 +391,8 @@ __attribute__((force_align_arg_pointer))
} }
} }
if (!error) { // Get the postamble 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"); PrintAndLogEx(WARNING, "Received packet frame error fetching postamble");
error = true; error = true;
} }
@ -417,7 +422,9 @@ __attribute__((force_align_arg_pointer))
} else { // Old style reply } else { // Old style reply
PacketResponseOLD rx_old; PacketResponseOLD rx_old;
memcpy(&rx_old, &rx_raw.pre, sizeof(PacketResponseNGPreamble)); 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)); PrintAndLogEx(WARNING, "Received packet OLD frame payload error too short? %d/%d", rxlen, sizeof(PacketResponseOLD) - sizeof(PacketResponseNGPreamble));
error = true; error = true;
} }
@ -476,23 +483,25 @@ __attribute__((force_align_arg_pointer))
pthread_mutex_lock(&spMutex); pthread_mutex_lock(&spMutex);
if (txBufferNGLen) { // NG packet if (txBufferNGLen) { // NG packet
if (!uart_send(sp, (uint8_t *) &txBufferNG, txBufferNGLen)) { res = uart_send(sp, (uint8_t *) &txBufferNG, txBufferNGLen);
counter_to_offline++; if (res == PM3_EIO) {
PrintAndLogEx(WARNING, "sending bytes to Proxmark3 device " _RED_("failed")); sendfailed = true;
} }
conn.last_command = txBufferNG.pre.cmd; conn.last_command = txBufferNG.pre.cmd;
txBufferNGLen = 0; txBufferNGLen = 0;
} else { } else {
if (!uart_send(sp, (uint8_t *) &txBuffer, sizeof(PacketCommandOLD))) { res = uart_send(sp, (uint8_t *) &txBuffer, sizeof(PacketCommandOLD));
counter_to_offline++; if (res == PM3_EIO) {
PrintAndLogEx(WARNING, "sending bytes to Proxmark3 device " _RED_("failed")); sendfailed = true;
} }
conn.last_command = txBuffer.cmd; conn.last_command = txBuffer.cmd;
} }
pthread_mutex_unlock(&spMutex); pthread_mutex_unlock(&spMutex);
txBuffer_pending = false; txBuffer_pending = false;
// main thread doesn't know send failed...
// tell main thread that txBuffer is empty // tell main thread that txBuffer is empty
pthread_cond_signal(&txBufferSig); pthread_cond_signal(&txBufferSig);
} }
@ -513,7 +522,8 @@ __attribute__((force_align_arg_pointer))
} }
bool IsCommunicationThreadDead(void) { bool IsCommunicationThreadDead(void) {
return comm_thread_dead; bool ret = __atomic_load_n(&comm_thread_dead, __ATOMIC_SEQ_CST);
return ret;
} }
bool ReConnectProxmark(void) { bool ReConnectProxmark(void) {

View file

@ -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 communications thread goes down. Device disconnected then this should hook up PM3 again.
if ( IsCommunicationThreadDead() ) { if ( IsCommunicationThreadDead() ) {
PrintAndLogEx(ERR, _RED_("ERROR:") "cannot communicate with the Proxmark, waiting for device to reconnect...");
session.pm3_present = ReConnectProxmark(); session.pm3_present = ReConnectProxmark();
if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) { if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) {
session.pm3_present = false; session.pm3_present = false;
continue;
} }
} }

View file

@ -460,7 +460,8 @@ extern capabilities_t pm3_capabilities;
#define PM3_EMALLOC -12 #define PM3_EMALLOC -12
// File error client: error related to file access on host // File error client: error related to file access on host
#define PM3_EFILE -13 #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) // No data pm3: no data available, no host frame available (not really an error)
#define PM3_ENODATA -98 #define PM3_ENODATA -98
// Quit program client: reserved, order to quit the program // Quit program client: reserved, order to quit the program

View file

@ -89,13 +89,13 @@ void uart_close(const serial_port sp);
* partial read may have completed into the buffer by the corresponding * partial read may have completed into the buffer by the corresponding
* implementation, so pszRxLen should be checked to see if any data was written. * 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. /* Sends a buffer to a given serial port.
* pbtTx: A pointer to a buffer containing the data to send. * pbtTx: A pointer to a buffer containing the data to send.
* len: The amount of data to be sent. * 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. /* Sets the current speed of the serial port, in baud.
*/ */

View file

@ -235,7 +235,7 @@ void uart_close(const serial_port sp) {
free(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 uint32_t byteCount; // FIONREAD returns size on 32b
fd_set rfds; fd_set rfds;
struct timeval tv; struct timeval tv;
@ -252,24 +252,24 @@ bool uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, ui
// Read error // Read error
if (res < 0) { if (res < 0) {
return false; return PM3_EIO;
} }
// Read time-out // Read time-out
if (res == 0) { if (res == 0) {
if (*pszRxLen == 0) { if (*pszRxLen == 0) {
// We received no data // We received no data
return false; return PM3_ENODATA;
} else { } else {
// We received some data, but nothing more is available // We received some data, but nothing more is available
return true; return PM3_SUCCESS;
} }
} }
// Retrieve the count of the incoming bytes // Retrieve the count of the incoming bytes
res = ioctl(((serial_port_unix *)sp)->fd, FIONREAD, &byteCount); res = ioctl(((serial_port_unix *)sp)->fd, FIONREAD, &byteCount);
// printf("UART:: RX ioctl res %d byteCount %u\n", res, 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 // Cap the number of bytes, so we don't overrun the buffer
if (pszMaxRxLen - (*pszRxLen) < byteCount) { 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 // Stop if the OS has some troubles reading the data
if (res <= 0) { if (res <= 0) {
return false; return PM3_EIO;
} }
*pszRxLen += res; *pszRxLen += res;
if (*pszRxLen == pszMaxRxLen) { if (*pszRxLen == pszMaxRxLen) {
// We have all the data we wanted. // We have all the data we wanted.
return true; return PM3_SUCCESS;
} }
} while (byteCount); } 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; uint32_t pos = 0;
fd_set rfds; fd_set rfds;
struct timeval tv; struct timeval tv;
@ -311,24 +311,25 @@ bool uart_send(const serial_port sp, const uint8_t *pbtTx, const uint32_t len) {
// Write error // Write error
if (res < 0) { if (res < 0) {
printf("UART:: write error (%d)\n", res); printf("UART:: write error (%d)\n", res);
return false; return PM3_ENOTTY;
} }
// Write time-out // Write time-out
if (res == 0) { if (res == 0) {
printf("UART:: write time-out\n"); printf("UART:: write time-out\n");
return false; return PM3_ETIMEOUT;
} }
// Send away the bytes // Send away the bytes
res = write(((serial_port_unix *)sp)->fd, pbtTx + pos, len - pos); res = write(((serial_port_unix *)sp)->fd, pbtTx + pos, len - pos);
// Stop if the OS has some troubles sending the data // Stop if the OS has some troubles sending the data
if (res <= 0) return false; if (res <= 0)
return PM3_EIO;
pos += res; pos += res;
} }
return true; return PM3_SUCCESS;
} }
bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) { bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {

View file

@ -162,13 +162,38 @@ uint32_t uart_get_speed(const serial_port sp) {
return 0; return 0;
} }
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) {
return ReadFile(((serial_port_windows *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL); 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; 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 #endif