From 24eaac86810e39a219431daf9bb959323366760d Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 6 Sep 2018 21:43:20 +0200 Subject: [PATCH] CHG: the thread comms refactoring from offical pm3 repo chg: FPC com speed limited to 115200 when compiled with FPC chg: USART remake (@drandreas) --- armsrc/Makefile | 2 +- armsrc/appmain.c | 81 ++++--- armsrc/apps.h | 4 +- armsrc/lfops.c | 2 +- bootrom/bootrom.c | 10 +- client/Makefile | 5 +- client/cmdanalyse.c | 3 +- client/cmddata.h | 2 +- client/cmdflashmem.h | 2 +- client/cmdhffelica.h | 2 +- client/cmdhficlass.h | 2 +- client/cmdhflegic.h | 2 +- client/cmdhfmfu.h | 1 + client/cmdlf.c | 6 +- client/cmdlfawid.c | 2 +- client/cmdlfcotag.h | 2 +- client/cmdlfem4x.h | 3 +- client/cmdlfhid.c | 2 +- client/cmdlfhitag.c | 2 +- client/cmdlfindala.c | 2 +- client/cmdlft55xx.c | 10 +- client/cmdlft55xx.h | 2 +- client/cmdmain.c | 292 +----------------------- client/cmdmain.h | 28 +-- client/cmdparser.c | 3 +- client/cmdscript.c | 1 + client/cmdsmartcard.h | 2 +- client/cmdtrace.h | 2 +- client/comms.c | 510 ++++++++++++++++++++++++++++++++++++++++++ client/comms.h | 67 ++++++ client/flash.c | 41 ++-- client/flash.h | 2 + client/flasher.c | 93 ++------ client/proxmark3.c | 192 ++-------------- client/proxmark3.h | 4 - client/scripting.h | 1 + client/ui.c | 11 +- client/ui.h | 3 +- common/cmd.c | 37 +-- common/cmd.h | 3 +- common/usart.c | 316 +++++++++----------------- common/usart.h | 13 +- uart/uart.h | 14 +- uart/uart_posix.c | 32 +-- uart/uart_win32.c | 48 ++-- 45 files changed, 915 insertions(+), 949 deletions(-) create mode 100644 client/comms.c create mode 100644 client/comms.h diff --git a/armsrc/Makefile b/armsrc/Makefile index b2ae9f9a2..8f0cd025e 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -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! diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e9237c25c..9cb3758af 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -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�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 + } } } diff --git a/armsrc/apps.h b/armsrc/apps.h index 7852d1439..f8d24f4ae 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -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); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 5afce8549..9d6cfbf0e 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -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 diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 0dcf52b28..d2a18628a 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -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 */ diff --git a/client/Makefile b/client/Makefile index af2efb26c..f577a6386 100644 --- a/client/Makefile +++ b/client/Makefile @@ -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 \ diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 1c65b8cc4..490dda9d3 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -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"); diff --git a/client/cmddata.h b/client/cmddata.h index dbd735747..27c446ecb 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -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 diff --git a/client/cmdflashmem.h b/client/cmdflashmem.h index 99b18b4c5..843c17d6f 100644 --- a/client/cmdflashmem.h +++ b/client/cmdflashmem.h @@ -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); diff --git a/client/cmdhffelica.h b/client/cmdhffelica.h index f82d2d574..bcec38a0b 100644 --- a/client/cmdhffelica.h +++ b/client/cmdhffelica.h @@ -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 diff --git a/client/cmdhficlass.h b/client/cmdhficlass.h index e9bedf9fe..c53e88f49 100644 --- a/client/cmdhficlass.h +++ b/client/cmdhficlass.h @@ -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" diff --git a/client/cmdhflegic.h b/client/cmdhflegic.h index 645a6b993..4e3c8cc86 100644 --- a/client/cmdhflegic.h +++ b/client/cmdhflegic.h @@ -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" diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index da9cfd02f..2e07bae80 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -9,6 +9,7 @@ #include "mifare.h" #include "util.h" #include "protocols.h" +#include "comms.h" typedef struct { uint8_t version[8]; diff --git a/client/cmdlf.c b/client/cmdlf.c index ec9527bcc..ccb781014 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -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); diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 8b1205e52..420caeb62 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -539,7 +539,7 @@ int CmdAWIDBrute(const char *Cmd) { // main loop for (;;){ - if ( offline ) { + if ( IsOffline() ) { PrintAndLogEx(WARNING, "Device offline\n"); return 2; } diff --git a/client/cmdlfcotag.h b/client/cmdlfcotag.h index 589089a61..e03f7d5f5 100644 --- a/client/cmdlfcotag.h +++ b/client/cmdlfcotag.h @@ -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 diff --git a/client/cmdlfem4x.h b/client/cmdlfem4x.h index aa044b9c7..676c6fd6b 100644 --- a/client/cmdlfem4x.h +++ b/client/cmdlfem4x.h @@ -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" diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 08cbc8661..02fd9c791 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -544,7 +544,7 @@ int CmdHIDBrute(const char *Cmd){ // main loop for (;;){ - if ( offline ) { + if ( IsOffline() ) { PrintAndLogEx(WARNING, "Device offline\n"); return 2; } diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index ed2250a0c..69bae1b38 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -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); diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 6f6eb4f37..f4993fb5e 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -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; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 0982337f3..c4d1e3be6 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -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; diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index ad170514c..b6c355778 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -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" diff --git a/client/cmdmain.c b/client/cmdmain.c index 351152179..85d7f19c3 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -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 ' 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; -} +} \ No newline at end of file diff --git a/client/cmdmain.h b/client/cmdmain.h index de728e11c..74804300d 100644 --- a/client/cmdmain.h +++ b/client/cmdmain.h @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -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 diff --git a/client/cmdparser.c b/client/cmdparser.c index f12b4966e..974439298 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -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; } diff --git a/client/cmdscript.c b/client/cmdscript.c index a34a42815..7159fa70b 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -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" diff --git a/client/cmdsmartcard.h b/client/cmdsmartcard.h index 1c7b5d3f8..5ba453e30 100644 --- a/client/cmdsmartcard.h +++ b/client/cmdsmartcard.h @@ -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 diff --git a/client/cmdtrace.h b/client/cmdtrace.h index 8e940d220..c6ba0cc38 100644 --- a/client/cmdtrace.h +++ b/client/cmdtrace.h @@ -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); diff --git a/client/comms.c b/client/comms.c new file mode 100644 index 000000000..ec1a36860 --- /dev/null +++ b/client/comms.c @@ -0,0 +1,510 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2009 Michael Gernoth +// Copyright (C) 2010 iZsh +// +// 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; +} diff --git a/client/comms.h b/client/comms.h new file mode 100644 index 000000000..eba0d45d5 --- /dev/null +++ b/client/comms.h @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2009 Michael Gernoth +// Copyright (C) 2010 iZsh +// +// 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 +#include + +#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 // 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 + + diff --git a/client/flash.c b/client/flash.c index ed58c1153..de6fdf7e6 100644 --- a/client/flash.c +++ b/client/flash.c @@ -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; diff --git a/client/flash.h b/client/flash.h index ec93a2787..5372df089 100644 --- a/client/flash.h +++ b/client/flash.h @@ -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; diff --git a/client/flasher.c b/client/flasher.c index 48e66d8f9..a20b264b9 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -10,31 +10,16 @@ #include #include #include +#include #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 -#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 [-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; } diff --git a/client/proxmark3.c b/client/proxmark3.c index b7dffe6e7..78230bd36 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -17,55 +17,16 @@ #include #include #include + +#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 [-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 [-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); } \ No newline at end of file diff --git a/client/proxmark3.h b/client/proxmark3.h index c68e8275c..0a69e71ba 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -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 diff --git a/client/scripting.h b/client/scripting.h index feb611549..a6aaf157a 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -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" diff --git a/client/ui.c b/client/ui.c index ba2e028a0..a8b45273d 100644 --- a/client/ui.c +++ b/client/ui.c @@ -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; diff --git a/client/ui.h b/client/ui.h index 6d59393b0..fc3439033 100644 --- a/client/ui.h +++ b/client/ui.h @@ -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; diff --git a/common/cmd.c b/common/cmd.c index 3aa6870ee..281ff0065 100644 --- a/common/cmd.c +++ b/common/cmd.c @@ -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; } \ No newline at end of file diff --git a/common/cmd.h b/common/cmd.h index 0fd2cc142..9aa6bec33 100644 --- a/common/cmd.h +++ b/common/cmd.h @@ -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_ diff --git a/common/usart.c b/common/usart.c index e8e613ddf..b58a7cbaa 100644 --- a/common/usart.c +++ b/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 "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); + } \ No newline at end of file diff --git a/common/usart.h b/common/usart.h index 3623451d5..271a24ba4 100644 --- a/common/usart.h +++ b/common/usart.h @@ -4,18 +4,9 @@ #include #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 diff --git a/uart/uart.h b/uart/uart.h index ab0f9c076..a1521a58d 100644 --- a/uart/uart.h +++ b/uart/uart.h @@ -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. */ diff --git a/uart/uart_posix.c b/uart/uart_posix.c index 33bdc525f..20a577ded 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -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; } diff --git a/uart/uart_win32.c b/uart/uart_win32.c index 7be3a8fe9..eef350cda 100644 --- a/uart/uart_win32.c +++ b/uart/uart_win32.c @@ -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 \ No newline at end of file