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" 
  32 unsigned int current_command 
= CMD_UNKNOWN
; 
  34 static int CmdHelp(const char *Cmd
); 
  35 static int CmdQuit(const char *Cmd
); 
  37 //For storing command that are received from the device 
  38 #define CMD_BUFFER_SIZE 50 
  39 static UsbCommand cmdBuffer
[CMD_BUFFER_SIZE
]; 
  40 //Points to the next empty position to write to 
  41 static int cmd_head
;//Starts as 0 
  42 //Points to the position of the last unread command 
  43 static int cmd_tail
;//Starts as 0 
  44 // to lock cmdBuffer operations from different threads 
  45 static pthread_mutex_t cmdBufferMutex 
= PTHREAD_MUTEX_INITIALIZER
; 
  47 static command_t CommandTable
[] =  
  49   {"help",  CmdHelp
,  1, "This help. Use '<command> help' for details of a particular command."}, 
  50   {"data",  CmdData
,  1, "{ Plot window / data buffer manipulation... }"}, 
  51   {"hf",    CmdHF
,    1, "{ High Frequency commands... }"}, 
  52   {"hw",    CmdHW
,    1, "{ Hardware commands... }"}, 
  53   {"lf",    CmdLF
,    1, "{ Low Frequency commands... }"}, 
  54   {"script",CmdScript
,1, "{ Scripting commands }"}, 
  55   {"quit",  CmdQuit
,  1, "Exit program"}, 
  56   {"exit",  CmdQuit
,  1, "Exit program"}, 
  60 command_t
* getTopLevelCommandTable() 
  64 int CmdHelp(const char *Cmd
) 
  66   CmdsHelp(CommandTable
); 
  70 int CmdQuit(const char *Cmd
) 
  76  * @brief This method should be called when sending a new command to the pm3. In case any old 
  77  *  responses from previous commands are stored in the buffer, a call to this method should clear them. 
  78  *  A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which 
  79  *  operation. Right now we'll just have to live with this. 
  81 void clearCommandBuffer() 
  83     //This is a very simple operation 
  84         pthread_mutex_lock(&cmdBufferMutex
); 
  86         pthread_mutex_unlock(&cmdBufferMutex
); 
  90  * @brief storeCommand stores a USB command in a circular buffer 
  93 void storeCommand(UsbCommand 
*command
) 
  95         pthread_mutex_lock(&cmdBufferMutex
); 
  96     if( ( cmd_head
+1) % CMD_BUFFER_SIZE 
== cmd_tail
) 
  98         //If these two are equal, we're about to overwrite in the 
 100         PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!"); 
 102     //Store the command at the 'head' location 
 103     UsbCommand
* destination 
= &cmdBuffer
[cmd_head
]; 
 104     memcpy(destination
, command
, sizeof(UsbCommand
)); 
 106     cmd_head 
= (cmd_head 
+1) % CMD_BUFFER_SIZE
; //increment head and wrap 
 107         pthread_mutex_unlock(&cmdBufferMutex
); 
 112  * @brief getCommand gets a command from an internal circular buffer. 
 113  * @param response location to write command 
 114  * @return 1 if response was returned, 0 if nothing has been received 
 116 int getCommand(UsbCommand
* response
) 
 118         pthread_mutex_lock(&cmdBufferMutex
); 
 119     //If head == tail, there's nothing to read, or if we just got initialized 
 120     if(cmd_head 
== cmd_tail
){ 
 121                 pthread_mutex_unlock(&cmdBufferMutex
); 
 124     //Pick out the next unread command 
 125     UsbCommand
* last_unread 
= &cmdBuffer
[cmd_tail
]; 
 126     memcpy(response
, last_unread
, sizeof(UsbCommand
)); 
 127     //Increment tail - this is a circular buffer, so modulo buffer size 
 128     cmd_tail 
= (cmd_tail 
+1 ) % CMD_BUFFER_SIZE
; 
 129         pthread_mutex_unlock(&cmdBufferMutex
); 
 135  * Waits for a certain response type. This method waits for a maximum of 
 136  * ms_timeout milliseconds for a specified response command. 
 137  *@brief WaitForResponseTimeout 
 138  * @param cmd command to wait for 
 139  * @param response struct to copy received command into. 
 141  * @return true if command was returned, otherwise false 
 143 bool WaitForResponseTimeoutW(uint32_t cmd
, UsbCommand
* response
, size_t ms_timeout
, bool show_warning
) { 
 147         if (response 
== NULL
) { 
 151         uint64_t start_time 
= msclock(); 
 153         // Wait until the command is received 
 155                 while(getCommand(response
)) { 
 156                         if(response
->cmd 
== cmd
){ 
 160                 if (msclock() - start_time 
> ms_timeout
) { 
 163                 if (msclock() - start_time 
> 2000 && show_warning
) { 
 164                         PrintAndLog("Waiting for a response from the proxmark..."); 
 165                         PrintAndLog("You can cancel this operation by pressing the pm3 button"); 
 166                         show_warning 
= false; 
 173 bool WaitForResponseTimeout(uint32_t cmd
, UsbCommand
* response
, size_t ms_timeout
) { 
 174         return WaitForResponseTimeoutW(cmd
, response
, ms_timeout
, true); 
 177 bool WaitForResponse(uint32_t cmd
, UsbCommand
* response
) { 
 178         return WaitForResponseTimeoutW(cmd
, response
, -1, true); 
 182 //----------------------------------------------------------------------------- 
 183 // Entry point into our code: called whenever the user types a command and 
 184 // then presses Enter, which the full command line that they typed. 
 185 //----------------------------------------------------------------------------- 
 186 int CommandReceived(char *Cmd
) { 
 187         return CmdsParse(CommandTable
, Cmd
); 
 191 //----------------------------------------------------------------------------- 
 192 // Entry point into our code: called whenever we received a packet over USB 
 193 // that we weren't necessarily expecting, for example a debug print. 
 194 //----------------------------------------------------------------------------- 
 195 void UsbCommandReceived(UsbCommand 
*UC
) 
 198                 // First check if we are handling a debug message 
 199                 case CMD_DEBUG_PRINT_STRING
: { 
 200                         char s
[USB_CMD_DATA_SIZE
+1]; 
 201                         memset(s
, 0x00, sizeof(s
)); 
 202                         size_t len 
= MIN(UC
->arg
[0],USB_CMD_DATA_SIZE
); 
 203                         memcpy(s
,UC
->d
.asBytes
,len
); 
 204                         PrintAndLog("#db# %s", s
); 
 208                 case CMD_DEBUG_PRINT_INTEGERS
: { 
 209                         PrintAndLog("#db# %08x, %08x, %08x       \r\n", UC
->arg
[0], UC
->arg
[1], UC
->arg
[2]); 
 213                 case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
: { 
 214                         memcpy(sample_buf
+(UC
->arg
[0]),UC
->d
.asBytes
,UC
->arg
[1]);