diff --git a/client/cmdhw.c b/client/cmdhw.c index e2a483ef2..8c687e232 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -425,7 +425,7 @@ static int CmdPing(const char *Cmd) { (void)Cmd; // Cmd is not used so far clearCommandBuffer(); PacketResponseNG resp; - SendCommandOLD(CMD_PING, 0, 0, 0, NULL, 0); + SendCommandMIX(CMD_PING, 0, 0, 0, NULL, 0); if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) PrintAndLogEx(NORMAL, "Ping " _GREEN_("successful")); else diff --git a/client/comms.c b/client/comms.c index dfc9e9863..9b5dd1c26 100644 --- a/client/comms.c +++ b/client/comms.c @@ -106,8 +106,7 @@ void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, v SendCommand(&c); } -void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) { - +static void SendCommandNG_internal(uint16_t cmd, uint8_t *data, size_t len, bool ng) { #ifdef COMMS_DEBUG PrintAndLogEx(NORMAL, "Sending %d bytes of payload | cmd %04x\n", len, cmd); #endif @@ -134,6 +133,7 @@ void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) { } txBufferNG.pre.magic = COMMANDNG_PREAMBLE_MAGIC; + txBufferNG.pre.ng = ng; txBufferNG.pre.length = len; txBufferNG.pre.cmd = cmd; memcpy(&txBufferNG.data, data, len); @@ -158,6 +158,24 @@ void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) { //__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST); } +void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) { + SendCommandNG_internal(cmd, data, len, true); +} + +void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { + uint64_t arg[3] = {arg0, arg1, arg2}; + if (len > USB_CMD_DATA_SIZE - sizeof(arg)) { + PrintAndLogEx(WARNING, "Sending %d bytes of payload is too much for MIX frames, abort", len); + return; + } + uint8_t cmddata[USB_CMD_DATA_SIZE]; + memcpy(cmddata, arg, sizeof(arg)); + if (len && data) + memcpy(cmddata + sizeof(arg), data, len); + SendCommandNG_internal(cmd, cmddata, len + sizeof(arg), false); +} + + /** * @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. diff --git a/client/comms.h b/client/comms.h index 6034a5741..c70a67c51 100644 --- a/client/comms.h +++ b/client/comms.h @@ -57,6 +57,7 @@ void *uart_receiver(void *targ); void SendCommand(PacketCommandOLD *c); void SendCommandOLD(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len); +void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); void clearCommandBuffer(void); #define FLASHMODE_SPEED 460800 diff --git a/common/cmd.c b/common/cmd.c index b08d88589..e9736a241 100644 --- a/common/cmd.c +++ b/common/cmd.c @@ -143,6 +143,7 @@ static int16_t receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t if (bytes != sizeof(PacketCommandNGPreamble)) return PM3_EIO; rx->magic = rx_raw.pre.magic; + rx->ng = rx_raw.pre.ng; rx->length = rx_raw.pre.length; rx->cmd = rx_raw.pre.cmd; if (rx->magic == COMMANDNG_PREAMBLE_MAGIC) { // New style NG command @@ -152,7 +153,18 @@ static int16_t receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t bytes = read_ng((uint8_t *)&rx_raw.data, rx->length); if (bytes != rx->length) return PM3_EIO; - memcpy(rx->data.asBytes, rx_raw.data, rx->length); + if (rx->ng) + memcpy(rx->data.asBytes, rx_raw.data, rx->length); + else { + uint64_t arg[3]; + if (rx->length < sizeof(arg)) + return PM3_EIO; + memcpy(arg, rx_raw.data, sizeof(arg)); + rx->oldarg[0] = arg[0]; + rx->oldarg[1] = arg[1]; + rx->oldarg[2] = arg[2]; + memcpy(rx->data.asBytes, rx_raw.data + sizeof(arg), rx->length - sizeof(arg)); + } // Get the postamble bytes = read_ng((uint8_t *)&rx_raw.foopost, sizeof(PacketCommandNGPostamble)); if (bytes != sizeof(PacketCommandNGPostamble)) @@ -166,7 +178,6 @@ static int16_t receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t return PM3_EIO; } reply_via_fpc = fpc; - rx->ng = true; } else { // Old style command PacketCommandOLD rx_old; memcpy(&rx_old, &rx_raw.pre, sizeof(PacketCommandNGPreamble)); diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 09b864a28..6ff7f1241 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -37,7 +37,8 @@ typedef struct { typedef struct { uint32_t magic; - uint16_t length; // length of the variable part, 0 if none. + uint16_t length : 15; // length of the variable part, 0 if none. + bool ng : 1; uint16_t cmd; } PACKED PacketCommandNGPreamble;