diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 0742625b7..10d57fbf5 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -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; diff --git a/client/cmdhw.c b/client/cmdhw.c index 0442052e1..6bdd65585 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -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 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); diff --git a/common/cmd.c b/common/cmd.c index d560c60f7..42c72269b 100644 --- a/common/cmd.c +++ b/common/cmd.c @@ -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; +} diff --git a/common/cmd.h b/common/cmd.h index 858466dd3..a07ef35d0 100644 --- a/common/cmd.h +++ b/common/cmd.h @@ -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_ diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 60077d630..0edf68dc8 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -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 */