mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -07:00
CHG: the thread comms refactoring from offical pm3 repo
chg: FPC com speed limited to 115200 when compiled with FPC chg: USART remake (@drandreas)
This commit is contained in:
parent
eb0b5116a2
commit
24eaac8681
45 changed files with 915 additions and 949 deletions
|
@ -104,7 +104,7 @@ ifneq (,$(findstring WITH_HF_MATTYRUN,$(APP_CFLAGS)))
|
|||
endif
|
||||
# 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!
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mifare.h"
|
||||
#include "util.h"
|
||||
#include "protocols.h"
|
||||
#include "comms.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t version[8];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -539,7 +539,7 @@ int CmdAWIDBrute(const char *Cmd) {
|
|||
// main loop
|
||||
for (;;){
|
||||
|
||||
if ( offline ) {
|
||||
if ( IsOffline() ) {
|
||||
PrintAndLogEx(WARNING, "Device offline\n");
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -544,7 +544,7 @@ int CmdHIDBrute(const char *Cmd){
|
|||
// main loop
|
||||
for (;;){
|
||||
|
||||
if ( offline ) {
|
||||
if ( IsOffline() ) {
|
||||
PrintAndLogEx(WARNING, "Device offline\n");
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
292
client/cmdmain.c
292
client/cmdmain.c
|
@ -15,18 +15,6 @@ static int CmdQuit(const char *Cmd);
|
|||
static int CmdRev(const char *Cmd);
|
||||
static int 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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
510
client/comms.c
Normal file
|
@ -0,0 +1,510 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
|
||||
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Code for communicating with the proxmark3 hardware.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "comms.h"
|
||||
|
||||
// Serial port that we are communicating with the PM3 on.
|
||||
static serial_port sp = NULL;
|
||||
static char *serial_port_name = NULL;
|
||||
|
||||
// If TRUE, then there is no active connection to the PM3, and we will drop commands sent.
|
||||
static bool offline;
|
||||
|
||||
static communication_arg_t conn;
|
||||
|
||||
static pthread_t USB_communication_thread;
|
||||
//static pthread_t FPC_communication_thread;
|
||||
|
||||
// Transmit buffer.
|
||||
static UsbCommand txBuffer;
|
||||
static bool txBuffer_pending = false;
|
||||
static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t txBufferSig = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
// Used by UsbReceiveCommand as a ring buffer for messages that are yet to be
|
||||
// processed by a command handler (WaitForResponse{,Timeout})
|
||||
static UsbCommand rxBuffer[CMD_BUFFER_SIZE];
|
||||
|
||||
// Points to the next empty position to write to
|
||||
static int cmd_head = 0;
|
||||
|
||||
// Points to the position of the last unread command
|
||||
static int cmd_tail = 0;
|
||||
|
||||
// to lock rxBuffer operations from different threads
|
||||
static pthread_mutex_t rxBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// These wrappers are required because it is not possible to access a static
|
||||
// global variable outside of the context of a single file.
|
||||
void SetOffline(bool value) {
|
||||
offline = value;
|
||||
}
|
||||
|
||||
bool IsOffline() {
|
||||
return offline;
|
||||
}
|
||||
|
||||
void SendCommand(UsbCommand *c) {
|
||||
|
||||
#ifdef COMMS_DEBUG
|
||||
PrintAndLogEx(NORMAL, "Sending %d bytes | cmd %04x\n", sizeof(UsbCommand), c->cmd);
|
||||
#endif
|
||||
|
||||
if (offline) {
|
||||
PrintAndLogEx(NORMAL, "Sending bytes to proxmark failed - offline");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&txBufferMutex);
|
||||
/**
|
||||
This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive,
|
||||
but comm thread just spins here. Not good.../holiman
|
||||
**/
|
||||
while (txBuffer_pending) {
|
||||
// wait for communication thread to complete sending a previous commmand
|
||||
pthread_cond_wait(&txBufferSig, &txBufferMutex);
|
||||
}
|
||||
|
||||
txBuffer = *c;
|
||||
txBuffer_pending = true;
|
||||
|
||||
// tell communication thread that a new command can be send
|
||||
pthread_cond_signal(&txBufferSig);
|
||||
|
||||
pthread_mutex_unlock(&txBufferMutex);
|
||||
|
||||
//__atomic_test_and_set(&txcmd_pending, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method should be called when sending a new command to the pm3. In case any old
|
||||
* responses from previous commands are stored in the buffer, a call to this method should clear them.
|
||||
* A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which
|
||||
* operation. Right now we'll just have to live with this.
|
||||
*/
|
||||
void clearCommandBuffer() {
|
||||
//This is a very simple operation
|
||||
pthread_mutex_lock(&rxBufferMutex);
|
||||
cmd_tail = cmd_head;
|
||||
pthread_mutex_unlock(&rxBufferMutex);
|
||||
}
|
||||
/**
|
||||
* @brief storeCommand stores a USB command in a circular buffer
|
||||
* @param UC
|
||||
*/
|
||||
static void storeCommand(UsbCommand *command) {
|
||||
|
||||
pthread_mutex_lock(&rxBufferMutex);
|
||||
if ( ( cmd_head+1) % CMD_BUFFER_SIZE == cmd_tail) {
|
||||
//If these two are equal, we're about to overwrite in the
|
||||
// circular buffer.
|
||||
PrintAndLogEx(FAILED, "WARNING: Command buffer about to overwrite command! This needs to be fixed!");
|
||||
fflush(NULL);
|
||||
}
|
||||
//Store the command at the 'head' location
|
||||
UsbCommand* destination = &rxBuffer[cmd_head];
|
||||
memcpy(destination, command, sizeof(UsbCommand));
|
||||
|
||||
//increment head and wrap
|
||||
cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE;
|
||||
pthread_mutex_unlock(&rxBufferMutex);
|
||||
}
|
||||
/**
|
||||
* @brief getCommand gets a command from an internal circular buffer.
|
||||
* @param response location to write command
|
||||
* @return 1 if response was returned, 0 if nothing has been received
|
||||
*/
|
||||
static int getCommand(UsbCommand* response) {
|
||||
pthread_mutex_lock(&rxBufferMutex);
|
||||
//If head == tail, there's nothing to read, or if we just got initialized
|
||||
if (cmd_head == cmd_tail) {
|
||||
pthread_mutex_unlock(&rxBufferMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Pick out the next unread command
|
||||
UsbCommand* last_unread = &rxBuffer[cmd_tail];
|
||||
memcpy(response, last_unread, sizeof(UsbCommand));
|
||||
|
||||
//Increment tail - this is a circular buffer, so modulo buffer size
|
||||
cmd_tail = (cmd_tail +1 ) % CMD_BUFFER_SIZE;
|
||||
|
||||
pthread_mutex_unlock(&rxBufferMutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Entry point into our code: called whenever we received a packet over USB
|
||||
// that we weren't necessarily expecting, for example a debug print.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void UsbCommandReceived(UsbCommand* c) {
|
||||
|
||||
switch(c->cmd) {
|
||||
// First check if we are handling a debug message
|
||||
case CMD_DEBUG_PRINT_STRING: {
|
||||
|
||||
char s[USB_CMD_DATA_SIZE+1];
|
||||
memset(s, 0x00, sizeof(s));
|
||||
size_t len = MIN(c->arg[0], USB_CMD_DATA_SIZE);
|
||||
memcpy(s, c->d.asBytes, len);
|
||||
|
||||
|
||||
//#define FLAG_RAWPRINT 0x0111
|
||||
//#define FLAG_NOOPT 0x0000
|
||||
//#define FLAG_NOLOG 0x0001
|
||||
//#define FLAG_NONEWLINE 0x0010
|
||||
//#define FLAG_NOPROMPT 0x0100
|
||||
uint64_t flag = c->arg[1];
|
||||
if (flag > 0) { // FLAG_RAWPRINT) {
|
||||
switch (flag) {
|
||||
case FLAG_RAWPRINT:
|
||||
printf("%s", s);
|
||||
return;
|
||||
case FLAG_NONEWLINE:
|
||||
printf("%s\r", s);
|
||||
return;
|
||||
case FLAG_NOLOG:
|
||||
printf("%s\r\n", s);
|
||||
return;
|
||||
}
|
||||
fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
// print debug line on same row. escape seq \r
|
||||
if ( c->arg[1] == CMD_MEASURE_ANTENNA_TUNING_HF) {
|
||||
PrintAndLogEx(NORMAL, "\r#db# %s", s);
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "#db# %s", s);
|
||||
}
|
||||
fflush(NULL);
|
||||
break;
|
||||
}
|
||||
case CMD_DEBUG_PRINT_INTEGERS: {
|
||||
PrintAndLogEx(NORMAL, "#db# %08x, %08x, %08x", c->arg[0], c->arg[1], c->arg[2]);
|
||||
break;
|
||||
}
|
||||
// iceman: hw status - down the path on device, runs printusbspeed which starts sending a lot of
|
||||
// CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K packages which is not dealt with. I wonder if simply ignoring them will
|
||||
// work. lets try it.
|
||||
default: {
|
||||
storeCommand(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bool hookUpPM3() {
|
||||
bool ret = false;
|
||||
sp = uart_open( comport );
|
||||
|
||||
if (sp == INVALID_SERIAL_PORT) {
|
||||
PrintAndLogEx(WARNING, "Reconnect failed, retrying... (reason: invalid serial port)\n");
|
||||
sp = NULL;
|
||||
serial_port_name = NULL;
|
||||
ret = false;
|
||||
offline = 1;
|
||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||
PrintAndLogEx(WARNING, "Reconnect failed, retrying... (reason: serial port is claimed by another process)\n");
|
||||
sp = NULL;
|
||||
serial_port_name = NULL;
|
||||
ret = false;
|
||||
offline = 1;
|
||||
} else {
|
||||
PrintAndLogEx(SUCCESS, "Proxmark reconnected\n");
|
||||
serial_port_name = ;
|
||||
ret = true;
|
||||
offline = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
#ifdef __has_attribute
|
||||
#if __has_attribute(force_align_arg_pointer)
|
||||
__attribute__((force_align_arg_pointer))
|
||||
#endif
|
||||
#endif
|
||||
*uart_communication(void *targ) {
|
||||
communication_arg_t *conn = (communication_arg_t*)targ;
|
||||
size_t rxlen;
|
||||
UsbCommand rx;
|
||||
UsbCommand *prx = ℞
|
||||
|
||||
//int counter_to_offline = 0;
|
||||
|
||||
while (conn->run) {
|
||||
rxlen = 0;
|
||||
bool ACK_received = false;
|
||||
if (uart_receive(sp, (uint8_t *)prx, sizeof(UsbCommand) - (prx - &rx), &rxlen) && rxlen) {
|
||||
prx += rxlen;
|
||||
|
||||
if (prx - &rx < sizeof(UsbCommand)) {
|
||||
PrintAndLogEx(NORMAL, "Foo %d | %d (will loop)", prx - &rx, rxlen);
|
||||
continue;
|
||||
}
|
||||
UsbCommandReceived(&rx);
|
||||
if (rx.cmd == CMD_ACK) {
|
||||
ACK_received = true;
|
||||
}
|
||||
}
|
||||
prx = ℞
|
||||
|
||||
pthread_mutex_lock(&txBufferMutex);
|
||||
|
||||
if (conn->block_after_ACK) {
|
||||
// if we just received an ACK, wait here until a new command is to be transmitted
|
||||
if (ACK_received) {
|
||||
while (!txBuffer_pending) {
|
||||
pthread_cond_wait(&txBufferSig, &txBufferMutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (txBuffer_pending) {
|
||||
if (!uart_send(sp, (uint8_t*) &txBuffer, sizeof(UsbCommand))) {
|
||||
//counter_to_offline++;
|
||||
PrintAndLogEx(WARNING, "sending bytes to proxmark failed");
|
||||
}
|
||||
txBuffer_pending = false;
|
||||
|
||||
// tell main thread that txBuffer is empty
|
||||
pthread_cond_signal(&txBufferSig);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&txBufferMutex);
|
||||
}
|
||||
|
||||
// when this reader thread dies, we close the serial port.
|
||||
uart_close(sp);
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) {
|
||||
|
||||
char *portname = (char *)port;
|
||||
if (!wait_for_port) {
|
||||
sp = uart_open(portname);
|
||||
} else {
|
||||
PrintAndLogEx(SUCCESS, "Waiting for Proxmark to appear on " _YELLOW_(%s), portname);
|
||||
fflush(stdout);
|
||||
int openCount = 0;
|
||||
do {
|
||||
sp = uart_open(portname);
|
||||
msleep(500);
|
||||
printf("."); fflush(stdout);
|
||||
} while (++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT));
|
||||
//PrintAndLogEx(NORMAL, "\n");
|
||||
}
|
||||
|
||||
// check result of uart opening
|
||||
if (sp == INVALID_SERIAL_PORT) {
|
||||
PrintAndLogEx(WARNING, _RED_(ERROR:) "invalid serial port");
|
||||
sp = NULL;
|
||||
serial_port_name = NULL;
|
||||
return false;
|
||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||
PrintAndLogEx(WARNING, _RED_(ERROR:) "serial port is claimed by another process");
|
||||
sp = NULL;
|
||||
serial_port_name = NULL;
|
||||
return false;
|
||||
} else {
|
||||
// start the USB communication thread
|
||||
serial_port_name = portname;
|
||||
conn.run = true;
|
||||
conn.block_after_ACK = flash_mode;
|
||||
pthread_create(&USB_communication_thread, NULL, &uart_communication, &conn);
|
||||
//pthread_create(&FPC_communication_thread, NULL, &uart_communication, &conn);
|
||||
|
||||
fflush(NULL);
|
||||
// create a mutex to avoid interlacing print commands from our different threads
|
||||
//pthread_mutex_init(&print_lock, NULL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void CloseProxmark(void) {
|
||||
conn.run = false;
|
||||
pthread_join(USB_communication_thread, NULL);
|
||||
//pthread_join(FPC_communication_thread, NULL);
|
||||
|
||||
if (sp) {
|
||||
uart_close(sp);
|
||||
}
|
||||
|
||||
#if defined(__linux__) && !defined(NO_UNLINK)
|
||||
// Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
|
||||
//
|
||||
// This may be disabled at compile-time with -DNO_UNLINK (used for a JNI-based serial port on Android).
|
||||
if (serial_port_name) {
|
||||
unlink(serial_port_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Clean up our state
|
||||
sp = NULL;
|
||||
serial_port_name = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits for a certain response type. This method waits for a maximum of
|
||||
* ms_timeout milliseconds for a specified response command.
|
||||
|
||||
* @param cmd command to wait for, or CMD_UNKNOWN to take any command.
|
||||
* @param response struct to copy received command into.
|
||||
* @param ms_timeout display message after 3 seconds
|
||||
* @param show_warning display message after 3 seconds
|
||||
* @return true if command was returned, otherwise false
|
||||
*/
|
||||
bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning) {
|
||||
|
||||
UsbCommand resp;
|
||||
|
||||
if (response == NULL)
|
||||
response = &resp;
|
||||
|
||||
uint64_t start_time = msclock();
|
||||
|
||||
// Wait until the command is received
|
||||
while (true) {
|
||||
|
||||
while ( getCommand(response) ) {
|
||||
if (cmd == CMD_UNKNOWN || response->cmd == cmd)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (msclock() - start_time > ms_timeout)
|
||||
break;
|
||||
|
||||
if (msclock() - start_time > 3000 && show_warning) {
|
||||
// 3 seconds elapsed (but this doesn't mean the timeout was exceeded)
|
||||
PrintAndLogEx(NORMAL, "Waiting for a response from the proxmark...");
|
||||
PrintAndLogEx(NORMAL, "You can cancel this operation by pressing the pm3 button");
|
||||
show_warning = false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
|
||||
return WaitForResponseTimeoutW(cmd, response, ms_timeout, true);
|
||||
}
|
||||
|
||||
bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
|
||||
return WaitForResponseTimeoutW(cmd, response, -1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data transfer from Proxmark to client. This method times out after
|
||||
* ms_timeout milliseconds.
|
||||
* @brief GetFromDevice
|
||||
* @param memtype Type of memory to download from proxmark
|
||||
* @param dest Destination address for transfer
|
||||
* @param bytes number of bytes to be transferred
|
||||
* @param start_index offset into Proxmark3 BigBuf[]
|
||||
* @param response struct to copy last command (CMD_ACK) into
|
||||
* @param ms_timeout timeout in milliseconds
|
||||
* @param show_warning display message after 2 seconds
|
||||
* @return true if command was returned, otherwise false
|
||||
*/
|
||||
bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) {
|
||||
|
||||
if (dest == NULL) return false;
|
||||
if (bytes == 0) return true;
|
||||
|
||||
UsbCommand resp;
|
||||
if (response == NULL)
|
||||
response = &resp;
|
||||
|
||||
// clear
|
||||
clearCommandBuffer();
|
||||
|
||||
switch (memtype) {
|
||||
case BIG_BUF: {
|
||||
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
||||
SendCommand(&c);
|
||||
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
|
||||
}
|
||||
case BIG_BUF_EML: {
|
||||
UsbCommand c = {CMD_DOWNLOAD_EML_BIGBUF, {start_index, bytes, 0}};
|
||||
SendCommand(&c);
|
||||
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF);
|
||||
}
|
||||
case FLASH_MEM: {
|
||||
UsbCommand c = {CMD_FLASHMEM_DOWNLOAD, {start_index, bytes, 0}};
|
||||
SendCommand(&c);
|
||||
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED);
|
||||
}
|
||||
case SIM_MEM: {
|
||||
//UsbCommand c = {CMD_DOWNLOAND_SIM_MEM, {start_index, bytes, 0}};
|
||||
//SendCommand(&c);
|
||||
//return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_SIMMEM);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd) {
|
||||
|
||||
uint32_t bytes_completed = 0;
|
||||
uint64_t start_time = msclock();
|
||||
|
||||
while (true) {
|
||||
|
||||
if (getCommand(response)) {
|
||||
|
||||
// sample_buf is a array pointer, located in data.c
|
||||
// arg0 = offset in transfer. Startindex of this chunk
|
||||
// arg1 = length bytes to transfer
|
||||
// arg2 = bigbuff tracelength (?)
|
||||
if (response->cmd == rec_cmd) {
|
||||
|
||||
uint32_t offset = response->arg[0];
|
||||
uint32_t copy_bytes = MIN(bytes - bytes_completed, response->arg[1]);
|
||||
//uint32_t tracelen = c->arg[2];
|
||||
|
||||
// extended bounds check1. upper limit is USB_CMD_DATA_SIZE
|
||||
// shouldn't happen
|
||||
copy_bytes = MIN(copy_bytes, USB_CMD_DATA_SIZE);
|
||||
|
||||
// extended bounds check2.
|
||||
if ( offset + copy_bytes > bytes ) {
|
||||
PrintAndLogEx(FAILED, "ERROR: Out of bounds when downloading from device, offset %u | len %u | total len %u > buf_size %u", offset, copy_bytes, offset+copy_bytes, bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(dest + offset, response->d.asBytes, copy_bytes);
|
||||
bytes_completed += copy_bytes;
|
||||
} else if (response->cmd == CMD_ACK) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (msclock() - start_time > ms_timeout) {
|
||||
PrintAndLogEx(FAILED, "Timed out while trying to download data from device");
|
||||
break;
|
||||
}
|
||||
|
||||
if (msclock() - start_time > 3000 && show_warning) {
|
||||
// 3 seconds elapsed (but this doesn't mean the timeout was exceeded)
|
||||
PrintAndLogEx(NORMAL, "Waiting for a response from the proxmark...");
|
||||
PrintAndLogEx(NORMAL, "You can cancel this operation by pressing the pm3 button");
|
||||
show_warning = false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
67
client/comms.h
Normal file
67
client/comms.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
|
||||
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Code for communicating with the proxmark3 hardware.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef COMMS_H_
|
||||
#define COMMS_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "usb_cmd.h"
|
||||
#include "uart.h"
|
||||
#include "ui.h"
|
||||
#include "common.h"
|
||||
#include "util_posix.h"
|
||||
#include "util.h"
|
||||
|
||||
#if defined(__linux__) && !defined(NO_UNLINK)
|
||||
#include <unistd.h> // for unlink()
|
||||
#endif
|
||||
|
||||
//For storing command that are received from the device
|
||||
#ifndef CMD_BUFFER_SIZE
|
||||
#define CMD_BUFFER_SIZE 100
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
BIG_BUF,
|
||||
BIG_BUF_EML,
|
||||
FLASH_MEM,
|
||||
SIM_MEM,
|
||||
} DeviceMemType_t;
|
||||
|
||||
typedef struct {
|
||||
bool run; // If TRUE, continue running the uart_communication thread
|
||||
bool block_after_ACK; // if true, block after receiving an ACK package
|
||||
} communication_arg_t;
|
||||
|
||||
|
||||
bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd);
|
||||
|
||||
void SetOffline(bool value);
|
||||
bool IsOffline();
|
||||
|
||||
void *uart_receiver(void *targ);
|
||||
void SendCommand(UsbCommand *c);
|
||||
void clearCommandBuffer();
|
||||
|
||||
bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode);
|
||||
void CloseProxmark(void);
|
||||
|
||||
bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
|
||||
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
|
||||
bool WaitForResponse(uint32_t cmd, UsbCommand* response);
|
||||
|
||||
extern bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -10,11 +10,6 @@
|
|||
|
||||
#include "flash.h"
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
11
client/ui.c
11
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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
37
common/cmd.c
37
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;
|
||||
}
|
|
@ -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_
|
||||
|
||||
|
|
316
common/usart.c
316
common/usart.c
|
@ -1,17 +1,23 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Iceman, July 2018
|
||||
// edists by - Anticat, August 2018
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// The main USART code, for serial communications over FPC connector
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "usart.h"
|
||||
#include "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);
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
14
uart/uart.h
14
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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue