Variable length frames, part1: USB Host -> Pm3

This commit is contained in:
Philippe Teuwen
2019-04-16 10:01:08 +02:00
parent 0b35dcbe0c
commit 34467b7550
8 changed files with 229 additions and 16 deletions

View File

@@ -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}
};

View File

@@ -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;

View File

@@ -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