mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
added a thread that starts when a device is detected to be offline. It runs until it finds a device and reconnects to it. Signals the READLINE hook event and the prompt is updated to match current status. This removes the need to type "hw connect" on clients that has been compiled with READLINE lib.
This commit is contained in:
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added a thread to check when device comes online again. It will connect and update prompt (@iceman1001)
|
||||
- Changed CLI offline prompt - replaces the old prompt when offline is detected (@iceman100)
|
||||
- Changed `hf mf info` - it now uses found keys to try identify Gen2 cards (@iceman1001)
|
||||
- Changed `hf 14a info` - disabled debug logging while performing the magic tests (@iceman1001)
|
||||
|
||||
+97
-1
@@ -29,6 +29,7 @@
|
||||
#include "util.h" // g_pendingPrompt
|
||||
#include "util_posix.h" // msclock
|
||||
#include "util_darwin.h" // en/dis-ableNapp();
|
||||
#include "usart_defs.h"
|
||||
|
||||
// #define COMMS_DEBUG
|
||||
// #define COMMS_DEBUG_RAW
|
||||
@@ -40,6 +41,10 @@ communication_arg_t g_conn;
|
||||
capabilities_t g_pm3_capabilities;
|
||||
|
||||
static pthread_t communication_thread;
|
||||
static pthread_t reconnect_thread;
|
||||
|
||||
static bool reconnect_ok = false;
|
||||
|
||||
static bool comm_thread_dead = false;
|
||||
static bool comm_raw_mode = false;
|
||||
static uint8_t *comm_raw_data = NULL;
|
||||
@@ -334,6 +339,52 @@ static void PacketResponseReceived(PacketResponseNG *packet) {
|
||||
}
|
||||
}
|
||||
|
||||
// The reconnect device thread.
|
||||
// When communication thread is dead, start up and try to start it again
|
||||
void *uart_reconnect(void *targ) {
|
||||
|
||||
communication_arg_t *connection = (communication_arg_t *)targ;
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
disableAppNap("Proxmark3 polling UART");
|
||||
#endif
|
||||
|
||||
uint32_t speed = USART_BAUD_RATE;
|
||||
if (connection->uart_speed) {
|
||||
speed = connection->uart_speed;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (OpenProxmarkSilent(&g_session.current_device, connection->serial_port_name, speed) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_session.pm3_present && (TestProxmark(g_session.current_device) != PM3_SUCCESS)) {
|
||||
CloseProxmark(g_session.current_device);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
enableAppNap();
|
||||
#endif
|
||||
|
||||
__atomic_test_and_set(&reconnect_ok, __ATOMIC_SEQ_CST);
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void StartReconnectProxmark(void) {
|
||||
pthread_create(&reconnect_thread, NULL, &uart_reconnect, &g_conn);
|
||||
}
|
||||
|
||||
bool IsReconnectedOk(void) {
|
||||
bool ret = __atomic_load_n(&reconnect_ok, __ATOMIC_SEQ_CST);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The communications thread.
|
||||
// signals to main thread when a response is ready to process.
|
||||
@@ -605,6 +656,8 @@ bool IsCommunicationThreadDead(void) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// To start raw receive mode:
|
||||
// 1. Call SetCommunicationRawReceiveBuffer(...)
|
||||
// 2. Call SetCommunicationReceiveMode(true)
|
||||
@@ -644,6 +697,47 @@ size_t GetCommunicationRawReceiveNum(void) {
|
||||
return __atomic_load_n(&comm_raw_pos, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
bool OpenProxmarkSilent(pm3_device_t **dev, const char *port, uint32_t speed) {
|
||||
|
||||
sp = uart_open(port, speed);
|
||||
|
||||
// check result of uart opening
|
||||
if (sp == INVALID_SERIAL_PORT) {
|
||||
sp = NULL;
|
||||
return false;
|
||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||
sp = NULL;
|
||||
return false;
|
||||
} else {
|
||||
// start the communication thread
|
||||
if (port != g_conn.serial_port_name) {
|
||||
uint16_t len = MIN(strlen(port), FILE_PATH_SIZE - 1);
|
||||
memset(g_conn.serial_port_name, 0, FILE_PATH_SIZE);
|
||||
memcpy(g_conn.serial_port_name, port, len);
|
||||
}
|
||||
g_conn.run = true;
|
||||
g_conn.block_after_ACK = false;
|
||||
// Flags to tell where to add CRC on sent replies
|
||||
g_conn.send_with_crc_on_usb = false;
|
||||
g_conn.send_with_crc_on_fpc = true;
|
||||
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
|
||||
g_conn.send_via_fpc_usart = false;
|
||||
|
||||
pthread_create(&communication_thread, NULL, &uart_communication, &g_conn);
|
||||
__atomic_clear(&comm_thread_dead, __ATOMIC_SEQ_CST);
|
||||
__atomic_clear(&reconnect_ok, __ATOMIC_SEQ_CST);
|
||||
|
||||
g_session.pm3_present = true; // TODO support for multiple devices
|
||||
|
||||
fflush(stdout);
|
||||
if (*dev == NULL) {
|
||||
*dev = calloc(sizeof(pm3_device_t), sizeof(uint8_t));
|
||||
}
|
||||
(*dev)->g_conn = &g_conn; // TODO g_conn shouldn't be global
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenProxmark(pm3_device_t **dev, const char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed) {
|
||||
|
||||
if (!wait_for_port) {
|
||||
@@ -817,8 +911,10 @@ void CloseProxmark(pm3_device_t *dev) {
|
||||
// ~ = 12000000 / USART_BAUD_RATE
|
||||
// Let's take 2x (maybe we need more for BT link?)
|
||||
static size_t communication_delay(void) {
|
||||
if (g_conn.send_via_fpc_usart) // needed also for Windows USB USART??
|
||||
// needed also for Windows USB USART??
|
||||
if (g_conn.send_via_fpc_usart) {
|
||||
return 2 * (12000000 / g_conn.uart_speed);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,9 @@ typedef struct pm3_device {
|
||||
int script_embedded;
|
||||
} pm3_device_t;
|
||||
|
||||
|
||||
void *uart_reconnect(void *targ);
|
||||
|
||||
void *uart_receiver(void *targ);
|
||||
void SendCommandBL(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
||||
void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
||||
@@ -97,13 +100,18 @@ void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, v
|
||||
void clearCommandBuffer(void);
|
||||
|
||||
#define FLASHMODE_SPEED 460800
|
||||
|
||||
bool IsReconnectedOk(void);
|
||||
bool IsCommunicationThreadDead(void);
|
||||
bool SetCommunicationReceiveMode(bool isRawMode);
|
||||
void SetCommunicationRawReceiveBuffer(uint8_t *buffer, size_t len);
|
||||
size_t GetCommunicationRawReceiveNum(void);
|
||||
|
||||
bool OpenProxmarkSilent(pm3_device_t **dev, const char *port, uint32_t speed);
|
||||
bool OpenProxmark(pm3_device_t **dev, const char *port, bool wait_for_port, int timeout, bool flash_mode, uint32_t speed);
|
||||
int TestProxmark(pm3_device_t *dev);
|
||||
void CloseProxmark(pm3_device_t *dev);
|
||||
void StartReconnectProxmark(void);
|
||||
|
||||
size_t WaitForRawDataTimeout(uint8_t *buffer, size_t len, size_t ms_timeout, bool show_process);
|
||||
bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms_timeout, bool show_warning);
|
||||
|
||||
+14
-1
@@ -133,10 +133,12 @@ static void prompt_compose(char *buf, size_t buflen, const char *promptctx, cons
|
||||
if (no_newline) {
|
||||
snprintf(buf, buflen - 1, PROXPROMPT_COMPOSE, promptdev, promptnet, promptctx);
|
||||
} else {
|
||||
snprintf(buf, buflen - 1, "\r" PROXPROMPT_COMPOSE, promptdev, promptnet, promptctx);
|
||||
|
||||
snprintf(buf, buflen - 1, "\r \r" PROXPROMPT_COMPOSE, promptdev, promptnet, promptctx);
|
||||
}
|
||||
}
|
||||
|
||||
// This function is hooked via RL_EVENT_HOOK.
|
||||
static int check_comm(void) {
|
||||
// If communications thread goes down. Device disconnected then this should hook up PM3 again.
|
||||
if (IsCommunicationThreadDead() && g_session.pm3_present) {
|
||||
@@ -148,7 +150,18 @@ static int check_comm(void) {
|
||||
memcpy_filter_ansi(prompt_filtered, prompt, sizeof(prompt_filtered), !g_session.supports_colors);
|
||||
pm3line_update_prompt(prompt_filtered);
|
||||
CloseProxmark(g_session.current_device);
|
||||
StartReconnectProxmark();
|
||||
}
|
||||
// its alive again
|
||||
if (IsReconnectedOk() && g_session.pm3_present) {
|
||||
prompt_dev = PROXPROMPT_DEV_USB;
|
||||
char prompt[PROXPROMPT_MAX_SIZE] = {0};
|
||||
prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev, prompt_net, false);
|
||||
char prompt_filtered[PROXPROMPT_MAX_SIZE] = {0};
|
||||
memcpy_filter_ansi(prompt_filtered, prompt, sizeof(prompt_filtered), !g_session.supports_colors);
|
||||
pm3line_update_prompt(prompt_filtered);
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user