chg: reconnect to a disconnected proxmark3 device without restarting the client. Old functionality restored :)

chg: renamed thread
chg: easier if-statements for USART
This commit is contained in:
iceman1001 2019-05-06 14:11:23 +02:00
commit cffd14a96b
3 changed files with 63 additions and 66 deletions

View file

@ -22,11 +22,13 @@
// Serial port that we are communicating with the PM3 on.
static serial_port sp = NULL;
static char *serial_port_name = NULL;
static uint32_t _speed = 0;
communication_arg_t conn;
capabilities_t pm3_capabilities;
static pthread_t USB_communication_thread;
static pthread_t communication_thread;
static bool comm_thread_dead = false;
// Transmit buffer.
static PacketCommandOLD txBuffer;
@ -304,33 +306,10 @@ static void PacketResponseReceived(PacketResponseNG *packet) {
}
}
/*
bool hookUpPM3() {
bool ret = false;
sp = uart_open( comport, speed );
if (sp == INVALID_SERIAL_PORT) {
PrintAndLogEx(WARNING, "Reconnect failed, retrying... (reason: invalid serial port)\n");
sp = NULL;
serial_port_name = NULL;
ret = false;
session.pm3_present = false;
} else if (sp == CLAIMED_SERIAL_PORT) {
PrintAndLogEx(WARNING, "Reconnect failed, retrying... (reason: serial port is claimed by another process)\n");
sp = NULL;
serial_port_name = NULL;
ret = false;
session.pm3_present = false;
} else {
PrintAndLogEx(SUCCESS, "Proxmark3 reconnected\n");
serial_port_name = ;
ret = true;
session.pm3_present = true;
}
return ret;
}
*/
// The communications thread.
// signals to main thread when a response is ready to process.
//
static void
#ifdef __has_attribute
#if __has_attribute(force_align_arg_pointer)
@ -340,20 +319,27 @@ __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;
PacketResponseNG rx;
PacketResponseNGRaw rx_raw;
//int counter_to_offline = 0;
#if defined(__MACH__) && defined(__APPLE__)
disableAppNap("Proxmark3 polling UART");
#endif
// is this connection->run a cross thread call?
while (connection->run) {
rxlen = 0;
bool ACK_received = false;
bool error = false;
// three failed attempts
if ( counter_to_offline >= 3 ) {
__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))) {
@ -491,14 +477,14 @@ __attribute__((force_align_arg_pointer))
pthread_mutex_lock(&spMutex);
if (txBufferNGLen) { // NG packet
if (!uart_send(sp, (uint8_t *) &txBufferNG, txBufferNGLen)) {
//counter_to_offline++;
counter_to_offline++;
PrintAndLogEx(WARNING, "sending bytes to Proxmark3 device " _RED_("failed"));
}
conn.last_command = txBufferNG.pre.cmd;
txBufferNGLen = 0;
} else {
if (!uart_send(sp, (uint8_t *) &txBuffer, sizeof(PacketCommandOLD))) {
//counter_to_offline++;
counter_to_offline++;
PrintAndLogEx(WARNING, "sending bytes to Proxmark3 device " _RED_("failed"));
}
conn.last_command = txBuffer.cmd;
@ -514,18 +500,30 @@ __attribute__((force_align_arg_pointer))
pthread_mutex_unlock(&txBufferMutex);
}
// when this reader thread dies, we close the serial port.
// when thread dies, we close the serial port.
uart_close(sp);
sp = NULL;
#if defined(__MACH__) && defined(__APPLE__)
enableAppNap();
#endif
pthread_exit(NULL);
return NULL;
}
bool IsCommunicationThreadDead(void) {
return comm_thread_dead;
}
bool ReConnectProxmark(void) {
char *port = serial_port_name;
bool res = OpenProxmark(port, true, 20, false, _speed);
if ( res )
__atomic_clear(&comm_thread_dead, __ATOMIC_SEQ_CST);
return res;
}
bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed) {
char *portname = (char *)port;
@ -548,16 +546,17 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode,
if (sp == INVALID_SERIAL_PORT) {
PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") "invalid serial port " _YELLOW_("%s"), portname);
sp = NULL;
serial_port_name = NULL;
//serial_port_name = NULL;
return false;
} else if (sp == CLAIMED_SERIAL_PORT) {
PrintAndLogEx(WARNING, "\n" _RED_("ERROR:") "serial port " _YELLOW_("%s") " is claimed by another process", portname);
sp = NULL;
serial_port_name = NULL;
//serial_port_name = NULL;
return false;
} else {
// start the USB communication thread
// start the communication thread
serial_port_name = portname;
_speed = speed;
conn.run = true;
conn.block_after_ACK = flash_mode;
// Flags to tell where to add CRC on sent replies
@ -566,7 +565,7 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode,
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
conn.send_via_fpc_usart = false;
pthread_create(&USB_communication_thread, NULL, &uart_communication, &conn);
pthread_create(&communication_thread, NULL, &uart_communication, &conn);
fflush(stdout);
// create a mutex to avoid interlacing print commands from our different threads
@ -583,16 +582,20 @@ int TestProxmark(void) {
uint8_t data[len];
for (uint16_t i = 0; i < len; i++)
data[i] = i & 0xFF;
SendCommandNG(CMD_PING, data, len);
uint32_t timeout = 1000;
#ifdef USART_SLOW_LINK
timeout = 10000;
// 10s timeout for slow FPC, e.g. over BT
// as this is the very first command sent to the pm3
// that initiates the BT connection
if (WaitForResponseTimeoutW(CMD_PING, &resp, 10000, false)) {
#else
if (WaitForResponseTimeoutW(CMD_PING, &resp, 1000, false)) {
// that initiates the BT connection
#endif
if (WaitForResponseTimeoutW(CMD_PING, &resp, timeout, false)) {
bool error = false;
if (len)
error = memcmp(data, resp.data.asBytes, len) != 0;
@ -600,6 +603,7 @@ int TestProxmark(void) {
return PM3_EIO;
SendCommandNG(CMD_CAPABILITIES, NULL, 0);
if (WaitForResponseTimeoutW(CMD_PING, &resp, 1000, false)) {
memcpy(&pm3_capabilities, resp.data.asBytes, resp.length);
conn.send_via_fpc_usart = pm3_capabilities.via_fpc;
@ -619,10 +623,8 @@ int TestProxmark(void) {
pthread_mutex_unlock(&spMutex);
#endif
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "UART reconfigure failed");
return res;
}
}
return PM3_SUCCESS;
} else {
@ -637,11 +639,11 @@ void CloseProxmark(void) {
conn.run = false;
#ifdef __BIONIC__
if (USB_communication_thread != 0) {
pthread_join(USB_communication_thread, NULL);
if (communication_thread != 0) {
pthread_join(communication_thread, NULL);
}
#else
pthread_join(USB_communication_thread, NULL);
pthread_join(communication_thread, NULL);
#endif
if (sp) {
@ -660,7 +662,7 @@ void CloseProxmark(void) {
// Clean up our state
sp = NULL;
serial_port_name = NULL;
memset(&USB_communication_thread, 0, sizeof(pthread_t));
memset(&communication_thread, 0, sizeof(pthread_t));
}
// Gives a rough estimate of the communication delay based on channel & baudrate