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 //----------------------------------------------------------------------------- 
  15 #include "cmdparser.h" 
  16 #include "proxmark3.h" 
  26 #include "cmdscript.h" 
  30 unsigned int current_command 
= CMD_UNKNOWN
; 
  32 static int CmdHelp(const char *Cmd
); 
  33 static int CmdQuit(const char *Cmd
); 
  34 static int CmdRev(const char *Cmd
); 
  36 //For storing command that are received from the device 
  37 #define CMD_BUFFER_SIZE 50 
  38 static UsbCommand cmdBuffer
[CMD_BUFFER_SIZE
]; 
  39 //Points to the next empty position to write to 
  40 static int cmd_head
;//Starts as 0 
  41 //Points to the position of the last unread command 
  42 static int cmd_tail
;//Starts as 0 
  44 static command_t CommandTable
[] =  
  46   {"help",  CmdHelp
,  1, "This help. Use '<command> help' for details of a particular command."}, 
  47   {"data",  CmdData
,  1, "{ Plot window / data buffer manipulation... }"}, 
  48   {"hf",    CmdHF
,    1, "{ High Frequency commands... }"}, 
  49   {"hw",    CmdHW
,    1, "{ Hardware commands... }"}, 
  50   {"lf",    CmdLF
,    1, "{ Low Frequency commands... }"}, 
  51   {"reveng",CmdRev
,   1, "Crc calculations from the software reveng1-30"}, 
  52   {"script",CmdScript
,1, "{ Scripting commands }"}, 
  53   {"quit",  CmdQuit
,  1, "Exit program"}, 
  54   {"exit",  CmdQuit
,  1, "Exit program"}, 
  58 command_t
* getTopLevelCommandTable() 
  62 int CmdHelp(const char *Cmd
) 
  64   CmdsHelp(CommandTable
); 
  68 int CmdQuit(const char *Cmd
) 
  73 int CmdRev(const char *Cmd
) 
  80  * @brief This method should be called when sending a new command to the pm3. In case any old 
  81  *  responses from previous commands are stored in the buffer, a call to this method should clear them. 
  82  *  A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which 
  83  *  operation. Right now we'll just have to live with this. 
  85 void clearCommandBuffer() 
  87     //This is a very simple operation 
  92  * @brief storeCommand stores a USB command in a circular buffer 
  95 void storeCommand(UsbCommand 
*command
) 
  97     if( ( cmd_head
+1) % CMD_BUFFER_SIZE 
== cmd_tail
) 
  99         //If these two are equal, we're about to overwrite in the 
 101         PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!"); 
 103     //Store the command at the 'head' location 
 104     UsbCommand
* destination 
= &cmdBuffer
[cmd_head
]; 
 105     memcpy(destination
, command
, sizeof(UsbCommand
)); 
 107     cmd_head 
= (cmd_head 
+1) % CMD_BUFFER_SIZE
; //increment head and wrap 
 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     //If head == tail, there's nothing to read, or if we just got initialized 
 119     if(cmd_head 
== cmd_tail
){ 
 122     //Pick out the next unread command 
 123     UsbCommand
* last_unread 
= &cmdBuffer
[cmd_tail
]; 
 124     memcpy(response
, last_unread
, sizeof(UsbCommand
)); 
 125     //Increment tail - this is a circular buffer, so modulo buffer size 
 126     cmd_tail 
= (cmd_tail 
+1 ) % CMD_BUFFER_SIZE
; 
 133  * Waits for a certain response type. This method waits for a maximum of 
 134  * ms_timeout milliseconds for a specified response command. 
 135  *@brief WaitForResponseTimeout 
 136  * @param cmd command to wait for 
 137  * @param response struct to copy received command into. 
 139  * @return true if command was returned, otherwise false 
 141 bool WaitForResponseTimeout(uint32_t cmd
, UsbCommand
* response
, size_t ms_timeout
) { 
 145         if (response 
== NULL
) { 
 149         // Wait until the command is received 
 150         for(size_t dm_seconds
=0; dm_seconds 
< ms_timeout
/10; dm_seconds
++) { 
 151                 while(getCommand(response
)) { 
 152                         if(response
->cmd 
== cmd
){ 
 156                 msleep(10); // XXX ugh 
 157                 if (dm_seconds 
== 200) { // Two seconds elapsed 
 158                         PrintAndLog("Waiting for a response from the proxmark..."); 
 159                         PrintAndLog("Don't forget to cancel its operation first by pressing on the button"); 
 166 bool WaitForResponse(uint32_t cmd
, UsbCommand
* response
) { 
 167         return WaitForResponseTimeout(cmd
,response
,-1); 
 171 //----------------------------------------------------------------------------- 
 172 // Entry point into our code: called whenever the user types a command and 
 173 // then presses Enter, which the full command line that they typed. 
 174 //----------------------------------------------------------------------------- 
 175 int CommandReceived(char *Cmd
) { 
 176         return CmdsParse(CommandTable
, Cmd
); 
 180 //----------------------------------------------------------------------------- 
 181 // Entry point into our code: called whenever we received a packet over USB 
 182 // that we weren't necessarily expecting, for example a debug print. 
 183 //----------------------------------------------------------------------------- 
 184 void UsbCommandReceived(UsbCommand 
*UC
) 
 187                 // First check if we are handling a debug message 
 188                 case CMD_DEBUG_PRINT_STRING
: { 
 189                         char s
[USB_CMD_DATA_SIZE
+1]; 
 190                         memset(s
, 0x00, sizeof(s
)); 
 191                         size_t len 
= MIN(UC
->arg
[0],USB_CMD_DATA_SIZE
); 
 192                         memcpy(s
,UC
->d
.asBytes
,len
); 
 193                         PrintAndLog("#db# %s", s
); 
 197                 case CMD_DEBUG_PRINT_INTEGERS
: { 
 198                         PrintAndLog("#db# %08x, %08x, %08x       \r\n", UC
->arg
[0], UC
->arg
[1], UC
->arg
[2]); 
 202                 case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
: { 
 203                         memcpy(sample_buf
+(UC
->arg
[0]),UC
->d
.asBytes
,UC
->arg
[1]);