mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
CHG: enables proxmark3 client to reconnect to serial port without exiting / restarting.
This commit is contained in:
parent
f054f5da32
commit
b18920b9f9
3 changed files with 89 additions and 41 deletions
|
@ -27,15 +27,15 @@ static char* serial_port_name;
|
|||
|
||||
void cmd_debug(UsbCommand* UC) {
|
||||
// Debug
|
||||
printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand));
|
||||
printf(" cmd[len=%zd]: %016" PRIx64"\n",sizeof(UC->cmd),UC->cmd);
|
||||
printf(" arg0[len=%zd]: %016" PRIx64"\n",sizeof(UC->arg[0]),UC->arg[0]);
|
||||
printf(" arg1[len=%zd]: %016" PRIx64"\n",sizeof(UC->arg[1]),UC->arg[1]);
|
||||
printf(" arg2[len=%zd]: %016" PRIx64"\n",sizeof(UC->arg[2]),UC->arg[2]);
|
||||
printf(" data[len=%zd]: ",sizeof(UC->d.asBytes));
|
||||
printf("UsbCommand length[len=%zd]\n", sizeof(UsbCommand));
|
||||
printf(" cmd[len=%zd]: %016" PRIx64"\n", sizeof(UC->cmd), UC->cmd);
|
||||
printf(" arg0[len=%zd]: %016" PRIx64"\n", sizeof(UC->arg[0]), UC->arg[0]);
|
||||
printf(" arg1[len=%zd]: %016" PRIx64"\n", sizeof(UC->arg[1]), UC->arg[1]);
|
||||
printf(" arg2[len=%zd]: %016" PRIx64"\n", sizeof(UC->arg[2]), UC->arg[2]);
|
||||
printf(" data[len=%zd]: ", sizeof(UC->d.asBytes));
|
||||
|
||||
for (size_t i=0; i<16; i++)
|
||||
printf("%02x",UC->d.asBytes[i]);
|
||||
printf("%02x", UC->d.asBytes[i]);
|
||||
|
||||
printf("...\n");
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ void cmd_debug(UsbCommand* UC) {
|
|||
void SendCommand(UsbCommand* txcmd) {
|
||||
// printf("send: ");
|
||||
// cmd_debug(txcmd);
|
||||
if (!uart_send(sp,(byte_t*)txcmd,sizeof(UsbCommand))) {
|
||||
if (!uart_send(sp,(byte_t*)txcmd, sizeof(UsbCommand))) {
|
||||
printf("Sending bytes to proxmark failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -80,8 +80,7 @@ int OpenProxmark(size_t i) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void usage(char *argv0)
|
||||
{
|
||||
static void usage(char *argv0) {
|
||||
fprintf(stderr, "Usage: %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
|
||||
fprintf(stderr, "\t-b\tEnable flashing of bootloader area (DANGEROUS)\n\n");
|
||||
fprintf(stderr, "\nExample (Linux):\n\n\t %s /dev/ttyACM0 armsrc/obj/fullimage.elf\n", argv0);
|
||||
|
|
|
@ -28,9 +28,10 @@
|
|||
|
||||
// a global mutex to prevent interlaced printing from different threads
|
||||
extern pthread_mutex_t print_lock;
|
||||
|
||||
static serial_port sp;
|
||||
static UsbCommand txcmd;
|
||||
static char comport[255];
|
||||
|
||||
volatile static bool txcmd_pending = false;
|
||||
|
||||
void SendCommand(UsbCommand *c) {
|
||||
|
@ -77,9 +78,30 @@ static void showBanner(void){
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool hookUpPM3() {
|
||||
bool ret = false;
|
||||
sp = uart_open( comport );
|
||||
if (sp == INVALID_SERIAL_PORT) {
|
||||
printf("ERROR: invalid serial port\n");
|
||||
ret = false;
|
||||
offline = 1;
|
||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||
printf("ERROR: serial port is claimed by another process\n");
|
||||
ret = false;
|
||||
offline = 1;
|
||||
} else {
|
||||
//printf("OK: connected to serial port %s\n", comport);
|
||||
ret = true;
|
||||
offline = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// (iceman) if uart_receiver fails a command three times, we conside the device to be offline.
|
||||
static void *uart_receiver(void *targ) {
|
||||
struct receiver_arg *arg = (struct receiver_arg*)targ;
|
||||
size_t rxlen;
|
||||
int counter_to_offline = 0;
|
||||
|
||||
while (arg->run) {
|
||||
rxlen = 0;
|
||||
|
@ -98,24 +120,36 @@ static void *uart_receiver(void *targ) {
|
|||
if ( tmpsignal ) {
|
||||
bool res = uart_send(sp, (byte_t*) &txcmd, sizeof(UsbCommand));
|
||||
if (!res) {
|
||||
counter_to_offline++;
|
||||
PrintAndLog("Sending bytes to proxmark failed");
|
||||
}
|
||||
__atomic_clear(&txcmd_pending, __ATOMIC_SEQ_CST);
|
||||
//txcmd_pending = false;
|
||||
|
||||
// set offline flag
|
||||
if ( counter_to_offline == 3 ) {
|
||||
__atomic_test_and_set(&offline, __ATOMIC_SEQ_CST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// when this reader thread dies, we close the serial port.
|
||||
uart_close(sp);
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void main_loop(char *script_cmds_file, bool usb_present) {
|
||||
|
||||
struct receiver_arg rarg;
|
||||
char *cmd = NULL;
|
||||
pthread_t reader_thread;
|
||||
char *cmd = NULL;
|
||||
|
||||
if (usb_present) {
|
||||
rarg.run = 1;
|
||||
//
|
||||
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
|
||||
// cache Version information now:
|
||||
CmdVersion(NULL);
|
||||
|
@ -133,8 +167,24 @@ void main_loop(char *script_cmds_file, bool usb_present) {
|
|||
|
||||
read_history(".history");
|
||||
|
||||
// loops everytime enter is pressed...
|
||||
while(1) {
|
||||
|
||||
// this should hook up the PM3 again.
|
||||
if (offline) {
|
||||
|
||||
// sets the global variable, SP and offline)
|
||||
usb_present = hookUpPM3();
|
||||
|
||||
// usb and the reader_thread is NULL, create a new reader thread.
|
||||
if (usb_present && !offline) {
|
||||
rarg.run = 1;
|
||||
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
|
||||
// cache Version information now:
|
||||
CmdVersion(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// If there is a script file
|
||||
if (script_file) {
|
||||
|
||||
|
@ -245,7 +295,8 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
if (argc < 2) {
|
||||
printf("syntax: %s <port>\n\n",argv[0]);
|
||||
printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv[0]);
|
||||
printf("\tLinux example:'%s /dev/ttyACM0'\n", argv[0]);
|
||||
printf("\tWindows example:'%s com3'\n\n", argv[0]);
|
||||
printf("help: %s -h\n\n", argv[0]);
|
||||
printf("\tDump all interactive help at once\n");
|
||||
printf("markdown: %s -m\n\n", argv[0]);
|
||||
|
@ -254,7 +305,8 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
if (strcmp(argv[1], "-h") == 0) {
|
||||
printf("syntax: %s <port>\n\n",argv[0]);
|
||||
printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv[0]);
|
||||
printf("\tLinux example:'%s /dev/ttyACM0'\n", argv[0]);
|
||||
printf("\tWindows example:'%s com3'\n\n", argv[0]);
|
||||
dumpAllHelp(0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -270,25 +322,20 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
set_my_executable_path();
|
||||
|
||||
bool usb_present = false;
|
||||
char *script_cmds_file = NULL;
|
||||
|
||||
sp = uart_open(argv[1]);
|
||||
if (sp == INVALID_SERIAL_PORT) {
|
||||
printf("ERROR: invalid serial port\n");
|
||||
usb_present = false;
|
||||
offline = 1;
|
||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||
printf("ERROR: serial port is claimed by another process\n");
|
||||
usb_present = false;
|
||||
offline = 1;
|
||||
} else {
|
||||
usb_present = true;
|
||||
offline = 0;
|
||||
}
|
||||
// lets copy the comport string.
|
||||
memset(comport, 0, sizeof(comport));
|
||||
memcpy(comport, argv[1], strlen(argv[1]));
|
||||
|
||||
// sets the global variable, SP and offline)
|
||||
bool usb_present = hookUpPM3();
|
||||
|
||||
// If the user passed the filename of the 'script' to execute, get it
|
||||
if (argc > 2 && argv[2]) {
|
||||
|
||||
printf("Num of args: %d -- %s\n", argc, argv[2]);
|
||||
|
||||
if (argv[2][0] == 'f' && //buzzy, if a word 'flush' passed, flush the output after every log entry.
|
||||
argv[2][1] == 'l' &&
|
||||
argv[2][2] == 'u' &&
|
||||
|
|
|
@ -62,11 +62,11 @@ serial_port uart_open(const char* pcPortName) {
|
|||
serial_port_windows* sp = malloc(sizeof(serial_port_windows));
|
||||
|
||||
// Copy the input "com?" to "\\.\COM?" format
|
||||
sprintf(acPortName,"\\\\.\\%s",pcPortName);
|
||||
sprintf(acPortName,"\\\\.\\%s", pcPortName);
|
||||
upcase(acPortName);
|
||||
|
||||
// Try to open the serial port
|
||||
sp->hPort = CreateFileA(acPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
|
||||
sp->hPort = CreateFileA(acPortName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (sp->hPort == INVALID_HANDLE_VALUE) {
|
||||
uart_close(sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
|
@ -75,13 +75,13 @@ serial_port uart_open(const char* pcPortName) {
|
|||
// Prepare the device control
|
||||
memset(&sp->dcb, 0, sizeof(DCB));
|
||||
sp->dcb.DCBlength = sizeof(DCB);
|
||||
if(!BuildCommDCBA("baud=115200 parity=N data=8 stop=1",&sp->dcb)) {
|
||||
if (!BuildCommDCBA("baud=115200 parity=N data=8 stop=1",&sp->dcb)) {
|
||||
uart_close(sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
||||
// Update the active serial port
|
||||
if(!SetCommState(sp->hPort,&sp->dcb)) {
|
||||
if (!SetCommState(sp->hPort, &sp->dcb)) {
|
||||
uart_close(sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ serial_port uart_open(const char* pcPortName) {
|
|||
sp->ct.WriteTotalTimeoutMultiplier = 0;//1;
|
||||
sp->ct.WriteTotalTimeoutConstant = 30;
|
||||
|
||||
if(!SetCommTimeouts(sp->hPort,&sp->ct)) {
|
||||
if (!SetCommTimeouts(sp->hPort, &sp->ct)) {
|
||||
uart_close(sp);
|
||||
return INVALID_SERIAL_PORT;
|
||||
}
|
||||
|
@ -107,18 +107,20 @@ serial_port uart_open(const char* pcPortName) {
|
|||
}
|
||||
|
||||
void uart_close(const serial_port sp) {
|
||||
if (!sp) return;
|
||||
if (((serial_port_windows*)sp)->hPort != NULL )
|
||||
CloseHandle(((serial_port_windows*)sp)->hPort);
|
||||
free(sp);
|
||||
}
|
||||
|
||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) {
|
||||
ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,pszMaxRxLen,(LPDWORD)pszRxLen,NULL);
|
||||
ReadFile(((serial_port_windows*)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
|
||||
return (*pszRxLen != 0);
|
||||
}
|
||||
|
||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen) {
|
||||
DWORD dwTxLen = 0;
|
||||
return WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL);
|
||||
return WriteFile(((serial_port_windows*)sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL);
|
||||
return (dwTxLen != 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue