mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-06 13:11:18 -07:00
Comms refactor (prerequisite of libproxmark work) (#371)
* Refactor the comms code only from PR#346, without comms_globals.h. * OSX: Add note for example serial port
This commit is contained in:
parent
e17660d5f7
commit
afdcb8c159
19 changed files with 540 additions and 334 deletions
|
@ -21,7 +21,7 @@ LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
|
||||||
LUALIB = ../liblua/liblua.a
|
LUALIB = ../liblua/liblua.a
|
||||||
LDFLAGS = $(ENV_LDFLAGS)
|
LDFLAGS = $(ENV_LDFLAGS)
|
||||||
CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall -g -O3
|
CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall -g -O3
|
||||||
CXXFLAGS = -I../include -Wall -O3
|
CXXFLAGS = -I../include -I../uart -Wall -O3
|
||||||
|
|
||||||
LUAPLATFORM = generic
|
LUAPLATFORM = generic
|
||||||
platform = $(shell uname)
|
platform = $(shell uname)
|
||||||
|
@ -82,7 +82,10 @@ POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d
|
||||||
CORESRCS = uart_posix.c \
|
CORESRCS = uart_posix.c \
|
||||||
uart_win32.c \
|
uart_win32.c \
|
||||||
util.c \
|
util.c \
|
||||||
util_posix.c
|
util_posix.c \
|
||||||
|
comms.c \
|
||||||
|
data.c \
|
||||||
|
ui.c
|
||||||
|
|
||||||
CMDSRCS = crapto1/crapto1.c\
|
CMDSRCS = crapto1/crapto1.c\
|
||||||
crapto1/crypto1.c\
|
crapto1/crypto1.c\
|
||||||
|
@ -102,9 +105,7 @@ CMDSRCS = crapto1/crapto1.c\
|
||||||
crc64.c \
|
crc64.c \
|
||||||
iso14443crc.c \
|
iso14443crc.c \
|
||||||
iso15693tools.c \
|
iso15693tools.c \
|
||||||
data.c \
|
|
||||||
graph.c \
|
graph.c \
|
||||||
ui.c \
|
|
||||||
cmddata.c \
|
cmddata.c \
|
||||||
lfdemod.c \
|
lfdemod.c \
|
||||||
cmdhf.c \
|
cmdhf.c \
|
||||||
|
@ -175,6 +176,7 @@ ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
|
||||||
#-DDEBUG -Dverbose=1
|
#-DDEBUG -Dverbose=1
|
||||||
|
|
||||||
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
|
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
|
||||||
|
NOGUISRCS = guidummy.cpp
|
||||||
|
|
||||||
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
||||||
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
|
|
|
@ -335,7 +335,7 @@ int CmdLFSetConfig(const char *Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lf_read(bool silent, uint32_t samples) {
|
bool lf_read(bool silent, uint32_t samples) {
|
||||||
if (offline) return false;
|
if (IsOffline()) return false;
|
||||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent,samples,0}};
|
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent,samples,0}};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
//And ship it to device
|
//And ship it to device
|
||||||
|
@ -878,7 +878,7 @@ int CmdVchDemod(const char *Cmd)
|
||||||
int CheckChipType(char cmdp) {
|
int CheckChipType(char cmdp) {
|
||||||
uint32_t wordData = 0;
|
uint32_t wordData = 0;
|
||||||
|
|
||||||
if (offline || cmdp == '1') return 0;
|
if (IsOffline() || cmdp == '1') return 0;
|
||||||
|
|
||||||
save_restoreGB(GRAPH_SAVE);
|
save_restoreGB(GRAPH_SAVE);
|
||||||
save_restoreDB(GRAPH_SAVE);
|
save_restoreDB(GRAPH_SAVE);
|
||||||
|
@ -923,7 +923,7 @@ int CmdLFfind(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!offline && (cmdp != '1')) {
|
if (!IsOffline() && (cmdp != '1')) {
|
||||||
lf_read(true, 30000);
|
lf_read(true, 30000);
|
||||||
} else if (GraphTraceLen < minLength) {
|
} else if (GraphTraceLen < minLength) {
|
||||||
PrintAndLog("Data in Graphbuffer was too small.");
|
PrintAndLog("Data in Graphbuffer was too small.");
|
||||||
|
@ -939,7 +939,7 @@ int CmdLFfind(const char *Cmd)
|
||||||
// only run if graphbuffer is just noise as it should be for hitag/cotag
|
// only run if graphbuffer is just noise as it should be for hitag/cotag
|
||||||
if (graphJustNoise(GraphBuffer, testLen)) {
|
if (graphJustNoise(GraphBuffer, testLen)) {
|
||||||
// only run these tests if we are in online mode
|
// only run these tests if we are in online mode
|
||||||
if (!offline && (cmdp != '1')) {
|
if (!IsOffline() && (cmdp != '1')) {
|
||||||
// test for em4x05 in reader talk first mode.
|
// test for em4x05 in reader talk first mode.
|
||||||
if (EM4x05Block0Test(&wordData)) {
|
if (EM4x05Block0Test(&wordData)) {
|
||||||
PrintAndLog("\nValid EM4x05/EM4x69 Chip Found\nUse lf em 4x05readword/dump commands to read\n");
|
PrintAndLog("\nValid EM4x05/EM4x69 Chip Found\nUse lf em 4x05readword/dump commands to read\n");
|
||||||
|
|
152
client/cmdmain.c
152
client/cmdmain.c
|
@ -36,15 +36,6 @@ static int CmdHelp(const char *Cmd);
|
||||||
static int CmdQuit(const char *Cmd);
|
static int CmdQuit(const char *Cmd);
|
||||||
static int CmdRev(const char *Cmd);
|
static int CmdRev(const char *Cmd);
|
||||||
|
|
||||||
//For storing command that are received from the device
|
|
||||||
#define CMD_BUFFER_SIZE 50
|
|
||||||
static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
|
|
||||||
//Points to the next empty position to write to
|
|
||||||
static int cmd_head;//Starts as 0
|
|
||||||
//Points to the position of the last unread command
|
|
||||||
static int cmd_tail;//Starts as 0
|
|
||||||
// to lock cmdBuffer operations from different threads
|
|
||||||
static pthread_mutex_t cmdBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
|
@ -64,6 +55,7 @@ command_t* getTopLevelCommandTable()
|
||||||
{
|
{
|
||||||
return CommandTable;
|
return CommandTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd)
|
int CmdHelp(const char *Cmd)
|
||||||
{
|
{
|
||||||
CmdsHelp(CommandTable);
|
CmdsHelp(CommandTable);
|
||||||
|
@ -81,113 +73,6 @@ int CmdRev(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.
|
|
||||||
PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!");
|
|
||||||
}
|
|
||||||
//Store the command at the 'head' location
|
|
||||||
UsbCommand* destination = &cmdBuffer[cmd_head];
|
|
||||||
memcpy(destination, command, sizeof(UsbCommand));
|
|
||||||
|
|
||||||
cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Waits for a certain response type. This method waits for a maximum of
|
|
||||||
* ms_timeout milliseconds for a specified response command.
|
|
||||||
*@brief WaitForResponseTimeout
|
|
||||||
* @param cmd command to wait for
|
|
||||||
* @param response struct to copy received command into.
|
|
||||||
* @param ms_timeout
|
|
||||||
* @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(response->cmd == cmd){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msclock() - start_time > ms_timeout) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (msclock() - start_time > 2000 && show_warning) {
|
|
||||||
PrintAndLog("Waiting for a response from the proxmark...");
|
|
||||||
PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
|
|
||||||
return WaitForResponseTimeoutW(cmd, response, ms_timeout, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
|
|
||||||
return WaitForResponseTimeoutW(cmd, response, -1, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Entry point into our code: called whenever the user types a command and
|
// Entry point into our code: called whenever the user types a command and
|
||||||
// then presses Enter, which the full command line that they typed.
|
// then presses Enter, which the full command line that they typed.
|
||||||
|
@ -196,38 +81,3 @@ int CommandReceived(char *Cmd) {
|
||||||
return CmdsParse(CommandTable, Cmd);
|
return CmdsParse(CommandTable, Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Entry point into our code: called whenever we received a packet over USB
|
|
||||||
// that we weren't necessarily expecting, for example a debug print.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void UsbCommandReceived(UsbCommand *UC)
|
|
||||||
{
|
|
||||||
switch(UC->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(UC->arg[0],USB_CMD_DATA_SIZE);
|
|
||||||
memcpy(s,UC->d.asBytes,len);
|
|
||||||
PrintAndLog("#db# %s", s);
|
|
||||||
return;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case CMD_DEBUG_PRINT_INTEGERS: {
|
|
||||||
PrintAndLog("#db# %08x, %08x, %08x \r\n", UC->arg[0], UC->arg[1], UC->arg[2]);
|
|
||||||
return;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
|
|
||||||
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
|
|
||||||
return;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
storeCommand(UC);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,10 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
|
|
||||||
extern void UsbCommandReceived(UsbCommand *UC);
|
|
||||||
extern int CommandReceived(char *Cmd);
|
extern int CommandReceived(char *Cmd);
|
||||||
extern bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
|
|
||||||
extern bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
|
|
||||||
extern bool WaitForResponse(uint32_t cmd, UsbCommand* response);
|
|
||||||
extern void clearCommandBuffer();
|
|
||||||
extern command_t* getTopLevelCommandTable();
|
extern command_t* getTopLevelCommandTable();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
|
|
||||||
void CmdsHelp(const command_t Commands[])
|
void CmdsHelp(const command_t Commands[])
|
||||||
|
@ -23,7 +24,7 @@ void CmdsHelp(const command_t Commands[])
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (Commands[i].Name)
|
while (Commands[i].Name)
|
||||||
{
|
{
|
||||||
if (!offline || Commands[i].Offline)
|
if (!IsOffline() || Commands[i].Offline)
|
||||||
PrintAndLog("%-16s %s", Commands[i].Name, Commands[i].Help);
|
PrintAndLog("%-16s %s", Commands[i].Name, Commands[i].Help);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
325
client/comms.c
Normal file
325
client/comms.c
Normal file
|
@ -0,0 +1,325 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 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 <pthread.h>
|
||||||
|
|
||||||
|
#include "comms.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "data.h"
|
||||||
|
#include "util_posix.h"
|
||||||
|
|
||||||
|
// Declare globals.
|
||||||
|
|
||||||
|
// Serial port that we are communicating with the PM3 on.
|
||||||
|
static serial_port* port;
|
||||||
|
|
||||||
|
// If TRUE, then there is no active connection to the PM3, and we will drop commands sent.
|
||||||
|
static bool offline;
|
||||||
|
|
||||||
|
// Transmit buffer.
|
||||||
|
// TODO: Use locks and execute this on the main thread, rather than the receiver
|
||||||
|
// thread. Running on the main thread means we need to be careful in the
|
||||||
|
// flasher, as it means SendCommand is no longer async, and can't be used as a
|
||||||
|
// buffer for a pending command when the connection is re-established.
|
||||||
|
static UsbCommand txcmd;
|
||||||
|
static bool txcmd_pending;
|
||||||
|
|
||||||
|
// Used by UsbReceiveCommand as a ring buffer for messages that are yet to be
|
||||||
|
// processed by a command handler (WaitForResponse{,Timeout})
|
||||||
|
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;
|
||||||
|
|
||||||
|
// These wrappers are required because it is not possible to access a static
|
||||||
|
// global variable outside of the context of a single file.
|
||||||
|
|
||||||
|
void SetSerialPort(serial_port* new_port) {
|
||||||
|
port = new_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_port* GetSerialPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetOffline(bool new_offline) {
|
||||||
|
offline = new_offline;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsOffline() {
|
||||||
|
return offline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendCommand(UsbCommand *c) {
|
||||||
|
#ifdef COMMS_DEBUG
|
||||||
|
printf("Sending %04x cmd\n", c->cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (offline) {
|
||||||
|
PrintAndLog("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;
|
||||||
|
txcmd_pending = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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.
|
||||||
|
PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the command at the 'head' location
|
||||||
|
UsbCommand* destination = &cmdBuffer[cmd_head];
|
||||||
|
memcpy(destination, command, sizeof(UsbCommand));
|
||||||
|
|
||||||
|
cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Entry point into our code: called whenever we received a packet over USB
|
||||||
|
// that we weren't necessarily expecting, for example a debug print.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void UsbCommandReceived(UsbCommand *UC)
|
||||||
|
{
|
||||||
|
switch(UC->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(UC->arg[0],USB_CMD_DATA_SIZE);
|
||||||
|
memcpy(s,UC->d.asBytes,len);
|
||||||
|
PrintAndLog("#db# %s", s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CMD_DEBUG_PRINT_INTEGERS: {
|
||||||
|
PrintAndLog("#db# %08x, %08x, %08x \r\n", UC->arg[0], UC->arg[1], UC->arg[2]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
|
||||||
|
// FIXME: This does unsanitised copies into memory when we don't know
|
||||||
|
// the size of the buffer.
|
||||||
|
if (sample_buf) {
|
||||||
|
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
storeCommand(UC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a single command from a proxmark3 device. This should never be used
|
||||||
|
// with the full client.
|
||||||
|
//
|
||||||
|
// @param conn A receiver_arg structure.
|
||||||
|
// @param command A buffer to store the received command.
|
||||||
|
bool ReceiveCommand(receiver_arg* conn, UsbCommand* command) {
|
||||||
|
// Local recieve buffer
|
||||||
|
size_t rxlen;
|
||||||
|
byte_t rx[sizeof(UsbCommand)];
|
||||||
|
byte_t* prx = rx;
|
||||||
|
|
||||||
|
while (conn->run) {
|
||||||
|
rxlen = 0;
|
||||||
|
if (uart_receive(port, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) {
|
||||||
|
prx += rxlen;
|
||||||
|
if (prx-rx < sizeof(UsbCommand)) {
|
||||||
|
// Keep reading until we have a completed response.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have a completed response.
|
||||||
|
memcpy(command, rx, sizeof(UsbCommand));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prx == rx) {
|
||||||
|
// We got no complete command while waiting, give up control
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// did not get a complete command before being cancelled.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Worker thread for processing incoming events from the PM3
|
||||||
|
void *uart_receiver(void *targ) {
|
||||||
|
receiver_arg *conn = (receiver_arg*)targ;
|
||||||
|
UsbCommand rx;
|
||||||
|
|
||||||
|
while (conn->run) {
|
||||||
|
#ifdef COMMS_DEBUG
|
||||||
|
printf("uart_receiver: get lock\n");
|
||||||
|
#endif
|
||||||
|
// Lock up receives, in case they try to take it away from us.
|
||||||
|
pthread_mutex_lock(&conn->recv_lock);
|
||||||
|
#ifdef COMMS_DEBUG
|
||||||
|
printf("uart_receiver: lock acquired\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (port == NULL) {
|
||||||
|
#ifdef COMMS_DEBUG
|
||||||
|
printf("uart_receiver: port disappeared\n");
|
||||||
|
#endif
|
||||||
|
// Our port disappeared, stall. This code path matters for the flasher,
|
||||||
|
// where it is fiddling with the serial port under us.
|
||||||
|
pthread_mutex_unlock(&conn->recv_lock);
|
||||||
|
msleep(10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool got_command = ReceiveCommand(conn, &rx);
|
||||||
|
#ifdef COMMS_DEBUG
|
||||||
|
printf("uart_receiver: got command\n");
|
||||||
|
#endif
|
||||||
|
pthread_mutex_unlock(&conn->recv_lock);
|
||||||
|
|
||||||
|
if (got_command) {
|
||||||
|
UsbCommandReceived(&rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We aren't normally trying to transmit in the flasher when the port would
|
||||||
|
// be reset, so we can just keep going at this point.
|
||||||
|
if (txcmd_pending) {
|
||||||
|
if (!uart_send(port, (byte_t*) &txcmd, sizeof(UsbCommand))) {
|
||||||
|
PrintAndLog("Sending bytes to proxmark failed");
|
||||||
|
}
|
||||||
|
txcmd_pending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits for a certain response type. This method waits for a maximum of
|
||||||
|
* ms_timeout milliseconds for a specified response command.
|
||||||
|
*@brief WaitForResponseTimeout
|
||||||
|
* @param cmd command to wait for, or CMD_ANY to take any command.
|
||||||
|
* @param response struct to copy received command into.
|
||||||
|
* @param ms_timeout
|
||||||
|
* @param show_warning
|
||||||
|
* @return true if command was returned, otherwise false
|
||||||
|
*/
|
||||||
|
bool WaitForResponseTimeoutW(uint64_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning) {
|
||||||
|
UsbCommand resp;
|
||||||
|
|
||||||
|
#ifdef COMMS_DEBUG
|
||||||
|
printf("Waiting for %04x cmd\n", cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (response == NULL) {
|
||||||
|
response = &resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t start_time = msclock();
|
||||||
|
|
||||||
|
// Wait until the command is received
|
||||||
|
for (;;) {
|
||||||
|
while(getCommand(response)) {
|
||||||
|
if (cmd == CMD_ANY || response->cmd == cmd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msclock() - start_time > ms_timeout) {
|
||||||
|
// We timed out.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msclock() - start_time > 2000 && show_warning) {
|
||||||
|
// 2 seconds elapsed (but this doesn't mean the timeout was exceeded)
|
||||||
|
PrintAndLog("Waiting for a response from the proxmark...");
|
||||||
|
PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitForResponseTimeout(uint64_t cmd, UsbCommand* response, size_t ms_timeout) {
|
||||||
|
return WaitForResponseTimeoutW(cmd, response, ms_timeout, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaitForResponse(uint64_t cmd, UsbCommand* response) {
|
||||||
|
return WaitForResponseTimeout(cmd, response, -1);
|
||||||
|
}
|
45
client/comms.h
Normal file
45
client/comms.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef COMMS_H_
|
||||||
|
#define COMMS_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "usb_cmd.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
#ifndef CMD_BUFFER_SIZE
|
||||||
|
#define CMD_BUFFER_SIZE 50
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_DEMOD_BUF_LEN
|
||||||
|
#define MAX_DEMOD_BUF_LEN (1024*128)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BIGBUF_SIZE
|
||||||
|
#define BIGBUF_SIZE 40000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// If TRUE, continue running the uart_receiver thread.
|
||||||
|
bool run;
|
||||||
|
|
||||||
|
// Lock around serial port receives
|
||||||
|
pthread_mutex_t recv_lock;
|
||||||
|
} receiver_arg;
|
||||||
|
|
||||||
|
|
||||||
|
// Wrappers required as static variables can only be used in one file.
|
||||||
|
void SetSerialPort(serial_port* new_port);
|
||||||
|
serial_port* GetSerialPort();
|
||||||
|
void SetOffline(bool new_offline);
|
||||||
|
bool IsOffline();
|
||||||
|
|
||||||
|
void SendCommand(UsbCommand *c);
|
||||||
|
void *uart_receiver(void *targ);
|
||||||
|
void UsbCommandReceived(UsbCommand *UC);
|
||||||
|
void clearCommandBuffer();
|
||||||
|
bool WaitForResponseTimeoutW(uint64_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
|
||||||
|
bool WaitForResponseTimeout(uint64_t cmd, UsbCommand* response, size_t ms_timeout);
|
||||||
|
bool WaitForResponse(uint64_t cmd, UsbCommand* response);
|
||||||
|
|
||||||
|
#endif // COMMS_H_
|
|
@ -13,6 +13,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
|
@ -20,11 +21,7 @@
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "proxendian.h"
|
#include "proxendian.h"
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
|
#include "comms.h"
|
||||||
void SendCommand(UsbCommand* txcmd);
|
|
||||||
void ReceiveCommand(UsbCommand* rxcmd);
|
|
||||||
void CloseProxmark();
|
|
||||||
int OpenProxmark(size_t i);
|
|
||||||
|
|
||||||
// FIXME: what the fuckity fuck
|
// FIXME: what the fuckity fuck
|
||||||
unsigned int current_command = CMD_UNKNOWN;
|
unsigned int current_command = CMD_UNKNOWN;
|
||||||
|
@ -44,6 +41,32 @@ static const uint8_t elf_ident[] = {
|
||||||
EV_CURRENT
|
EV_CURRENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void CloseProxmark(receiver_arg* conn, char* serial_port_name) {
|
||||||
|
pthread_mutex_lock(&conn->recv_lock);
|
||||||
|
|
||||||
|
// Block the port from being used by anything
|
||||||
|
serial_port* my_port = GetSerialPort();
|
||||||
|
SetSerialPort(NULL);
|
||||||
|
|
||||||
|
// Then close the port.
|
||||||
|
uart_close(my_port);
|
||||||
|
pthread_mutex_unlock(&conn->recv_lock);
|
||||||
|
|
||||||
|
// Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
|
||||||
|
unlink(serial_port_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenProxmark(char* serial_port_name) {
|
||||||
|
serial_port *new_port = uart_open(serial_port_name);
|
||||||
|
if (new_port == INVALID_SERIAL_PORT || new_port == CLAIMED_SERIAL_PORT) {
|
||||||
|
//poll once a second
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSerialPort(new_port);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent
|
// Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent
|
||||||
// unaligned segments if needed
|
// unaligned segments if needed
|
||||||
static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, int num_phdrs)
|
static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, int num_phdrs)
|
||||||
|
@ -278,9 +301,12 @@ static int get_proxmark_state(uint32_t *state)
|
||||||
{
|
{
|
||||||
UsbCommand c;
|
UsbCommand c;
|
||||||
c.cmd = CMD_DEVICE_INFO;
|
c.cmd = CMD_DEVICE_INFO;
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
ReceiveCommand(&resp);
|
while (!WaitForResponse(CMD_ANY, &resp)) {
|
||||||
|
// Keep waiting for a response
|
||||||
|
msleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
// Three outcomes:
|
// Three outcomes:
|
||||||
// 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
|
// 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
|
||||||
|
@ -307,7 +333,7 @@ static int get_proxmark_state(uint32_t *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter the bootloader to be able to start flashing
|
// Enter the bootloader to be able to start flashing
|
||||||
static int enter_bootloader(char *serial_port_name)
|
static int enter_bootloader(receiver_arg* conn, char *serial_port_name)
|
||||||
{
|
{
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
|
|
||||||
|
@ -338,16 +364,17 @@ static int enter_bootloader(char *serial_port_name)
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
fprintf(stderr,"Press and hold down button NOW if your bootloader requires it.\n");
|
fprintf(stderr,"Press and hold down button NOW if your bootloader requires it.\n");
|
||||||
}
|
}
|
||||||
msleep(100);
|
|
||||||
CloseProxmark();
|
msleep(100);
|
||||||
|
CloseProxmark(conn, serial_port_name);
|
||||||
|
|
||||||
fprintf(stderr,"Waiting for Proxmark to reappear on %s",serial_port_name);
|
fprintf(stderr,"Waiting for Proxmark to reappear on %s",serial_port_name);
|
||||||
do {
|
do {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
fprintf(stderr, ".");
|
fprintf(stderr, ".");
|
||||||
} while (!OpenProxmark(0));
|
} while (!OpenProxmark(serial_port_name));
|
||||||
|
|
||||||
fprintf(stderr," Found.\n");
|
fprintf(stderr," Found.\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,23 +382,25 @@ static int enter_bootloader(char *serial_port_name)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_for_ack(void)
|
static int wait_for_ack()
|
||||||
{
|
{
|
||||||
UsbCommand ack;
|
UsbCommand resp;
|
||||||
ReceiveCommand(&ack);
|
while (!WaitForResponse(CMD_ANY, &resp)) {
|
||||||
if (ack.cmd != CMD_ACK) {
|
msleep(100);
|
||||||
printf("Error: Unexpected reply 0x%04" PRIx64 " (expected ACK)\n", ack.cmd);
|
}
|
||||||
|
if (resp.cmd != CMD_ACK) {
|
||||||
|
printf("Error: Unexpected reply 0x%04" PRIx64 " (expected ACK)\n", resp.cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go into flashing mode
|
// Go into flashing mode
|
||||||
int flash_start_flashing(int enable_bl_writes,char *serial_port_name)
|
int flash_start_flashing(receiver_arg* conn, int enable_bl_writes,char *serial_port_name)
|
||||||
{
|
{
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
|
|
||||||
if (enter_bootloader(serial_port_name) < 0)
|
if (enter_bootloader(conn, serial_port_name) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (get_proxmark_state(&state) < 0)
|
if (get_proxmark_state(&state) < 0)
|
||||||
|
@ -470,9 +499,9 @@ void flash_free(flash_file_t *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// just reset the unit
|
// just reset the unit
|
||||||
int flash_stop_flashing(void) {
|
int flash_stop_flashing() {
|
||||||
UsbCommand c = {CMD_HARDWARE_RESET};
|
UsbCommand c = {CMD_HARDWARE_RESET};
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *data;
|
void *data;
|
||||||
|
@ -26,10 +27,12 @@ typedef struct {
|
||||||
} flash_file_t;
|
} flash_file_t;
|
||||||
|
|
||||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl);
|
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl);
|
||||||
int flash_start_flashing(int enable_bl_writes,char *serial_port_name);
|
int flash_start_flashing(receiver_arg* conn, int enable_bl_writes, char *serial_port_name);
|
||||||
int flash_write(flash_file_t *ctx);
|
int flash_write(flash_file_t *ctx);
|
||||||
void flash_free(flash_file_t *ctx);
|
void flash_free(flash_file_t *ctx);
|
||||||
int flash_stop_flashing(void);
|
int flash_stop_flashing(void);
|
||||||
|
void CloseProxmark(receiver_arg* conn, char* serial_port_name);
|
||||||
|
bool OpenProxmark(char* serial_port_name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,15 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# define unlink(x)
|
# define unlink(x)
|
||||||
|
@ -23,9 +26,6 @@
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static serial_port sp;
|
|
||||||
static char* serial_port_name;
|
|
||||||
|
|
||||||
void cmd_debug(UsbCommand* UC) {
|
void cmd_debug(UsbCommand* UC) {
|
||||||
// Debug
|
// Debug
|
||||||
printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand));
|
printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand));
|
||||||
|
@ -40,45 +40,6 @@ void cmd_debug(UsbCommand* UC) {
|
||||||
printf("...\n");
|
printf("...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendCommand(UsbCommand* txcmd) {
|
|
||||||
// printf("send: ");
|
|
||||||
// cmd_debug(txcmd);
|
|
||||||
if (!uart_send(sp,(byte_t*)txcmd,sizeof(UsbCommand))) {
|
|
||||||
printf("Sending bytes to proxmark failed\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReceiveCommand(UsbCommand* rxcmd) {
|
|
||||||
byte_t* prxcmd = (byte_t*)rxcmd;
|
|
||||||
byte_t* prx = prxcmd;
|
|
||||||
size_t rxlen;
|
|
||||||
while (true) {
|
|
||||||
if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-prxcmd), &rxlen)) {
|
|
||||||
prx += rxlen;
|
|
||||||
if ((prx-prxcmd) >= sizeof(UsbCommand)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloseProxmark() {
|
|
||||||
// Clean up the port
|
|
||||||
uart_close(sp);
|
|
||||||
// Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
|
|
||||||
unlink(serial_port_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
int OpenProxmark(size_t i) {
|
|
||||||
sp = uart_open(serial_port_name);
|
|
||||||
if (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT) {
|
|
||||||
//poll once a second
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usage(char *argv0)
|
static void usage(char *argv0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
|
fprintf(stderr, "Usage: %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
|
||||||
|
@ -86,9 +47,10 @@ static void usage(char *argv0)
|
||||||
//Is the example below really true? /Martin
|
//Is the example below really true? /Martin
|
||||||
fprintf(stderr, "Example:\n\n\t %s path/to/osimage.elf path/to/fpgaimage.elf\n", argv0);
|
fprintf(stderr, "Example:\n\n\t %s path/to/osimage.elf path/to/fpgaimage.elf\n", argv0);
|
||||||
fprintf(stderr, "\nExample (Linux):\n\n\t %s /dev/ttyACM0 armsrc/obj/fullimage.elf\n", argv0);
|
fprintf(stderr, "\nExample (Linux):\n\n\t %s /dev/ttyACM0 armsrc/obj/fullimage.elf\n", argv0);
|
||||||
fprintf(stderr, "\nNote (Linux): if the flasher gets stuck in 'Waiting for Proxmark to reappear on <DEVICE>',\n");
|
fprintf(stderr, "\nNote (Linux): if the flasher gets stuck at 'Waiting for Proxmark to reappear',\n");
|
||||||
fprintf(stderr, " you need to blacklist proxmark for modem-manager - see wiki for more details:\n");
|
fprintf(stderr, " you may need to blacklist proxmark for modem-manager. v1.4.14 and later\n");
|
||||||
fprintf(stderr, " http://code.google.com/p/proxmark3/wiki/Linux\n\n");
|
fprintf(stderr, " include this configuration patch already. The change can be found at:\n");
|
||||||
|
fprintf(stderr, " https://cgit.freedesktop.org/ModemManager/ModemManager/commit/?id=6e7ff47\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_FILES 4
|
#define MAX_FILES 4
|
||||||
|
@ -99,7 +61,10 @@ int main(int argc, char **argv)
|
||||||
int num_files = 0;
|
int num_files = 0;
|
||||||
int res;
|
int res;
|
||||||
flash_file_t files[MAX_FILES];
|
flash_file_t files[MAX_FILES];
|
||||||
|
receiver_arg conn;
|
||||||
|
pthread_t reader_thread;
|
||||||
|
|
||||||
|
memset(&conn, 0, sizeof(receiver_arg));
|
||||||
memset(files, 0, sizeof(files));
|
memset(files, 0, sizeof(files));
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
|
@ -126,16 +91,22 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serial_port_name = argv[1];
|
pthread_mutex_init(&conn.recv_lock, NULL);
|
||||||
|
|
||||||
fprintf(stderr,"Waiting for Proxmark to appear on %s",serial_port_name);
|
|
||||||
do {
|
|
||||||
msleep(1000);
|
|
||||||
fprintf(stderr, ".");
|
|
||||||
} while (!OpenProxmark(0));
|
|
||||||
fprintf(stderr," Found.\n");
|
|
||||||
|
|
||||||
res = flash_start_flashing(can_write_bl,serial_port_name);
|
char* serial_port_name = argv[1];
|
||||||
|
|
||||||
|
fprintf(stderr,"Waiting for Proxmark to appear on %s", serial_port_name);
|
||||||
|
do {
|
||||||
|
sleep(1);
|
||||||
|
fprintf(stderr, ".");
|
||||||
|
} while (!OpenProxmark(serial_port_name));
|
||||||
|
fprintf(stderr," Found.\n");
|
||||||
|
|
||||||
|
// Lets start up the communications thread
|
||||||
|
conn.run = true;
|
||||||
|
pthread_create(&reader_thread, NULL, &uart_receiver, &conn);
|
||||||
|
|
||||||
|
res = flash_start_flashing(&conn, can_write_bl, serial_port_name);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -155,7 +126,11 @@ int main(int argc, char **argv)
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CloseProxmark();
|
// Stop the command thread.
|
||||||
|
conn.run = false;
|
||||||
|
pthread_join(reader_thread, NULL);
|
||||||
|
CloseProxmark(&conn, serial_port_name);
|
||||||
|
pthread_mutex_destroy(&conn.recv_lock);
|
||||||
|
|
||||||
fprintf(stderr, "All done.\n\n");
|
fprintf(stderr, "All done.\n\n");
|
||||||
fprintf(stderr, "Have a nice day!\n");
|
fprintf(stderr, "Have a nice day!\n");
|
||||||
|
|
|
@ -11,11 +11,15 @@
|
||||||
#include "proxgui.h"
|
#include "proxgui.h"
|
||||||
#include "proxguiqt.h"
|
#include "proxguiqt.h"
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
static ProxGuiQT *gui = NULL;
|
static ProxGuiQT *gui = NULL;
|
||||||
static WorkerThread *main_loop_thread = NULL;
|
static WorkerThread *main_loop_thread = NULL;
|
||||||
|
|
||||||
WorkerThread::WorkerThread(char *script_cmds_file, char *script_cmd, bool usb_present) : script_cmds_file(script_cmds_file), script_cmd(script_cmd), usb_present(usb_present)
|
WorkerThread::WorkerThread(char *script_cmds_file, char *script_cmd,
|
||||||
|
bool usb_present, serial_port* sp)
|
||||||
|
: script_cmds_file(script_cmds_file), script_cmd(script_cmd),
|
||||||
|
usb_present(usb_present), sp(sp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +28,7 @@ WorkerThread::~WorkerThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkerThread::run() {
|
void WorkerThread::run() {
|
||||||
main_loop(script_cmds_file, script_cmd, usb_present);
|
main_loop(script_cmds_file, script_cmd, usb_present, sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ShowGraphWindow(void)
|
extern "C" void ShowGraphWindow(void)
|
||||||
|
@ -59,7 +63,9 @@ extern "C" void MainGraphics(void)
|
||||||
gui->MainLoop();
|
gui->MainLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool usb_present)
|
extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file,
|
||||||
|
char *script_cmd, bool usb_present,
|
||||||
|
serial_port* sp)
|
||||||
{
|
{
|
||||||
#ifdef Q_WS_X11
|
#ifdef Q_WS_X11
|
||||||
bool useGUI = getenv("DISPLAY") != 0;
|
bool useGUI = getenv("DISPLAY") != 0;
|
||||||
|
@ -69,7 +75,7 @@ extern "C" void InitGraphics(int argc, char **argv, char *script_cmds_file, char
|
||||||
if (!useGUI)
|
if (!useGUI)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
main_loop_thread = new WorkerThread(script_cmds_file, script_cmd, usb_present);
|
main_loop_thread = new WorkerThread(script_cmds_file, script_cmd, usb_present, sp);
|
||||||
gui = new ProxGuiQT(argc, argv, main_loop_thread);
|
gui = new ProxGuiQT(argc, argv, main_loop_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,13 @@ extern "C" {
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
void ShowGraphWindow(void);
|
void ShowGraphWindow(void);
|
||||||
void HideGraphWindow(void);
|
void HideGraphWindow(void);
|
||||||
void RepaintGraphWindow(void);
|
void RepaintGraphWindow(void);
|
||||||
void MainGraphics(void);
|
void MainGraphics(void);
|
||||||
void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool usb_present);
|
void InitGraphics(int argc, char **argv, char *script_cmds_file, char *script_cmd, bool usb_present, serial_port* sp);
|
||||||
void ExitGraphics(void);
|
void ExitGraphics(void);
|
||||||
|
|
||||||
#define MAX_GRAPH_TRACE_LEN (40000*8)
|
#define MAX_GRAPH_TRACE_LEN (40000*8)
|
||||||
|
@ -30,7 +31,6 @@ extern int s_Buff[MAX_GRAPH_TRACE_LEN];
|
||||||
extern double CursorScaleFactor;
|
extern double CursorScaleFactor;
|
||||||
extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
|
extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
|
||||||
extern int CommandFinished;
|
extern int CommandFinished;
|
||||||
extern int offline;
|
|
||||||
extern bool GridLocked;
|
extern bool GridLocked;
|
||||||
|
|
||||||
//Operations defined in data_operations
|
//Operations defined in data_operations
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
#include "ui/ui_overlays.h"
|
#include "ui/ui_overlays.h"
|
||||||
/**
|
/**
|
||||||
* @brief The actual plot, black area were we paint the graph
|
* @brief The actual plot, black area were we paint the graph
|
||||||
|
@ -91,13 +92,14 @@ class ProxWidget : public QWidget
|
||||||
class WorkerThread : public QThread {
|
class WorkerThread : public QThread {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
public:
|
public:
|
||||||
WorkerThread(char*, char*, bool);
|
WorkerThread(char*, char*, bool, serial_port*);
|
||||||
~WorkerThread();
|
~WorkerThread();
|
||||||
void run();
|
void run();
|
||||||
private:
|
private:
|
||||||
char *script_cmds_file = NULL;
|
char *script_cmds_file = NULL;
|
||||||
char *script_cmd = NULL;
|
char *script_cmd = NULL;
|
||||||
bool usb_present;
|
bool usb_present;
|
||||||
|
serial_port *sp = NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProxGuiQT : public QObject
|
class ProxGuiQT : public QObject
|
||||||
|
|
|
@ -27,86 +27,42 @@
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmdhw.h"
|
#include "cmdhw.h"
|
||||||
#include "whereami.h"
|
#include "whereami.h"
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define SERIAL_PORT_H "com3"
|
#define SERIAL_PORT_H "com3"
|
||||||
|
#elif __APPLE__
|
||||||
|
#define SERIAL_PORT_H "/dev/tty.usbmodem*"
|
||||||
#else
|
#else
|
||||||
#define SERIAL_PORT_H "/dev/ttyACM0"
|
#define SERIAL_PORT_H "/dev/ttyACM0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// a global mutex to prevent interlaced printing from different threads
|
void main_loop(char *script_cmds_file, char* script_cmd, bool usb_present, serial_port* sp) {
|
||||||
pthread_mutex_t print_lock;
|
receiver_arg conn;
|
||||||
|
|
||||||
static serial_port sp;
|
|
||||||
static UsbCommand txcmd;
|
|
||||||
volatile static bool txcmd_pending = false;
|
|
||||||
|
|
||||||
void SendCommand(UsbCommand *c) {
|
|
||||||
#if 0
|
|
||||||
printf("Sending %d bytes\n", sizeof(UsbCommand));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (offline) {
|
|
||||||
PrintAndLog("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;
|
|
||||||
txcmd_pending = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct receiver_arg {
|
|
||||||
int run;
|
|
||||||
};
|
|
||||||
|
|
||||||
byte_t rx[sizeof(UsbCommand)];
|
|
||||||
byte_t* prx = rx;
|
|
||||||
|
|
||||||
static void *uart_receiver(void *targ) {
|
|
||||||
struct receiver_arg *arg = (struct receiver_arg*)targ;
|
|
||||||
size_t rxlen;
|
|
||||||
|
|
||||||
while (arg->run) {
|
|
||||||
rxlen = 0;
|
|
||||||
if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) {
|
|
||||||
prx += rxlen;
|
|
||||||
if (prx-rx < sizeof(UsbCommand)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
UsbCommandReceived((UsbCommand*)rx);
|
|
||||||
}
|
|
||||||
prx = rx;
|
|
||||||
|
|
||||||
if(txcmd_pending) {
|
|
||||||
if (!uart_send(sp, (byte_t*) &txcmd, sizeof(UsbCommand))) {
|
|
||||||
PrintAndLog("Sending bytes to proxmark failed");
|
|
||||||
}
|
|
||||||
txcmd_pending = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_exit(NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
|
||||||
struct receiver_arg rarg;
|
|
||||||
char *cmd = NULL;
|
char *cmd = NULL;
|
||||||
pthread_t reader_thread;
|
pthread_t reader_thread;
|
||||||
bool execCommand = (script_cmd != NULL);
|
bool execCommand = (script_cmd != NULL);
|
||||||
bool stdinOnPipe = !isatty(STDIN_FILENO);
|
bool stdinOnPipe = !isatty(STDIN_FILENO);
|
||||||
|
|
||||||
|
memset(&conn, 0, sizeof(receiver_arg));
|
||||||
|
pthread_mutex_init(&conn.recv_lock, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Move this into comms.c
|
||||||
|
PlotGridXdefault = 64;
|
||||||
|
PlotGridYdefault = 64;
|
||||||
|
showDemod = true;
|
||||||
|
CursorScaleFactor = 1;
|
||||||
|
|
||||||
if (usb_present) {
|
if (usb_present) {
|
||||||
rarg.run = 1;
|
conn.run = true;
|
||||||
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
|
SetSerialPort(sp);
|
||||||
|
SetOffline(false);
|
||||||
|
pthread_create(&reader_thread, NULL, &uart_receiver, &conn);
|
||||||
// cache Version information now:
|
// cache Version information now:
|
||||||
CmdVersion(NULL);
|
CmdVersion(NULL);
|
||||||
|
} else {
|
||||||
|
SetOffline(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// file with script
|
// file with script
|
||||||
|
@ -122,7 +78,7 @@ void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||||
|
|
||||||
read_history(".history");
|
read_history(".history");
|
||||||
|
|
||||||
while(1) {
|
while (1) {
|
||||||
// If there is a script file
|
// If there is a script file
|
||||||
if (script_file)
|
if (script_file)
|
||||||
{
|
{
|
||||||
|
@ -194,7 +150,7 @@ void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||||
write_history(".history");
|
write_history(".history");
|
||||||
|
|
||||||
if (usb_present) {
|
if (usb_present) {
|
||||||
rarg.run = 0;
|
conn.run = false;
|
||||||
pthread_join(reader_thread, NULL);
|
pthread_join(reader_thread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +158,8 @@ void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||||
fclose(script_file);
|
fclose(script_file);
|
||||||
script_file = NULL;
|
script_file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&conn.recv_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpAllHelp(int markdown)
|
static void dumpAllHelp(int markdown)
|
||||||
|
@ -274,6 +232,8 @@ int main(int argc, char* argv[]) {
|
||||||
bool addLuaExec = false;
|
bool addLuaExec = false;
|
||||||
char *script_cmds_file = NULL;
|
char *script_cmds_file = NULL;
|
||||||
char *script_cmd = NULL;
|
char *script_cmd = NULL;
|
||||||
|
serial_port *sp = NULL;
|
||||||
|
g_debugMode = 0;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
show_help(true, argv[0]);
|
show_help(true, argv[0]);
|
||||||
|
@ -370,14 +330,11 @@ int main(int argc, char* argv[]) {
|
||||||
if (sp == INVALID_SERIAL_PORT) {
|
if (sp == INVALID_SERIAL_PORT) {
|
||||||
printf("ERROR: invalid serial port\n");
|
printf("ERROR: invalid serial port\n");
|
||||||
usb_present = false;
|
usb_present = false;
|
||||||
offline = 1;
|
|
||||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||||
printf("ERROR: serial port is claimed by another process\n");
|
printf("ERROR: serial port is claimed by another process\n");
|
||||||
usb_present = false;
|
usb_present = false;
|
||||||
offline = 1;
|
|
||||||
} else {
|
} else {
|
||||||
usb_present = true;
|
usb_present = true;
|
||||||
offline = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a mutex to avoid interlacing print commands from our different threads
|
// create a mutex to avoid interlacing print commands from our different threads
|
||||||
|
@ -385,23 +342,23 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
#ifdef HAVE_GUI
|
#ifdef HAVE_GUI
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present);
|
InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present, sp);
|
||||||
MainGraphics();
|
MainGraphics();
|
||||||
#else
|
#else
|
||||||
char* display = getenv("DISPLAY");
|
char* display = getenv("DISPLAY");
|
||||||
|
|
||||||
if (display && strlen(display) > 1)
|
if (display && strlen(display) > 1)
|
||||||
{
|
{
|
||||||
InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present);
|
InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present, sp);
|
||||||
MainGraphics();
|
MainGraphics();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
main_loop(script_cmds_file, script_cmd, usb_present);
|
main_loop(script_cmds_file, script_cmd, usb_present, sp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
main_loop(script_cmds_file, script_cmd, usb_present);
|
main_loop(script_cmds_file, script_cmd, usb_present, sp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Clean up the port
|
// Clean up the port
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define PROXMARK3_H__
|
#define PROXMARK3_H__
|
||||||
|
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
#define PROXPROMPT "proxmark3> "
|
#define PROXPROMPT "proxmark3> "
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ extern "C" {
|
||||||
void SendCommand(UsbCommand *c);
|
void SendCommand(UsbCommand *c);
|
||||||
const char *get_my_executable_path(void);
|
const char *get_my_executable_path(void);
|
||||||
const char *get_my_executable_directory(void);
|
const char *get_my_executable_directory(void);
|
||||||
void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present);
|
void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present, serial_port* sp);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
12
client/ui.c
12
client/ui.c
|
@ -21,7 +21,7 @@
|
||||||
double CursorScaleFactor = 1;
|
double CursorScaleFactor = 1;
|
||||||
int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
|
int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
|
||||||
int offline;
|
int offline;
|
||||||
int flushAfterWrite = 0; //buzzy
|
bool flushAfterWrite = false; //buzzy
|
||||||
int GridOffset = 0;
|
int GridOffset = 0;
|
||||||
bool GridLocked = false;
|
bool GridLocked = false;
|
||||||
bool showDemod = true;
|
bool showDemod = true;
|
||||||
|
@ -62,7 +62,6 @@ void PrintAndLog(char *fmt, ...)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// We are using libedit (OSX), which doesn't support this flag.
|
// We are using libedit (OSX), which doesn't support this flag.
|
||||||
int need_hack = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
va_start(argptr, fmt);
|
va_start(argptr, fmt);
|
||||||
|
@ -72,6 +71,9 @@ void PrintAndLog(char *fmt, ...)
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
// This needs to be wrapped in ifdefs, as this if optimisation is disabled,
|
||||||
|
// this block won't be removed, and it'll fail at the linker.
|
||||||
|
#ifdef RL_STATE_READCMD
|
||||||
if (need_hack) {
|
if (need_hack) {
|
||||||
rl_restore_prompt();
|
rl_restore_prompt();
|
||||||
rl_replace_line(saved_line, 0);
|
rl_replace_line(saved_line, 0);
|
||||||
|
@ -79,6 +81,7 @@ void PrintAndLog(char *fmt, ...)
|
||||||
rl_redisplay();
|
rl_redisplay();
|
||||||
free(saved_line);
|
free(saved_line);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (logging && logfile) {
|
if (logging && logfile) {
|
||||||
vfprintf(logfile, fmt, argptr2);
|
vfprintf(logfile, fmt, argptr2);
|
||||||
|
@ -100,3 +103,8 @@ void SetLogFilename(char *fn)
|
||||||
{
|
{
|
||||||
logfilename = fn;
|
logfilename = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetFlushAfterWrite(bool flush_after_write) {
|
||||||
|
flushAfterWrite = flush_after_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,11 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
// a global mutex to prevent interlaced printing from different threads
|
||||||
|
pthread_mutex_t print_lock;
|
||||||
|
extern uint8_t g_debugMode;
|
||||||
|
|
||||||
void ShowGui(void);
|
void ShowGui(void);
|
||||||
void HideGraphWindow(void);
|
void HideGraphWindow(void);
|
||||||
|
@ -23,8 +28,7 @@ void SetLogFilename(char *fn);
|
||||||
|
|
||||||
extern double CursorScaleFactor;
|
extern double CursorScaleFactor;
|
||||||
extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
|
extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset;
|
||||||
extern int offline;
|
extern bool flushAfterWrite; //buzzy
|
||||||
extern int flushAfterWrite; //buzzy
|
|
||||||
extern bool GridLocked;
|
extern bool GridLocked;
|
||||||
extern bool showDemod;
|
extern bool showDemod;
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,9 @@ int Iso15693AddCrc(uint8_t *req, int n) {
|
||||||
return n+2;
|
return n+2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ON_DEVICE
|
||||||
int sprintf(char *str, const char *format, ...);
|
int sprintf(char *str, const char *format, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
// returns a string representation of the UID
|
// returns a string representation of the UID
|
||||||
// UID is transmitted and stored LSB first, displayed MSB first
|
// UID is transmitted and stored LSB first, displayed MSB first
|
||||||
|
|
|
@ -212,7 +212,7 @@ typedef struct{
|
||||||
#define CMD_HF_SNIFFER 0x0800
|
#define CMD_HF_SNIFFER 0x0800
|
||||||
|
|
||||||
#define CMD_UNKNOWN 0xFFFF
|
#define CMD_UNKNOWN 0xFFFF
|
||||||
|
#define CMD_ANY 0xFFFFFFFFFFFFFFFF
|
||||||
|
|
||||||
//Mifare simulation flags
|
//Mifare simulation flags
|
||||||
#define FLAG_INTERACTIVE 0x01
|
#define FLAG_INTERACTIVE 0x01
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue