1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com> 
   4 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   5 // at your option, any later version. See the LICENSE.txt file for the text of 
   7 //----------------------------------------------------------------------------- 
   8 // Main command parser entry point 
   9 //----------------------------------------------------------------------------- 
  18 #include "cmdparser.h" 
  19 #include "proxmark3.h" 
  28 #include "util_posix.h" 
  29 #include "cmdscript.h" 
  33 unsigned int current_command 
= CMD_UNKNOWN
; 
  35 static int CmdHelp(const char *Cmd
); 
  36 static int CmdQuit(const char *Cmd
); 
  37 static int CmdRev(const char *Cmd
); 
  39 //For storing command that are received from the device 
  40 #define CMD_BUFFER_SIZE 50 
  41 static UsbCommand cmdBuffer
[CMD_BUFFER_SIZE
]; 
  42 //Points to the next empty position to write to 
  43 static int cmd_head
;//Starts as 0 
  44 //Points to the position of the last unread command 
  45 static int cmd_tail
;//Starts as 0 
  46 // to lock cmdBuffer operations from different threads 
  47 static pthread_mutex_t cmdBufferMutex 
= PTHREAD_MUTEX_INITIALIZER
; 
  49 static command_t CommandTable
[] =  
  51   {"help",  CmdHelp
,  1, "This help. Use '<command> help' for details of a particular command."}, 
  52   {"data",  CmdData
,  1, "{ Plot window / data buffer manipulation... }"}, 
  53   {"hf",    CmdHF
,    1, "{ High Frequency commands... }"}, 
  54   {"hw",    CmdHW
,    1, "{ Hardware commands... }"}, 
  55   {"lf",    CmdLF
,    1, "{ Low Frequency commands... }"}, 
  56   {"reveng",CmdRev
,   1, "Crc calculations from the software reveng1-30"}, 
  57   {"script",CmdScript
,1, "{ Scripting commands }"}, 
  58   {"quit",  CmdQuit
,  1, "Exit program"}, 
  59   {"exit",  CmdQuit
,  1, "Exit program"}, 
  63 command_t
* getTopLevelCommandTable() 
  67 int CmdHelp(const char *Cmd
) 
  69   CmdsHelp(CommandTable
); 
  73 int CmdQuit(const char *Cmd
) 
  78 int CmdRev(const char *Cmd
) 
  85  * @brief This method should be called when sending a new command to the pm3. In case any old 
  86  *  responses from previous commands are stored in the buffer, a call to this method should clear them. 
  87  *  A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which 
  88  *  operation. Right now we'll just have to live with this. 
  90 void clearCommandBuffer() 
  92     //This is a very simple operation 
  93         pthread_mutex_lock(&cmdBufferMutex
); 
  95         pthread_mutex_unlock(&cmdBufferMutex
); 
  99  * @brief storeCommand stores a USB command in a circular buffer 
 102 void storeCommand(UsbCommand 
*command
) 
 104         pthread_mutex_lock(&cmdBufferMutex
); 
 105     if( ( cmd_head
+1) % CMD_BUFFER_SIZE 
== cmd_tail
) 
 107         //If these two are equal, we're about to overwrite in the 
 109         PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!"); 
 111     //Store the command at the 'head' location 
 112     UsbCommand
* destination 
= &cmdBuffer
[cmd_head
]; 
 113     memcpy(destination
, command
, sizeof(UsbCommand
)); 
 115     cmd_head 
= (cmd_head 
+1) % CMD_BUFFER_SIZE
; //increment head and wrap 
 116         pthread_mutex_unlock(&cmdBufferMutex
); 
 121  * @brief getCommand gets a command from an internal circular buffer. 
 122  * @param response location to write command 
 123  * @return 1 if response was returned, 0 if nothing has been received 
 125 int getCommand(UsbCommand
* response
) 
 127         pthread_mutex_lock(&cmdBufferMutex
); 
 128     //If head == tail, there's nothing to read, or if we just got initialized 
 129     if(cmd_head 
== cmd_tail
){ 
 130                 pthread_mutex_unlock(&cmdBufferMutex
); 
 133     //Pick out the next unread command 
 134     UsbCommand
* last_unread 
= &cmdBuffer
[cmd_tail
]; 
 135     memcpy(response
, last_unread
, sizeof(UsbCommand
)); 
 136     //Increment tail - this is a circular buffer, so modulo buffer size 
 137     cmd_tail 
= (cmd_tail 
+1 ) % CMD_BUFFER_SIZE
; 
 138         pthread_mutex_unlock(&cmdBufferMutex
); 
 144  * Waits for a certain response type. This method waits for a maximum of 
 145  * ms_timeout milliseconds for a specified response command. 
 146  *@brief WaitForResponseTimeout 
 147  * @param cmd command to wait for 
 148  * @param response struct to copy received command into. 
 150  * @return true if command was returned, otherwise false 
 152 bool WaitForResponseTimeoutW(uint32_t cmd
, UsbCommand
* response
, size_t ms_timeout
, bool show_warning
) { 
 156         if (response 
== NULL
) { 
 160         uint64_t start_time 
= msclock(); 
 162         // Wait until the command is received 
 164                 while(getCommand(response
)) { 
 165                         if(response
->cmd 
== cmd
){ 
 169                 if (msclock() - start_time 
> ms_timeout
) { 
 172                 if (msclock() - start_time 
> 2000 && show_warning
) { 
 173                         PrintAndLog("Waiting for a response from the proxmark..."); 
 174                         PrintAndLog("Don't forget to cancel its operation first by pressing on the button"); 
 182 bool WaitForResponseTimeout(uint32_t cmd
, UsbCommand
* response
, size_t ms_timeout
) { 
 183         return WaitForResponseTimeoutW(cmd
, response
, ms_timeout
, true); 
 186 bool WaitForResponse(uint32_t cmd
, UsbCommand
* response
) { 
 187         return WaitForResponseTimeoutW(cmd
, response
, -1, true); 
 191 //----------------------------------------------------------------------------- 
 192 // Entry point into our code: called whenever the user types a command and 
 193 // then presses Enter, which the full command line that they typed. 
 194 //----------------------------------------------------------------------------- 
 195 int CommandReceived(char *Cmd
) { 
 196         return CmdsParse(CommandTable
, Cmd
); 
 200 //----------------------------------------------------------------------------- 
 201 // Entry point into our code: called whenever we received a packet over USB 
 202 // that we weren't necessarily expecting, for example a debug print. 
 203 //----------------------------------------------------------------------------- 
 204 void UsbCommandReceived(UsbCommand 
*UC
) 
 207                 // First check if we are handling a debug message 
 208                 case CMD_DEBUG_PRINT_STRING
: { 
 209                         char s
[USB_CMD_DATA_SIZE
+1]; 
 210                         memset(s
, 0x00, sizeof(s
)); 
 211                         size_t len 
= MIN(UC
->arg
[0],USB_CMD_DATA_SIZE
); 
 212                         memcpy(s
,UC
->d
.asBytes
,len
); 
 213                         PrintAndLog("#db# %s", s
); 
 217                 case CMD_DEBUG_PRINT_INTEGERS
: { 
 218                         PrintAndLog("#db# %08x, %08x, %08x       \r\n", UC
->arg
[0], UC
->arg
[1], UC
->arg
[2]); 
 222                 case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
: { 
 223                         memcpy(sample_buf
+(UC
->arg
[0]),UC
->d
.asBytes
,UC
->arg
[1]);