X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/61aaee35cc838af65f943c9b6f62db28beb48c93..9b4661c53baa99a649b26bd123b6f5d71e7bd812:/client/comms.c diff --git a/client/comms.c b/client/comms.c index 2dd5534c..b62f6fda 100644 --- a/client/comms.c +++ b/client/comms.c @@ -15,13 +15,12 @@ #include "uart.h" #include "ui.h" #include "common.h" -#include "data.h" #include "util_posix.h" // Declare globals. // Serial port that we are communicating with the PM3 on. -serial_port sp; +static serial_port sp; // If TRUE, then there is no active connection to the PM3, and we will drop commands sent. static bool offline; @@ -58,6 +57,38 @@ bool IsOffline() { return offline; } +bool OpenProxmark(char *portname, bool waitCOMPort, int timeout) { + if (!waitCOMPort) { + sp = uart_open(portname); + } else { + printf("Waiting for Proxmark to appear on %s ", portname); + fflush(stdout); + int openCount = 0; + do { + sp = uart_open(portname); + msleep(1000); + printf("."); + fflush(stdout); + } while(++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT)); + printf("\n"); + } + + // check result of uart opening + if (sp == INVALID_SERIAL_PORT) { + printf("ERROR: invalid serial port\n"); + return false; + } else if (sp == CLAIMED_SERIAL_PORT) { + printf("ERROR: serial port is claimed by another process\n"); + return false; + } else { + return true; + } +} + +void CloseProxmark(void) { + uart_close(sp); +} + void SendCommand(UsbCommand *c) { #ifdef COMMS_DEBUG printf("Sending %04x cmd\n", c->cmd); @@ -73,6 +104,7 @@ void SendCommand(UsbCommand *c) { Not good.../holiman **/ while(txcmd_pending); + txcmd = *c; txcmd_pending = true; } @@ -140,11 +172,11 @@ int getCommand(UsbCommand* response) } -//----------------------------------------------------------------------------- -// 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 *UC) +//---------------------------------------------------------------------------------- +// Entry point into our code: called whenever we received a packet over USB. +// Handle debug commands directly, store all other commands in circular buffer. +//---------------------------------------------------------------------------------- +static void UsbCommandReceived(UsbCommand *UC) { switch(UC->cmd) { // First check if we are handling a debug message @@ -162,15 +194,8 @@ void UsbCommandReceived(UsbCommand *UC) return; } break; - case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: { - // FIXME: This does unsanitised copies into memory when we don't know - // the size of the buffer. - memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]); - return; - } break; - default: - storeCommand(UC); + storeCommand(UC); break; } @@ -184,12 +209,12 @@ __attribute__((force_align_arg_pointer)) #endif #endif *uart_receiver(void *targ) { - receiver_arg *arg = (receiver_arg*)targ; + receiver_arg *conn = (receiver_arg*)targ; size_t rxlen; uint8_t rx[sizeof(UsbCommand)]; uint8_t *prx = rx; - while (arg->run) { + while (conn->run) { rxlen = 0; if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) { prx += rxlen; @@ -213,6 +238,58 @@ __attribute__((force_align_arg_pointer)) } + +/** + * Data transfer from Proxmark to client. This method times out after + * ms_timeout milliseconds. + * @brief GetFromBigBuf + * @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 GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) +{ + UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}}; + SendCommand(&c); + + uint64_t start_time = msclock(); + + UsbCommand resp; + if (response == NULL) { + response = &resp; + } + + int bytes_completed = 0; + while(true) { + if (getCommand(response)) { + if (response->cmd == CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) { + int copy_bytes = MIN(bytes - bytes_completed, response->arg[1]); + memcpy(dest + response->arg[0], response->d.asBytes, copy_bytes); + bytes_completed += copy_bytes; + } else if (response->cmd == CMD_ACK) { + return true; + } + } + + if (msclock() - start_time > ms_timeout) { + break; + } + + if (msclock() - start_time > 2000 && show_warning) { + PrintAndLog("Waiting for a response from the proxmark..."); + PrintAndLog("You can cancel this operation by pressing the pm3 button"); + show_warning = false; + } + } + + return false; +} + + /** * Waits for a certain response type. This method waits for a maximum of * ms_timeout milliseconds for a specified response command. @@ -220,7 +297,7 @@ __attribute__((force_align_arg_pointer)) * @param cmd command to wait for, or CMD_UNKNOWN to take any command. * @param response struct to copy received command into. * @param ms_timeout - * @param show_warning + * @param show_warning 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) {