Variable length frames, part1: USB Host -> Pm3
This commit is contained in:
@@ -438,6 +438,31 @@ static int CmdPing(const char *Cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CmdPingNG(const char *Cmd) {
|
||||
uint32_t len = strtol(Cmd, NULL, 0);
|
||||
if (len > USB_CMD_DATA_SIZE)
|
||||
len = USB_CMD_DATA_SIZE;
|
||||
PrintAndLogEx(NORMAL, "Pinging with payload len=%d", len);
|
||||
clearCommandBuffer();
|
||||
UsbCommand resp;
|
||||
UsbCommand c = {CMD_PING, {len, 0, 0}, {{0}}};
|
||||
if (len >= 4)
|
||||
c.d.asDwords[0] = 0xAABBCCDD;
|
||||
if (len >= 8)
|
||||
c.d.asDwords[(len-1)/4] = 0xDDCCBBAA;
|
||||
SendCommandNG(&c, len);
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
|
||||
PrintAndLogEx(NORMAL, "PingNG successful");
|
||||
if (len >= 4)
|
||||
PrintAndLogEx(NORMAL, "%08x -> %08x", 0xAABBCCDD, resp.arg[1]);
|
||||
if (len >= 8)
|
||||
PrintAndLogEx(NORMAL, "%08x -> %08x", 0xDDCCBBAA, resp.arg[2]);
|
||||
}
|
||||
else
|
||||
PrintAndLogEx(NORMAL, "PingNG failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"detectreader", CmdDetectReader, 0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
|
||||
@@ -454,6 +479,7 @@ static command_t CommandTable[] = {
|
||||
{"version", CmdVersion, 0, "Show version information about the connected Proxmark"},
|
||||
{"status", CmdStatus, 0, "Show runtime status information about the connected Proxmark"},
|
||||
{"ping", CmdPing, 0, "Test if the pm3 is responsive"},
|
||||
{"pingng", CmdPingNG, 0, "Test if the pm3 is responsive"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -25,10 +25,12 @@ static pthread_t USB_communication_thread;
|
||||
|
||||
// Transmit buffer.
|
||||
static UsbCommand txBuffer;
|
||||
static uint8_t txBufferNG[sizeof(UsbCommandNGPreamble) + sizeof(UsbCommand) + sizeof(UsbCommandNGPostamble)];
|
||||
size_t txBufferNGLen;
|
||||
static bool txBuffer_pending = false;
|
||||
static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t txBufferSig = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
|
||||
// Used by UsbReceiveCommand as a ring buffer for messages that are yet to be
|
||||
// processed by a command handler (WaitForResponse{,Timeout})
|
||||
static UsbCommand rxBuffer[CMD_BUFFER_SIZE];
|
||||
@@ -84,6 +86,50 @@ void SendCommand(UsbCommand *c) {
|
||||
//__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void SendCommandNG(UsbCommand *c, size_t len) {
|
||||
|
||||
#ifdef COMMS_DEBUG
|
||||
PrintAndLogEx(NORMAL, "Sending %d bytes of payload | cmd %04x\n", len, c->cmd);
|
||||
#endif
|
||||
|
||||
if (offline) {
|
||||
PrintAndLogEx(NORMAL, "Sending bytes to proxmark failed - offline");
|
||||
return;
|
||||
}
|
||||
if (len > USB_CMD_DATA_SIZE) {
|
||||
PrintAndLogEx(WARNING, "Sending %d bytes of payload is too much, abort", len);
|
||||
return;
|
||||
}
|
||||
|
||||
UsbCommandNGPreamble *tx_pre = (UsbCommandNGPreamble *)txBufferNG;
|
||||
UsbCommandNGPostamble *tx_post = (UsbCommandNGPostamble *)(txBufferNG + sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNG) + len);
|
||||
|
||||
pthread_mutex_lock(&txBufferMutex);
|
||||
/**
|
||||
This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive,
|
||||
but comm thread just spins here. Not good.../holiman
|
||||
**/
|
||||
while (txBuffer_pending) {
|
||||
// wait for communication thread to complete sending a previous commmand
|
||||
pthread_cond_wait(&txBufferSig, &txBufferMutex);
|
||||
}
|
||||
|
||||
tx_pre->magic = USB_PREAMBLE_MAGIC;
|
||||
tx_pre->length = len;
|
||||
memcpy(txBufferNG + sizeof(UsbCommandNGPreamble), c, sizeof(UsbCommandNG) + len);
|
||||
// TODO CRC
|
||||
tx_post->magic = USB_POSTAMBLE_MAGIC;
|
||||
txBufferNGLen = sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNG) + len + sizeof(UsbCommandNGPostamble);
|
||||
txBuffer_pending = true;
|
||||
|
||||
// tell communication thread that a new command can be send
|
||||
pthread_cond_signal(&txBufferSig);
|
||||
|
||||
pthread_mutex_unlock(&txBufferMutex);
|
||||
|
||||
//__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method should be called when sending a new command to the pm3. In case any old
|
||||
* responses from previous commands are stored in the buffer, a call to this method should clear them.
|
||||
@@ -273,9 +319,17 @@ __attribute__((force_align_arg_pointer))
|
||||
}
|
||||
|
||||
if (txBuffer_pending) {
|
||||
if (!uart_send(sp, (uint8_t *) &txBuffer, sizeof(UsbCommand))) {
|
||||
//counter_to_offline++;
|
||||
PrintAndLogEx(WARNING, "sending bytes to proxmark failed");
|
||||
if (txBufferNGLen) { // NG packet
|
||||
if (!uart_send(sp, (uint8_t *) &txBufferNG, txBufferNGLen)) {
|
||||
//counter_to_offline++;
|
||||
PrintAndLogEx(WARNING, "sending bytes to proxmark failed");
|
||||
}
|
||||
txBufferNGLen = 0;
|
||||
} else {
|
||||
if (!uart_send(sp, (uint8_t *) &txBuffer, sizeof(UsbCommand))) {
|
||||
//counter_to_offline++;
|
||||
PrintAndLogEx(WARNING, "sending bytes to proxmark failed");
|
||||
}
|
||||
}
|
||||
txBuffer_pending = false;
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ bool IsOffline(void);
|
||||
|
||||
void *uart_receiver(void *targ);
|
||||
void SendCommand(UsbCommand *c);
|
||||
void SendCommandNG(UsbCommand *c, size_t len);
|
||||
void clearCommandBuffer(void);
|
||||
|
||||
#define FLASHMODE_SPEED 460800
|
||||
|
||||
Reference in New Issue
Block a user