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 //----------------------------------------------------------------------------- 
  16 #include "cmdparser.h" 
  17 #include "proxmark3.h" 
  27 #include "cmdscript.h" 
  30 unsigned int current_command 
= CMD_UNKNOWN
; 
  32 static int CmdHelp(const char *Cmd
); 
  33 static int CmdQuit(const char *Cmd
); 
  35 //For storing command that are received from the device 
  36 #define CMD_BUFFER_SIZE 50 
  37 static UsbCommand cmdBuffer
[CMD_BUFFER_SIZE
]; 
  38 //Points to the next empty position to write to 
  39 static int cmd_head
;//Starts as 0 
  40 //Points to the position of the last unread command 
  41 static int cmd_tail
;//Starts as 0 
  43 static command_t CommandTable
[] =  
  45   {"help",  CmdHelp
,  1, "This help. Use '<command> help' for details of a particular command."}, 
  46   {"data",  CmdData
,  1, "{ Plot window / data buffer manipulation... }"}, 
  47   {"hf",        CmdHF
,          1, "{ High Frequency commands... }"}, 
  48   {"hw",    CmdHW
,    1, "{ Hardware commands... }"}, 
  49   {"lf",        CmdLF
,          1, "{ Low Frequency commands... }"}, 
  50   {"script", CmdScript
,   1,"{ Scripting commands }"}, 
  51   {"quit",  CmdQuit
,  1, "Exit program"}, 
  52   {"exit",  CmdQuit
,  1, "Exit program"}, 
  56 command_t
* getTopLevelCommandTable() 
  60 int CmdHelp(const char *Cmd
) 
  62   CmdsHelp(CommandTable
); 
  66 int CmdQuit(const char *Cmd
) 
  72  * @brief This method should be called when sending a new command to the pm3. In case any old 
  73  *  responses from previous commands are stored in the buffer, a call to this method should clear them. 
  74  *  A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which 
  75  *  operation. Right now we'll just have to live with this. 
  77 void clearCommandBuffer() 
  79     //This is a very simple operation 
  84  * @brief storeCommand stores a USB command in a circular buffer 
  87 void storeCommand(UsbCommand 
*command
) 
  89     if( ( cmd_head
+1) % CMD_BUFFER_SIZE 
== cmd_tail
) 
  91         //If these two are equal, we're about to overwrite in the 
  93         PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!"); 
  95     //Store the command at the 'head' location 
  96     UsbCommand
* destination 
= &cmdBuffer
[cmd_head
]; 
  97     memcpy(destination
, command
, sizeof(UsbCommand
)); 
  99     cmd_head 
= (cmd_head 
+1) % CMD_BUFFER_SIZE
; //increment head and wrap 
 103  * @brief getCommand gets a command from an internal circular buffer. 
 104  * @param response location to write command 
 105  * @return 1 if response was returned, 0 if nothing has been received 
 107 int getCommand(UsbCommand
* response
) 
 109     //If head == tail, there's nothing to read, or if we just got initialized 
 110     if(cmd_head 
== cmd_tail
){ 
 113     //Pick out the next unread command 
 114     UsbCommand
* last_unread 
= &cmdBuffer
[cmd_tail
]; 
 115     memcpy(response
, last_unread
, sizeof(UsbCommand
)); 
 116     //Increment tail - this is a circular buffer, so modulo buffer size 
 117     cmd_tail 
= (cmd_tail 
+1 ) % CMD_BUFFER_SIZE
; 
 124  * Waits for a certain response type. This method waits for a maximum of 
 125  * ms_timeout milliseconds for a specified response command. 
 126  *@brief WaitForResponseTimeout 
 127  * @param cmd command to wait for 
 128  * @param response struct to copy received command into. 
 130  * @return true if command was returned, otherwise false 
 132 bool WaitForResponseTimeout(uint32_t cmd
, UsbCommand
* response
, size_t ms_timeout
) { 
 136         if (response 
== NULL
) 
 140   // Wait until the command is received 
 141   for(size_t dm_seconds
=0; dm_seconds 
< ms_timeout
/10; dm_seconds
++) { 
 143                 while(getCommand(response
)) { 
 144           if(response
->cmd 
== cmd
){ 
 148         msleep(10); // XXX ugh 
 149         if (dm_seconds 
== 200) { // Two seconds elapsed 
 150           PrintAndLog("Waiting for a response from the proxmark..."); 
 151           PrintAndLog("Don't forget to cancel its operation first by pressing on the button"); 
 157 bool WaitForResponse(uint32_t cmd
, UsbCommand
* response
) { 
 158         return WaitForResponseTimeout(cmd
,response
,-1); 
 161 //----------------------------------------------------------------------------- 
 162 // Entry point into our code: called whenever the user types a command and 
 163 // then presses Enter, which the full command line that they typed. 
 164 //----------------------------------------------------------------------------- 
 165 void CommandReceived(char *Cmd
) { 
 166   CmdsParse(CommandTable
, Cmd
); 
 169 //----------------------------------------------------------------------------- 
 170 // Entry point into our code: called whenever we received a packet over USB 
 171 // that we weren't necessarily expecting, for example a debug print. 
 172 //----------------------------------------------------------------------------- 
 173 void UsbCommandReceived(UsbCommand 
*UC
) 
 176                 // First check if we are handling a debug message 
 177                 case CMD_DEBUG_PRINT_STRING
: { 
 178                         char s
[USB_CMD_DATA_SIZE
+1] = {0x00}; 
 179                         size_t len 
= MIN(UC
->arg
[0],USB_CMD_DATA_SIZE
); 
 180                         memcpy(s
,UC
->d
.asBytes
,len
); 
 181                         PrintAndLog("#db# %s       ", s
); 
 185                 case CMD_DEBUG_PRINT_INTEGERS
: { 
 186                         PrintAndLog("#db# %08x, %08x, %08x       \r\n", UC
->arg
[0], UC
->arg
[1], UC
->arg
[2]); 
 190                 case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K
: { 
 191                         memcpy(sample_buf
+(UC
->arg
[0]),UC
->d
.asBytes
,UC
->arg
[1]);