1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2009 Michael Gernoth <michael at gernoth.net> 
   3 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com> 
   5 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   6 // at your option, any later version. See the LICENSE.txt file for the text of 
   8 //----------------------------------------------------------------------------- 
  10 //----------------------------------------------------------------------------- 
  17 #include <readline/readline.h> 
  18 #include <readline/history.h> 
  20 #include "proxmark3.h" 
  26 #include "cmdparser.h" 
  29 // a global mutex to prevent interlaced printing from different threads 
  30 pthread_mutex_t print_lock
; 
  32 static serial_port sp
; 
  33 static UsbCommand txcmd
; 
  34 volatile static bool txcmd_pending 
= false; 
  36 void SendCommand(UsbCommand 
*c
) { 
  38         printf("Sending %d bytes\n", sizeof(UsbCommand
)); 
  42                 PrintAndLog("Sending bytes to proxmark failed - offline"); 
  46         The while-loop below causes hangups at times, when the pm3 unit is unresponsive 
  47         or disconnected. The main console thread is alive, but comm thread just spins here. 
  60 struct main_loop_arg 
{ 
  62   char *script_cmds_file
; 
  68 static void *uart_receiver(void *targ
) { 
  69         struct receiver_arg 
*arg 
= (struct receiver_arg
*)targ
; 
  75                 rxlen 
= sizeof(UsbCommand
); 
  77                 if (uart_receive(sp
, prx
, &rxlen
)) { 
  79                         if (((prx
-rx
) % sizeof(UsbCommand
)) != 0) 
  82                         cmd_count 
= (prx
-rx
) / sizeof(UsbCommand
); 
  84                         for (size_t i 
= 0; i 
< cmd_count
; i
++) 
  85                                 UsbCommandReceived((UsbCommand
*)( rx 
+ ( i 
* sizeof(UsbCommand
)))); 
  91                         if ( !uart_send(sp
, (byte_t
*) &txcmd
, sizeof(UsbCommand
))) { 
  92                                 PrintAndLog("Sending bytes to proxmark failed"); 
  94                         txcmd_pending 
= false; 
 102 static void *main_loop(void *targ
) { 
 103         struct main_loop_arg 
*arg 
= (struct main_loop_arg
*)targ
; 
 104         struct receiver_arg rarg
; 
 106         pthread_t reader_thread
; 
 108         if (arg
->usb_present 
== 1) { 
 110                 pthread_create(&reader_thread
, NULL
, &uart_receiver
, &rarg
); 
 111                 // cache Version information now: 
 115         FILE *script_file 
= NULL
; 
 116         char script_cmd_buf
[256] = {0x00};  // iceman, needs lua script the same file_path_buffer as the rest 
 118         if (arg
->script_cmds_file
) { 
 119                 script_file 
= fopen(arg
->script_cmds_file
, "r"); 
 122                         printf("using 'scripting' commands file %s\n", arg
->script_cmds_file
); 
 125         read_history(".history"); 
 129                 // If there is a script file 
 132                         if (!fgets(script_cmd_buf
, sizeof(script_cmd_buf
), script_file
)) { 
 137                                 nl 
= strrchr(script_cmd_buf
, '\r'); 
 141                                 nl 
= strrchr(script_cmd_buf
, '\n'); 
 146                                 int newlen 
= strlen(script_cmd_buf
); 
 147                                 if ((cmd 
= (char*) malloc( newlen 
+ 1)) != NULL
) { 
 148                                         memset(cmd
, 0x00, newlen
); 
 149                                         strcpy(cmd
, script_cmd_buf
); 
 154                         cmd 
= readline(PROXPROMPT
); 
 157                 // this one should pick up all non-null cmd... 
 161                         while(cmd
[strlen(cmd
) - 1] == ' ') 
 162                                 cmd
[strlen(cmd
) - 1] = 0x00; 
 164                         if (cmd
[0] != 0x00) { 
 165                                 int ret 
= CommandReceived(cmd
); 
 185         write_history(".history"); 
 190         if (arg
->usb_present 
== 1) { 
 192                 pthread_join(reader_thread
, NULL
); 
 200 static void dumpAllHelp(int markdown
) 
 202         printf("\n%sProxmark3 command dump%s\n\n",markdown
?"# ":"",markdown
?"":"\n======================"); 
 203         printf("Some commands are available only if a Proxmark is actually connected.%s\n",markdown
?"  ":""); 
 204         printf("Check column \"offline\" for their availability.\n"); 
 206         command_t 
*cmds 
= getTopLevelCommandTable(); 
 207         dumpCommandsRecursive(cmds
, markdown
); 
 210 int main(int argc
, char* argv
[]) { 
 214                 printf("syntax: %s <port>\n\n",argv
[0]); 
 215                 printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv
[0]); 
 216                 printf("help:   %s -h\n\n", argv
[0]); 
 217                 printf("\tDump all interactive help at once\n"); 
 218                 printf("markdown:   %s -m\n\n", argv
[0]); 
 219                 printf("\tDump all interactive help at once in markdown syntax\n"); 
 222         if (strcmp(argv
[1], "-h") == 0) { 
 223                 printf("syntax: %s <port>\n\n",argv
[0]); 
 224                 printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv
[0]); 
 228         if (strcmp(argv
[1], "-m") == 0) { 
 232         // Make sure to initialize 
 233         struct main_loop_arg marg 
= { 
 235                 .script_cmds_file 
= NULL
 
 238         pthread_t main_loop_threat
; 
 241         sp 
= uart_open(argv
[1]); 
 242         if (sp 
== INVALID_SERIAL_PORT
) { 
 243                 printf("ERROR: invalid serial port\n"); 
 244                 marg
.usb_present 
= 0; 
 246         } else if (sp 
== CLAIMED_SERIAL_PORT
) { 
 247                 printf("ERROR: serial port is claimed by another process\n"); 
 248                 marg
.usb_present 
= 0; 
 251                 marg
.usb_present 
= 1; 
 255         // If the user passed the filename of the 'script' to execute, get it 
 256         if (argc 
> 2 && argv
[2]) { 
 257                 if (argv
[2][0] == 'f' &&  //buzzy, if a word 'flush' passed, flush the output after every log entry. 
 263                         printf("Output will be flushed after every print.\n"); 
 267                         marg
.script_cmds_file 
= argv
[2]; 
 271         // create a mutex to avoid interlacing print commands from our different threads 
 272         pthread_mutex_init(&print_lock
, NULL
); 
 274         pthread_create(&main_loop_threat
, NULL
, &main_loop
, &marg
); 
 275         InitGraphics(argc
, argv
); 
 279         pthread_join(main_loop_threat
, NULL
); 
 286         pthread_mutex_destroy(&print_lock
);