mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
CHG: the thread comms refactoring from offical pm3 repo
chg: FPC com speed limited to 115200 when compiled with FPC chg: USART remake (@drandreas)
This commit is contained in:
parent
eb0b5116a2
commit
24eaac8681
45 changed files with 915 additions and 949 deletions
|
@ -104,7 +104,7 @@ ifneq (,$(findstring WITH_HF_MATTYRUN,$(APP_CFLAGS)))
|
||||||
endif
|
endif
|
||||||
# WITH_HF_COLIN
|
# WITH_HF_COLIN
|
||||||
ifneq (,$(findstring WITH_HF_COLIN,$(APP_CFLAGS)))
|
ifneq (,$(findstring WITH_HF_COLIN,$(APP_CFLAGS)))
|
||||||
SRC_STANDALONE = hf_colin.c vtsend.c
|
SRC_STANDALONE = vtsend.c hf_colin.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#the FPGA bitstream files. Note: order matters!
|
#the FPGA bitstream files. Note: order matters!
|
||||||
|
|
|
@ -441,7 +441,7 @@ void printStandAloneModes(void) {
|
||||||
DbpString(" LF HID corporate 1000 bruteforce - (Federico dotta & Maurizio Agazzini)");
|
DbpString(" LF HID corporate 1000 bruteforce - (Federico dotta & Maurizio Agazzini)");
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_HF_MATTYRUN)
|
#if defined(WITH_HF_MATTYRUN)
|
||||||
DbpString(" HF Mifare sniff/clone - aka MattyRun (Mat<EFBFBD>as A. R<> Medina)");
|
DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)");
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_HF_COLIN)
|
#if defined(WITH_HF_COLIN)
|
||||||
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
|
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
|
||||||
|
@ -1063,15 +1063,45 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
|
|
||||||
#ifdef WITH_FPC
|
#ifdef WITH_FPC
|
||||||
case CMD_FPC_SEND: {
|
case CMD_FPC_SEND: {
|
||||||
// char header[] = {"*** Iceman Usart ***"};
|
|
||||||
// uint32_t res = usart_writebuffer((uint8_t *)header, sizeof(header), 10000);
|
char dest[USB_CMD_DATA_SIZE] = { '\0' };
|
||||||
|
|
||||||
|
static const char* welcome = "Proxmark3 Serial interface ready\n";
|
||||||
|
strncat(dest, welcome, sizeof(dest) - strlen(dest) - 1);
|
||||||
|
|
||||||
//temp++;
|
sprintf(dest + strlen(dest) - 1, "Arg0 | 0x%" PRIx64 " \n", c->arg[0]);
|
||||||
uint8_t got = usart_read(10000);
|
sprintf(dest + strlen(dest) - 1, "Arg1 | 0x%" PRIx64 " \n", c->arg[1]);
|
||||||
if ( got > 0 ) {
|
sprintf(dest + strlen(dest) - 1, "Arg2 | 0x%" PRIx64 " \n", c->arg[2]);
|
||||||
Dbprintf("got %02x", got);
|
sprintf(dest + strlen(dest) - 1, "bytes | 0x%02x 0x%02x 0x%02x 0x%02x \n"
|
||||||
usart_write(got, 10000);
|
,c->d.asBytes[0], c->d.asBytes[1], c->d.asBytes[2], c->d.asBytes[3]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
UsbCommand txcmd;
|
||||||
|
for (size_t i=0; i < sizeof(UsbCommand); i++)
|
||||||
|
((uint8_t*)&txcmd)[i] = 0x00;
|
||||||
|
|
||||||
|
// Compose the outgoing command frame
|
||||||
|
txcmd.cmd = CMD_DEBUG_PRINT_STRING;
|
||||||
|
txcmd.arg[0] = len;
|
||||||
|
txcmd.arg[1] = 0;
|
||||||
|
txcmd.arg[2] = 0;
|
||||||
|
memcpy(txcmd.d.asBytes, dest, USB_CMD_DATA_SIZE);
|
||||||
|
usart_writebuffer((uint8_t*)&txcmd, sizeof(UsbCommand));
|
||||||
|
*/
|
||||||
|
DbpString("Starting to listen");
|
||||||
|
LED_A_ON();
|
||||||
|
/*
|
||||||
|
uint8_t rx[sizeof(UsbCommand)];
|
||||||
|
usart_init();
|
||||||
|
while (!BUTTON_PRESS() && !usb_poll_validate_length()) {
|
||||||
|
WaitMS(1);
|
||||||
|
if (usart_readbuffer(rx, sizeof(rx)) )
|
||||||
|
DbpString("got 544");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
cmd_send(CMD_DEBUG_PRINT_STRING, strlen(dest), 0, 0, dest, strlen(dest));
|
||||||
|
//DbpString("finished");
|
||||||
|
LED_A_OFF();
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1114,7 +1144,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
||||||
len = MIN( (numofbytes - i), USB_CMD_DATA_SIZE);
|
len = MIN( (numofbytes - i), USB_CMD_DATA_SIZE);
|
||||||
isok = cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, BigBuf_get_traceLen(), mem + startidx + i, len);
|
isok = cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, BigBuf_get_traceLen(), mem + startidx + i, len);
|
||||||
if (!isok)
|
if (isok != 0)
|
||||||
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
|
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
|
||||||
}
|
}
|
||||||
// Trigger a finish downloading signal with an ACK frame
|
// Trigger a finish downloading signal with an ACK frame
|
||||||
|
@ -1160,8 +1190,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
||||||
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
||||||
isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len);
|
isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len);
|
||||||
if (!isok)
|
if (isok != 0)
|
||||||
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
|
||||||
}
|
}
|
||||||
// Trigger a finish downloading signal with an ACK frame
|
// Trigger a finish downloading signal with an ACK frame
|
||||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||||
|
@ -1180,7 +1210,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
uint16_t isok = 0;
|
uint16_t isok = 0;
|
||||||
uint32_t startidx = c->arg[0];
|
uint32_t startidx = c->arg[0];
|
||||||
uint16_t len = c->arg[1];
|
uint16_t len = c->arg[1];
|
||||||
//uint8_t fast = c->arg[2];
|
|
||||||
|
|
||||||
Dbprintf("FlashMem read | %d - %d | ", startidx, len);
|
Dbprintf("FlashMem read | %d - %d | ", startidx, len);
|
||||||
|
|
||||||
|
@ -1285,8 +1314,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
uint32_t startidx = c->arg[0];
|
uint32_t startidx = c->arg[0];
|
||||||
uint32_t numofbytes = c->arg[1];
|
uint32_t numofbytes = c->arg[1];
|
||||||
//uint8_t fast = c->arg[2];
|
|
||||||
|
|
||||||
// arg0 = startindex
|
// arg0 = startindex
|
||||||
// arg1 = length bytes to transfer
|
// arg1 = length bytes to transfer
|
||||||
// arg2 = RFU
|
// arg2 = RFU
|
||||||
|
@ -1301,7 +1328,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len);
|
Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len);
|
||||||
|
|
||||||
isok = cmd_send(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len);
|
isok = cmd_send(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len);
|
||||||
if (!isok)
|
if (isok != 0)
|
||||||
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||||
}
|
}
|
||||||
FlashStop();
|
FlashStop();
|
||||||
|
@ -1458,19 +1485,20 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
#ifdef WITH_FPC
|
|
||||||
// check if there is a FPC USART1 message?
|
|
||||||
/*
|
|
||||||
uint32_t fpc_rxlen = usart_read(rx, sizeof(UsbCommand));
|
|
||||||
if ( fpc_rxlen > 0)
|
|
||||||
Dbprintf("got a package [len %d] %02x", fpc_rxlen, rx[0]);
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check if there is a usb packet available
|
// Check if there is a usb packet available
|
||||||
if ( cmd_receive( (UsbCommand*)rx ) ) {
|
if (usb_poll_validate_length()) {
|
||||||
UsbPacketReceived(rx, sizeof(UsbCommand) );
|
if (usb_read(rx, sizeof(rx)) )
|
||||||
|
UsbPacketReceived(rx, sizeof(rx));
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_FPC
|
||||||
|
// Check is there is FPC package available
|
||||||
|
/*
|
||||||
|
usart_init();
|
||||||
|
if (usart_readbuffer(rx, sizeof(rx)) )
|
||||||
|
UsbPacketReceived(rx, sizeof(rx) );
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Press button for one second to enter a possible standalone mode
|
// Press button for one second to enter a possible standalone mode
|
||||||
if (BUTTON_HELD(1000) > 0) {
|
if (BUTTON_HELD(1000) > 0) {
|
||||||
|
@ -1487,6 +1515,7 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
#if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) )
|
#if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) )
|
||||||
RunMod();
|
RunMod();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,8 +230,8 @@ void WritePageHitagS(hitag_function htf, hitag_data* htd,int page);
|
||||||
void check_challenges(bool file_given, byte_t* data);
|
void check_challenges(bool file_given, byte_t* data);
|
||||||
|
|
||||||
// cmd.h
|
// cmd.h
|
||||||
bool cmd_receive(UsbCommand* cmd);
|
uint8_t cmd_receive(UsbCommand* cmd);
|
||||||
bool cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len);
|
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len);
|
||||||
|
|
||||||
// util.h
|
// util.h
|
||||||
void HfSnoop(int , int);
|
void HfSnoop(int , int);
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define START_GAP 48*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc)
|
#define START_GAP 52*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc)
|
||||||
#define WRITE_GAP 18*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc)
|
#define WRITE_GAP 18*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc)
|
||||||
#define WRITE_0 24*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc)
|
#define WRITE_0 24*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc)
|
||||||
#define WRITE_1 54*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (56fc) 432 for T55x7; 448 for E5550
|
#define WRITE_1 54*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (56fc) 432 for T55x7; 448 for E5550
|
||||||
|
|
|
@ -191,7 +191,7 @@ static void flash_mode(int externally_entered) {
|
||||||
start_addr = 0;
|
start_addr = 0;
|
||||||
end_addr = 0;
|
end_addr = 0;
|
||||||
bootrom_unlocked = 0;
|
bootrom_unlocked = 0;
|
||||||
byte_t rx[sizeof(UsbCommand)];
|
uint8_t rx[sizeof(UsbCommand)];
|
||||||
|
|
||||||
usb_enable();
|
usb_enable();
|
||||||
|
|
||||||
|
@ -200,10 +200,12 @@ static void flash_mode(int externally_entered) {
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
// Check if there is a usb packet available
|
// Check if there is a usb packet available
|
||||||
if ( cmd_receive( (UsbCommand*)rx ) )
|
if (usb_poll_validate_length()) {
|
||||||
UsbPacketReceived(rx, sizeof(UsbCommand) );
|
if (usb_read(rx, sizeof(rx)) )
|
||||||
|
UsbPacketReceived(rx, sizeof(rx));
|
||||||
|
}
|
||||||
|
|
||||||
if (!externally_entered && !BUTTON_PRESS()) {
|
if (!externally_entered && !BUTTON_PRESS()) {
|
||||||
/* Perform a reset to leave flash mode */
|
/* Perform a reset to leave flash mode */
|
||||||
|
|
|
@ -82,7 +82,7 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# RDV40 flag enables flashmemory commands in client. comment out if you don't have rdv40
|
# RDV40 flag enables flashmemory commands in client. comment out if you don't have rdv40
|
||||||
CFLAGS += -DWITH_FLASH -DWITH_SMARTCARD
|
CFLAGS += -DWITH_FLASH -DWITH_SMARTCARD -DWITH_FPC
|
||||||
|
|
||||||
# Flags to generate temporary dependency files
|
# Flags to generate temporary dependency files
|
||||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
||||||
|
@ -94,7 +94,8 @@ CORESRCS = uart_posix.c \
|
||||||
ui.c \
|
ui.c \
|
||||||
util.c \
|
util.c \
|
||||||
util_posix.c \
|
util_posix.c \
|
||||||
scandir.c
|
scandir.c \
|
||||||
|
comms.c
|
||||||
|
|
||||||
CMDSRCS = crapto1/crapto1.c \
|
CMDSRCS = crapto1/crapto1.c \
|
||||||
crapto1/crypto1.c \
|
crapto1/crypto1.c \
|
||||||
|
|
|
@ -515,6 +515,7 @@ int CmdAnalyseA(const char *Cmd){
|
||||||
|
|
||||||
|
|
||||||
UsbCommand c = {CMD_FPC_SEND, {0, 0, 0}};
|
UsbCommand c = {CMD_FPC_SEND, {0, 0, 0}};
|
||||||
|
memcpy(c.d.asBytes, data, USB_CMD_DATA_SIZE);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
|
||||||
|
@ -522,7 +523,7 @@ int CmdAnalyseA(const char *Cmd){
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(NORMAL, "got ack");
|
PrintAndLogEx(NORMAL, "got ack. Status %d", resp.arg[0]);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");
|
PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "proxmark3.h" // sendcommand
|
#include "proxmark3.h" // sendcommand
|
||||||
#include "ui.h" // for show graph controls
|
#include "ui.h" // for show graph controls
|
||||||
#include "graph.h" // for graph data
|
#include "graph.h" // for graph data
|
||||||
#include "usb_cmd.h" // already included in cmdmain.h and proxmark3.h
|
#include "comms.h"
|
||||||
#include "lfdemod.h" // for demod code
|
#include "lfdemod.h" // for demod code
|
||||||
#include "crc.h" // for pyramid checksum maxim
|
#include "crc.h" // for pyramid checksum maxim
|
||||||
#include "crc16.h" // for FDXB demod checksum
|
#include "crc16.h" // for FDXB demod checksum
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "util_posix.h" // msclock
|
#include "util_posix.h" // msclock
|
||||||
#include "loclass/fileutils.h" //saveFile
|
#include "loclass/fileutils.h" //saveFile
|
||||||
#include "cmdmain.h" //getfromdevice
|
#include "comms.h" //getfromdevice
|
||||||
|
|
||||||
extern int CmdFlashMem(const char *Cmd);
|
extern int CmdFlashMem(const char *Cmd);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmdmain.h"
|
#include "comms.h" // getfromdevice
|
||||||
#include "iso14443crc.h"
|
#include "iso14443crc.h"
|
||||||
#include "cmdhf.h" // list cmd
|
#include "cmdhf.h" // list cmd
|
||||||
#include "mifare.h" // felica_card_select_t struct
|
#include "mifare.h" // felica_card_select_t struct
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cmdmain.h"
|
#include "comms.h"
|
||||||
#include "des.h"
|
#include "des.h"
|
||||||
#include "loclass/cipherutils.h"
|
#include "loclass/cipherutils.h"
|
||||||
#include "loclass/cipher.h"
|
#include "loclass/cipher.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmdmain.h"
|
#include "comms.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "legic_prng.h"
|
#include "legic_prng.h"
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t version[8];
|
uint8_t version[8];
|
||||||
|
|
|
@ -320,7 +320,7 @@ int CmdLFSetConfig(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lf_read(bool silent, uint32_t samples) {
|
bool lf_read(bool silent, uint32_t samples) {
|
||||||
if (offline) return false;
|
if ( IsOffline() ) return false;
|
||||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent, samples, 0}};
|
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent, samples, 0}};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
@ -342,7 +342,7 @@ bool lf_read(bool silent, uint32_t samples) {
|
||||||
|
|
||||||
int CmdLFRead(const char *Cmd) {
|
int CmdLFRead(const char *Cmd) {
|
||||||
|
|
||||||
if (offline) return 0;
|
if ( IsOffline() ) return 0;
|
||||||
|
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
bool silent = false;
|
bool silent = false;
|
||||||
|
@ -844,7 +844,7 @@ int CmdLFfind(const char *Cmd) {
|
||||||
|
|
||||||
if (cmdp == 'u') testRaw = 'u';
|
if (cmdp == 'u') testRaw = 'u';
|
||||||
|
|
||||||
bool isOnline = (!offline && (cmdp != '1') );
|
bool isOnline = (!IsOffline() && (cmdp != '1') );
|
||||||
|
|
||||||
if (isOnline)
|
if (isOnline)
|
||||||
lf_read(true, 30000);
|
lf_read(true, 30000);
|
||||||
|
|
|
@ -539,7 +539,7 @@ int CmdAWIDBrute(const char *Cmd) {
|
||||||
// main loop
|
// main loop
|
||||||
for (;;){
|
for (;;){
|
||||||
|
|
||||||
if ( offline ) {
|
if ( IsOffline() ) {
|
||||||
PrintAndLogEx(WARNING, "Device offline\n");
|
PrintAndLogEx(WARNING, "Device offline\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "util.h" // FALSE / TRUE
|
#include "util.h" // FALSE / TRUE
|
||||||
#include "cmddata.h" // getSamples
|
#include "cmddata.h" // getSamples
|
||||||
#include "cmdparser.h" // CmdsParse, CmdsHelp
|
#include "cmdparser.h" // CmdsParse, CmdsHelp
|
||||||
#include "cmdmain.h"
|
#include "comms.h"
|
||||||
#include "ui.h" // PrintAndLog
|
#include "ui.h" // PrintAndLog
|
||||||
#include "cmdlf.h" // Setconfig
|
#include "cmdlf.h" // Setconfig
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmddata.h"
|
#include "cmddata.h"
|
||||||
#include "cmdmain.h"
|
#include "comms.h"
|
||||||
#include "cmdmain.h"
|
|
||||||
#include "cmdlf.h"
|
#include "cmdlf.h"
|
||||||
#include "lfdemod.h"
|
#include "lfdemod.h"
|
||||||
|
|
||||||
|
|
|
@ -544,7 +544,7 @@ int CmdHIDBrute(const char *Cmd){
|
||||||
// main loop
|
// main loop
|
||||||
for (;;){
|
for (;;){
|
||||||
|
|
||||||
if ( offline ) {
|
if ( IsOffline() ) {
|
||||||
PrintAndLogEx(WARNING, "Device offline\n");
|
PrintAndLogEx(WARNING, "Device offline\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "hitag2.h"
|
#include "hitag2.h"
|
||||||
#include "hitagS.h"
|
#include "hitagS.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "cmdmain.h"
|
#include "comms.h"
|
||||||
#include "cmddata.h"
|
#include "cmddata.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
|
@ -122,7 +122,7 @@ int CmdIndalaDemod(const char *Cmd) {
|
||||||
ans = PSKDemod("32", 0);
|
ans = PSKDemod("32", 0);
|
||||||
|
|
||||||
if (!ans){
|
if (!ans){
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - Indala can't demod signal: %d",ans);
|
PrintAndLogEx(DEBUG, "DEBUG: Error - Indala can't demod signal: %d", ans);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -452,7 +452,7 @@ bool DecodeT5555TraceBlock() {
|
||||||
|
|
||||||
// sanity check. Don't use proxmark if it is offline and you didn't specify useGraphbuf
|
// sanity check. Don't use proxmark if it is offline and you didn't specify useGraphbuf
|
||||||
static int SanityOfflineCheck( bool useGraphBuffer ){
|
static int SanityOfflineCheck( bool useGraphBuffer ){
|
||||||
if ( !useGraphBuffer && offline) {
|
if ( !useGraphBuffer && IsOffline() ) {
|
||||||
PrintAndLogEx(NORMAL, "Your proxmark3 device is offline. Specify [1] to use graphbuffer data instead");
|
PrintAndLogEx(NORMAL, "Your proxmark3 device is offline. Specify [1] to use graphbuffer data instead");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -466,13 +466,11 @@ int CmdT55xxDetect(const char *Cmd){
|
||||||
uint32_t password = 0;
|
uint32_t password = 0;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
|
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch(param_getchar(Cmd, cmdp)) {
|
switch ( tolower(param_getchar(Cmd, cmdp))) {
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
|
||||||
return usage_t55xx_detect();
|
return usage_t55xx_detect();
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'P':
|
|
||||||
password = param_get32ex(Cmd, cmdp+1, 0, 16);
|
password = param_get32ex(Cmd, cmdp+1, 0, 16);
|
||||||
usepwd = true;
|
usepwd = true;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
|
@ -1572,7 +1570,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
||||||
uint64_t testpwd = 0x00;
|
uint64_t testpwd = 0x00;
|
||||||
for (uint16_t c = 0; c < keycnt; ++c ) {
|
for (uint16_t c = 0; c < keycnt; ++c ) {
|
||||||
|
|
||||||
if ( offline ) {
|
if ( IsOffline() ) {
|
||||||
PrintAndLogEx(WARNING, "Device offline\n");
|
PrintAndLogEx(WARNING, "Device offline\n");
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
return 2;
|
return 2;
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "cmdmain.h"
|
#include "comms.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmddata.h"
|
#include "cmddata.h"
|
||||||
#include "cmdlf.h"
|
#include "cmdlf.h"
|
||||||
|
|
292
client/cmdmain.c
292
client/cmdmain.c
|
@ -15,18 +15,6 @@ static int CmdQuit(const char *Cmd);
|
||||||
static int CmdRev(const char *Cmd);
|
static int CmdRev(const char *Cmd);
|
||||||
static int CmdRem(const char *Cmd);
|
static int CmdRem(const char *Cmd);
|
||||||
|
|
||||||
//For storing command that are received from the device
|
|
||||||
static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//Points to the next empty position to write to
|
|
||||||
static int cmd_head = 0;
|
|
||||||
|
|
||||||
//Points to the position of the last unread command
|
|
||||||
static int cmd_tail = 0;
|
|
||||||
|
|
||||||
// to lock cmdBuffer operations from different threads
|
|
||||||
static pthread_mutex_t cmdBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, 1, "This help. Use '<command> help' for details of a particular command."},
|
{"help", CmdHelp, 1, "This help. Use '<command> help' for details of a particular command."},
|
||||||
{"analyse", CmdAnalyse, 1, "{ Analyse utils... }"},
|
{"analyse", CmdAnalyse, 1, "{ Analyse utils... }"},
|
||||||
|
@ -38,7 +26,7 @@ static command_t CommandTable[] = {
|
||||||
{"reveng", CmdRev, 1, "{ Crc calculations from the software reveng 1.53... }"},
|
{"reveng", CmdRev, 1, "{ Crc calculations from the software reveng 1.53... }"},
|
||||||
{"script", CmdScript, 1, "{ Scripting commands }"},
|
{"script", CmdScript, 1, "{ Scripting commands }"},
|
||||||
{"trace", CmdTrace, 1, "{ Trace manipulation... }"},
|
{"trace", CmdTrace, 1, "{ Trace manipulation... }"},
|
||||||
#ifdef WITH_FLASH
|
#ifdef WITH_FLASH
|
||||||
{"mem", CmdFlashMem, 1, "{ RDV40, Flash Memory manipulation... }"},
|
{"mem", CmdFlashMem, 1, "{ RDV40, Flash Memory manipulation... }"},
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_SMARTCARD
|
#ifdef WITH_SMARTCARD
|
||||||
|
@ -79,286 +67,10 @@ int CmdRev(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd);
|
|
||||||
/**
|
|
||||||
* @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.
|
|
||||||
* A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which
|
|
||||||
* operation. Right now we'll just have to live with this.
|
|
||||||
*/
|
|
||||||
void clearCommandBuffer() {
|
|
||||||
//This is a very simple operation
|
|
||||||
pthread_mutex_lock(&cmdBufferMutex);
|
|
||||||
cmd_tail = cmd_head;
|
|
||||||
pthread_mutex_unlock(&cmdBufferMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief storeCommand stores a USB command in a circular buffer
|
|
||||||
* @param UC
|
|
||||||
*/
|
|
||||||
void storeCommand(UsbCommand *command) {
|
|
||||||
|
|
||||||
pthread_mutex_lock(&cmdBufferMutex);
|
|
||||||
if ( ( cmd_head+1) % CMD_BUFFER_SIZE == cmd_tail) {
|
|
||||||
//If these two are equal, we're about to overwrite in the
|
|
||||||
// circular buffer.
|
|
||||||
PrintAndLogEx(FAILED, "WARNING: Command buffer about to overwrite command! This needs to be fixed!");
|
|
||||||
fflush(NULL);
|
|
||||||
}
|
|
||||||
//Store the command at the 'head' location
|
|
||||||
UsbCommand* destination = &cmdBuffer[cmd_head];
|
|
||||||
memcpy(destination, command, sizeof(UsbCommand));
|
|
||||||
|
|
||||||
//increment head and wrap
|
|
||||||
cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE;
|
|
||||||
pthread_mutex_unlock(&cmdBufferMutex);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @brief getCommand gets a command from an internal circular buffer.
|
|
||||||
* @param response location to write command
|
|
||||||
* @return 1 if response was returned, 0 if nothing has been received
|
|
||||||
*/
|
|
||||||
int getCommand(UsbCommand* response) {
|
|
||||||
pthread_mutex_lock(&cmdBufferMutex);
|
|
||||||
//If head == tail, there's nothing to read, or if we just got initialized
|
|
||||||
if (cmd_head == cmd_tail) {
|
|
||||||
pthread_mutex_unlock(&cmdBufferMutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Pick out the next unread command
|
|
||||||
UsbCommand* last_unread = &cmdBuffer[cmd_tail];
|
|
||||||
memcpy(response, last_unread, sizeof(UsbCommand));
|
|
||||||
|
|
||||||
//Increment tail - this is a circular buffer, so modulo buffer size
|
|
||||||
cmd_tail = (cmd_tail +1 ) % CMD_BUFFER_SIZE;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&cmdBufferMutex);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Waits for a certain response type. This method waits for a maximum of
|
|
||||||
* ms_timeout milliseconds for a specified response command.
|
|
||||||
* @param cmd command to wait for, or CMD_UNKNOWN to take any command.
|
|
||||||
* @param response struct to copy received command into.
|
|
||||||
* @param ms_timeout display message after 2 seconds
|
|
||||||
* @return true if command was returned, otherwise false
|
|
||||||
*/
|
|
||||||
bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning) {
|
|
||||||
|
|
||||||
UsbCommand resp;
|
|
||||||
|
|
||||||
if (response == NULL)
|
|
||||||
response = &resp;
|
|
||||||
|
|
||||||
uint64_t start_time = msclock();
|
|
||||||
|
|
||||||
// Wait until the command is received
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
while ( getCommand(response) ) {
|
|
||||||
if (cmd == CMD_UNKNOWN || response->cmd == cmd)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msclock() - start_time > ms_timeout)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (msclock() - start_time > 3000 && show_warning) {
|
|
||||||
// 3 seconds elapsed (but this doesn't mean the timeout was exceeded)
|
|
||||||
PrintAndLogEx(NORMAL, "Waiting for a response from the proxmark...");
|
|
||||||
PrintAndLogEx(NORMAL, "You can cancel this operation by pressing the pm3 button");
|
|
||||||
show_warning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
|
|
||||||
return WaitForResponseTimeoutW(cmd, response, ms_timeout, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
|
|
||||||
return WaitForResponseTimeoutW(cmd, response, -1, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Entry point into our code: called whenever the user types a command and
|
// Entry point into our code: called whenever the user types a command and
|
||||||
// then presses Enter, which the full command line that they typed.
|
// then presses Enter, which the full command line that they typed.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
int CommandReceived(char *Cmd) {
|
int CommandReceived(char *Cmd) {
|
||||||
return CmdsParse(CommandTable, Cmd);
|
return CmdsParse(CommandTable, Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Entry point into our code: called whenever we received a packet over USB
|
|
||||||
// that we weren't necessarily expecting, for example a debug print.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void UsbCommandReceived(UsbCommand* _ch) {
|
|
||||||
|
|
||||||
//UsbCommand *c = malloc(sizeof(UsbCommand));
|
|
||||||
//memset(cp, 0x00, sizeof(*cp));
|
|
||||||
|
|
||||||
pthread_mutex_lock(&cmdBufferMutex);
|
|
||||||
UsbCommand* c = _ch;
|
|
||||||
pthread_mutex_unlock(&cmdBufferMutex);
|
|
||||||
|
|
||||||
switch(c->cmd) {
|
|
||||||
// First check if we are handling a debug message
|
|
||||||
case CMD_DEBUG_PRINT_STRING: {
|
|
||||||
|
|
||||||
char s[USB_CMD_DATA_SIZE+1];
|
|
||||||
memset(s, 0x00, sizeof(s));
|
|
||||||
size_t len = MIN(c->arg[0], USB_CMD_DATA_SIZE);
|
|
||||||
memcpy(s, c->d.asBytes, len);
|
|
||||||
|
|
||||||
//#define FLAG_RAWPRINT 0x0111
|
|
||||||
//#define FLAG_NOOPT 0x0000
|
|
||||||
//#define FLAG_NOLOG 0x0001
|
|
||||||
//#define FLAG_NONEWLINE 0x0010
|
|
||||||
//#define FLAG_NOPROMPT 0x0100
|
|
||||||
uint64_t flag = c->arg[1];
|
|
||||||
if (flag > 0) { // FLAG_RAWPRINT) {
|
|
||||||
switch (flag) {
|
|
||||||
case FLAG_RAWPRINT: {
|
|
||||||
printf("%s", s);
|
|
||||||
} return; break;
|
|
||||||
case FLAG_NONEWLINE: {
|
|
||||||
printf("%s\r", s);
|
|
||||||
} return; break;
|
|
||||||
case FLAG_NOLOG: {
|
|
||||||
printf("%s\r\n", s);
|
|
||||||
} return; break;
|
|
||||||
// printf("%s", s);
|
|
||||||
fflush(stdout);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// print debug line on same row. escape seq \r
|
|
||||||
if ( c->arg[1] == CMD_MEASURE_ANTENNA_TUNING_HF) {
|
|
||||||
PrintAndLogEx(NORMAL, "\r#db# %s", s);
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(NORMAL, "#db# %s", s);
|
|
||||||
}
|
|
||||||
fflush(NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CMD_DEBUG_PRINT_INTEGERS: {
|
|
||||||
PrintAndLogEx(NORMAL, "#db# %08x, %08x, %08x", c->arg[0], c->arg[1], c->arg[2]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// iceman: hw status - down the path on device, runs printusbspeed which starts sending a lot of
|
|
||||||
// CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K packages which is not dealt with. I wonder if simply ignoring them will
|
|
||||||
// work. lets try it.
|
|
||||||
default: {
|
|
||||||
storeCommand(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data transfer from Proxmark to client. This method times out after
|
|
||||||
* ms_timeout milliseconds.
|
|
||||||
* @brief GetFromDevice
|
|
||||||
* @param memtype Type of memory to download from proxmark
|
|
||||||
* @param dest Destination address for transfer
|
|
||||||
* @param bytes number of bytes to be transferred
|
|
||||||
* @param start_index offset into Proxmark3 BigBuf[]
|
|
||||||
* @param response struct to copy last command (CMD_ACK) into
|
|
||||||
* @param ms_timeout timeout in milliseconds
|
|
||||||
* @param show_warning display message after 2 seconds
|
|
||||||
* @return true if command was returned, otherwise false
|
|
||||||
*/
|
|
||||||
bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) {
|
|
||||||
|
|
||||||
if (dest == NULL) return false;
|
|
||||||
if (bytes == 0) return true;
|
|
||||||
|
|
||||||
UsbCommand resp;
|
|
||||||
if (response == NULL)
|
|
||||||
response = &resp;
|
|
||||||
|
|
||||||
// clear
|
|
||||||
clearCommandBuffer();
|
|
||||||
|
|
||||||
switch (memtype) {
|
|
||||||
case BIG_BUF: {
|
|
||||||
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
|
||||||
SendCommand(&c);
|
|
||||||
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
|
|
||||||
}
|
|
||||||
case BIG_BUF_EML: {
|
|
||||||
UsbCommand c = {CMD_DOWNLOAD_EML_BIGBUF, {start_index, bytes, 0}};
|
|
||||||
SendCommand(&c);
|
|
||||||
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF);
|
|
||||||
}
|
|
||||||
case FLASH_MEM: {
|
|
||||||
UsbCommand c = {CMD_FLASHMEM_DOWNLOAD, {start_index, bytes, 0}};
|
|
||||||
SendCommand(&c);
|
|
||||||
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED);
|
|
||||||
}
|
|
||||||
case SIM_MEM: {
|
|
||||||
//UsbCommand c = {CMD_DOWNLOAND_SIM_MEM, {start_index, bytes, 0}};
|
|
||||||
//SendCommand(&c);
|
|
||||||
//return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd) {
|
|
||||||
|
|
||||||
uint32_t bytes_completed = 0;
|
|
||||||
uint64_t start_time = msclock();
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
if (getCommand(response)) {
|
|
||||||
|
|
||||||
// sample_buf is a array pointer, located in data.c
|
|
||||||
// arg0 = offset in transfer. Startindex of this chunk
|
|
||||||
// arg1 = length bytes to transfer
|
|
||||||
// arg2 = bigbuff tracelength (?)
|
|
||||||
if (response->cmd == rec_cmd) {
|
|
||||||
|
|
||||||
uint32_t offset = response->arg[0];
|
|
||||||
uint32_t copy_bytes = MIN(bytes - bytes_completed, response->arg[1]);
|
|
||||||
//uint32_t tracelen = c->arg[2];
|
|
||||||
|
|
||||||
// extended bounds check1. upper limit is USB_CMD_DATA_SIZE
|
|
||||||
// shouldn't happen
|
|
||||||
copy_bytes = MIN(copy_bytes, USB_CMD_DATA_SIZE);
|
|
||||||
|
|
||||||
// extended bounds check2.
|
|
||||||
if ( offset + copy_bytes > bytes ) {
|
|
||||||
PrintAndLogEx(FAILED, "ERROR: Out of bounds when downloading from device, offset %u | len %u | total len %u > buf_size %u", offset, copy_bytes, offset+copy_bytes, bytes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dest + offset, response->d.asBytes, copy_bytes);
|
|
||||||
bytes_completed += copy_bytes;
|
|
||||||
} else if (response->cmd == CMD_ACK) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msclock() - start_time > ms_timeout) {
|
|
||||||
PrintAndLogEx(FAILED, "Timed out while trying to download data from device");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msclock() - start_time > 3000 && show_warning) {
|
|
||||||
// 3 seconds elapsed (but this doesn't mean the timeout was exceeded)
|
|
||||||
PrintAndLogEx(NORMAL, "Waiting for a response from the proxmark...");
|
|
||||||
PrintAndLogEx(NORMAL, "You can cancel this operation by pressing the pm3 button");
|
|
||||||
show_warning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <pthread.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -24,7 +23,6 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "loclass/fileutils.h"
|
|
||||||
#include "cmdhf.h"
|
#include "cmdhf.h"
|
||||||
#include "cmddata.h"
|
#include "cmddata.h"
|
||||||
#include "cmdhw.h"
|
#include "cmdhw.h"
|
||||||
|
@ -33,26 +31,16 @@
|
||||||
#include "cmdscript.h"
|
#include "cmdscript.h"
|
||||||
#include "cmdcrc.h"
|
#include "cmdcrc.h"
|
||||||
#include "cmdanalyse.h"
|
#include "cmdanalyse.h"
|
||||||
#include "cmdflashmem.h" // rdv40 flashmem commands
|
|
||||||
#include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands
|
|
||||||
|
|
||||||
//For storing command that are received from the device
|
#ifdef WITH_FLASH
|
||||||
#define CMD_BUFFER_SIZE 100
|
#include "cmdflashmem.h" // rdv40 flashmem commands
|
||||||
typedef enum {
|
#endif
|
||||||
BIG_BUF,
|
|
||||||
BIG_BUF_EML,
|
#ifdef WITH_SMARTCARD
|
||||||
FLASH_MEM,
|
#include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands
|
||||||
SIM_MEM,
|
#endif
|
||||||
} DeviceMemType_t;
|
|
||||||
|
|
||||||
extern void UsbCommandReceived(UsbCommand *c);
|
|
||||||
extern int CommandReceived(char *Cmd);
|
extern int CommandReceived(char *Cmd);
|
||||||
extern bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
|
|
||||||
extern bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
|
|
||||||
extern bool WaitForResponse(uint32_t cmd, UsbCommand* response);
|
|
||||||
extern void clearCommandBuffer();
|
|
||||||
extern command_t* getTopLevelCommandTable();
|
extern command_t* getTopLevelCommandTable();
|
||||||
|
|
||||||
extern bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,12 +15,13 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
void CmdsHelp(const command_t Commands[]) {
|
void CmdsHelp(const command_t Commands[]) {
|
||||||
if (Commands[0].Name == NULL) return;
|
if (Commands[0].Name == NULL) return;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (Commands[i].Name) {
|
while (Commands[i].Name) {
|
||||||
if (!offline || Commands[i].Offline)
|
if (!IsOffline() || Commands[i].Offline)
|
||||||
PrintAndLogEx(NORMAL, "%-16s %s", Commands[i].Name, Commands[i].Help);
|
PrintAndLogEx(NORMAL, "%-16s %s", Commands[i].Name, Commands[i].Help);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
|
#include "comms.h"
|
||||||
#include "cmdscript.h"
|
#include "cmdscript.h"
|
||||||
#include "cmdhfmf.h"
|
#include "cmdhfmf.h"
|
||||||
#include "pm3_binlib.h"
|
#include "pm3_binlib.h"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "loclass/fileutils.h" // saveFile
|
#include "loclass/fileutils.h" // saveFile
|
||||||
#include "cmdmain.h" // getfromdevice
|
#include "comms.h" // getfromdevice
|
||||||
#include "emv/emvcore.h" // decodeTVL
|
#include "emv/emvcore.h" // decodeTVL
|
||||||
#include "emv/apduinfo.h" // APDUcode description
|
#include "emv/apduinfo.h" // APDUcode description
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "util.h" // for parsing cli command utils
|
#include "util.h" // for parsing cli command utils
|
||||||
#include "ui.h" // for show graph controls
|
#include "ui.h" // for show graph controls
|
||||||
#include "cmdparser.h" // for getting cli commands included in cmdmain.h
|
#include "cmdparser.h" // for getting cli commands included in cmdmain.h
|
||||||
#include "cmdmain.h" // for sending cmds to device. GetFromBigBuf
|
#include "comms.h" // for sending cmds to device. GetFromBigBuf
|
||||||
#include "loclass/fileutils.h" // for saveFile
|
#include "loclass/fileutils.h" // for saveFile
|
||||||
|
|
||||||
extern int CmdTrace(const char *Cmd);
|
extern int CmdTrace(const char *Cmd);
|
||||||
|
|
510
client/comms.c
Normal file
510
client/comms.c
Normal file
|
@ -0,0 +1,510 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
|
||||||
|
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Code for communicating with the proxmark3 hardware.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
|
// Serial port that we are communicating with the PM3 on.
|
||||||
|
static serial_port sp = NULL;
|
||||||
|
static char *serial_port_name = NULL;
|
||||||
|
|
||||||
|
// If TRUE, then there is no active connection to the PM3, and we will drop commands sent.
|
||||||
|
static bool offline;
|
||||||
|
|
||||||
|
static communication_arg_t conn;
|
||||||
|
|
||||||
|
static pthread_t USB_communication_thread;
|
||||||
|
//static pthread_t FPC_communication_thread;
|
||||||
|
|
||||||
|
// Transmit buffer.
|
||||||
|
static UsbCommand txBuffer;
|
||||||
|
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];
|
||||||
|
|
||||||
|
// Points to the next empty position to write to
|
||||||
|
static int cmd_head = 0;
|
||||||
|
|
||||||
|
// Points to the position of the last unread command
|
||||||
|
static int cmd_tail = 0;
|
||||||
|
|
||||||
|
// to lock rxBuffer operations from different threads
|
||||||
|
static pthread_mutex_t rxBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
// These wrappers are required because it is not possible to access a static
|
||||||
|
// global variable outside of the context of a single file.
|
||||||
|
void SetOffline(bool value) {
|
||||||
|
offline = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsOffline() {
|
||||||
|
return offline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendCommand(UsbCommand *c) {
|
||||||
|
|
||||||
|
#ifdef COMMS_DEBUG
|
||||||
|
PrintAndLogEx(NORMAL, "Sending %d bytes | cmd %04x\n", sizeof(UsbCommand), c->cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (offline) {
|
||||||
|
PrintAndLogEx(NORMAL, "Sending bytes to proxmark failed - offline");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
txBuffer = *c;
|
||||||
|
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.
|
||||||
|
* A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which
|
||||||
|
* operation. Right now we'll just have to live with this.
|
||||||
|
*/
|
||||||
|
void clearCommandBuffer() {
|
||||||
|
//This is a very simple operation
|
||||||
|
pthread_mutex_lock(&rxBufferMutex);
|
||||||
|
cmd_tail = cmd_head;
|
||||||
|
pthread_mutex_unlock(&rxBufferMutex);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief storeCommand stores a USB command in a circular buffer
|
||||||
|
* @param UC
|
||||||
|
*/
|
||||||
|
static void storeCommand(UsbCommand *command) {
|
||||||
|
|
||||||
|
pthread_mutex_lock(&rxBufferMutex);
|
||||||
|
if ( ( cmd_head+1) % CMD_BUFFER_SIZE == cmd_tail) {
|
||||||
|
//If these two are equal, we're about to overwrite in the
|
||||||
|
// circular buffer.
|
||||||
|
PrintAndLogEx(FAILED, "WARNING: Command buffer about to overwrite command! This needs to be fixed!");
|
||||||
|
fflush(NULL);
|
||||||
|
}
|
||||||
|
//Store the command at the 'head' location
|
||||||
|
UsbCommand* destination = &rxBuffer[cmd_head];
|
||||||
|
memcpy(destination, command, sizeof(UsbCommand));
|
||||||
|
|
||||||
|
//increment head and wrap
|
||||||
|
cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE;
|
||||||
|
pthread_mutex_unlock(&rxBufferMutex);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief getCommand gets a command from an internal circular buffer.
|
||||||
|
* @param response location to write command
|
||||||
|
* @return 1 if response was returned, 0 if nothing has been received
|
||||||
|
*/
|
||||||
|
static int getCommand(UsbCommand* response) {
|
||||||
|
pthread_mutex_lock(&rxBufferMutex);
|
||||||
|
//If head == tail, there's nothing to read, or if we just got initialized
|
||||||
|
if (cmd_head == cmd_tail) {
|
||||||
|
pthread_mutex_unlock(&rxBufferMutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pick out the next unread command
|
||||||
|
UsbCommand* last_unread = &rxBuffer[cmd_tail];
|
||||||
|
memcpy(response, last_unread, sizeof(UsbCommand));
|
||||||
|
|
||||||
|
//Increment tail - this is a circular buffer, so modulo buffer size
|
||||||
|
cmd_tail = (cmd_tail +1 ) % CMD_BUFFER_SIZE;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&rxBufferMutex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Entry point into our code: called whenever we received a packet over USB
|
||||||
|
// that we weren't necessarily expecting, for example a debug print.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
static void UsbCommandReceived(UsbCommand* c) {
|
||||||
|
|
||||||
|
switch(c->cmd) {
|
||||||
|
// First check if we are handling a debug message
|
||||||
|
case CMD_DEBUG_PRINT_STRING: {
|
||||||
|
|
||||||
|
char s[USB_CMD_DATA_SIZE+1];
|
||||||
|
memset(s, 0x00, sizeof(s));
|
||||||
|
size_t len = MIN(c->arg[0], USB_CMD_DATA_SIZE);
|
||||||
|
memcpy(s, c->d.asBytes, len);
|
||||||
|
|
||||||
|
|
||||||
|
//#define FLAG_RAWPRINT 0x0111
|
||||||
|
//#define FLAG_NOOPT 0x0000
|
||||||
|
//#define FLAG_NOLOG 0x0001
|
||||||
|
//#define FLAG_NONEWLINE 0x0010
|
||||||
|
//#define FLAG_NOPROMPT 0x0100
|
||||||
|
uint64_t flag = c->arg[1];
|
||||||
|
if (flag > 0) { // FLAG_RAWPRINT) {
|
||||||
|
switch (flag) {
|
||||||
|
case FLAG_RAWPRINT:
|
||||||
|
printf("%s", s);
|
||||||
|
return;
|
||||||
|
case FLAG_NONEWLINE:
|
||||||
|
printf("%s\r", s);
|
||||||
|
return;
|
||||||
|
case FLAG_NOLOG:
|
||||||
|
printf("%s\r\n", s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print debug line on same row. escape seq \r
|
||||||
|
if ( c->arg[1] == CMD_MEASURE_ANTENNA_TUNING_HF) {
|
||||||
|
PrintAndLogEx(NORMAL, "\r#db# %s", s);
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(NORMAL, "#db# %s", s);
|
||||||
|
}
|
||||||
|
fflush(NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_DEBUG_PRINT_INTEGERS: {
|
||||||
|
PrintAndLogEx(NORMAL, "#db# %08x, %08x, %08x", c->arg[0], c->arg[1], c->arg[2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// iceman: hw status - down the path on device, runs printusbspeed which starts sending a lot of
|
||||||
|
// CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K packages which is not dealt with. I wonder if simply ignoring them will
|
||||||
|
// work. lets try it.
|
||||||
|
default: {
|
||||||
|
storeCommand(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool hookUpPM3() {
|
||||||
|
bool ret = false;
|
||||||
|
sp = uart_open( comport );
|
||||||
|
|
||||||
|
if (sp == INVALID_SERIAL_PORT) {
|
||||||
|
PrintAndLogEx(WARNING, "Reconnect failed, retrying... (reason: invalid serial port)\n");
|
||||||
|
sp = NULL;
|
||||||
|
serial_port_name = NULL;
|
||||||
|
ret = false;
|
||||||
|
offline = 1;
|
||||||
|
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||||
|
PrintAndLogEx(WARNING, "Reconnect failed, retrying... (reason: serial port is claimed by another process)\n");
|
||||||
|
sp = NULL;
|
||||||
|
serial_port_name = NULL;
|
||||||
|
ret = false;
|
||||||
|
offline = 1;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(SUCCESS, "Proxmark reconnected\n");
|
||||||
|
serial_port_name = ;
|
||||||
|
ret = true;
|
||||||
|
offline = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
#ifdef __has_attribute
|
||||||
|
#if __has_attribute(force_align_arg_pointer)
|
||||||
|
__attribute__((force_align_arg_pointer))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
*uart_communication(void *targ) {
|
||||||
|
communication_arg_t *conn = (communication_arg_t*)targ;
|
||||||
|
size_t rxlen;
|
||||||
|
UsbCommand rx;
|
||||||
|
UsbCommand *prx = ℞
|
||||||
|
|
||||||
|
//int counter_to_offline = 0;
|
||||||
|
|
||||||
|
while (conn->run) {
|
||||||
|
rxlen = 0;
|
||||||
|
bool ACK_received = false;
|
||||||
|
if (uart_receive(sp, (uint8_t *)prx, sizeof(UsbCommand) - (prx - &rx), &rxlen) && rxlen) {
|
||||||
|
prx += rxlen;
|
||||||
|
|
||||||
|
if (prx - &rx < sizeof(UsbCommand)) {
|
||||||
|
PrintAndLogEx(NORMAL, "Foo %d | %d (will loop)", prx - &rx, rxlen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
UsbCommandReceived(&rx);
|
||||||
|
if (rx.cmd == CMD_ACK) {
|
||||||
|
ACK_received = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prx = ℞
|
||||||
|
|
||||||
|
pthread_mutex_lock(&txBufferMutex);
|
||||||
|
|
||||||
|
if (conn->block_after_ACK) {
|
||||||
|
// if we just received an ACK, wait here until a new command is to be transmitted
|
||||||
|
if (ACK_received) {
|
||||||
|
while (!txBuffer_pending) {
|
||||||
|
pthread_cond_wait(&txBufferSig, &txBufferMutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txBuffer_pending) {
|
||||||
|
if (!uart_send(sp, (uint8_t*) &txBuffer, sizeof(UsbCommand))) {
|
||||||
|
//counter_to_offline++;
|
||||||
|
PrintAndLogEx(WARNING, "sending bytes to proxmark failed");
|
||||||
|
}
|
||||||
|
txBuffer_pending = false;
|
||||||
|
|
||||||
|
// tell main thread that txBuffer is empty
|
||||||
|
pthread_cond_signal(&txBufferSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&txBufferMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// when this reader thread dies, we close the serial port.
|
||||||
|
uart_close(sp);
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) {
|
||||||
|
|
||||||
|
char *portname = (char *)port;
|
||||||
|
if (!wait_for_port) {
|
||||||
|
sp = uart_open(portname);
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(SUCCESS, "Waiting for Proxmark to appear on " _YELLOW_(%s), portname);
|
||||||
|
fflush(stdout);
|
||||||
|
int openCount = 0;
|
||||||
|
do {
|
||||||
|
sp = uart_open(portname);
|
||||||
|
msleep(500);
|
||||||
|
printf("."); fflush(stdout);
|
||||||
|
} while (++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT));
|
||||||
|
//PrintAndLogEx(NORMAL, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check result of uart opening
|
||||||
|
if (sp == INVALID_SERIAL_PORT) {
|
||||||
|
PrintAndLogEx(WARNING, _RED_(ERROR:) "invalid serial port");
|
||||||
|
sp = NULL;
|
||||||
|
serial_port_name = NULL;
|
||||||
|
return false;
|
||||||
|
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||||
|
PrintAndLogEx(WARNING, _RED_(ERROR:) "serial port is claimed by another process");
|
||||||
|
sp = NULL;
|
||||||
|
serial_port_name = NULL;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// start the USB communication thread
|
||||||
|
serial_port_name = portname;
|
||||||
|
conn.run = true;
|
||||||
|
conn.block_after_ACK = flash_mode;
|
||||||
|
pthread_create(&USB_communication_thread, NULL, &uart_communication, &conn);
|
||||||
|
//pthread_create(&FPC_communication_thread, NULL, &uart_communication, &conn);
|
||||||
|
|
||||||
|
fflush(NULL);
|
||||||
|
// create a mutex to avoid interlacing print commands from our different threads
|
||||||
|
//pthread_mutex_init(&print_lock, NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseProxmark(void) {
|
||||||
|
conn.run = false;
|
||||||
|
pthread_join(USB_communication_thread, NULL);
|
||||||
|
//pthread_join(FPC_communication_thread, NULL);
|
||||||
|
|
||||||
|
if (sp) {
|
||||||
|
uart_close(sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__linux__) && !defined(NO_UNLINK)
|
||||||
|
// Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
|
||||||
|
//
|
||||||
|
// This may be disabled at compile-time with -DNO_UNLINK (used for a JNI-based serial port on Android).
|
||||||
|
if (serial_port_name) {
|
||||||
|
unlink(serial_port_name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Clean up our state
|
||||||
|
sp = NULL;
|
||||||
|
serial_port_name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Waits for a certain response type. This method waits for a maximum of
|
||||||
|
* ms_timeout milliseconds for a specified response command.
|
||||||
|
|
||||||
|
* @param cmd command to wait for, or CMD_UNKNOWN to take any command.
|
||||||
|
* @param response struct to copy received command into.
|
||||||
|
* @param ms_timeout display message after 3 seconds
|
||||||
|
* @param show_warning display message after 3 seconds
|
||||||
|
* @return true if command was returned, otherwise false
|
||||||
|
*/
|
||||||
|
bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning) {
|
||||||
|
|
||||||
|
UsbCommand resp;
|
||||||
|
|
||||||
|
if (response == NULL)
|
||||||
|
response = &resp;
|
||||||
|
|
||||||
|
uint64_t start_time = msclock();
|
||||||
|
|
||||||
|
// Wait until the command is received
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
while ( getCommand(response) ) {
|
||||||
|
if (cmd == CMD_UNKNOWN || response->cmd == cmd)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msclock() - start_time > ms_timeout)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (msclock() - start_time > 3000 && show_warning) {
|
||||||
|
// 3 seconds elapsed (but this doesn't mean the timeout was exceeded)
|
||||||
|
PrintAndLogEx(NORMAL, "Waiting for a response from the proxmark...");
|
||||||
|
PrintAndLogEx(NORMAL, "You can cancel this operation by pressing the pm3 button");
|
||||||
|
show_warning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
|
||||||
|
return WaitForResponseTimeoutW(cmd, response, ms_timeout, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
|
||||||
|
return WaitForResponseTimeoutW(cmd, response, -1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data transfer from Proxmark to client. This method times out after
|
||||||
|
* ms_timeout milliseconds.
|
||||||
|
* @brief GetFromDevice
|
||||||
|
* @param memtype Type of memory to download from proxmark
|
||||||
|
* @param dest Destination address for transfer
|
||||||
|
* @param bytes number of bytes to be transferred
|
||||||
|
* @param start_index offset into Proxmark3 BigBuf[]
|
||||||
|
* @param response struct to copy last command (CMD_ACK) into
|
||||||
|
* @param ms_timeout timeout in milliseconds
|
||||||
|
* @param show_warning display message after 2 seconds
|
||||||
|
* @return true if command was returned, otherwise false
|
||||||
|
*/
|
||||||
|
bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) {
|
||||||
|
|
||||||
|
if (dest == NULL) return false;
|
||||||
|
if (bytes == 0) return true;
|
||||||
|
|
||||||
|
UsbCommand resp;
|
||||||
|
if (response == NULL)
|
||||||
|
response = &resp;
|
||||||
|
|
||||||
|
// clear
|
||||||
|
clearCommandBuffer();
|
||||||
|
|
||||||
|
switch (memtype) {
|
||||||
|
case BIG_BUF: {
|
||||||
|
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
||||||
|
SendCommand(&c);
|
||||||
|
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
|
||||||
|
}
|
||||||
|
case BIG_BUF_EML: {
|
||||||
|
UsbCommand c = {CMD_DOWNLOAD_EML_BIGBUF, {start_index, bytes, 0}};
|
||||||
|
SendCommand(&c);
|
||||||
|
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF);
|
||||||
|
}
|
||||||
|
case FLASH_MEM: {
|
||||||
|
UsbCommand c = {CMD_FLASHMEM_DOWNLOAD, {start_index, bytes, 0}};
|
||||||
|
SendCommand(&c);
|
||||||
|
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED);
|
||||||
|
}
|
||||||
|
case SIM_MEM: {
|
||||||
|
//UsbCommand c = {CMD_DOWNLOAND_SIM_MEM, {start_index, bytes, 0}};
|
||||||
|
//SendCommand(&c);
|
||||||
|
//return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd) {
|
||||||
|
|
||||||
|
uint32_t bytes_completed = 0;
|
||||||
|
uint64_t start_time = msclock();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
if (getCommand(response)) {
|
||||||
|
|
||||||
|
// sample_buf is a array pointer, located in data.c
|
||||||
|
// arg0 = offset in transfer. Startindex of this chunk
|
||||||
|
// arg1 = length bytes to transfer
|
||||||
|
// arg2 = bigbuff tracelength (?)
|
||||||
|
if (response->cmd == rec_cmd) {
|
||||||
|
|
||||||
|
uint32_t offset = response->arg[0];
|
||||||
|
uint32_t copy_bytes = MIN(bytes - bytes_completed, response->arg[1]);
|
||||||
|
//uint32_t tracelen = c->arg[2];
|
||||||
|
|
||||||
|
// extended bounds check1. upper limit is USB_CMD_DATA_SIZE
|
||||||
|
// shouldn't happen
|
||||||
|
copy_bytes = MIN(copy_bytes, USB_CMD_DATA_SIZE);
|
||||||
|
|
||||||
|
// extended bounds check2.
|
||||||
|
if ( offset + copy_bytes > bytes ) {
|
||||||
|
PrintAndLogEx(FAILED, "ERROR: Out of bounds when downloading from device, offset %u | len %u | total len %u > buf_size %u", offset, copy_bytes, offset+copy_bytes, bytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dest + offset, response->d.asBytes, copy_bytes);
|
||||||
|
bytes_completed += copy_bytes;
|
||||||
|
} else if (response->cmd == CMD_ACK) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msclock() - start_time > ms_timeout) {
|
||||||
|
PrintAndLogEx(FAILED, "Timed out while trying to download data from device");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msclock() - start_time > 3000 && show_warning) {
|
||||||
|
// 3 seconds elapsed (but this doesn't mean the timeout was exceeded)
|
||||||
|
PrintAndLogEx(NORMAL, "Waiting for a response from the proxmark...");
|
||||||
|
PrintAndLogEx(NORMAL, "You can cancel this operation by pressing the pm3 button");
|
||||||
|
show_warning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
67
client/comms.h
Normal file
67
client/comms.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
|
||||||
|
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Code for communicating with the proxmark3 hardware.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef COMMS_H_
|
||||||
|
#define COMMS_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "usb_cmd.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "util_posix.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#if defined(__linux__) && !defined(NO_UNLINK)
|
||||||
|
#include <unistd.h> // for unlink()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//For storing command that are received from the device
|
||||||
|
#ifndef CMD_BUFFER_SIZE
|
||||||
|
#define CMD_BUFFER_SIZE 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BIG_BUF,
|
||||||
|
BIG_BUF_EML,
|
||||||
|
FLASH_MEM,
|
||||||
|
SIM_MEM,
|
||||||
|
} DeviceMemType_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool run; // If TRUE, continue running the uart_communication thread
|
||||||
|
bool block_after_ACK; // if true, block after receiving an ACK package
|
||||||
|
} communication_arg_t;
|
||||||
|
|
||||||
|
|
||||||
|
bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd);
|
||||||
|
|
||||||
|
void SetOffline(bool value);
|
||||||
|
bool IsOffline();
|
||||||
|
|
||||||
|
void *uart_receiver(void *targ);
|
||||||
|
void SendCommand(UsbCommand *c);
|
||||||
|
void clearCommandBuffer();
|
||||||
|
|
||||||
|
bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode);
|
||||||
|
void CloseProxmark(void);
|
||||||
|
|
||||||
|
bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
|
||||||
|
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
|
||||||
|
bool WaitForResponse(uint32_t cmd, UsbCommand* response);
|
||||||
|
|
||||||
|
extern bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,6 @@
|
||||||
|
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
|
|
||||||
void SendCommand(UsbCommand* txcmd);
|
|
||||||
void ReceiveCommand(UsbCommand* rxcmd);
|
|
||||||
void CloseProxmark();
|
|
||||||
int OpenProxmark();
|
|
||||||
|
|
||||||
#define FLASH_START 0x100000
|
#define FLASH_START 0x100000
|
||||||
|
|
||||||
#ifdef HAS_512_FLASH
|
#ifdef HAS_512_FLASH
|
||||||
|
@ -192,12 +187,12 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) {
|
||||||
|
|
||||||
fd = fopen(name, "rb");
|
fd = fopen(name, "rb");
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
fprintf(stderr, "Could not open file '%s': ", name);
|
fprintf(stderr, _RED_(Could not open file) "%s >>> ", name);
|
||||||
perror(NULL);
|
perror(NULL);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "Loading ELF file '%s'...\n", name);
|
fprintf(stdout, _BLUE_(Loading ELF file) "%s\n", name);
|
||||||
|
|
||||||
if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
|
if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
|
||||||
fprintf(stderr, "Error while reading ELF file header\n");
|
fprintf(stderr, "Error while reading ELF file header\n");
|
||||||
|
@ -268,7 +263,7 @@ static int get_proxmark_state(uint32_t *state) {
|
||||||
UsbCommand c = {CMD_DEVICE_INFO};
|
UsbCommand c = {CMD_DEVICE_INFO};
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
ReceiveCommand(&resp);
|
WaitForResponse(CMD_UNKNOWN, &resp); // wait for any response. No timeout.
|
||||||
|
|
||||||
// Three outcomes:
|
// Three outcomes:
|
||||||
// 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
|
// 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
|
||||||
|
@ -286,7 +281,7 @@ static int get_proxmark_state(uint32_t *state) {
|
||||||
*state = resp.arg[0];
|
*state = resp.arg[0];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Error: Couldn't get proxmark state, bad response type: 0x%04" PRIx64 "\n", resp.cmd);
|
fprintf(stderr, _RED_(Error:) "Couldn't get proxmark state, bad response type: 0x%04" PRIx64 "\n", resp.cmd);
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +300,7 @@ static int enter_bootloader(char *serial_port_name) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
||||||
fprintf(stdout, "Entering bootloader...\n");
|
fprintf(stdout, _BLUE_(Entering bootloader...) "\n");
|
||||||
UsbCommand c;
|
UsbCommand c;
|
||||||
memset(&c, 0, sizeof (c));
|
memset(&c, 0, sizeof (c));
|
||||||
|
|
||||||
|
@ -325,21 +320,22 @@ static int enter_bootloader(char *serial_port_name) {
|
||||||
msleep(100);
|
msleep(100);
|
||||||
CloseProxmark();
|
CloseProxmark();
|
||||||
|
|
||||||
fprintf(stdout, "Waiting for Proxmark to reappear on %s", serial_port_name);
|
bool opened = OpenProxmark(serial_port_name, true, 60, true);
|
||||||
do {
|
if (opened) {
|
||||||
msleep(1000);
|
fprintf(stdout, " " _GREEN_(Found) "\n");
|
||||||
fprintf(stdout, "."); fflush(stdout);
|
return 0;
|
||||||
} while ( !OpenProxmark());
|
} else {
|
||||||
fprintf(stdout, " Found.\n");
|
fprintf(stdout, _RED_(Error:) "Proxmark not found.\n");
|
||||||
return 0;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Error: Unknown Proxmark mode\n");
|
fprintf(stderr, _RED_(Error:) "Unknown Proxmark mode\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_for_ack(UsbCommand *ack) {
|
static int wait_for_ack(UsbCommand *ack) {
|
||||||
ReceiveCommand(ack);
|
WaitForResponse(CMD_UNKNOWN, ack);
|
||||||
|
|
||||||
if (ack->cmd != CMD_ACK) {
|
if (ack->cmd != CMD_ACK) {
|
||||||
printf("Error: Unexpected reply 0x%04" PRIx64 " %s (expected ACK)\n",
|
printf("Error: Unexpected reply 0x%04" PRIx64 " %s (expected ACK)\n",
|
||||||
|
@ -378,10 +374,9 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name) {
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return wait_for_ack(&c);
|
return wait_for_ack(&c);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Note: Your bootloader does not understand the new START_FLASH command\n");
|
fprintf(stderr, _RED_(Note: Your bootloader does not understand the new START_FLASH command) "\n");
|
||||||
fprintf(stderr, " It is recommended that you update your bootloader\n\n");
|
fprintf(stderr, _RED_( It is recommended that you update your bootloader) "\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,7 +434,7 @@ int flash_write(flash_file_t *ctx) {
|
||||||
block++;
|
block++;
|
||||||
fprintf(stdout, "."); fflush(stdout);
|
fprintf(stdout, "."); fflush(stdout);
|
||||||
}
|
}
|
||||||
fprintf(stdout, " OK\n");
|
fprintf(stdout, _GREEN_(OK) "\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
#include "at91sam7s512.h"
|
#include "at91sam7s512.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *data;
|
void *data;
|
||||||
|
|
|
@ -10,31 +10,16 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
|
#include "util.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "uart.h"
|
#include "comms.h"
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
|
|
||||||
#define MAX_FILES 4
|
#define MAX_FILES 4
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# define unlink(x)
|
|
||||||
#else
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (_WIN32)
|
|
||||||
#define SERIAL_PORT_H "com3"
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#define SERIAL_PORT_H "/dev/cu.usbmodem888"
|
|
||||||
#else
|
|
||||||
#define SERIAL_PORT_H "/dev/ttyACM0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static serial_port sp;
|
|
||||||
static char* serial_port_name;
|
|
||||||
|
|
||||||
void cmd_debug(UsbCommand* c) {
|
void cmd_debug(UsbCommand* c) {
|
||||||
// Debug
|
// Debug
|
||||||
printf("UsbCommand length[len=%zd]\n", sizeof(UsbCommand));
|
printf("UsbCommand length[len=%zd]\n", sizeof(UsbCommand));
|
||||||
|
@ -50,49 +35,6 @@ void cmd_debug(UsbCommand* c) {
|
||||||
printf("...\n");
|
printf("...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendCommand(UsbCommand* txcmd) {
|
|
||||||
// printf("send: ");
|
|
||||||
// cmd_debug(txcmd);
|
|
||||||
if (!uart_send(sp, (byte_t*)txcmd, sizeof(UsbCommand))) {
|
|
||||||
printf("Sending bytes to proxmark failed\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReceiveCommand(UsbCommand* rxcmd) {
|
|
||||||
byte_t* prxcmd = (byte_t*)rxcmd;
|
|
||||||
byte_t* prx = prxcmd;
|
|
||||||
size_t rxlen;
|
|
||||||
while (true) {
|
|
||||||
if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-prxcmd), &rxlen)) {
|
|
||||||
prx += rxlen;
|
|
||||||
if ((prx-prxcmd) >= sizeof(UsbCommand)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloseProxmark() {
|
|
||||||
// Clean up the port
|
|
||||||
uart_close(sp);
|
|
||||||
// Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
|
|
||||||
unlink(serial_port_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
int OpenProxmark() {
|
|
||||||
sp = uart_open(serial_port_name);
|
|
||||||
|
|
||||||
//poll once a second
|
|
||||||
if (sp == INVALID_SERIAL_PORT) {
|
|
||||||
return 0;
|
|
||||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
|
||||||
fprintf(stderr, "ERROR: serial port is claimed by another process\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usage(char *argv0) {
|
static void usage(char *argv0) {
|
||||||
fprintf(stdout, "Usage: %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
|
fprintf(stdout, "Usage: %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
|
||||||
fprintf(stdout, "\t-b\tEnable flashing of bootloader area (DANGEROUS)\n\n");
|
fprintf(stdout, "\t-b\tEnable flashing of bootloader area (DANGEROUS)\n\n");
|
||||||
|
@ -129,30 +71,28 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res = flash_load(&files[num_files], argv[i], can_write_bl);
|
res = flash_load(&files[num_files], argv[i], can_write_bl);
|
||||||
if (res < 0) {
|
if (res < 0)
|
||||||
fprintf(stderr, "Error while loading %s\n", argv[i]);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
num_files++;
|
num_files++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* serial_port_name = argv[1];
|
||||||
|
|
||||||
serial_port_name = argv[1];
|
if (!OpenProxmark(serial_port_name, true, 60, true)) {
|
||||||
|
fprintf(stderr, "Could not find Proxmark on " _RED_(%s) ".\n\n", serial_port_name);
|
||||||
fprintf(stdout, "Waiting for Proxmark to appear on %s", serial_port_name);
|
return -1;
|
||||||
do {
|
} else {
|
||||||
msleep(500);
|
fprintf(stderr, _GREEN_(Found) "\n");
|
||||||
fprintf(stderr, "."); fflush(stdout);
|
}
|
||||||
} while (!OpenProxmark());
|
|
||||||
|
|
||||||
fprintf(stdout, " Found.\n");
|
|
||||||
|
|
||||||
res = flash_start_flashing(can_write_bl, serial_port_name);
|
res = flash_start_flashing(can_write_bl, serial_port_name);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
fprintf(stdout, "\nFlashing...\n");
|
fprintf(stdout, "\n" _BLUE_(Flashing...)"\n");
|
||||||
|
|
||||||
for (int i = 0; i < num_files; i++) {
|
for (int i = 0; i < num_files; i++) {
|
||||||
res = flash_write(&files[i]);
|
res = flash_write(&files[i]);
|
||||||
|
@ -162,7 +102,7 @@ int main(int argc, char **argv) {
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "Resetting hardware...\n");
|
fprintf(stdout, _BLUE_(Resetting hardware...) "\n");
|
||||||
|
|
||||||
res = flash_stop_flashing();
|
res = flash_stop_flashing();
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
|
@ -170,7 +110,6 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
CloseProxmark();
|
CloseProxmark();
|
||||||
|
|
||||||
fprintf(stdout, "All done.\n\n");
|
fprintf(stdout, _BLUE_(All done.) "\n\nHave a nice day!\n");
|
||||||
fprintf(stdout, "Have a nice day!\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,55 +17,16 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
|
||||||
|
#include "util_posix.h"
|
||||||
#include "proxgui.h"
|
#include "proxgui.h"
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
#include "uart.h"
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmdhw.h"
|
#include "cmdhw.h"
|
||||||
#include "whereami.h"
|
#include "whereami.h"
|
||||||
|
#include "comms.h"
|
||||||
#if defined (_WIN32)
|
|
||||||
#define SERIAL_PORT_H "com3"
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#define SERIAL_PORT_H "/dev/cu.usbmodem888"
|
|
||||||
#else
|
|
||||||
#define SERIAL_PORT_H "/dev/ttyACM0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static serial_port sp;
|
|
||||||
static UsbCommand txcmd;
|
|
||||||
static char comport[255];
|
|
||||||
byte_t rx[sizeof(UsbCommand)];
|
|
||||||
byte_t* prx = rx;
|
|
||||||
volatile static bool txcmd_pending = false;
|
|
||||||
struct receiver_arg {
|
|
||||||
int run;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SendCommand(UsbCommand *c) {
|
|
||||||
#if 0
|
|
||||||
//pthread_mutex_lock(&print_lock);
|
|
||||||
PrintAndLogEx(NORMAL, "Sending %d bytes\n", sizeof(UsbCommand));
|
|
||||||
//pthread_mutex_unlock(&print_lock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (offline) {
|
|
||||||
PrintAndLogEx(NORMAL, "Sending bytes to proxmark failed - offline");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
The while-loop below 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 (txcmd_pending);
|
|
||||||
|
|
||||||
txcmd = *c;
|
|
||||||
__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__linux__) || (__APPLE__)
|
#if defined(__linux__) || (__APPLE__)
|
||||||
static void showBanner(void){
|
static void showBanner(void){
|
||||||
|
@ -83,84 +44,6 @@ static void showBanner(void){
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool hookUpPM3() {
|
|
||||||
bool ret = false;
|
|
||||||
sp = uart_open( comport );
|
|
||||||
|
|
||||||
//pthread_mutex_lock(&print_lock);
|
|
||||||
|
|
||||||
if (sp == INVALID_SERIAL_PORT) {
|
|
||||||
PrintAndLogEx(WARNING, "Reconnect failed, retrying... (reason: invalid serial port)\n");
|
|
||||||
sp = NULL;
|
|
||||||
ret = false;
|
|
||||||
offline = 1;
|
|
||||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
|
||||||
PrintAndLogEx(WARNING, "Reconnect failed, retrying... (reason: serial port is claimed by another process)\n");
|
|
||||||
sp = NULL;
|
|
||||||
ret = false;
|
|
||||||
offline = 1;
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(SUCCESS, "Proxmark reconnected\n");
|
|
||||||
ret = true;
|
|
||||||
offline = 0;
|
|
||||||
}
|
|
||||||
//pthread_mutex_unlock(&print_lock);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (iceman) if uart_receiver fails a command three times, we conside the device to be offline.
|
|
||||||
void
|
|
||||||
#ifdef __has_attribute
|
|
||||||
#if __has_attribute(force_align_arg_pointer)
|
|
||||||
__attribute__((force_align_arg_pointer))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
*uart_receiver(void *targ) {
|
|
||||||
struct receiver_arg *arg = (struct receiver_arg*)targ;
|
|
||||||
size_t rxlen;
|
|
||||||
bool tmpsignal;
|
|
||||||
int counter_to_offline = 0;
|
|
||||||
|
|
||||||
while (arg->run) {
|
|
||||||
rxlen = 0;
|
|
||||||
|
|
||||||
if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen)) {
|
|
||||||
|
|
||||||
if ( rxlen == 0 ) continue;
|
|
||||||
|
|
||||||
prx += rxlen;
|
|
||||||
if ( (prx-rx) < sizeof(UsbCommand)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
UsbCommandReceived((UsbCommand*)rx);
|
|
||||||
}
|
|
||||||
prx = rx;
|
|
||||||
|
|
||||||
__atomic_load(&txcmd_pending, &tmpsignal, __ATOMIC_SEQ_CST);
|
|
||||||
if ( tmpsignal ) {
|
|
||||||
bool res = uart_send(sp, (byte_t*) &txcmd, sizeof(UsbCommand));
|
|
||||||
if (!res) {
|
|
||||||
counter_to_offline++;
|
|
||||||
PrintAndLogEx(NORMAL, "sending bytes to proxmark failed");
|
|
||||||
}
|
|
||||||
__atomic_clear(&txcmd_pending, __ATOMIC_SEQ_CST);
|
|
||||||
|
|
||||||
// set offline flag
|
|
||||||
if ( counter_to_offline == 3 ) {
|
|
||||||
__atomic_test_and_set(&offline, __ATOMIC_SEQ_CST);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// when this reader thread dies, we close the serial port.
|
|
||||||
uart_close(sp);
|
|
||||||
|
|
||||||
pthread_exit(NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
#ifdef __has_attribute
|
#ifdef __has_attribute
|
||||||
#if __has_attribute(force_align_arg_pointer)
|
#if __has_attribute(force_align_arg_pointer)
|
||||||
|
@ -169,9 +52,7 @@ __attribute__((force_align_arg_pointer))
|
||||||
#endif
|
#endif
|
||||||
main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||||
|
|
||||||
struct receiver_arg rarg;
|
|
||||||
char *cmd = NULL;
|
char *cmd = NULL;
|
||||||
pthread_t reader_thread;
|
|
||||||
bool execCommand = (script_cmd != NULL);
|
bool execCommand = (script_cmd != NULL);
|
||||||
bool stdinOnPipe = !isatty(STDIN_FILENO);
|
bool stdinOnPipe = !isatty(STDIN_FILENO);
|
||||||
FILE *sf = NULL;
|
FILE *sf = NULL;
|
||||||
|
@ -180,13 +61,14 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||||
PrintAndLogEx(DEBUG, "ISATTY/STDIN_FILENO == %s\n", (stdinOnPipe) ? "true" : "false");
|
PrintAndLogEx(DEBUG, "ISATTY/STDIN_FILENO == %s\n", (stdinOnPipe) ? "true" : "false");
|
||||||
|
|
||||||
if (usb_present) {
|
if (usb_present) {
|
||||||
rarg.run = 1;
|
SetOffline(false);
|
||||||
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
|
|
||||||
// cache Version information now:
|
// cache Version information now:
|
||||||
if ( execCommand || script_cmds_file || stdinOnPipe)
|
if ( execCommand || script_cmds_file || stdinOnPipe)
|
||||||
CmdVersion("s");
|
CmdVersion("s");
|
||||||
else
|
else
|
||||||
CmdVersion("");
|
CmdVersion("");
|
||||||
|
} else {
|
||||||
|
SetOffline(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script_cmds_file) {
|
if (script_cmds_file) {
|
||||||
|
@ -202,13 +84,14 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
// this should hook up the PM3 again.
|
// this should hook up the PM3 again.
|
||||||
if (offline) {
|
/*
|
||||||
|
if ( IsOffline() ) {
|
||||||
|
|
||||||
// sets the global variable, SP and offline)
|
// sets the global variable, SP and offline)
|
||||||
usb_present = hookUpPM3();
|
usb_present = hookUpPM3();
|
||||||
|
|
||||||
// usb and the reader_thread is NULL, create a new reader thread.
|
// usb and the reader_thread is NULL, create a new reader thread.
|
||||||
if (usb_present && !offline) {
|
if (usb_present && !IsOffline() ) {
|
||||||
rarg.run = 1;
|
rarg.run = 1;
|
||||||
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
|
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
|
||||||
// cache Version information now:
|
// cache Version information now:
|
||||||
|
@ -218,6 +101,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||||
CmdVersion("");
|
CmdVersion("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// If there is a script file
|
// If there is a script file
|
||||||
if (sf) {
|
if (sf) {
|
||||||
|
@ -304,11 +188,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||||
|
|
||||||
free(cmd);
|
free(cmd);
|
||||||
cmd = NULL;
|
cmd = NULL;
|
||||||
|
|
||||||
if (usb_present) {
|
|
||||||
rarg.run = 0;
|
|
||||||
pthread_join(reader_thread, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpAllHelp(int markdown) {
|
static void dumpAllHelp(int markdown) {
|
||||||
|
@ -346,7 +226,7 @@ static void set_my_executable_path(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_help(bool showFullHelp, char *command_line){
|
static void show_help(bool showFullHelp, char *command_line){
|
||||||
PrintAndLogEx(NORMAL, "syntax: %s <port> [-h|-help|-m|-f|-flush|-w|-wait|-c|-command|-l|-lua] [cmd_script_file_name] [command][lua_script_name]\n", command_line);
|
PrintAndLogEx(NORMAL, "syntax: %s <port> [-h | -help | -m | -f | -flush | -w | -wait | -c | -command | -l | -lua] [cmd_script_file_name] [command][lua_script_name]\n", command_line);
|
||||||
PrintAndLogEx(NORMAL, "\texample:'%s "SERIAL_PORT_H"'\n\n", command_line);
|
PrintAndLogEx(NORMAL, "\texample:'%s "SERIAL_PORT_H"'\n\n", command_line);
|
||||||
|
|
||||||
if (showFullHelp){
|
if (showFullHelp){
|
||||||
|
@ -384,10 +264,6 @@ int main(int argc, char* argv[]) {
|
||||||
show_help(true, argv[0]);
|
show_help(true, argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lets copy the comport string.
|
|
||||||
memset(comport, 0, sizeof(comport));
|
|
||||||
memcpy(comport, argv[1], strlen(argv[1]));
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
|
|
||||||
|
@ -406,7 +282,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
// flush output
|
// flush output
|
||||||
if(strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "-flush") == 0){
|
if(strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "-flush") == 0){
|
||||||
g_flushAfterWrite = 1;
|
SetFlushAfterWrite(true);
|
||||||
PrintAndLogEx(INFO, "Output will be flushed after every print.\n");
|
PrintAndLogEx(INFO, "Output will be flushed after every print.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,39 +350,11 @@ int main(int argc, char* argv[]) {
|
||||||
// set global variables
|
// set global variables
|
||||||
set_my_executable_path();
|
set_my_executable_path();
|
||||||
|
|
||||||
// open uart
|
// try to open USB connection to Proxmark
|
||||||
if (!waitCOMPort) {
|
usb_present = OpenProxmark(argv[1], waitCOMPort, 20, false);
|
||||||
sp = uart_open(argv[1]);
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(SUCCESS, "waiting for Proxmark to appear on %s ", argv[1]);
|
|
||||||
fflush(stdout);
|
|
||||||
int openCount = 0;
|
|
||||||
do {
|
|
||||||
sp = uart_open(argv[1]);
|
|
||||||
msleep(500);
|
|
||||||
printf("."); fflush(stdout);
|
|
||||||
} while (++openCount < 30 && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT));
|
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// check result of uart opening
|
|
||||||
if (sp == INVALID_SERIAL_PORT) {
|
|
||||||
PrintAndLogEx(WARNING, "ERROR: invalid serial port");
|
|
||||||
usb_present = false;
|
|
||||||
offline = 1;
|
|
||||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
|
||||||
PrintAndLogEx(WARNING, "ERROR: serial port is claimed by another process");
|
|
||||||
usb_present = false;
|
|
||||||
offline = 1;
|
|
||||||
} else {
|
|
||||||
usb_present = true;
|
|
||||||
offline = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fflush(NULL);
|
|
||||||
// create a mutex to avoid interlacing print commands from our different threads
|
|
||||||
pthread_mutex_init(&print_lock, NULL);
|
|
||||||
|
|
||||||
|
|
||||||
|
printf("\x1b[31m test\n");
|
||||||
#ifdef HAVE_GUI
|
#ifdef HAVE_GUI
|
||||||
|
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
|
@ -527,8 +375,10 @@ int main(int argc, char* argv[]) {
|
||||||
main_loop(script_cmds_file, script_cmd, usb_present);
|
main_loop(script_cmds_file, script_cmd, usb_present);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// clean up mutex
|
// Clean up the port
|
||||||
pthread_mutex_destroy(&print_lock);
|
if (usb_present) {
|
||||||
|
CloseProxmark();
|
||||||
|
}
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
|
@ -21,14 +21,10 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void SendCommand(UsbCommand *c);
|
|
||||||
const char *get_my_executable_path(void);
|
const char *get_my_executable_path(void);
|
||||||
const char *get_my_executable_directory(void);
|
const char *get_my_executable_directory(void);
|
||||||
void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present);
|
void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present);
|
||||||
|
|
||||||
bool hookUpPM3(void);
|
|
||||||
void *uart_receiver(void *targ);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
|
#include "comms.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "mifarehost.h"
|
#include "mifarehost.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
11
client/ui.c
11
client/ui.c
|
@ -13,8 +13,7 @@
|
||||||
|
|
||||||
double CursorScaleFactor = 1;
|
double CursorScaleFactor = 1;
|
||||||
int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
|
int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
|
||||||
int offline;
|
bool flushAfterWrite = 0;
|
||||||
int g_flushAfterWrite = 0; //buzzy
|
|
||||||
int GridOffset = 0;
|
int GridOffset = 0;
|
||||||
bool GridLocked = false;
|
bool GridLocked = false;
|
||||||
bool showDemod = true;
|
bool showDemod = true;
|
||||||
|
@ -178,7 +177,7 @@ void PrintAndLog(char *fmt, ...) {
|
||||||
}
|
}
|
||||||
va_end(argptr2);
|
va_end(argptr2);
|
||||||
|
|
||||||
if (g_flushAfterWrite == 1)
|
if (flushAfterWrite)
|
||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
|
|
||||||
//release lock
|
//release lock
|
||||||
|
@ -189,7 +188,11 @@ void SetLogFilename(char *fn) {
|
||||||
logfilename = fn;
|
logfilename = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iceIIR_Butterworth(int *data, const size_t len){
|
void SetFlushAfterWrite(bool value) {
|
||||||
|
flushAfterWrite = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iceIIR_Butterworth(int *data, const size_t len){
|
||||||
|
|
||||||
int i,j;
|
int i,j;
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,13 @@ extern void PrintAndLog(char *fmt, ...);
|
||||||
void PrintAndLogOptions(char *str[][2], size_t size, size_t space);
|
void PrintAndLogOptions(char *str[][2], size_t size, size_t space);
|
||||||
void PrintAndLogEx(logLevel_t level, char *fmt, ...);
|
void PrintAndLogEx(logLevel_t level, char *fmt, ...);
|
||||||
extern void SetLogFilename(char *fn);
|
extern void SetLogFilename(char *fn);
|
||||||
|
void SetFlushAfterWrite(bool value);
|
||||||
|
|
||||||
extern double CursorScaleFactor;
|
extern double CursorScaleFactor;
|
||||||
extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
|
extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
|
||||||
extern bool GridLocked;
|
extern bool GridLocked;
|
||||||
extern bool showDemod;
|
extern bool showDemod;
|
||||||
|
|
||||||
extern int offline;
|
|
||||||
extern int g_flushAfterWrite; //buzzy
|
|
||||||
//extern uint8_t g_debugMode;
|
//extern uint8_t g_debugMode;
|
||||||
|
|
||||||
extern pthread_mutex_t print_lock;
|
extern pthread_mutex_t print_lock;
|
||||||
|
|
37
common/cmd.c
37
common/cmd.c
|
@ -31,29 +31,9 @@
|
||||||
*/
|
*/
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
|
||||||
bool cmd_receive(UsbCommand* cmd) {
|
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len) {
|
||||||
|
|
||||||
// Check if there is a usb packet available
|
|
||||||
if (!usb_poll_validate_length()) return false;
|
|
||||||
|
|
||||||
// Try to retrieve the available command frame
|
|
||||||
usb_read((uint8_t*)cmd, sizeof(UsbCommand));
|
|
||||||
|
|
||||||
// (iceman) this check is wrong. Since USB can send packages which is not sizeof(usbcommand) 544 bytes.
|
|
||||||
// hence, I comment it out
|
|
||||||
|
|
||||||
// Check if the transfer was complete
|
|
||||||
//if (rxlen != sizeof(UsbCommand)) return false;
|
|
||||||
// Received command successfully
|
|
||||||
//return true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len) {
|
|
||||||
|
|
||||||
UsbCommand txcmd;
|
UsbCommand txcmd;
|
||||||
|
|
||||||
// 0x00 the whole command.
|
|
||||||
for (size_t i=0; i < sizeof(UsbCommand); i++)
|
for (size_t i=0; i < sizeof(UsbCommand); i++)
|
||||||
((uint8_t*)&txcmd)[i] = 0x00;
|
((uint8_t*)&txcmd)[i] = 0x00;
|
||||||
|
|
||||||
|
@ -70,10 +50,15 @@ bool cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* d
|
||||||
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
|
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send frame and make sure all bytes are transmitted
|
|
||||||
if ( usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand)) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
uint32_t sendlen = 0;
|
||||||
|
// Send frame and make sure all bytes are transmitted
|
||||||
|
sendlen = usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand) );
|
||||||
|
|
||||||
|
#ifdef WITH_FPC
|
||||||
|
usart_init();
|
||||||
|
usart_writebuffer( (uint8_t*)&txcmd, sizeof(UsbCommand) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return sendlen;
|
||||||
}
|
}
|
|
@ -39,8 +39,7 @@
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
|
|
||||||
bool cmd_receive(UsbCommand* cmd);
|
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len);
|
||||||
bool cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len);
|
|
||||||
|
|
||||||
#endif // _PROXMARK_CMD_H_
|
#endif // _PROXMARK_CMD_H_
|
||||||
|
|
||||||
|
|
316
common/usart.c
316
common/usart.c
|
@ -1,17 +1,23 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Iceman, July 2018
|
||||||
|
// edists by - Anticat, August 2018
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// The main USART code, for serial communications over FPC connector
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "apps.h"
|
#include "string.h"
|
||||||
|
|
||||||
#define USART_INTERRUPT_LEVEL 7
|
|
||||||
#define AT91_BAUD_RATE 115200
|
#define AT91_BAUD_RATE 115200
|
||||||
|
|
||||||
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
|
|
||||||
volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
|
volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
|
||||||
volatile AT91PS_AIC pAIC = AT91C_BASE_AIC;
|
|
||||||
volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
|
volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
|
||||||
|
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
|
||||||
|
|
||||||
#define usart_rx_ready {(pUS1->US_CSR & AT91C_US_RXRDY)}
|
/*
|
||||||
#define usart_tx_ready {(pUS1->US_CSR & AT91C_US_TXRDY)}
|
|
||||||
|
|
||||||
void usart_close(void) {
|
void usart_close(void) {
|
||||||
// Reset the USART mode
|
// Reset the USART mode
|
||||||
pUS1->US_MR = 0;
|
pUS1->US_MR = 0;
|
||||||
|
@ -25,259 +31,155 @@ void usart_close(void) {
|
||||||
// Disable all interrupts
|
// Disable all interrupts
|
||||||
pUS1->US_IDR = 0xFFFFFFFF;
|
pUS1->US_IDR = 0xFFFFFFFF;
|
||||||
|
|
||||||
//* Abort the Peripheral Data Transfers
|
// Abort the Peripheral Data Transfers
|
||||||
//AT91F_PDC_Close((AT91PS_PDC) &(pUSART->US_RPR));
|
pUS1->US_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
|
||||||
|
|
||||||
// Disable receiver and transmitter and stop any activity immediately
|
// Disable receiver and transmitter and stop any activity immediately
|
||||||
pUS1->US_CR = AT91C_US_TXDIS | AT91C_US_RXDIS | AT91C_US_RSTTX | AT91C_US_RSTRX;
|
pUS1->US_CR = AT91C_US_TXDIS | AT91C_US_RXDIS | AT91C_US_RSTTX | AT91C_US_RSTRX;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/// Reads data from an USART peripheral, filling the provided buffer until it
|
static uint8_t outbuf[sizeof(UsbCommand)];
|
||||||
/// becomes full. This function returns immediately with 1 if the buffer has
|
//static uint8_t inbuf[sizeof(UsbCommand)];
|
||||||
/// been queued for transmission; otherwise 0.
|
|
||||||
|
|
||||||
|
/// Reads data from an USART peripheral
|
||||||
/// \param data Pointer to the buffer where the received data will be stored.
|
/// \param data Pointer to the buffer where the received data will be stored.
|
||||||
/// \param len Size of the data buffer (in bytes).
|
/// \param len Size of the data buffer (in bytes).
|
||||||
uint8_t usart_readbuffer(uint8_t *data, size_t len) {
|
inline int usart_readbuffer(uint8_t *data, size_t len) {
|
||||||
|
|
||||||
|
pUS1->US_PTSR = AT91C_PDC_TXTEN;
|
||||||
|
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
||||||
|
|
||||||
// Check if the first PDC bank is free
|
// Check if the first PDC bank is free
|
||||||
if ((pUS1->US_RCR == 0) && (pUS1->US_RNCR == 0)) {
|
if (!(pUS1->US_RCR)) {
|
||||||
|
|
||||||
pUS1->US_RPR = (uint32_t)data;
|
pUS1->US_RPR = (uint32_t)data;
|
||||||
pUS1->US_RCR = len;
|
pUS1->US_RCR = len;
|
||||||
pUS1->US_PTCR = AT91C_PDC_RXTEN;
|
return 2;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
// Check if the second PDC bank is free
|
// Check if the second PDC bank is free
|
||||||
else if (pUS1->US_RNCR == 0) {
|
else if (!(pUS1->US_RNCR)) {
|
||||||
|
|
||||||
pUS1->US_RNPR = (uint32_t)data;
|
pUS1->US_RNPR = (uint32_t)data;
|
||||||
pUS1->US_RNCR = len;
|
pUS1->US_RNCR = len;
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pPDC->PDC_PTSR = AT91C_PDC_RXTEN;
|
||||||
|
pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||||
|
|
||||||
|
//check if data is available
|
||||||
|
if (pPDC->PDC_RCR != 0) return -1;
|
||||||
|
|
||||||
|
memcpy(data, inbuf, len);
|
||||||
|
|
||||||
|
//start next transfer
|
||||||
|
pPDC->PDC_RNPR = (uint32_t)inbuf;
|
||||||
|
pPDC->PDC_RNCR = sizeof(inbuf);
|
||||||
|
|
||||||
|
return sizeof(inbuf);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
int16_t usart_writebuffer(uint8_t *data, size_t len) {
|
||||||
|
|
||||||
/// Reads and return a packet of data on the specified USART peripheral. This
|
// pUS1->US_PTSR = AT91C_PDC_TXTEN;
|
||||||
/// function operates asynchronously, so it waits until some data has been
|
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
||||||
/// received.
|
|
||||||
/// \param timeout Time out value (0 -> no timeout).
|
// if buffer is sent
|
||||||
uint8_t usart_read(uint32_t timeout) {
|
if (pUS1->US_TCR != 0) return -1;
|
||||||
if (timeout == 0) {
|
|
||||||
while ((pUS1->US_CSR & AT91C_US_RXRDY) == 0) {};
|
memcpy(outbuf, data, len);
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
while ((pUS1->US_CSR & AT91C_US_RXRDY) == 0) {
|
//start next transfer
|
||||||
|
pUS1->US_TNPR = (uint32_t)outbuf;
|
||||||
|
pUS1->US_TNCR = sizeof(outbuf);
|
||||||
|
|
||||||
if (timeout == 0) {
|
return sizeof(outbuf);
|
||||||
|
|
||||||
DbpString("USART_Read: Timed out.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
timeout--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint8_t res = pUS1->US_RHR;
|
|
||||||
Dbprintf(" usar got %02x", res);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/// Sends one packet of data through the specified USART peripheral. This
|
// works.
|
||||||
/// function operates synchronously, so it only returns when the data has been
|
// transfer to client
|
||||||
/// actually sent.
|
inline int16_t usart_writebuffer(uint8_t *data, size_t len) {
|
||||||
/// \param data Data to send including 9nth bit and sync field if necessary (in
|
|
||||||
/// the same format as the US_THR register in the datasheet).
|
|
||||||
/// \param timeOut Time out value (0 = no timeout).
|
|
||||||
void usart_write( uint8_t data, uint32_t timeout) {
|
|
||||||
if ( timeout == 0) {
|
|
||||||
|
|
||||||
while ((pUS1->US_CSR & AT91C_US_TXEMPTY) == 0) {};
|
|
||||||
|
|
||||||
} else {
|
|
||||||
while ((pUS1->US_CSR & AT91C_US_TXEMPTY) == 0) {
|
|
||||||
|
|
||||||
if (timeout == 0) {
|
|
||||||
DbpString("USART_Write: Timed out.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
timeout--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pUS1->US_THR = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t usart_writebuffer(uint8_t *data, size_t len, uint32_t timeout) {
|
|
||||||
|
|
||||||
|
pUS1->US_PTSR = AT91C_PDC_TXTEN;
|
||||||
|
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
||||||
|
|
||||||
// Check if the first PDC bank is free
|
// Check if the first PDC bank is free
|
||||||
if ((pUS1->US_TCR == 0) && (pUS1->US_TNCR == 0)) {
|
if (!(pUS1->US_TCR)) {
|
||||||
|
|
||||||
pUS1->US_TPR = (uint32_t)data;
|
memcpy(outbuf, data, len);
|
||||||
pUS1->US_TCR = len;
|
|
||||||
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
pUS1->US_TPR = (uint32_t)outbuf;
|
||||||
return 1;
|
pUS1->US_TCR = sizeof(outbuf);
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
// Check if the second PDC bank is free
|
// Check if the second PDC bank is free
|
||||||
else if (pUS1->US_TNCR == 0) {
|
else if (!(pUS1->US_TNCR)) {
|
||||||
|
memcpy(outbuf, data, len);
|
||||||
pUS1->US_TNPR = (uint32_t)data;
|
|
||||||
pUS1->US_TNCR = len;
|
pUS1->US_TNPR = (uint32_t)outbuf;
|
||||||
return 1;
|
pUS1->US_TNCR = sizeof(outbuf);
|
||||||
}
|
return 1;
|
||||||
else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// interupt version
|
|
||||||
void Usart_c_irq_handler(void) {
|
|
||||||
|
|
||||||
// get Usart status register
|
|
||||||
uint32_t status = pUS1->US_CSR;
|
|
||||||
|
|
||||||
if ( status & AT91C_US_RXRDY){
|
|
||||||
// Get byte and send
|
|
||||||
pUS1->US_THR = (pUS1->US_RHR & 0x1FF);
|
|
||||||
LED_B_INV();
|
|
||||||
}
|
|
||||||
// tx
|
|
||||||
if ( status & AT91C_US_TXRDY){
|
|
||||||
LED_D_INV();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( status & AT91C_US_OVRE) {
|
|
||||||
// clear US_RXRDY
|
|
||||||
(void)(pUS1->US_RHR & 0x1FF);
|
|
||||||
pUS1->US_THR = ('O' & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check error
|
|
||||||
if ( status & AT91C_US_PARE) {
|
|
||||||
pUS1->US_THR = ('P' & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( status & AT91C_US_FRAME) {
|
|
||||||
pUS1->US_THR = ('F' & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( status & AT91C_US_TIMEOUT){
|
|
||||||
pUS1->US_CR = AT91C_US_STTTO;
|
|
||||||
pUS1->US_THR = ('T' & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the status bit
|
|
||||||
pUS1->US_CR = AT91C_US_RSTSTA;
|
|
||||||
}
|
|
||||||
|
|
||||||
__inline unsigned int AT91F_AIC_ConfigureIt (
|
|
||||||
AT91PS_AIC pAIC, // \arg pointer to the AIC registers
|
|
||||||
unsigned int irq_id, // \arg interrupt number to initialize
|
|
||||||
unsigned int priority, // \arg priority to give to the interrupt
|
|
||||||
unsigned int src_type, // \arg activation and sense of activation
|
|
||||||
void (*newHandler) (void) ) // \arg address of the interrupt handler
|
|
||||||
{
|
|
||||||
unsigned int oldHandler;
|
|
||||||
unsigned int mask;
|
|
||||||
|
|
||||||
oldHandler = pAIC->AIC_SVR[irq_id];
|
|
||||||
|
|
||||||
mask = (0x1 << irq_id);
|
|
||||||
// Disable the interrupt on the interrupt controller
|
|
||||||
pAIC->AIC_IDCR = mask;
|
|
||||||
// Save the interrupt handler routine pointer and the interrupt priority
|
|
||||||
pAIC->AIC_SVR[irq_id] = (unsigned int) newHandler;
|
|
||||||
// Store the Source Mode Register
|
|
||||||
pAIC->AIC_SMR[irq_id] = (src_type | priority);
|
|
||||||
// Clear the interrupt on the interrupt controller
|
|
||||||
pAIC->AIC_ICCR = mask;
|
|
||||||
|
|
||||||
return oldHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usart_init(void) {
|
void usart_init(void) {
|
||||||
|
|
||||||
|
// disable & reset receiver / transmitter for configuration
|
||||||
|
pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX);
|
||||||
|
|
||||||
// disable & reset receiver / transmitter
|
//enable the USART1 Peripheral clock
|
||||||
pUS1->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
|
|
||||||
|
|
||||||
//enable the USART 1 Peripheral clock
|
|
||||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
|
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
|
||||||
|
|
||||||
// Configure PIO controllers to peripheral mode A
|
|
||||||
pPIOA->PIO_ASR = (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
|
||||||
|
|
||||||
// Disable PIO control of the following pins, allows use by the SPI peripheral
|
|
||||||
pPIOA->PIO_PDR = (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
|
||||||
|
|
||||||
// kill pull-ups
|
// disable PIO control of receive / transmit pins
|
||||||
// pPIOA->PIO_PPUDR = ~(AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
pPIOA->PIO_PDR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||||
// pPIOA->PIO_MDDR = (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
|
||||||
|
|
||||||
// Pull-up Enable
|
// enable peripheral mode A on receive / transmit pins
|
||||||
|
pPIOA->PIO_ASR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||||
|
|
||||||
|
// enable pull-up on receive / transmit pins (see 31.5.1 I/O Lines)
|
||||||
pPIOA->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
pPIOA->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||||
// MultiDriver Enable
|
|
||||||
//pPIOA->PIO_MDER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
|
||||||
|
|
||||||
// Enable the pins to be controlled
|
|
||||||
pPIOA->PIO_PER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
|
||||||
|
|
||||||
// Configure the pins to be outputs
|
|
||||||
pPIOA->PIO_OER |= AT91C_PA22_TXD1;
|
|
||||||
|
|
||||||
//enable PIO in input mode
|
|
||||||
//pPIOA->PIO_ODR = AT91C_PA21_RXD1;
|
|
||||||
|
|
||||||
// set mode
|
// set mode
|
||||||
pUS1->US_MR = AT91C_US_USMODE_NORMAL | // normal mode
|
pUS1->US_MR = AT91C_US_USMODE_NORMAL | // normal mode
|
||||||
AT91C_US_CLKS_CLOCK | // MCK
|
AT91C_US_CLKS_CLOCK | // MCK (48MHz)
|
||||||
AT91C_US_CHRL_8_BITS | // 8 bits
|
AT91C_US_CHRL_8_BITS | // 8 bits
|
||||||
AT91C_US_PAR_NONE | // parity: none
|
AT91C_US_PAR_NONE | // parity: none
|
||||||
AT91C_US_NBSTOP_1_BIT | // 1 stop bit
|
AT91C_US_NBSTOP_1_BIT | // 1 stop bit
|
||||||
AT91C_US_CHMODE_NORMAL; // channel mode: normal
|
AT91C_US_CHMODE_NORMAL; // channel mode: normal
|
||||||
|
|
||||||
// baud rate
|
// set baudrate to 115200
|
||||||
// CD = MCK / (16 * baud)
|
pUS1->US_BRGR = (48UL*1000*1000) / (115200*16);
|
||||||
// MCK = 24027428 (pm3 runs on 24MHZ clock PMC_PCKR[0] )
|
|
||||||
|
|
||||||
|
|
||||||
// baudrate 115200
|
|
||||||
// 16*115200 = 1843200
|
|
||||||
// 24027428 / 1843200 == 13 --< CD
|
|
||||||
|
|
||||||
// baudrate 460800
|
|
||||||
// 16*460800 = 7372800
|
|
||||||
// 24027428 / 7372800 == 3
|
|
||||||
pUS1->US_BRGR = 24*1024*1024/(115200*16); // OVER=0 16
|
|
||||||
|
|
||||||
// Write the Timeguard Register
|
// Write the Timeguard Register
|
||||||
pUS1->US_TTGR = 0;
|
pUS1->US_TTGR = 0;
|
||||||
|
|
||||||
pUS1->US_RTOR = 0;
|
pUS1->US_RTOR = 0;
|
||||||
pUS1->US_FIDI = 0;
|
pUS1->US_FIDI = 0;
|
||||||
pUS1->US_IF = 0;
|
pUS1->US_IF = 0;
|
||||||
|
|
||||||
// Enable USART IT error and RXRDY
|
|
||||||
// Write to the IER register
|
|
||||||
// pUS1->US_IER = (AT91C_US_TIMEOUT | AT91C_US_FRAME | AT91C_US_OVRE | AT91C_US_RXRDY);
|
|
||||||
|
|
||||||
// open Usart 1 interrupt
|
/*
|
||||||
/*
|
//Empty PDC
|
||||||
AT91F_AIC_ConfigureIt(
|
pUS1->US_RNPR = (uint32_t)(char *)0;
|
||||||
pAIC,
|
pUS1->US_RNCR = 0;
|
||||||
AT91C_ID_US1,
|
pUS1->US_RPR = (uint32_t)(char *)0;
|
||||||
USART_INTERRUPT_LEVEL,
|
pUS1->US_RCR = 0;
|
||||||
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
|
|
||||||
Usart_c_irq_handler
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// enable interupt
|
|
||||||
// pAIC->AIC_IECR = (1 << AT91C_ID_US1);
|
|
||||||
|
|
||||||
// trigger interrup software
|
|
||||||
// pAIC->AIC_ISCR = (1 << AT91C_ID_US1) ;
|
|
||||||
|
|
||||||
// enable RX + TX
|
|
||||||
pUS1->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
|
|
||||||
|
|
||||||
|
pUS1->US_TNPR = (uint32_t)(char *)0;
|
||||||
|
pUS1->US_TNCR = 0;
|
||||||
|
pUS1->US_TPR = (uint32_t)(char *)0;
|
||||||
|
pUS1->US_TCR = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
//pUS1->US_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN);
|
||||||
|
//pUS1->US_PTSR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN);
|
||||||
|
|
||||||
|
// re-enable receiver / transmitter
|
||||||
|
pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN);
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,18 +4,9 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
||||||
extern void Dbprintf(const char *fmt, ...);
|
|
||||||
|
|
||||||
void usart_init(void);
|
void usart_init(void);
|
||||||
void usart_close(void);
|
void usart_close(void);
|
||||||
|
|
||||||
uint32_t usart_rx_ready();
|
int usart_readbuffer(uint8_t *data, size_t len);
|
||||||
uint32_t usart_tx_ready();
|
int16_t usart_writebuffer(uint8_t *data, size_t len);
|
||||||
|
|
||||||
uint8_t usart_read(uint32_t timeout);
|
|
||||||
uint8_t usart_readbuffer(uint8_t *data, size_t len);
|
|
||||||
|
|
||||||
void usart_write( uint8_t data, uint32_t timeout);
|
|
||||||
uint8_t usart_writebuffer(uint8_t *data, size_t len, uint32_t timeout);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
14
uart/uart.h
14
uart/uart.h
|
@ -41,6 +41,16 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "util_posix.h" // msclock
|
#include "util_posix.h" // msclock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (_WIN32)
|
||||||
|
#define SERIAL_PORT_H "com3"
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#define SERIAL_PORT_H "/dev/cu.usbmodem"
|
||||||
|
#else
|
||||||
|
#define SERIAL_PORT_H "/dev/ttyACM0"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* serial_port is declared as a void*, which you should cast to whatever type
|
/* serial_port is declared as a void*, which you should cast to whatever type
|
||||||
* makes sense to your connection method. Both the posix and win32
|
* makes sense to your connection method. Both the posix and win32
|
||||||
* implementations define their own structs in place.
|
* implementations define their own structs in place.
|
||||||
|
@ -78,13 +88,13 @@ void uart_close(const serial_port sp);
|
||||||
* partial read may have completed into the buffer by the corresponding
|
* partial read may have completed into the buffer by the corresponding
|
||||||
* implementation, so pszRxLen should be checked to see if any data was written.
|
* implementation, so pszRxLen should be checked to see if any data was written.
|
||||||
*/
|
*/
|
||||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen);
|
bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen);
|
||||||
|
|
||||||
/* Sends a buffer to a given serial port.
|
/* Sends a buffer to a given serial port.
|
||||||
* pbtTx: A pointer to a buffer containing the data to send.
|
* pbtTx: A pointer to a buffer containing the data to send.
|
||||||
* len: The amount of data to be sent.
|
* len: The amount of data to be sent.
|
||||||
*/
|
*/
|
||||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t len);
|
bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t len);
|
||||||
|
|
||||||
/* Sets the current speed of the serial port, in baud.
|
/* Sets the current speed of the serial port, in baud.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -117,10 +117,19 @@ serial_port uart_open(const char* pcPortName)
|
||||||
// Flush all lingering data that may exist
|
// Flush all lingering data that may exist
|
||||||
tcflush(sp->fd, TCIOFLUSH);
|
tcflush(sp->fd, TCIOFLUSH);
|
||||||
|
|
||||||
|
#ifdef WITH_FPC
|
||||||
|
uart_set_speed(sp, 115200);
|
||||||
|
printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n");
|
||||||
|
#else
|
||||||
// set speed, works for UBUNTU 14.04
|
// set speed, works for UBUNTU 14.04
|
||||||
bool err = uart_set_speed(sp, 460800);
|
bool success = uart_set_speed(sp, 460800);
|
||||||
if (!err)
|
if (success) {
|
||||||
uart_set_speed(sp, 115200);
|
printf("[=] UART Setting serial baudrate 460800\n");
|
||||||
|
} else {
|
||||||
|
uart_set_speed(sp, 115200);
|
||||||
|
printf("[=] UART Setting serial baudrate 115200\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +153,7 @@ void uart_close(const serial_port sp) {
|
||||||
free(sp);
|
free(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) {
|
bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) {
|
||||||
int res;
|
int res;
|
||||||
int byteCount;
|
int byteCount;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
|
@ -156,9 +165,9 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_
|
||||||
do {
|
do {
|
||||||
// Reset file descriptor
|
// Reset file descriptor
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(((serial_port_unix*)sp)->fd,&rfds);
|
FD_SET(((serial_port_unix*)sp)->fd, &rfds);
|
||||||
tv = timeout;
|
tv = timeout;
|
||||||
res = select(((serial_port_unix*)sp)->fd+1, &rfds, NULL, NULL, &tv);
|
res = select(((serial_port_unix*)sp)->fd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
|
||||||
// Read error
|
// Read error
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -186,7 +195,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is something available, read the data
|
// There is something available, read the data
|
||||||
res = read(((serial_port_unix*)sp)->fd, pbtRx+(*pszRxLen), byteCount);
|
res = read(((serial_port_unix*)sp)->fd, pbtRx + (*pszRxLen), byteCount);
|
||||||
|
|
||||||
// Stop if the OS has some troubles reading the data
|
// Stop if the OS has some troubles reading the data
|
||||||
if (res <= 0) return false;
|
if (res <= 0) return false;
|
||||||
|
@ -203,7 +212,7 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t len) {
|
bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t len) {
|
||||||
int32_t res;
|
int32_t res;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
|
@ -229,13 +238,10 @@ bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send away the bytes
|
// Send away the bytes
|
||||||
res = write(((serial_port_unix*)sp)->fd, pbtTx+pos, len-pos);
|
res = write(((serial_port_unix*)sp)->fd, pbtTx + pos, len - pos);
|
||||||
|
|
||||||
// Stop if the OS has some troubles sending the data
|
// Stop if the OS has some troubles sending the data
|
||||||
if (res <= 0) {
|
if (res <= 0) return false;
|
||||||
printf("UART:: os troubles (%d)\n", res);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += res;
|
pos += res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,16 +47,6 @@ typedef struct {
|
||||||
DCB dcb; // Device control settings
|
DCB dcb; // Device control settings
|
||||||
COMMTIMEOUTS ct; // Serial port time-out configuration
|
COMMTIMEOUTS ct; // Serial port time-out configuration
|
||||||
} serial_port_windows;
|
} serial_port_windows;
|
||||||
/*
|
|
||||||
void upcase(char *p) {
|
|
||||||
while(*p != '\0') {
|
|
||||||
if(*p >= 97 && *p <= 122) {
|
|
||||||
*p -= 32;
|
|
||||||
}
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
serial_port uart_open(const char* pcPortName) {
|
serial_port uart_open(const char* pcPortName) {
|
||||||
char acPortName[255];
|
char acPortName[255];
|
||||||
|
@ -110,10 +100,17 @@ serial_port uart_open(const char* pcPortName) {
|
||||||
|
|
||||||
PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
||||||
|
|
||||||
|
#ifdef WITH_FPC
|
||||||
|
uart_set_speed(sp, 115200);
|
||||||
|
#else
|
||||||
bool success = uart_set_speed(sp, 460800);
|
bool success = uart_set_speed(sp, 460800);
|
||||||
if (!success)
|
if (success) {
|
||||||
|
printf("[=] UART Setting serial baudrate 460800\n");
|
||||||
|
} else {
|
||||||
uart_set_speed(sp, 115200);
|
uart_set_speed(sp, 115200);
|
||||||
|
printf("[=] UART Setting serial baudrate 115200\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,32 +152,13 @@ uint32_t uart_get_speed(const serial_port sp) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_receive(const serial_port sp, byte_t* p_rx, size_t pszMaxRxLen, size_t* p_rxlen) {
|
bool uart_receive(const serial_port sp, uint8_t* p_rx, size_t pszMaxRxLen, size_t* len) {
|
||||||
int res = ReadFile(((serial_port_windows*)sp)->hPort, p_rx, pszMaxRxLen, (LPDWORD)p_rxlen, NULL);
|
return ReadFile(((serial_port_windows*)sp)->hPort, p_rx, pszMaxRxLen, (LPDWORD)len, NULL);
|
||||||
if ( res == 0 ) {
|
|
||||||
//printf("[!] UART error reading from port\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool read_test = ( pszMaxRxLen == *p_rxlen );
|
|
||||||
if ( !read_test && *p_rxlen > 0 ) {
|
|
||||||
printf("[!] UART error, not all data read from port len %u | read %u\n", pszMaxRxLen, *p_rxlen);
|
|
||||||
}
|
|
||||||
return read_test;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_send(const serial_port sp, const byte_t* p_tx, const size_t len) {
|
bool uart_send(const serial_port sp, const uint8_t* p_tx, const size_t len) {
|
||||||
DWORD txlen = 0;
|
DWORD txlen = 0;
|
||||||
int res = WriteFile(((serial_port_windows*)sp)->hPort, p_tx, len, &txlen, NULL);
|
return WriteFile(((serial_port_windows*)sp)->hPort, p_tx, len, &txlen, NULL);
|
||||||
if ( res == 0) {
|
|
||||||
printf("[!] UART error writing to port\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool write_test = ( len == txlen );
|
|
||||||
if ( !write_test ) {
|
|
||||||
printf("[!] UART error, not all data written to port len %u | sent %lu\n", len, txlen);
|
|
||||||
}
|
|
||||||
return write_test;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue