mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 15:26:13 +08:00
new frame format, smaller and with crc. Some code simplified
This commit is contained in:
parent
34467b7550
commit
44bbb7d2c7
|
@ -632,11 +632,23 @@ void ListenReaderField(int limit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UsbPacketReceived(uint8_t *packet, int len) {
|
static void UsbPacketReceived(bool cmd_ng, uint8_t *packet) {
|
||||||
UsbCommand *c = (UsbCommand *)packet;
|
uint64_t cmd; // To accomodate old cmd, can be reduced to uint16_t once all old cmds are gone.
|
||||||
//Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d", len, c->cmd, c->arg[0], c->arg[1], c->arg[2]);
|
UsbCommandNGPreamble *pre_ng = (UsbCommandNGPreamble *)packet;
|
||||||
|
uint8_t *data_ng = packet + sizeof(UsbCommandNGPreamble);
|
||||||
|
uint16_t datalen_ng = pre_ng->length;
|
||||||
|
|
||||||
switch (c->cmd) {
|
// For cmd handlers still using old cmd format:
|
||||||
|
UsbCommand *c = (UsbCommand *)packet;
|
||||||
|
if (cmd_ng) {
|
||||||
|
cmd = pre_ng->cmd;
|
||||||
|
// Dbprintf("received %d bytes payload, with command: 0x%04x", datalen_ng, cmd);
|
||||||
|
} else {
|
||||||
|
// Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d", USB_CMD_DATA_SIZE, c->cmd, c->arg[0], c->arg[1], c->arg[2]);
|
||||||
|
cmd = c->cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
#ifdef WITH_LF
|
#ifdef WITH_LF
|
||||||
case CMD_SET_LF_T55XX_CONFIG:
|
case CMD_SET_LF_T55XX_CONFIG:
|
||||||
setT55xxConfig(c->arg[0], (t55xx_config *) c->d.asBytes);
|
setT55xxConfig(c->arg[0], (t55xx_config *) c->d.asBytes);
|
||||||
|
@ -1443,11 +1455,19 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
SendStatus();
|
SendStatus();
|
||||||
break;
|
break;
|
||||||
case CMD_PING:
|
case CMD_PING:
|
||||||
|
if (cmd_ng) {
|
||||||
#ifdef WITH_FPC_HOST
|
#ifdef WITH_FPC_HOST
|
||||||
cmd_send(CMD_ACK, reply_via_fpc, c->d.asDwords[0], c->d.asDwords[(c->arg[0]-1)/4], 0, 0);
|
cmd_send(CMD_ACK, reply_via_fpc, ((uint32_t *)data_ng)[0], ((uint32_t *)data_ng)[(datalen_ng-1)/4], 0, 0);
|
||||||
#else
|
#else
|
||||||
cmd_send(CMD_ACK, 0, c->d.asDwords[0], c->d.asDwords[(c->arg[0]-1)/4], 0, 0);
|
cmd_send(CMD_ACK, 0, ((uint32_t *)data_ng)[0], ((uint32_t *)data_ng)[(c->arg[0]-1)/4], 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef WITH_FPC_HOST
|
||||||
|
cmd_send(CMD_ACK, reply_via_fpc, 0, 0, 0, 0);
|
||||||
|
#else
|
||||||
|
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef WITH_LCD
|
#ifdef WITH_LCD
|
||||||
case CMD_LCD_RESET:
|
case CMD_LCD_RESET:
|
||||||
|
@ -1488,7 +1508,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
Dbprintf("%s: 0x%04x", "unknown command:", c->cmd);
|
Dbprintf("%s: 0x%04x", "unknown command:", cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1553,10 +1573,9 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
usb_disable();
|
usb_disable();
|
||||||
usb_enable();
|
usb_enable();
|
||||||
|
|
||||||
// Worst case: Command as large as the old one but encapsulated in NG style
|
uint8_t rx[USB_PACKET_NG_MAXLEN];
|
||||||
uint8_t rx[sizeof(UsbCommandNGPreamble) + sizeof(UsbCommand) + sizeof(UsbCommandNGPostamble)];
|
|
||||||
UsbCommandNGPreamble *pre = (UsbCommandNGPreamble *)rx;
|
UsbCommandNGPreamble *pre = (UsbCommandNGPreamble *)rx;
|
||||||
UsbCommandNGPostamble *post = (UsbCommandNGPostamble *)(rx + sizeof(UsbCommandNGPreamble) + sizeof(UsbCommand));
|
UsbCommandNGPostamble *post = (UsbCommandNGPostamble *)(rx + sizeof(UsbCommandNGPreamble) + USB_CMD_DATA_SIZE);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -1564,54 +1583,54 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
// Check if there is a usb packet available
|
// Check if there is a usb packet available
|
||||||
if (usb_poll_validate_length()) {
|
if (usb_poll_validate_length()) {
|
||||||
bool error = false;
|
bool error = false;
|
||||||
size_t bytes = usb_read_ng(rx, sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNG));
|
size_t bytes = usb_read_ng(rx, sizeof(UsbCommandNGPreamble));
|
||||||
if (bytes == sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNG)) {
|
if (bytes == sizeof(UsbCommandNGPreamble)) {
|
||||||
if (pre->magic == USB_PREAMBLE_MAGIC) { // New style NG command
|
if (pre->magic == USB_PREAMBLE_MAGIC) { // New style NG command
|
||||||
// Dbprintf("Packet frame NG incoming!");
|
|
||||||
use_cmd_ng = true;
|
|
||||||
if (pre->length > USB_CMD_DATA_SIZE) {
|
if (pre->length > USB_CMD_DATA_SIZE) {
|
||||||
Dbprintf("Packet frame with incompatible length: 0x%04x", pre->length);
|
Dbprintf("Packet frame with incompatible length: 0x%04x", pre->length);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
if ((!error) && (pre->length > 0)) { // Get the variable length payload
|
if ((!error) && (pre->length > 0)) { // Get the variable length payload
|
||||||
bytes = usb_read_ng(rx + sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNG), pre->length);
|
bytes = usb_read_ng(rx + sizeof(UsbCommandNGPreamble), pre->length);
|
||||||
if (bytes != pre->length) {
|
if (bytes != pre->length) {
|
||||||
Dbprintf("Packet frame error variable part too short? %d/%d", bytes, pre->length);
|
Dbprintf("Packet frame error variable part too short? %d/%d", bytes, pre->length);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!error) { // Get the postamble
|
if (!error) { // Get the postamble
|
||||||
bytes = usb_read_ng(rx + sizeof(UsbCommandNGPreamble) + sizeof(UsbCommand), sizeof(UsbCommandNGPostamble));
|
bytes = usb_read_ng(rx + sizeof(UsbCommandNGPreamble) + USB_CMD_DATA_SIZE, sizeof(UsbCommandNGPostamble));
|
||||||
if ((bytes != sizeof(UsbCommandNGPostamble)) || (post->magic != USB_POSTAMBLE_MAGIC)) {
|
if (bytes != sizeof(UsbCommandNGPostamble)) {
|
||||||
Dbprintf("Packet frame error no postamble magic found");
|
Dbprintf("Packet frame error fetching postamble");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
uint8_t first, second;
|
||||||
|
compute_crc(CRC_14443_A, rx, sizeof(UsbCommandNGPreamble) + pre->length, &first, &second);
|
||||||
|
if ((first << 8) + second != post->crc) {
|
||||||
|
Dbprintf("Packet frame CRC error %02X%02X <> %04X", first, second, post->crc);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
// TODO check also CRC...
|
|
||||||
}
|
}
|
||||||
if (!error) {
|
if (!error) {
|
||||||
// Dbprintf("Packet frame NG fully received");
|
|
||||||
#ifdef WITH_FPC_HOST
|
#ifdef WITH_FPC_HOST
|
||||||
reply_via_fpc = false;
|
reply_via_fpc = false;
|
||||||
#endif
|
#endif
|
||||||
UsbPacketReceived(rx + sizeof(UsbCommandNGPreamble), sizeof(UsbCommand));
|
UsbPacketReceived(true, rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // Old style command
|
} else { // Old style command
|
||||||
bytes = usb_read_ng(rx + sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNG), sizeof(UsbCommand) - sizeof(UsbCommandNGPreamble) - sizeof(UsbCommandNG));
|
bytes = usb_read_ng(rx + sizeof(UsbCommandNGPreamble), sizeof(UsbCommand) - sizeof(UsbCommandNGPreamble));
|
||||||
|
if (bytes != sizeof(UsbCommand) - sizeof(UsbCommandNGPreamble)) {
|
||||||
if (bytes != sizeof(UsbCommand) - sizeof(UsbCommandNGPreamble) - sizeof(UsbCommandNG)) {
|
Dbprintf("Packet frame error var part too short? %d/%d", bytes, sizeof(UsbCommand) - sizeof(UsbCommandNGPreamble));
|
||||||
Dbprintf("Packet frame error var part too short? %d/%d", bytes, sizeof(UsbCommand) - sizeof(UsbCommandNGPreamble) - sizeof(UsbCommandNG));
|
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
if (!error) {
|
if (!error) {
|
||||||
use_cmd_ng = false;
|
|
||||||
#ifdef WITH_FPC_HOST
|
#ifdef WITH_FPC_HOST
|
||||||
reply_via_fpc = false;
|
reply_via_fpc = false;
|
||||||
#endif
|
#endif
|
||||||
UsbPacketReceived(rx, sizeof(UsbCommand));
|
UsbPacketReceived(false, rx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Dbprintf("Packet frame preamble too short: %d/%d", bytes, sizeof(UsbCommandNGPreamble));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
// TODO if error, shall we resync ?
|
// TODO if error, shall we resync ?
|
||||||
|
@ -1620,7 +1639,7 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
// Check if there is a FPC packet available
|
// Check if there is a FPC packet available
|
||||||
if (usart_readbuffer(rx)) {
|
if (usart_readbuffer(rx)) {
|
||||||
reply_via_fpc = true;
|
reply_via_fpc = true;
|
||||||
UsbPacketReceived(rx, sizeof(rx));
|
UsbPacketReceived(false, rx);
|
||||||
}
|
}
|
||||||
usart_readcheck(rx, sizeof(rx));
|
usart_readcheck(rx, sizeof(rx));
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -119,6 +119,7 @@ CORESRCS = uart_posix.c \
|
||||||
util.c \
|
util.c \
|
||||||
util_posix.c \
|
util_posix.c \
|
||||||
scandir.c \
|
scandir.c \
|
||||||
|
crc16.c \
|
||||||
comms.c
|
comms.c
|
||||||
|
|
||||||
CMDSRCS = crapto1/crapto1.c \
|
CMDSRCS = crapto1/crapto1.c \
|
||||||
|
@ -143,7 +144,6 @@ CMDSRCS = crapto1/crapto1.c \
|
||||||
mifare/mifarehost.c \
|
mifare/mifarehost.c \
|
||||||
parity.c \
|
parity.c \
|
||||||
crc.c \
|
crc.c \
|
||||||
crc16.c \
|
|
||||||
crc64.c \
|
crc64.c \
|
||||||
legic_prng.c \
|
legic_prng.c \
|
||||||
iso15693tools.c \
|
iso15693tools.c \
|
||||||
|
|
|
@ -445,12 +445,13 @@ static int CmdPingNG(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "Pinging with payload len=%d", len);
|
PrintAndLogEx(NORMAL, "Pinging with payload len=%d", len);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
UsbCommand c = {CMD_PING, {len, 0, 0}, {{0}}};
|
uint8_t data[USB_CMD_DATA_SIZE] = {0};
|
||||||
|
uint16_t cmd = CMD_PING;
|
||||||
if (len >= 4)
|
if (len >= 4)
|
||||||
c.d.asDwords[0] = 0xAABBCCDD;
|
((uint32_t *)data)[0]=0xAABBCCDD;
|
||||||
if (len >= 8)
|
if (len >= 8)
|
||||||
c.d.asDwords[(len-1)/4] = 0xDDCCBBAA;
|
((uint32_t *)data)[(len-1)/4] = 0xDDCCBBAA;
|
||||||
SendCommandNG(&c, len);
|
SendCommandNG(cmd, data, len);
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
|
||||||
PrintAndLogEx(NORMAL, "PingNG successful");
|
PrintAndLogEx(NORMAL, "PingNG successful");
|
||||||
if (len >= 4)
|
if (len >= 4)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
|
#include "crc16.h"
|
||||||
|
|
||||||
// Serial port that we are communicating with the PM3 on.
|
// Serial port that we are communicating with the PM3 on.
|
||||||
static serial_port sp = NULL;
|
static serial_port sp = NULL;
|
||||||
|
@ -25,7 +26,7 @@ static pthread_t USB_communication_thread;
|
||||||
|
|
||||||
// Transmit buffer.
|
// Transmit buffer.
|
||||||
static UsbCommand txBuffer;
|
static UsbCommand txBuffer;
|
||||||
static uint8_t txBufferNG[sizeof(UsbCommandNGPreamble) + sizeof(UsbCommand) + sizeof(UsbCommandNGPostamble)];
|
static uint8_t txBufferNG[USB_PACKET_NG_MAXLEN];
|
||||||
size_t txBufferNGLen;
|
size_t txBufferNGLen;
|
||||||
static bool txBuffer_pending = false;
|
static bool txBuffer_pending = false;
|
||||||
static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
@ -86,10 +87,10 @@ void SendCommand(UsbCommand *c) {
|
||||||
//__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST);
|
//__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendCommandNG(UsbCommand *c, size_t len) {
|
void SendCommandNG(uint16_t cmd, uint8_t* data, size_t len) {
|
||||||
|
|
||||||
#ifdef COMMS_DEBUG
|
#ifdef COMMS_DEBUG
|
||||||
PrintAndLogEx(NORMAL, "Sending %d bytes of payload | cmd %04x\n", len, c->cmd);
|
PrintAndLogEx(NORMAL, "Sending %d bytes of payload | cmd %04x\n", len, cmd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (offline) {
|
if (offline) {
|
||||||
|
@ -102,7 +103,7 @@ void SendCommandNG(UsbCommand *c, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
UsbCommandNGPreamble *tx_pre = (UsbCommandNGPreamble *)txBufferNG;
|
UsbCommandNGPreamble *tx_pre = (UsbCommandNGPreamble *)txBufferNG;
|
||||||
UsbCommandNGPostamble *tx_post = (UsbCommandNGPostamble *)(txBufferNG + sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNG) + len);
|
UsbCommandNGPostamble *tx_post = (UsbCommandNGPostamble *)(txBufferNG + sizeof(UsbCommandNGPreamble) + len);
|
||||||
|
|
||||||
pthread_mutex_lock(&txBufferMutex);
|
pthread_mutex_lock(&txBufferMutex);
|
||||||
/**
|
/**
|
||||||
|
@ -116,10 +117,12 @@ void SendCommandNG(UsbCommand *c, size_t len) {
|
||||||
|
|
||||||
tx_pre->magic = USB_PREAMBLE_MAGIC;
|
tx_pre->magic = USB_PREAMBLE_MAGIC;
|
||||||
tx_pre->length = len;
|
tx_pre->length = len;
|
||||||
memcpy(txBufferNG + sizeof(UsbCommandNGPreamble), c, sizeof(UsbCommandNG) + len);
|
tx_pre->cmd = cmd;
|
||||||
// TODO CRC
|
memcpy(txBufferNG + sizeof(UsbCommandNGPreamble), data, len);
|
||||||
tx_post->magic = USB_POSTAMBLE_MAGIC;
|
uint8_t first, second;
|
||||||
txBufferNGLen = sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNG) + len + sizeof(UsbCommandNGPostamble);
|
compute_crc(CRC_14443_A, txBufferNG, sizeof(UsbCommandNGPreamble) + len, &first, &second);
|
||||||
|
tx_post->crc = (first << 8) + second;
|
||||||
|
txBufferNGLen = sizeof(UsbCommandNGPreamble) + len + sizeof(UsbCommandNGPostamble);
|
||||||
txBuffer_pending = true;
|
txBuffer_pending = true;
|
||||||
|
|
||||||
// tell communication thread that a new command can be send
|
// tell communication thread that a new command can be send
|
||||||
|
|
|
@ -52,7 +52,7 @@ bool IsOffline(void);
|
||||||
|
|
||||||
void *uart_receiver(void *targ);
|
void *uart_receiver(void *targ);
|
||||||
void SendCommand(UsbCommand *c);
|
void SendCommand(UsbCommand *c);
|
||||||
void SendCommandNG(UsbCommand *c, size_t len);
|
void SendCommandNG(uint16_t cmd, uint8_t* data, size_t len);
|
||||||
void clearCommandBuffer(void);
|
void clearCommandBuffer(void);
|
||||||
|
|
||||||
#define FLASHMODE_SPEED 460800
|
#define FLASHMODE_SPEED 460800
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
*/
|
*/
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
|
||||||
bool use_cmd_ng = false;
|
|
||||||
#ifdef WITH_FPC_HOST
|
#ifdef WITH_FPC_HOST
|
||||||
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
|
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
|
||||||
bool reply_via_fpc = false;
|
bool reply_via_fpc = false;
|
||||||
|
|
|
@ -37,24 +37,20 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t length; // length of the variable part, 0 if none.
|
uint16_t length; // length of the variable part, 0 if none.
|
||||||
|
uint16_t cmd;
|
||||||
} PACKED UsbCommandNGPreamble;
|
} PACKED UsbCommandNGPreamble;
|
||||||
|
|
||||||
#define USB_PREAMBLE_MAGIC 0xAA5500FF
|
#define USB_PREAMBLE_MAGIC 0xAA5500FF
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint64_t cmd;
|
|
||||||
uint64_t arg[3];
|
|
||||||
} PACKED UsbCommandNG;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
uint32_t magic;
|
|
||||||
} PACKED UsbCommandNGPostamble;
|
} PACKED UsbCommandNGPostamble;
|
||||||
|
|
||||||
#define USB_POSTAMBLE_MAGIC 0xFF0055AA
|
#define USB_POSTAMBLE_MAGIC 0xFF0055AA
|
||||||
|
|
||||||
extern bool use_cmd_ng;
|
#define USB_PACKET_NG_MINLEN (sizeof(UsbCommandNGPreamble) + sizeof(UsbCommandNGPostamble))
|
||||||
|
#define USB_PACKET_NG_MAXLEN (sizeof(UsbCommandNGPreamble) + USB_CMD_DATA_SIZE + sizeof(UsbCommandNGPostamble))
|
||||||
|
|
||||||
#ifdef WITH_FPC_HOST
|
#ifdef WITH_FPC_HOST
|
||||||
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
|
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
|
||||||
|
|
Loading…
Reference in a new issue