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:
Chris 2018-09-06 21:43:20 +02:00
commit 24eaac8681
45 changed files with 915 additions and 949 deletions

View file

@ -104,7 +104,7 @@ ifneq (,$(findstring WITH_HF_MATTYRUN,$(APP_CFLAGS)))
endif
# WITH_HF_COLIN
ifneq (,$(findstring WITH_HF_COLIN,$(APP_CFLAGS)))
SRC_STANDALONE = hf_colin.c vtsend.c
SRC_STANDALONE = vtsend.c hf_colin.c
endif
#the FPGA bitstream files. Note: order matters!

View file

@ -441,7 +441,7 @@ void printStandAloneModes(void) {
DbpString(" LF HID corporate 1000 bruteforce - (Federico dotta & Maurizio Agazzini)");
#endif
#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
#if defined(WITH_HF_COLIN)
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
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++;
uint8_t got = usart_read(10000);
if ( got > 0 ) {
Dbprintf("got %02x", got);
usart_write(got, 10000);
sprintf(dest + strlen(dest) - 1, "Arg0 | 0x%" PRIx64 " \n", c->arg[0]);
sprintf(dest + strlen(dest) - 1, "Arg1 | 0x%" PRIx64 " \n", c->arg[1]);
sprintf(dest + strlen(dest) - 1, "Arg2 | 0x%" PRIx64 " \n", c->arg[2]);
sprintf(dest + strlen(dest) - 1, "bytes | 0x%02x 0x%02x 0x%02x 0x%02x \n"
,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);
break;
}
@ -1114,7 +1144,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
for(size_t i = 0; i < 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);
if (!isok)
if (isok != 0)
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
}
// 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) {
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len);
if (!isok)
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
if (isok != 0)
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
}
// Trigger a finish downloading signal with an ACK frame
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
@ -1180,7 +1210,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
uint16_t isok = 0;
uint32_t startidx = c->arg[0];
uint16_t len = c->arg[1];
//uint8_t fast = c->arg[2];
Dbprintf("FlashMem read | %d - %d | ", startidx, len);
@ -1285,8 +1314,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
size_t len = 0;
uint32_t startidx = c->arg[0];
uint32_t numofbytes = c->arg[1];
//uint8_t fast = c->arg[2];
// arg0 = startindex
// arg1 = length bytes to transfer
// arg2 = RFU
@ -1301,7 +1328,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, 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);
}
FlashStop();
@ -1458,19 +1485,20 @@ void __attribute__((noreturn)) AppMain(void) {
for(;;) {
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
if ( cmd_receive( (UsbCommand*)rx ) ) {
UsbPacketReceived(rx, sizeof(UsbCommand) );
if (usb_poll_validate_length()) {
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
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) )
RunMod();
#endif
}
}
}

View file

@ -230,8 +230,8 @@ void WritePageHitagS(hitag_function htf, hitag_data* htd,int page);
void check_challenges(bool file_given, byte_t* data);
// cmd.h
bool 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_receive(UsbCommand* cmd);
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len);
// util.h
void HfSnoop(int , int);

View file

@ -27,7 +27,7 @@
#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_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

View file

