New reply frames transmission (reception still to be done)

This commit is contained in:
Philippe Teuwen 2019-04-16 23:15:23 +02:00
commit 96843c3f47
6 changed files with 112 additions and 23 deletions

View file

@ -1457,11 +1457,7 @@ static void UsbPacketReceived(bool cmd_ng, uint8_t *packet) {
break;
case CMD_PING:
if (cmd_ng) {
#ifdef WITH_FPC_HOST
cmd_send(CMD_ACK, reply_via_fpc, ((uint32_t *)data_ng)[0], ((uint32_t *)data_ng)[(datalen_ng - 1) / 4], 0, 0);
#else
cmd_send(CMD_ACK, 0, ((uint32_t *)data_ng)[0], ((uint32_t *)data_ng)[(c->arg[0] - 1) / 4], 0, 0);
#endif
reply_ng(CMD_PING, PM3_SUCCESS, data_ng, datalen_ng);
} else {
#ifdef WITH_FPC_HOST
cmd_send(CMD_ACK, reply_via_fpc, 0, 0, 0, 0);
@ -1574,9 +1570,9 @@ void __attribute__((noreturn)) AppMain(void) {
usb_disable();
usb_enable();
uint8_t rx[USB_PACKET_NG_MAXLEN];
uint8_t rx[USB_COMMANDNG_MAXLEN];
UsbCommandNGPreamble *pre = (UsbCommandNGPreamble *)rx;
UsbCommandNGPostamble *post = (UsbCommandNGPostamble *)(rx + sizeof(UsbCommandNGPreamble) + USB_CMD_DATA_SIZE);
UsbCommandNGPostamble *post = (UsbCommandNGPostamble *)(rx + sizeof(UsbCommandNGPreamble) + USB_DATANG_SIZE);
for (;;) {
WDT_HIT();
@ -1586,8 +1582,8 @@ void __attribute__((noreturn)) AppMain(void) {
bool error = false;
size_t bytes = usb_read_ng(rx, sizeof(UsbCommandNGPreamble));
if (bytes == sizeof(UsbCommandNGPreamble)) {
if (pre->magic == USB_PREAMBLE_MAGIC) { // New style NG command
if (pre->length > USB_CMD_DATA_SIZE) {
if (pre->magic == USB_COMMANDNG_PREAMBLE_MAGIC) { // New style NG command
if (pre->length > USB_DATANG_SIZE) {
Dbprintf("Packet frame with incompatible length: 0x%04x", pre->length);
error = true;
}
@ -1599,7 +1595,7 @@ void __attribute__((noreturn)) AppMain(void) {
}
}
if (!error) { // Get the postamble
bytes = usb_read_ng(rx + sizeof(UsbCommandNGPreamble) + USB_CMD_DATA_SIZE, sizeof(UsbCommandNGPostamble));
bytes = usb_read_ng(rx + sizeof(UsbCommandNGPreamble) + USB_DATANG_SIZE, sizeof(UsbCommandNGPostamble));
if (bytes != sizeof(UsbCommandNGPostamble)) {
Dbprintf("Packet frame error fetching postamble");
error = true;

View file

@ -440,17 +440,16 @@ static int CmdPing(const char *Cmd) {
static int CmdPingNG(const char *Cmd) {
uint32_t len = strtol(Cmd, NULL, 0);
if (len > USB_CMD_DATA_SIZE)
len = USB_CMD_DATA_SIZE;
if (len > USB_DATANG_SIZE)
len = USB_DATANG_SIZE;
PrintAndLogEx(NORMAL, "Pinging with payload len=%d", len);
clearCommandBuffer();
UsbCommand resp;
uint8_t data[USB_CMD_DATA_SIZE] = {0};
uint8_t data[USB_DATANG_SIZE] = {0};
uint16_t cmd = CMD_PING;
if (len >= 4)
((uint32_t *)data)[0] = 0xAABBCCDD;
if (len >= 8)
((uint32_t *)data)[(len - 1) / 4] = 0xDDCCBBAA;
if (len)
for (uint16_t i=0; i<len; i++)
data[i] = i & 0xFF;
SendCommandNG(cmd, data, len);
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
PrintAndLogEx(NORMAL, "PingNG successful");

View file

@ -26,7 +26,7 @@ static pthread_t USB_communication_thread;
// Transmit buffer.
static UsbCommand txBuffer;
static uint8_t txBufferNG[USB_PACKET_NG_MAXLEN];
static uint8_t txBufferNG[USB_COMMANDNG_MAXLEN];
size_t txBufferNGLen;
static bool txBuffer_pending = false;
static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER;
@ -97,7 +97,7 @@ void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) {
PrintAndLogEx(NORMAL, "Sending bytes to proxmark failed - offline");
return;
}
if (len > USB_CMD_DATA_SIZE) {
if (len > USB_DATANG_SIZE) {
PrintAndLogEx(WARNING, "Sending %d bytes of payload is too much, abort", len);
return;
}
@ -115,7 +115,7 @@ void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) {
pthread_cond_wait(&txBufferSig, &txBufferMutex);
}
tx_pre->magic = USB_PREAMBLE_MAGIC;
tx_pre->magic = USB_COMMANDNG_PREAMBLE_MAGIC;
tx_pre->length = len;
tx_pre->cmd = cmd;
memcpy(txBufferNG + sizeof(UsbCommandNGPreamble), data, len);

View file

@ -30,6 +30,7 @@
* @brief
*/
#include "cmd.h"
#include "crc16.h"
#ifdef WITH_FPC_HOST
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
@ -78,3 +79,53 @@ uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void
return sendlen;
}
uint8_t reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len) {
uint8_t txBufferNG[USB_REPLYNG_MAXLEN];
size_t txBufferNGLen;
// for (size_t i = 0; i < sizeof(txBufferNG); i++)
// ((uint8_t *)&txBufferNG)[i] = 0x00;
// Compose the outgoing command frame
UsbReplyNGPreamble *tx_pre = (UsbReplyNGPreamble *)txBufferNG;
tx_pre->magic = USB_REPLYNG_PREAMBLE_MAGIC;
tx_pre->cmd = cmd;
tx_pre->status = status;
if (len > USB_DATANG_SIZE) {
len = USB_DATANG_SIZE;
// overwrite status
tx_pre->status = PM3_EOVFLOW;
}
tx_pre->length = len;
uint8_t *tx_data = txBufferNG + sizeof(UsbReplyNGPreamble);
UsbReplyNGPostamble *tx_post = (UsbReplyNGPostamble *)(txBufferNG + sizeof(UsbReplyNGPreamble) + len);
// Add the (optional) content to the frame, with a maximum size of USB_DATANG_SIZE
if (data && len) {
for (size_t i = 0; i < len; i++) {
tx_data[i] = data[i];
}
}
uint8_t first, second;
compute_crc(CRC_14443_A, txBufferNG, sizeof(UsbReplyNGPreamble) + len, &first, &second);
tx_post->crc = (first << 8) + second;
txBufferNGLen = sizeof(UsbReplyNGPreamble) + len + sizeof(UsbReplyNGPostamble);
uint32_t sendlen = 0;
// Send frame and make sure all bytes are transmitted
#ifdef WITH_FPC_HOST
if (reply_via_fpc) {
sendlen = usart_writebuffer(txBufferNG, txBufferNGLen);
// Dbprintf_usb("Sent %i bytes over usart", len);
} else {
sendlen = usb_write(txBufferNG, txBufferNGLen);
}
#else
sendlen = usb_write(txBufferNG, txBufferNGLen);
#endif
return sendlen;
}

View file

@ -40,6 +40,7 @@
#include "proxmark3.h"
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
uint8_t reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
#endif // _PROXMARK_CMD_H_

View file

@ -25,6 +25,7 @@ typedef BYTE uint8_t;
#endif
#define USB_CMD_DATA_SIZE 512
#define USB_DATANG_SIZE 512
typedef struct {
uint64_t cmd;
@ -41,14 +42,30 @@ typedef struct {
uint16_t cmd;
} PACKED UsbCommandNGPreamble;
#define USB_PREAMBLE_MAGIC 0x61334d50 // PM3a
#define USB_COMMANDNG_PREAMBLE_MAGIC 0x61334d50 // PM3a
typedef struct {
uint16_t crc;
} PACKED UsbCommandNGPostamble;
#define USB_PACKET_NG_MINLEN (sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNGPostamble))
#define USB_PACKET_NG_MAXLEN (sizeof(UsbCommandNGPreamble) + USB_CMD_DATA_SIZE + sizeof(UsbCommandNGPostamble))
#define USB_COMMANDNG_MINLEN (sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNGPostamble))
#define USB_COMMANDNG_MAXLEN (sizeof(UsbCommandNGPreamble) + USB_DATANG_SIZE + sizeof(UsbCommandNGPostamble))
typedef struct {
uint32_t magic;
uint16_t length; // length of the variable part, 0 if none.
uint16_t cmd;
int16_t status;
} PACKED UsbReplyNGPreamble;
#define USB_REPLYNG_PREAMBLE_MAGIC 0x62334d50 // PM3b
typedef struct {
uint16_t crc;
} PACKED UsbReplyNGPostamble;
#define USB_REPLYNG_MINLEN (sizeof(UsbReplyNGPreamble) + sizeof(UsbReplyNGPostamble))
#define USB_REPLYNG_MAXLEN (sizeof(UsbReplyNGPreamble) + USB_DATANG_SIZE + sizeof(UsbReplyNGPostamble))
#ifdef WITH_FPC_HOST
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
@ -332,6 +349,31 @@ typedef struct {
#define FLAG_NONEWLINE 0x0010
#define FLAG_NOPROMPT 0x0100
// Error codes
// Success (no error)
#define PM3_SUCCESS 0
// Undefined error
#define PM3_EUNDEF -1
// Invalid argument(s)
#define PM3_EINVARG -2
// Operation not supported by device
#define PM3_EDEVNOTSUPP -3
// Operation timed out
#define PM3_ETIMEOUT -4
// Operation aborted (by user)
#define PM3_EOPABORTED -5
// Not (yet) implemented
#define PM3_ENOTIMPL -6
// Error while RF transmission
#define PM3_ERFTRANS -7
// Input / output error
#define PM3_EIO -8
// Buffer overflow
#define PM3_EOVFLOW -9
// Software error
#define PM3_ESOFT -10
// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:
/* Whether a bootloader that understands the common_area is present */