@ -191,7 +191,7 @@ static void flash_mode(int externally_entered) {
start_addr = 0;
end_addr = 0;
bootrom_unlocked = 0;
byte_t rx[sizeof(UsbCommand)];
uint8_t rx[sizeof(UsbCommand)];
usb_enable();
@ -200,10 +200,12 @@ static void flash_mode(int externally_entered) {
for(;;) {
WDT_HIT();
// Check if there is a usb packet available
if ( cmd_receive( (UsbCommand*)rx ) )
UsbPacketReceived(rx, sizeof(UsbCommand) );
if (usb_poll_validate_length()) {
if (usb_read(rx, sizeof(rx)) )
UsbPacketReceived(rx, sizeof(rx));
}
if (!externally_entered && !BUTTON_PRESS()) {
/* Perform a reset to leave flash mode */

View file

@ -82,7 +82,7 @@ else
endif
# 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
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
@ -94,7 +94,8 @@ CORESRCS = uart_posix.c \
ui.c \
util.c \
util_posix.c \
scandir.c
scandir.c \
comms.c
CMDSRCS = crapto1/crapto1.c \
crapto1/crypto1.c \

View file

@ -515,6 +515,7 @@ int CmdAnalyseA(const char *Cmd){
UsbCommand c = {CMD_FPC_SEND, {0, 0, 0}};
memcpy(c.d.asBytes, data, USB_CMD_DATA_SIZE);
clearCommandBuffer();
SendCommand(&c);
@ -522,7 +523,7 @@ int CmdAnalyseA(const char *Cmd){
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
return 1;
}
PrintAndLogEx(NORMAL, "got ack");
PrintAndLogEx(NORMAL, "got ack. Status %d", resp.arg[0]);
return 0;
PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");

View file

@ -25,7 +25,7 @@
#include "proxmark3.h" // sendcommand
#include "ui.h" // for show graph controls
#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 "crc.h" // for pyramid checksum maxim
#include "crc16.h" // for FDXB demod checksum

View file

@ -22,7 +22,7 @@
#include "util.h"
#include "util_posix.h" // msclock
#include "loclass/fileutils.h" //saveFile
#include "cmdmain.h" //getfromdevice
#include "comms.h" //getfromdevice
extern int CmdFlashMem(const char *Cmd);

View file

@ -21,7 +21,7 @@
#include "ui.h"
#include "util.h"
#include "cmdparser.h"
#include "cmdmain.h"
#include "comms.h" // getfromdevice
#include "iso14443crc.h"
#include "cmdhf.h" // list cmd
#include "mifare.h" // felica_card_select_t struct

View file

@ -21,7 +21,7 @@
#include "cmdparser.h"
#include "common.h"
#include "util.h"
#include "cmdmain.h"
#include "comms.h"
#include "des.h"
#include "loclass/cipherutils.h"
#include "loclass/cipher.h"

View file

@ -16,7 +16,7 @@
#include "proxmark3.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdmain.h"
#include "comms.h"
#include "util.h"
#include "crc.h"
#include "legic_prng.h"

View file

@ -9,6 +9,7 @@
#include "mifare.h"
#include "util.h"
#include "protocols.h"
#include "comms.h"
typedef struct {
uint8_t version[8];

View file

@ -320,7 +320,7 @@ int CmdLFSetConfig(const char *Cmd) {
}
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}};
clearCommandBuffer();
SendCommand(&c);
@ -342,7 +342,7 @@ bool lf_read(bool silent, uint32_t samples) {
int CmdLFRead(const char *Cmd) {
if (offline) return 0;
if ( IsOffline() ) return 0;
bool errors = false;
bool silent = false;
@ -844,7 +844,7 @@ int CmdLFfind(const char *Cmd) {
if (cmdp == 'u') testRaw = 'u';
bool isOnline = (!offline && (cmdp != '1') );
bool isOnline = (!IsOffline() && (cmdp != '1') );
if (isOnline)
lf_read(true, 30000);

View file

@ -539,7 +539,7 @@ int CmdAWIDBrute(const char *Cmd) {
// main loop
for (;;){
if ( offline ) {
if ( IsOffline() ) {
PrintAndLogEx(WARNING, "Device offline\n");
return 2;
}

View file

@ -15,7 +15,7 @@
#include "util.h" // FALSE / TRUE
#include "cmddata.h" // getSamples
#include "cmdparser.h" // CmdsParse, CmdsHelp
#include "cmdmain.h"
#include "comms.h"
#include "ui.h" // PrintAndLog
#include "cmdlf.h" // Setconfig

View file

@ -21,8 +21,7 @@
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdmain.h"
#include "cmdmain.h"
#include "comms.h"
#include "cmdlf.h"
#include "lfdemod.h"

View file

@ -544,7 +544,7 @@ int CmdHIDBrute(const char *Cmd){
// main loop
for (;;){
if ( offline ) {
if ( IsOffline() ) {
PrintAndLogEx(WARNING, "Device offline\n");
return 2;
}

View file

@ -20,7 +20,7 @@
#include "hitag2.h"
#include "hitagS.h"
#include "util_posix.h"
#include "cmdmain.h"
#include "comms.h"
#include "cmddata.h"
static int CmdHelp(const char *Cmd);

View file

@ -122,7 +122,7 @@ int CmdIndalaDemod(const char *Cmd) {
ans = PSKDemod("32", 0);
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;
}

View file

@ -452,7 +452,7 @@ bool DecodeT5555TraceBlock() {
// sanity check. Don't use proxmark if it is offline and you didn't specify useGraphbuf
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");
return 0;
}
@ -466,13 +466,11 @@ int CmdT55xxDetect(const char *Cmd){
uint32_t password = 0;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) {
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch ( tolower(param_getchar(Cmd, cmdp))) {
case 'h':
case 'H':
return usage_t55xx_detect();
case 'p':
case 'P':
password = param_get32ex(Cmd, cmdp+1, 0, 16);
usepwd = true;
cmdp += 2;
@ -1572,7 +1570,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
uint64_t testpwd = 0x00;
for (uint16_t c = 0; c < keycnt; ++c ) {
if ( offline ) {
if ( IsOffline() ) {
PrintAndLogEx(WARNING, "Device offline\n");
free(keyBlock);
return 2;

View file

@ -18,7 +18,7 @@
#include "proxmark3.h"
#include "ui.h"
#include "graph.h"
#include "cmdmain.h"
#include "comms.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdlf.h"

View file

@ -15,18 +15,6 @@ static int CmdQuit(const char *Cmd);
static int CmdRev(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[] = {
{"help", CmdHelp, 1, "This help. Use '<command> help' for details of a particular command."},
{"analyse", CmdAnalyse, 1, "{ Analyse utils... }"},
@ -38,7 +26,7 @@ static command_t CommandTable[] = {
{"reveng", CmdRev, 1, "{ Crc calculations from the software reveng 1.53... }"},
{"script", CmdScript, 1, "{ Scripting commands }"},
{"trace", CmdTrace, 1, "{ Trace manipulation... }"},
#ifdef WITH_FLASH
#ifdef WITH_FLASH
{"mem", CmdFlashMem, 1, "{ RDV40, Flash Memory manipulation... }"},
#endif
#ifdef WITH_SMARTCARD
@ -79,286 +67,10 @@ int CmdRev(const char *Cmd) {
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
// then presses Enter, which the full command line that they typed.
//-----------------------------------------------------------------------------
int CommandReceived(char *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;
}
}

View file

@ -13,7 +13,6 @@
#include <stdint.h>
#include <stddef.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -24,7 +23,6 @@
#include "util.h"
#include "ui.h"
#include "cmdparser.h"
#include "loclass/fileutils.h"
#include "cmdhf.h"
#include "cmddata.h"
#include "cmdhw.h"
@ -33,26 +31,16 @@
#include "cmdscript.h"
#include "cmdcrc.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
#define CMD_BUFFER_SIZE 100
typedef enum {
BIG_BUF,
BIG_BUF_EML,
FLASH_MEM,
SIM_MEM,
} DeviceMemType_t;
extern void UsbCommandReceived(UsbCommand *c);
#ifdef WITH_FLASH
#include "cmdflashmem.h" // rdv40 flashmem commands
#endif
#ifdef WITH_SMARTCARD
#include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands
#endif
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 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

View file

@ -15,12 +15,13 @@
#include "ui.h"
#include "cmdparser.h"
#include "proxmark3.h"
#include "comms.h"
void CmdsHelp(const command_t Commands[]) {
if (Commands[0].Name == NULL) return;
int i = 0;
while (Commands[i].Name) {
if (!offline || Commands[i].Offline)
if (!IsOffline() || Commands[i].Offline)
PrintAndLogEx(NORMAL, "%-16s %s", Commands[i].Name, Commands[i].Help);
++i;
}

View file

@ -24,6 +24,7 @@
#include "graph.h"
#include "cmdparser.h"
#include "cmdmain.h"
#include "comms.h"
#include "cmdscript.h"
#include "cmdhfmf.h"
#include "pm3_binlib.h"

View file

@ -21,7 +21,7 @@
#include "common.h"
#include "util.h"
#include "loclass/fileutils.h" // saveFile
#include "cmdmain.h" // getfromdevice
#include "comms.h" // getfromdevice
#include "emv/emvcore.h" // decodeTVL
#include "emv/apduinfo.h" // APDUcode description

View file

@ -24,7 +24,7 @@
#include "util.h" // for parsing cli command utils
#include "ui.h" // for show graph controls
#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
extern int CmdTrace(const char *Cmd);

510
client/comms.c Normal file
View 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 = &rx;
//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 = &rx;
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
View 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

View file

@ -10,11 +10,6 @@
#include "flash.h"
void SendCommand(UsbCommand* txcmd);
void ReceiveCommand(UsbCommand* rxcmd);
void CloseProxmark();
int OpenProxmark();
#define FLASH_START 0x100000
#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");
if (!fd) {
fprintf(stderr, "Could not open file '%s': ", name);
fprintf(stderr, _RED_(Could not open file) "%s >>> ", name);
perror(NULL);
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) {
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};
SendCommand(&c);
UsbCommand resp;
ReceiveCommand(&resp);
WaitForResponse(CMD_UNKNOWN, &resp); // wait for any response. No timeout.
// Three outcomes:
// 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];
break;
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;
break;
}
@ -305,7 +300,7 @@ static int enter_bootloader(char *serial_port_name) {
return 0;
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
fprintf(stdout, "Entering bootloader...\n");
fprintf(stdout, _BLUE_(Entering bootloader...) "\n");
UsbCommand c;
memset(&c, 0, sizeof (c));
@ -325,21 +320,22 @@ static int enter_bootloader(char *serial_port_name) {
msleep(100);
CloseProxmark();
fprintf(stdout, "Waiting for Proxmark to reappear on %s", serial_port_name);
do {
msleep(1000);
fprintf(stdout, "."); fflush(stdout);
} while ( !OpenProxmark());
fprintf(stdout, " Found.\n");
return 0;
bool opened = OpenProxmark(serial_port_name, true, 60, true);
if (opened) {
fprintf(stdout, " " _GREEN_(Found) "\n");
return 0;
} else {
fprintf(stdout, _RED_(Error:) "Proxmark not found.\n");
return -1;
}
}
fprintf(stderr, "Error: Unknown Proxmark mode\n");
fprintf(stderr, _RED_(Error:) "Unknown Proxmark mode\n");
return -1;
}
static int wait_for_ack(UsbCommand *ack) {
ReceiveCommand(ack);
WaitForResponse(CMD_UNKNOWN, ack);
if (ack->cmd != CMD_ACK) {
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);
return wait_for_ack(&c);
} else {
fprintf(stderr, "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_(Note: Your bootloader does not understand the new START_FLASH command) "\n");
fprintf(stderr, _RED_( It is recommended that you update your bootloader) "\n\n");
}
return 0;
}
@ -439,7 +434,7 @@ int flash_write(flash_file_t *ctx) {
block++;
fprintf(stdout, "."); fflush(stdout);
}
fprintf(stdout, " OK\n");
fprintf(stdout, _GREEN_(OK) "\n");
fflush(stdout);
}
return 0;

View file

@ -21,6 +21,8 @@
#include "usb_cmd.h"
#include "at91sam7s512.h"
#include "util_posix.h"
#include "util.h"
#include "comms.h"
typedef struct {
void *data;

View file

@ -10,31 +10,16 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <pthread.h>
#include "util_posix.h"
#include "proxmark3.h"
#include "util.h"
#include "flash.h"
#include "uart.h"
#include "comms.h"
#include "usb_cmd.h"
#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) {
// Debug
printf("UsbCommand length[len=%zd]\n", sizeof(UsbCommand));
@ -50,49 +35,6 @@ void cmd_debug(UsbCommand* c) {
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) {
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");
@ -129,30 +71,28 @@ int main(int argc, char **argv) {
}
} else {
res = flash_load(&files[num_files], argv[i], can_write_bl);
if (res < 0) {
fprintf(stderr, "Error while loading %s\n", argv[i]);
if (res < 0)
return -1;
}
fprintf(stderr, "\n");
num_files++;
}
}
char* serial_port_name = argv[1];
serial_port_name = argv[1];
fprintf(stdout, "Waiting for Proxmark to appear on %s", serial_port_name);
do {
msleep(500);
fprintf(stderr, "."); fflush(stdout);
} while (!OpenProxmark());
fprintf(stdout, " Found.\n");
if (!OpenProxmark(serial_port_name, true, 60, true)) {
fprintf(stderr, "Could not find Proxmark on " _RED_(%s) ".\n\n", serial_port_name);
return -1;
} else {
fprintf(stderr, _GREEN_(Found) "\n");
}
res = flash_start_flashing(can_write_bl, serial_port_name);
if (res < 0)
return -1;
fprintf(stdout, "\nFlashing...\n");
fprintf(stdout, "\n" _BLUE_(Flashing...)"\n");
for (int i = 0; i < num_files; i++) {
res = flash_write(&files[i]);
@ -162,7 +102,7 @@ int main(int argc, char **argv) {
fprintf(stdout, "\n");
}
fprintf(stdout, "Resetting hardware...\n");
fprintf(stdout, _BLUE_(Resetting hardware...) "\n");
res = flash_stop_flashing();
if (res < 0)
@ -170,7 +110,6 @@ int main(int argc, char **argv) {
CloseProxmark();
fprintf(stdout, "All done.\n\n");
fprintf(stdout, "Have a nice day!\n");
fprintf(stdout, _BLUE_(All done.) "\n\nHave a nice day!\n");
return 0;
}

View file

@ -17,55 +17,16 @@
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "util_posix.h"
#include "proxgui.h"
#include "cmdmain.h"
#include "uart.h"
#include "ui.h"
#include "util.h"
#include "cmdparser.h"
#include "cmdhw.h"
#include "whereami.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);
}
#include "comms.h"
#if defined(__linux__) || (__APPLE__)
static void showBanner(void){
@ -83,84 +44,6 @@ static void showBanner(void){
}
#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
#ifdef __has_attribute
#if __has_attribute(force_align_arg_pointer)
@ -169,9 +52,7 @@ __attribute__((force_align_arg_pointer))
#endif
main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
struct receiver_arg rarg;
char *cmd = NULL;
pthread_t reader_thread;
bool execCommand = (script_cmd != NULL);
bool stdinOnPipe = !isatty(STDIN_FILENO);
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");
if (usb_present) {
rarg.run = 1;
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
SetOffline(false);
// cache Version information now:
if ( execCommand || script_cmds_file || stdinOnPipe)
CmdVersion("s");
else
CmdVersion("");
} else {
SetOffline(true);
}
if (script_cmds_file) {
@ -202,13 +84,14 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
while (1) {
// this should hook up the PM3 again.
if (offline) {
/*
if ( IsOffline() ) {
// sets the global variable, SP and offline)
usb_present = hookUpPM3();
// usb and the reader_thread is NULL, create a new reader thread.
if (usb_present && !offline) {
if (usb_present && !IsOffline() ) {
rarg.run = 1;
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
// cache Version information now:
@ -218,6 +101,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
CmdVersion("");
}
}
*/
// If there is a script file
if (sf) {
@ -304,11 +188,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
free(cmd);
cmd = NULL;
if (usb_present) {
rarg.run = 0;
pthread_join(reader_thread, NULL);
}
}
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){
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);
if (showFullHelp){
@ -384,10 +264,6 @@ int main(int argc, char* argv[]) {
show_help(true, argv[0]);
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++) {
@ -406,7 +282,7 @@ int main(int argc, char* argv[]) {
// flush output
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");
}
@ -474,39 +350,11 @@ int main(int argc, char* argv[]) {
// set global variables
set_my_executable_path();
// open uart
if (!waitCOMPort) {
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);
// try to open USB connection to Proxmark
usb_present = OpenProxmark(argv[1], waitCOMPort, 20, false);
printf("\x1b[31m test\n");
#ifdef HAVE_GUI
# ifdef _WIN32
@ -527,8 +375,10 @@ int main(int argc, char* argv[]) {
main_loop(script_cmds_file, script_cmd, usb_present);
#endif
// clean up mutex
pthread_mutex_destroy(&print_lock);
// Clean up the port
if (usb_present) {
CloseProxmark();
}
exit(0);
}

View file

@ -21,14 +21,10 @@
extern "C" {
#endif
void SendCommand(UsbCommand *c);
const char *get_my_executable_path(void);
const char *get_my_executable_directory(void);
void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present);
bool hookUpPM3(void);
void *uart_receiver(void *targ);
#ifdef __cplusplus
}
#endif

View file

@ -17,6 +17,7 @@
#include "proxmark3.h"
#include "usb_cmd.h"
#include "cmdmain.h"
#include "comms.h"
#include "util.h"
#include "mifarehost.h"
#include "crc.h"

View file

@ -13,8 +13,7 @@
double CursorScaleFactor = 1;
int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
int offline;
int g_flushAfterWrite = 0; //buzzy
bool flushAfterWrite = 0;
int GridOffset = 0;
bool GridLocked = false;
bool showDemod = true;
@ -178,7 +177,7 @@ void PrintAndLog(char *fmt, ...) {
}
va_end(argptr2);
if (g_flushAfterWrite == 1)
if (flushAfterWrite)
fflush(NULL);
//release lock
@ -189,7 +188,11 @@ void SetLogFilename(char *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;

View file

@ -37,14 +37,13 @@ extern void PrintAndLog(char *fmt, ...);
void PrintAndLogOptions(char *str[][2], size_t size, size_t space);
void PrintAndLogEx(logLevel_t level, char *fmt, ...);
extern void SetLogFilename(char *fn);
void SetFlushAfterWrite(bool value);
extern double CursorScaleFactor;
extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
extern bool GridLocked;
extern bool showDemod;
extern int offline;
extern int g_flushAfterWrite; //buzzy
//extern uint8_t g_debugMode;
extern pthread_mutex_t print_lock;

View file

@ -31,29 +31,9 @@
*/
#include "cmd.h"
bool cmd_receive(UsbCommand* cmd) {
// 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) {
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* data, size_t len) {
UsbCommand txcmd;
// 0x00 the whole command.
for (size_t i=0; i < sizeof(UsbCommand); i++)
((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];
}
}
// 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;
}

View file

@ -39,8 +39,7 @@
#include "usart.h"
#include "proxmark3.h"
bool 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);
#endif // _PROXMARK_CMD_H_

View file

@ -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 "apps.h"
#include "string.h"
#define USART_INTERRUPT_LEVEL 7
#define AT91_BAUD_RATE 115200
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1;
volatile AT91PS_USART pUS1 = AT91C_BASE_US1;
volatile AT91PS_AIC pAIC = AT91C_BASE_AIC;
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) {
// Reset the USART mode
pUS1->US_MR = 0;
@ -25,259 +31,155 @@ void usart_close(void) {
// Disable all interrupts
pUS1->US_IDR = 0xFFFFFFFF;
//* Abort the Peripheral Data Transfers
//AT91F_PDC_Close((AT91PS_PDC) &(pUSART->US_RPR));
// Abort the Peripheral Data Transfers
pUS1->US_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
// Disable receiver and transmitter and stop any activity immediately
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
/// becomes full. This function returns immediately with 1 if the buffer has
/// been queued for transmission; otherwise 0.
static uint8_t outbuf[sizeof(UsbCommand)];
//static uint8_t inbuf[sizeof(UsbCommand)];
/// Reads data from an USART peripheral
/// \param data Pointer to the buffer where the received data will be stored.
/// \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
if ((pUS1->US_RCR == 0) && (pUS1->US_RNCR == 0)) {
if (!(pUS1->US_RCR)) {
pUS1->US_RPR = (uint32_t)data;
pUS1->US_RCR = len;
pUS1->US_PTCR = AT91C_PDC_RXTEN;
return 1;
return 2;
}
// 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_RNCR = len;
return 1;
} else {
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
/// function operates asynchronously, so it waits until some data has been
/// received.
/// \param timeout Time out value (0 -> no timeout).
uint8_t usart_read(uint32_t timeout) {
if (timeout == 0) {
while ((pUS1->US_CSR & AT91C_US_RXRDY) == 0) {};
}
else {
// pUS1->US_PTSR = AT91C_PDC_TXTEN;
pUS1->US_PTCR = AT91C_PDC_TXTEN;
// if buffer is sent
if (pUS1->US_TCR != 0) return -1;
memcpy(outbuf, data, len);
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) {
DbpString("USART_Read: Timed out.");
return 0;
}
timeout--;
}
}
uint8_t res = pUS1->US_RHR;
Dbprintf(" usar got %02x", res);
return res;
return sizeof(outbuf);
}
*/
/// Sends one packet of data through the specified USART peripheral. This
/// function operates synchronously, so it only returns when the data has been
/// actually sent.
/// \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) {
// works.
// transfer to client
inline int16_t usart_writebuffer(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
if ((pUS1->US_TCR == 0) && (pUS1->US_TNCR == 0)) {
pUS1->US_TPR = (uint32_t)data;
pUS1->US_TCR = len;
pUS1->US_PTCR = AT91C_PDC_TXTEN;
return 1;
if (!(pUS1->US_TCR)) {
memcpy(outbuf, data, len);
pUS1->US_TPR = (uint32_t)outbuf;
pUS1->US_TCR = sizeof(outbuf);
return 2;
}
// Check if the second PDC bank is free
else if (pUS1->US_TNCR == 0) {
pUS1->US_TNPR = (uint32_t)data;
pUS1->US_TNCR = len;
return 1;
}
else {
else if (!(pUS1->US_TNCR)) {
memcpy(outbuf, data, len);
pUS1->US_TNPR = (uint32_t)outbuf;
pUS1->US_TNCR = sizeof(outbuf);
return 1;
} else {
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) {
// disable & reset receiver / transmitter for configuration
pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX);
// disable & reset receiver / transmitter
pUS1->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
//enable the USART 1 Peripheral clock
//enable the USART1 Peripheral clock
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
// pPIOA->PIO_PPUDR = ~(AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
// pPIOA->PIO_MDDR = (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
// disable PIO control of receive / transmit pins
pPIOA->PIO_PDR |= (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);
// 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
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_PAR_NONE | // parity: none
AT91C_US_NBSTOP_1_BIT | // 1 stop bit
AT91C_US_CHMODE_NORMAL; // channel mode: normal
// baud rate
// CD = MCK / (16 * baud)
// 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
// set baudrate to 115200
pUS1->US_BRGR = (48UL*1000*1000) / (115200*16);
// Write the Timeguard Register
pUS1->US_TTGR = 0;
pUS1->US_RTOR = 0;
pUS1->US_FIDI = 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
/*
AT91F_AIC_ConfigureIt(
pAIC,
AT91C_ID_US1,
USART_INTERRUPT_LEVEL,
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;
/*
//Empty PDC
pUS1->US_RNPR = (uint32_t)(char *)0;
pUS1->US_RNCR = 0;
pUS1->US_RPR = (uint32_t)(char *)0;
pUS1->US_RCR = 0;
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);
}

View file

@ -4,18 +4,9 @@
#include <stddef.h>
#include "proxmark3.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
extern void Dbprintf(const char *fmt, ...);
void usart_init(void);
void usart_close(void);
uint32_t usart_rx_ready();
uint32_t usart_tx_ready();
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);
int usart_readbuffer(uint8_t *data, size_t len);
int16_t usart_writebuffer(uint8_t *data, size_t len);
#endif

View file

@ -41,6 +41,16 @@
#include "common.h"
#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
* makes sense to your connection method. Both the posix and win32
* 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
* 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.
* pbtTx: A pointer to a buffer containing the data to send.
* 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.
*/

View file

@ -117,10 +117,19 @@ serial_port uart_open(const char* pcPortName)
// Flush all lingering data that may exist
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
bool err = uart_set_speed(sp, 460800);
if (!err)
uart_set_speed(sp, 115200);
bool success = uart_set_speed(sp, 460800);
if (success) {
printf("[=] UART Setting serial baudrate 460800\n");
} else {
uart_set_speed(sp, 115200);
printf("[=] UART Setting serial baudrate 115200\n");
}
#endif
return sp;
}
@ -144,7 +153,7 @@ void uart_close(const serial_port 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 byteCount;
fd_set rfds;
@ -156,9 +165,9 @@ bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_
do {
// Reset file descriptor
FD_ZERO(&rfds);
FD_SET(((serial_port_unix*)sp)->fd,&rfds);
FD_SET(((serial_port_unix*)sp)->fd, &rfds);
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
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
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
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;
}
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;
size_t pos = 0;
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
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
if (res <= 0) {
printf("UART:: os troubles (%d)\n", res);
return false;
}
if (res <= 0) return false;
pos += res;
}

View file

@ -47,16 +47,6 @@ typedef struct {
DCB dcb; // Device control settings
COMMTIMEOUTS ct; // Serial port time-out configuration
} 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) {
char acPortName[255];
@ -110,10 +100,17 @@ serial_port uart_open(const char* pcPortName) {
PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
#ifdef WITH_FPC
uart_set_speed(sp, 115200);
#else
bool success = uart_set_speed(sp, 460800);
if (!success)
if (success) {
printf("[=] UART Setting serial baudrate 460800\n");
} else {
uart_set_speed(sp, 115200);
printf("[=] UART Setting serial baudrate 115200\n");
}
#endif
return sp;
}
@ -155,32 +152,13 @@ uint32_t uart_get_speed(const serial_port sp) {
return 0;
}
bool uart_receive(const serial_port sp, byte_t* p_rx, size_t pszMaxRxLen, size_t* p_rxlen) {
int res = ReadFile(((serial_port_windows*)sp)->hPort, p_rx, pszMaxRxLen, (LPDWORD)p_rxlen, 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_receive(const serial_port sp, uint8_t* p_rx, size_t pszMaxRxLen, size_t* len) {
return ReadFile(((serial_port_windows*)sp)->hPort, p_rx, pszMaxRxLen, (LPDWORD)len, NULL);
}
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;
int res = 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;
return WriteFile(((serial_port_windows*)sp)->hPort, p_tx, len, &txlen, NULL);
}
#endif