2010-02-21 05:24:25 +08:00
//-----------------------------------------------------------------------------
// Jonathan Westhues, Mar 2006
// Edits by Gerhard de Koning Gans, Sep 2007 (##)
2010-02-21 08:12:52 +08:00
//
// 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 application code. This is the first thing called after start.c
// executes.
2010-02-21 05:24:25 +08:00
//-----------------------------------------------------------------------------
2017-03-07 02:11:08 +08:00
# include <stdarg.h>
2017-07-07 18:34:57 +08:00
# include <inttypes.h>
2015-05-26 17:04:57 +08:00
# include "usb_cdc.h"
# include "proxmark3.h"
2010-02-21 05:24:25 +08:00
# include "apps.h"
2018-07-28 20:25:12 +08:00
# include "fpga.h"
2010-02-21 06:51:00 +08:00
# include "util.h"
2010-02-21 08:10:28 +08:00
# include "printf.h"
# include "string.h"
2010-02-21 05:24:25 +08:00
# include "legicrf.h"
2018-09-06 04:23:25 +08:00
# include "legicrfsim.h"
2015-01-31 06:03:44 +08:00
# include "lfsampling.h"
2015-02-08 03:49:40 +08:00
# include "BigBuf.h"
2015-07-23 05:00:52 +08:00
# include "mifareutil.h"
2019-04-07 17:41:43 +08:00
# include "mifaresim.h"
2019-03-26 16:09:43 +08:00
# include "hitag.h"
2016-03-13 14:16:42 +08:00
2018-05-22 18:09:17 +08:00
# define DEBUG 1
2010-02-21 05:24:25 +08:00
# ifdef WITH_LCD
2019-03-10 07:00:59 +08:00
# include "LCD.h"
2010-02-21 05:24:25 +08:00
# endif
2018-04-08 16:51:19 +08:00
# ifdef WITH_SMARTCARD
2018-07-04 18:19:04 +08:00
# include "i2c.h"
2018-04-08 16:51:19 +08:00
# endif
2018-09-06 11:15:52 +08:00
# ifdef WITH_FPC
# include "usart.h"
# endif
2018-09-17 02:47:23 +08:00
# ifdef WITH_FLASH
# include "flashmem.h"
# endif
2010-02-21 05:24:25 +08:00
//=============================================================================
// A buffer where we can queue things up to be sent through the FPGA, for
// any purpose (fake tag, as reader, whatever). We go MSB first, since that
// is the order in which they go out on the wire.
//=============================================================================
2019-03-09 15:59:13 +08:00
# define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
2014-12-18 03:33:21 +08:00
uint8_t ToSend [ TOSEND_BUFFER_SIZE ] ;
2017-07-07 18:34:57 +08:00
int ToSendMax = - 1 ;
2010-02-21 05:24:25 +08:00
static int ToSendBit ;
struct common_area common_area __attribute__ ( ( section ( " .commonarea " ) ) ) ;
2019-03-10 18:20:22 +08:00
void ToSendReset ( void ) {
2019-03-10 03:34:41 +08:00
ToSendMax = - 1 ;
ToSendBit = 8 ;
2010-02-21 05:24:25 +08:00
}
2019-03-10 18:20:22 +08:00
void ToSendStuffBit ( int b ) {
2019-03-10 07:00:59 +08:00
if ( ToSendBit > = 8 ) {
2019-03-10 03:34:41 +08:00
ToSendMax + + ;
ToSend [ ToSendMax ] = 0 ;
ToSendBit = 0 ;
}
2010-02-21 05:24:25 +08:00
2019-03-10 07:00:59 +08:00
if ( b )
2019-03-10 03:34:41 +08:00
ToSend [ ToSendMax ] | = ( 1 < < ( 7 - ToSendBit ) ) ;
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
ToSendBit + + ;
2010-02-21 05:24:25 +08:00
2019-03-10 07:00:59 +08:00
if ( ToSendMax > = sizeof ( ToSend ) ) {
2019-03-10 03:34:41 +08:00
ToSendBit = 0 ;
DbpString ( " ToSendStuffBit overflowed! " ) ;
}
2010-02-21 05:24:25 +08:00
}
2019-04-07 17:36:24 +08:00
/* useful when debugging new protocol implementations like FeliCa
2019-03-10 18:20:22 +08:00
void PrintToSendBuffer ( void ) {
2019-03-10 03:34:41 +08:00
DbpString ( " Printing ToSendBuffer: " ) ;
Dbhexdump ( ToSendMax , ToSend , 0 ) ;
2016-04-27 17:21:29 +08:00
}
2019-04-07 17:36:24 +08:00
*/
2016-04-27 17:21:29 +08:00
2019-03-10 18:20:22 +08:00
void print_result ( char * name , uint8_t * buf , size_t len ) {
2018-09-06 11:15:52 +08:00
2019-03-10 03:34:41 +08:00
uint8_t * p = buf ;
uint16_t tmp = len & 0xFFF0 ;
2019-03-10 07:00:59 +08:00
for ( ; p - buf < tmp ; p + = 16 ) {
2019-03-10 03:34:41 +08:00
Dbprintf ( " [%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x " ,
2019-03-10 07:00:59 +08:00
name ,
p - buf ,
len ,
p [ 0 ] , p [ 1 ] , p [ 2 ] , p [ 3 ] , p [ 4 ] , p [ 5 ] , p [ 6 ] , p [ 7 ] , p [ 8 ] , p [ 9 ] , p [ 10 ] , p [ 11 ] , p [ 12 ] , p [ 13 ] , p [ 14 ] , p [ 15 ]
) ;
2019-03-10 03:34:41 +08:00
}
if ( len % 16 ! = 0 ) {
char s [ 46 ] = { 0 } ;
char * sp = s ;
2019-03-10 07:00:59 +08:00
for ( ; p - buf < len ; p + + ) {
sprintf ( sp , " %02x " , p [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
sp + = 3 ;
}
2019-03-10 07:00:59 +08:00
Dbprintf ( " [%s: %02d/%02d] %s " , name , p - buf , len , s ) ;
2019-03-10 03:34:41 +08:00
}
2017-01-25 07:33:03 +08:00
}
2010-02-21 05:24:25 +08:00
//=============================================================================
// Debug print functions, to go out over USB, to the usual PC-side client.
//=============================================================================
2019-03-10 18:20:22 +08:00
void DbpStringEx ( char * str , uint32_t cmd ) {
2018-05-22 18:09:17 +08:00
# if DEBUG
2019-03-10 03:34:41 +08:00
uint8_t len = strlen ( str ) ;
2019-03-10 07:00:59 +08:00
cmd_send ( CMD_DEBUG_PRINT_STRING , len , cmd , 0 , ( uint8_t * ) str , len ) ;
2019-03-09 15:59:13 +08:00
# endif
2016-03-06 17:35:25 +08:00
}
2019-03-10 18:20:22 +08:00
void DbpString ( char * str ) {
2018-05-22 18:09:17 +08:00
# if DEBUG
2019-03-10 03:34:41 +08:00
DbpStringEx ( str , 0 ) ;
2019-03-09 15:59:13 +08:00
# endif
2010-02-21 05:24:25 +08:00
}
#if 0
2019-03-10 18:20:22 +08:00
void DbpIntegers ( int x1 , int x2 , int x3 ) {
2019-03-10 07:00:59 +08:00
cmd_send ( CMD_DEBUG_PRINT_INTEGERS , x1 , x2 , x3 , 0 , 0 ) ;
2010-02-21 05:24:25 +08:00
}
# endif
2019-03-10 18:20:22 +08:00
void DbprintfEx ( uint32_t cmd , const char * fmt , . . . ) {
2018-05-22 18:09:17 +08:00
# if DEBUG
2019-03-10 03:34:41 +08:00
// should probably limit size here; oh well, let's just use a big buffer
char output_string [ 128 ] = { 0x00 } ;
va_list ap ;
va_start ( ap , fmt ) ;
kvsprintf ( fmt , output_string , 10 , ap ) ;
va_end ( ap ) ;
DbpStringEx ( output_string , cmd ) ;
2019-03-09 15:59:13 +08:00
# endif
2016-03-06 17:35:25 +08:00
}
2010-02-21 05:24:25 +08:00
2019-03-10 18:20:22 +08:00
void Dbprintf ( const char * fmt , . . . ) {
2018-05-22 18:09:17 +08:00
# if DEBUG
2019-03-10 03:34:41 +08:00
// should probably limit size here; oh well, let's just use a big buffer
char output_string [ 128 ] = { 0x00 } ;
va_list ap ;
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
va_start ( ap , fmt ) ;
kvsprintf ( fmt , output_string , 10 , ap ) ;
va_end ( ap ) ;
2010-02-21 05:57:20 +08:00
2019-03-10 03:34:41 +08:00
DbpString ( output_string ) ;
2019-03-09 15:59:13 +08:00
# endif
2010-02-21 05:24:25 +08:00
}
2010-10-19 22:25:17 +08:00
// prints HEX & ASCII
2019-03-10 18:20:22 +08:00
void Dbhexdump ( int len , uint8_t * d , bool bAsci ) {
2018-05-22 18:09:17 +08:00
# if DEBUG
2019-03-10 03:34:41 +08:00
char ascii [ 9 ] ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
while ( len > 0 ) {
2016-01-26 03:17:08 +08:00
2019-04-07 17:36:24 +08:00
int l = ( len > 8 ) ? 8 : len ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
memcpy ( ascii , d , l ) ;
ascii [ l ] = 0 ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
// filter safe ascii
2019-04-07 17:36:24 +08:00
for ( int i = 0 ; i < l ; i + + ) {
2017-10-24 03:19:46 +08:00
if ( ascii [ i ] < 32 | | ascii [ i ] > 126 ) {
2017-10-20 21:29:33 +08:00
ascii [ i ] = ' . ' ;
2019-03-10 03:34:41 +08:00
}
2017-10-24 03:19:46 +08:00
}
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
if ( bAsci )
Dbprintf ( " %-8s %*D " , ascii , l , d , " " ) ;
else
Dbprintf ( " %*D " , l , d , " " ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
len - = 8 ;
d + = 8 ;
}
2019-03-09 15:59:13 +08:00
# endif
2010-10-19 22:25:17 +08:00
}
2010-02-21 05:24:25 +08:00
//-----------------------------------------------------------------------------
// Read an ADC channel and block till it completes, then return the result
// in ADC units (0 to 1023). Also a routine to average 32 samples and
// return that.
//-----------------------------------------------------------------------------
2019-03-10 18:20:22 +08:00
static uint16_t ReadAdc ( int ch ) {
2015-02-03 14:21:57 +08:00
2019-03-10 03:34:41 +08:00
// Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value.
// AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant
// of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged.
//
// The maths are:
// If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be
//
// v_cap = v_in * (1 - exp(-SHTIM/RC)) = v_in * (1 - exp(-40us/10.9us)) = v_in * 0,97 (i.e. an error of 3%)
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
AT91C_BASE_ADC - > ADC_CR = AT91C_ADC_SWRST ;
2019-03-09 15:59:13 +08:00
AT91C_BASE_ADC - > ADC_MR =
2019-03-10 07:00:59 +08:00
ADC_MODE_PRESCALE ( 63 ) // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
| ADC_MODE_STARTUP_TIME ( 1 ) // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us
| ADC_MODE_SAMPLE_HOLD_TIME ( 15 ) ; // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
2018-01-09 21:53:17 +08:00
2019-03-10 03:34:41 +08:00
AT91C_BASE_ADC - > ADC_CHER = ADC_CHANNEL ( ch ) ;
AT91C_BASE_ADC - > ADC_CR = AT91C_ADC_START ;
2015-02-03 14:21:57 +08:00
2019-03-10 03:34:41 +08:00
while ( ! ( AT91C_BASE_ADC - > ADC_SR & ADC_END_OF_CONVERSION ( ch ) ) ) { } ;
2018-01-09 21:53:17 +08:00
2019-03-10 03:34:41 +08:00
return ( AT91C_BASE_ADC - > ADC_CDR [ ch ] & 0x3FF ) ;
2010-02-21 05:24:25 +08:00
}
2019-03-09 15:59:13 +08:00
// was static - merlok
2019-03-10 18:20:22 +08:00
uint16_t AvgAdc ( int ch ) {
2019-03-10 03:34:41 +08:00
uint16_t a = 0 ;
2019-03-10 07:00:59 +08:00
for ( uint8_t i = 0 ; i < 32 ; i + + )
2019-03-10 03:34:41 +08:00
a + = ReadAdc ( ch ) ;
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
//division by 32
return ( a + 15 ) > > 5 ;
2010-02-21 05:24:25 +08:00
}
2019-03-10 18:20:22 +08:00
void MeasureAntennaTuning ( void ) {
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
uint8_t LF_Results [ 256 ] ;
2019-04-07 17:36:24 +08:00
uint32_t i , peak = 0 , peakv = 0 , peakf = 0 ;
2019-03-10 03:34:41 +08:00
uint32_t v_lf125 = 0 , v_lf134 = 0 , v_hf = 0 ; // in mV
2016-09-01 06:52:54 +08:00
2019-03-10 03:34:41 +08:00
memset ( LF_Results , 0 , sizeof ( LF_Results ) ) ;
LED_B_ON ( ) ;
2010-02-21 05:24:25 +08:00
2019-03-10 07:00:59 +08:00
/*
* Sweeps the useful LF range of the proxmark from
* 46.8 kHz ( divisor = 255 ) to 600 kHz ( divisor = 19 ) and
* read the voltage in the antenna , the result left
* in the buffer is a graph which should clearly show
* the resonating frequency of your LF antenna
* ( hopefully around 95 if it is tuned to 125 kHz ! )
*/
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
FpgaDownloadAndGo ( FPGA_BITSTREAM_LF ) ;
FpgaWriteConfWord ( FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD ) ;
SpinDelay ( 50 ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 07:00:59 +08:00
for ( i = 255 ; i > = 19 ; i - - ) {
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
FpgaSendCommand ( FPGA_CMD_SET_DIVISOR , i ) ;
SpinDelay ( 20 ) ;
2019-04-07 17:36:24 +08:00
uint32_t adcval = ( ( MAX_ADC_LF_VOLTAGE * AvgAdc ( ADC_CHAN_LF ) ) > > 10 ) ;
2017-10-20 21:29:33 +08:00
if ( i = = 95 )
2018-01-12 04:47:27 +08:00
v_lf125 = adcval ; // voltage at 125Khz
2017-10-20 21:29:33 +08:00
if ( i = = 89 )
2018-01-12 04:47:27 +08:00
v_lf134 = adcval ; // voltage at 134Khz
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
LF_Results [ i ] = adcval > > 9 ; // scale int to fit in byte for graphing purposes
2019-03-10 07:00:59 +08:00
if ( LF_Results [ i ] > peak ) {
2019-03-10 03:34:41 +08:00
peakv = adcval ;
peakf = i ;
peak = LF_Results [ i ] ;
}
}
LED_A_ON ( ) ;
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
FpgaDownloadAndGo ( FPGA_BITSTREAM_HF ) ;
FpgaWriteConfWord ( FPGA_MAJOR_MODE_HF_READER_RX_XCORR ) ;
SpinDelay ( 50 ) ;
v_hf = ( MAX_ADC_HF_VOLTAGE * AvgAdc ( ADC_CHAN_HF ) ) > > 10 ;
// RDV40 will hit the roof, try other ADC channel used in that hardware revision.
2019-03-10 07:00:59 +08:00
if ( v_hf > MAX_ADC_HF_VOLTAGE - 300 ) {
2019-03-10 03:34:41 +08:00
v_hf = ( MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc ( ADC_CHAN_HF_RDV40 ) ) > > 10 ;
}
uint64_t arg0 = v_lf134 ;
arg0 < < = 32 ;
arg0 | = v_lf125 ;
uint64_t arg2 = peakv ;
arg2 < < = 32 ;
arg2 | = peakf ;
cmd_send ( CMD_MEASURED_ANTENNA_TUNING , arg0 , v_hf , arg2 , LF_Results , 256 ) ;
FpgaWriteConfWord ( FPGA_MAJOR_MODE_OFF ) ;
LEDsoff ( ) ;
2010-02-21 05:24:25 +08:00
}
2019-03-10 18:20:22 +08:00
void MeasureAntennaTuningHf ( void ) {
2019-03-10 03:34:41 +08:00
uint16_t volt = 0 ; // in mV
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
FpgaDownloadAndGo ( FPGA_BITSTREAM_HF ) ;
FpgaWriteConfWord ( FPGA_MAJOR_MODE_HF_READER_RX_XCORR ) ;
SpinDelay ( 50 ) ;
volt = ( MAX_ADC_HF_VOLTAGE * AvgAdc ( ADC_CHAN_HF ) ) > > 10 ;
2019-03-10 07:00:59 +08:00
bool use_high = ( volt > MAX_ADC_HF_VOLTAGE - 300 ) ;
2019-03-10 03:34:41 +08:00
2019-03-10 07:00:59 +08:00
while ( ! BUTTON_PRESS ( ) ) {
2019-03-10 03:34:41 +08:00
SpinDelay ( 20 ) ;
2019-03-10 07:00:59 +08:00
if ( ! use_high ) {
2019-03-10 03:34:41 +08:00
volt = ( MAX_ADC_HF_VOLTAGE * AvgAdc ( ADC_CHAN_HF ) ) > > 10 ;
} else {
volt = ( MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc ( ADC_CHAN_HF_RDV40 ) ) > > 10 ;
}
2019-03-10 07:00:59 +08:00
DbprintfEx ( FLAG_NONEWLINE , " %u mV / %5u V " , volt , ( uint16_t ) ( volt / 1000 ) ) ;
2019-03-10 03:34:41 +08:00
}
FpgaWriteConfWord ( FPGA_MAJOR_MODE_OFF ) ;
DbprintfEx ( FLAG_NOOPT , " \n [+] cancelled " , 1 ) ;
2010-02-21 05:24:25 +08:00
}
2019-03-10 18:20:22 +08:00
void ReadMem ( int addr ) {
2019-03-10 03:34:41 +08:00
const uint8_t * data = ( ( uint8_t * ) addr ) ;
2010-02-21 05:24:25 +08:00
2017-10-20 21:29:33 +08:00
Dbprintf ( " %x: %02x %02x %02x %02x %02x %02x %02x %02x " , addr , data [ 0 ] , data [ 1 ] , data [ 2 ] , data [ 3 ] , data [ 4 ] , data [ 5 ] , data [ 6 ] , data [ 7 ] ) ;
2010-02-21 05:24:25 +08:00
}
/* osimage version information is linked in */
extern struct version_information version_information ;
/* bootrom version information is pointed to from _bootphase1_version_pointer */
2015-06-25 18:22:34 +08:00
extern char * _bootphase1_version_pointer , _flash_start , _flash_end , _bootrom_start , _bootrom_end , __data_src_start__ ;
2019-03-10 18:20:22 +08:00
void SendVersion ( void ) {
2019-03-10 03:34:41 +08:00
char temp [ USB_CMD_DATA_SIZE ] ; /* Limited data payload in USB packets */
char VersionString [ USB_CMD_DATA_SIZE ] = { ' \0 ' } ;
/* Try to find the bootrom version information. Expect to find a pointer at
* symbol _bootphase1_version_pointer , perform slight sanity checks on the
* pointer , then use it .
*/
2019-03-10 07:00:59 +08:00
char * bootrom_version = * ( char * * ) & _bootphase1_version_pointer ;
2019-03-10 03:34:41 +08:00
strncat ( VersionString , " [ ARM ] \n " , sizeof ( VersionString ) - strlen ( VersionString ) - 1 ) ;
2019-03-10 07:00:59 +08:00
if ( bootrom_version < & _flash_start | | bootrom_version > = & _flash_end ) {
2019-03-10 03:34:41 +08:00
strcat ( VersionString , " bootrom version information appears invalid \n " ) ;
} else {
FormatVersionInformation ( temp , sizeof ( temp ) , " bootrom: " , bootrom_version ) ;
strncat ( VersionString , temp , sizeof ( VersionString ) - strlen ( VersionString ) - 1 ) ;
}
FormatVersionInformation ( temp , sizeof ( temp ) , " os: " , & version_information ) ;
strncat ( VersionString , temp , sizeof ( VersionString ) - strlen ( VersionString ) - 1 ) ;
strncat ( VersionString , " \n [ FPGA ] \n " , sizeof ( VersionString ) - strlen ( VersionString ) - 1 ) ;
for ( int i = 0 ; i < fpga_bitstream_num ; i + + ) {
strncat ( VersionString , fpga_version_information [ i ] , sizeof ( VersionString ) - strlen ( VersionString ) - 1 ) ;
if ( i < fpga_bitstream_num - 1 ) {
strncat ( VersionString , " \n " , sizeof ( VersionString ) - strlen ( VersionString ) - 1 ) ;
}
}
// Send Chip ID and used flash memory
uint32_t text_and_rodata_section_size = ( uint32_t ) & __data_src_start__ - ( uint32_t ) & _flash_start ;
uint32_t compressed_data_section_size = common_area . arg1 ;
cmd_send ( CMD_ACK , * ( AT91C_DBGU_CIDR ) , text_and_rodata_section_size + compressed_data_section_size , 0 , VersionString , strlen ( VersionString ) ) ;
2010-02-21 05:24:25 +08:00
}
2015-07-31 16:37:24 +08:00
// measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
2019-04-18 05:44:48 +08:00
// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommandOLD structure included.
2019-03-10 18:20:22 +08:00
void printUSBSpeed ( void ) {
2019-03-10 03:34:41 +08:00
Dbprintf ( " USB Speed " ) ;
Dbprintf ( " Sending USB packets to client... " ) ;
2019-03-10 07:00:59 +08:00
# define USB_SPEED_TEST_MIN_TIME 1500 // in milliseconds
2019-03-10 03:34:41 +08:00
uint8_t * test_data = BigBuf_get_addr ( ) ;
uint32_t end_time ;
uint32_t start_time = end_time = GetTickCount ( ) ;
uint32_t bytes_transferred = 0 ;
LED_B_ON ( ) ;
2019-04-18 04:08:10 +08:00
2019-03-10 03:34:41 +08:00
while ( end_time < start_time + USB_SPEED_TEST_MIN_TIME ) {
2019-04-18 05:44:48 +08:00
reply_ng ( CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K , PM3_SUCCESS , test_data , USB_CMD_DATA_SIZE ) ;
2019-03-10 03:34:41 +08:00
end_time = GetTickCount ( ) ;
2019-04-18 05:44:48 +08:00
bytes_transferred + = USB_CMD_DATA_SIZE ;
2019-03-10 03:34:41 +08:00
}
LED_B_OFF ( ) ;
Dbprintf ( " Time elapsed............%dms " , end_time - start_time ) ;
Dbprintf ( " Bytes transferred.......%d " , bytes_transferred ) ;
2017-10-20 21:29:33 +08:00
Dbprintf ( " USB Transfer Speed PM3 -> Client = %d Bytes/s " , 1000 * bytes_transferred / ( end_time - start_time ) ) ;
2015-07-31 16:37:24 +08:00
}
2019-03-09 15:59:13 +08:00
2015-07-23 05:00:52 +08:00
/**
* Prints runtime information about the PM3 .
* */
2019-03-10 18:20:22 +08:00
void SendStatus ( void ) {
2019-03-10 03:34:41 +08:00
BigBuf_print_status ( ) ;
Fpga_print_status ( ) ;
2019-03-09 15:59:13 +08:00
# ifdef WITH_FLASH
2019-03-10 03:34:41 +08:00
Flashmem_print_status ( ) ;
2018-09-17 02:47:23 +08:00
# endif
2019-03-09 15:59:13 +08:00
# ifdef WITH_SMARTCARD
2019-03-10 03:34:41 +08:00
I2C_print_status ( ) ;
2019-03-09 15:59:13 +08:00
# endif
2018-04-18 22:17:49 +08:00
# ifdef WITH_LF
2019-03-10 03:34:41 +08:00
printConfig ( ) ; // LF Sampling config
printT55xxConfig ( ) ; // LF T55XX Config
2019-03-09 15:59:13 +08:00
# endif
2019-03-10 03:34:41 +08:00
printUSBSpeed ( ) ;
Dbprintf ( " Various " ) ;
Dbprintf ( " MF_DBGLEVEL.............%d " , MF_DBGLEVEL ) ;
Dbprintf ( " ToSendMax...............%d " , ToSendMax ) ;
Dbprintf ( " ToSendBit...............%d " , ToSendBit ) ;
Dbprintf ( " ToSend BUFFERSIZE.......%d " , TOSEND_BUFFER_SIZE ) ;
printStandAloneModes ( ) ;
cmd_send ( CMD_ACK , 1 , 0 , 0 , 0 , 0 ) ;
2015-07-23 05:00:52 +08:00
}
2010-02-21 05:24:25 +08:00
2017-08-26 18:57:18 +08:00
// Show some leds in a pattern to identify StandAlone mod is running
2019-03-10 18:20:22 +08:00
void StandAloneMode ( void ) {
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
DbpString ( " Stand-alone mode! No PC necessary. " ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
SpinDown ( 50 ) ;
2018-11-16 09:52:42 +08:00
SpinOff ( 50 ) ;
SpinUp ( 50 ) ;
SpinOff ( 50 ) ;
SpinDown ( 50 ) ;
2019-03-10 03:34:41 +08:00
SpinDelay ( 500 ) ;
2015-07-23 05:00:52 +08:00
}
2017-08-26 18:57:18 +08:00
// detection of which Standalone Modes is installed
// (iceman)
2019-03-10 18:20:22 +08:00
void printStandAloneModes ( void ) {
2017-09-29 04:33:03 +08:00
2019-03-10 03:34:41 +08:00
DbpString ( " Installed StandAlone Mode " ) ;
2019-03-09 15:59:13 +08:00
2018-03-12 19:27:43 +08:00
# if defined(WITH_LF_ICERUN)
2019-03-10 03:34:41 +08:00
DbpString ( " LF sniff/clone/simulation - aka IceRun (iceman) " ) ;
2018-03-12 19:27:43 +08:00
# endif
# if defined(WITH_HF_YOUNG)
2019-03-10 03:34:41 +08:00
DbpString ( " HF Mifare sniff/simulation - (Craig Young) " ) ;
2018-03-12 19:27:43 +08:00
# endif
# if defined(WITH_LF_SAMYRUN)
2019-03-10 03:34:41 +08:00
DbpString ( " LF HID26 standalone - aka SamyRun (Samy Kamkar) " ) ;
2018-03-12 19:27:43 +08:00
# endif
# if defined(WITH_LF_PROXBRUTE)
2019-03-10 03:34:41 +08:00
DbpString ( " LF HID ProxII bruteforce - aka Proxbrute (Brad Antoniewicz) " ) ;
2019-03-09 15:59:13 +08:00
# endif
2018-03-12 19:27:43 +08:00
# if defined(WITH_LF_HIDBRUTE)
2019-03-10 03:34:41 +08:00
DbpString ( " LF HID corporate 1000 bruteforce - aka Corporatebrute (Federico dotta & Maurizio Agazzini) " ) ;
2019-03-09 15:59:13 +08:00
# endif
2018-03-12 19:27:43 +08:00
# if defined(WITH_HF_MATTYRUN)
2019-03-10 03:34:41 +08:00
DbpString ( " HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina) " ) ;
2019-03-09 15:59:13 +08:00
# endif
2017-10-20 21:29:33 +08:00
# if defined(WITH_HF_COLIN)
DbpString ( " HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato) " ) ;
# endif
2018-10-22 02:29:49 +08:00
# if defined(WITH_HF_BOG)
2019-03-10 03:34:41 +08:00
DbpString ( " HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito) " ) ;
2018-10-22 02:29:49 +08:00
# endif
2019-03-10 03:34:41 +08:00
//DbpString("Running ");
//Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No");
//Dbprintf(" Is Device attached to FPC| %s", 0 ? "Yes" : "No");
//Dbprintf(" Is USB_reconnect value | %d", GetUSBreconnect() );
//Dbprintf(" Is USB_configured value | %d", GetUSBconfigured() );
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
//.. add your own standalone detection based on with compiler directive you are used.
// don't "reuse" the already taken ones, this will make things easier when trying to detect the different modes
// 2017-08-06 must adapt the makefile and have individual compilation flags for all mods
//
2010-02-21 05:24:25 +08:00
}
/*
OBJECTIVE
Listen and detect an external reader . Determine the best location
for the antenna .
INSTRUCTIONS :
Inside the ListenReaderField ( ) function , there is two mode .
By default , when you call the function , you will enter mode 1.
If you press the PM3 button one time , you will enter mode 2.
If you press the PM3 button a second time , you will exit the function .
DESCRIPTION OF MODE 1 :
This mode just listens for an external reader field and lights up green
for HF and / or red for LF . This is the original mode of the detectreader
function .
DESCRIPTION OF MODE 2 :
This mode will visually represent , using the LEDs , the actual strength of the
current compared to the maximum current detected . Basically , once you know
what kind of external reader is present , it will help you spot the best location to place
your antenna . You will probably not get some good results if there is a LF and a HF reader
at the same place ! : - )
LIGHT SCHEME USED :
*/
static const char LIGHT_SCHEME [ ] = {
2019-03-10 07:00:59 +08:00
0x0 , /* ---- | No field detected */
0x1 , /* X--- | 14% of maximum current detected */
0x2 , /* -X-- | 29% of maximum current detected */
0x4 , /* --X- | 43% of maximum current detected */
0x8 , /* ---X | 57% of maximum current detected */
0xC , /* --XX | 71% of maximum current detected */
0xE , /* -XXX | 86% of maximum current detected */
0xF , /* XXXX | 100% of maximum current detected */
2010-02-21 05:24:25 +08:00
} ;
2019-03-10 07:00:59 +08:00
static const int LIGHT_LEN = sizeof ( LIGHT_SCHEME ) / sizeof ( LIGHT_SCHEME [ 0 ] ) ;
2010-02-21 05:24:25 +08:00
2019-03-10 18:20:22 +08:00
void ListenReaderField ( int limit ) {
2019-03-10 03:34:41 +08:00
# define LF_ONLY 1
# define HF_ONLY 2
# define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE
uint16_t lf_av , lf_av_new , lf_baseline = 0 , lf_max ;
uint16_t hf_av , hf_av_new , hf_baseline = 0 , hf_max ;
uint16_t mode = 1 , display_val , display_max , i ;
// switch off FPGA - we don't want to measure our own signal
// 20180315 - iceman, why load this before and then turn off?
FpgaDownloadAndGo ( FPGA_BITSTREAM_HF ) ;
FpgaWriteConfWord ( FPGA_MAJOR_MODE_OFF ) ;
LEDsoff ( ) ;
lf_av = lf_max = AvgAdc ( ADC_CHAN_LF ) ;
if ( limit ! = HF_ONLY ) {
Dbprintf ( " LF 125/134kHz Baseline: %dmV " , ( MAX_ADC_LF_VOLTAGE * lf_av ) > > 10 ) ;
lf_baseline = lf_av ;
}
hf_av = hf_max = AvgAdc ( ADC_CHAN_HF ) ;
// iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader.
// RDV40 will hit the roof, try other ADC channel used in that hardware revision.
2019-03-10 07:00:59 +08:00
bool use_high = ( ( ( MAX_ADC_HF_VOLTAGE * hf_max ) > > 10 ) > MAX_ADC_HF_VOLTAGE - 300 ) ;
if ( use_high ) {
2019-03-10 03:34:41 +08:00
hf_av = hf_max = AvgAdc ( ADC_CHAN_HF_RDV40 ) ;
}
if ( limit ! = LF_ONLY ) {
Dbprintf ( " HF 13.56MHz Baseline: %dmV " , ( MAX_ADC_HF_VOLTAGE * hf_av ) > > 10 ) ;
hf_baseline = hf_av ;
}
2019-03-10 07:00:59 +08:00
for ( ; ; ) {
2019-03-10 03:34:41 +08:00
// Switch modes with button
if ( BUTTON_PRESS ( ) ) {
SpinDelay ( 500 ) ;
switch ( mode ) {
case 1 :
mode = 2 ;
DbpString ( " Signal Strength Mode " ) ;
break ;
case 2 :
default :
DbpString ( " Stopped " ) ;
LEDsoff ( ) ;
return ;
break ;
}
}
WDT_HIT ( ) ;
if ( limit ! = HF_ONLY ) {
2019-03-10 07:00:59 +08:00
if ( mode = = 1 ) {
2019-03-10 03:34:41 +08:00
if ( ABS ( lf_av - lf_baseline ) > REPORT_CHANGE )
LED_D_ON ( ) ;
else
LED_D_OFF ( ) ;
}
lf_av_new = AvgAdc ( ADC_CHAN_LF ) ;
// see if there's a significant change
if ( ABS ( lf_av - lf_av_new ) > REPORT_CHANGE ) {
Dbprintf ( " LF 125/134kHz Field Change: %5dmV " , ( MAX_ADC_LF_VOLTAGE * lf_av_new ) > > 10 ) ;
lf_av = lf_av_new ;
if ( lf_av > lf_max )
lf_max = lf_av ;
}
}
if ( limit ! = LF_ONLY ) {
2019-03-10 07:00:59 +08:00
if ( mode = = 1 ) {
2019-03-10 03:34:41 +08:00
if ( ABS ( hf_av - hf_baseline ) > REPORT_CHANGE )
LED_B_ON ( ) ;
else
LED_B_OFF ( ) ;
}
hf_av_new = ( use_high ) ? AvgAdc ( ADC_CHAN_HF_RDV40 ) : AvgAdc ( ADC_CHAN_HF ) ;
// see if there's a significant change
2019-03-10 07:00:59 +08:00
if ( ABS ( hf_av - hf_av_new ) > REPORT_CHANGE ) {
2019-03-10 03:34:41 +08:00
Dbprintf ( " HF 13.56MHz Field Change: %5dmV " , ( MAX_ADC_HF_VOLTAGE * hf_av_new ) > > 10 ) ;
hf_av = hf_av_new ;
if ( hf_av > hf_max )
hf_max = hf_av ;
}
}
if ( mode = = 2 ) {
if ( limit = = LF_ONLY ) {
display_val = lf_av ;
display_max = lf_max ;
} else if ( limit = = HF_ONLY ) {
display_val = hf_av ;
display_max = hf_max ;
} else { /* Pick one at random */
2019-03-10 07:00:59 +08:00
if ( ( hf_max - hf_baseline ) > ( lf_max - lf_baseline ) ) {
2019-03-10 03:34:41 +08:00
display_val = hf_av ;
display_max = hf_max ;
} else {
display_val = lf_av ;
display_max = lf_max ;
}
}
2019-03-10 07:00:59 +08:00
for ( i = 0 ; i < LIGHT_LEN ; i + + ) {
if ( display_val > = ( ( display_max / LIGHT_LEN ) * i ) & & display_val < = ( ( display_max / LIGHT_LEN ) * ( i + 1 ) ) ) {
if ( LIGHT_SCHEME [ i ] & 0x1 ) LED_C_ON ( ) ;
else LED_C_OFF ( ) ;
if ( LIGHT_SCHEME [ i ] & 0x2 ) LED_A_ON ( ) ;
else LED_A_OFF ( ) ;
if ( LIGHT_SCHEME [ i ] & 0x4 ) LED_B_ON ( ) ;
else LED_B_OFF ( ) ;
if ( LIGHT_SCHEME [ i ] & 0x8 ) LED_D_ON ( ) ;
else LED_D_OFF ( ) ;
2019-03-10 03:34:41 +08:00
break ;
}
}
}
}
2010-02-21 05:24:25 +08:00
}
2019-04-18 03:30:01 +08:00
static void UsbPacketReceived ( UsbCommandNG * packet ) {
2019-04-17 07:06:26 +08:00
uint64_t cmd ; // To accommodate old cmd, can be reduced to uint16_t once all old cmds are gone.
2019-04-17 02:00:17 +08:00
// For cmd handlers still using old cmd format:
2019-04-18 03:30:01 +08:00
if ( packet - > ng ) {
cmd = packet - > core . ng . cmd ;
// Dbprintf("received NG frame with %d bytes payload, with command: 0x%04x", packet->length, cmd);
2019-04-17 02:00:17 +08:00
} else {
2019-04-18 03:30:01 +08:00
cmd = packet - > core . old . cmd ;
// Dbprintf("received OLD frame of %d bytes, with command: 0x%04x and args: %d %d %d", packet->length, packet->core.old.cmd, packet->core.old.arg[0], packet->core.old.arg[1], packet->core.old.arg[2]);
2019-04-17 02:00:17 +08:00
}
2019-03-09 15:59:13 +08:00
2019-04-17 02:00:17 +08:00
switch ( cmd ) {
2010-02-21 05:24:25 +08:00
# ifdef WITH_LF
2019-03-10 03:34:41 +08:00
case CMD_SET_LF_T55XX_CONFIG :
2019-04-18 03:30:01 +08:00
setT55xxConfig ( packet - > core . old . arg [ 0 ] , ( t55xx_config * ) packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_SET_LF_SAMPLING_CONFIG :
2019-04-18 03:30:01 +08:00
setSamplingConfig ( ( sample_config * ) packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K : {
2019-04-18 03:30:01 +08:00
uint32_t bits = SampleLF ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
cmd_send ( CMD_ACK , bits , 0 , 0 , 0 , 0 ) ;
break ;
}
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K :
2019-04-18 03:30:01 +08:00
ModThenAcquireRawAdcSamples125k ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
2019-03-12 20:15:39 +08:00
case CMD_LF_SNIFF_RAW_ADC_SAMPLES : {
uint32_t bits = SniffLF ( ) ;
2019-03-10 03:34:41 +08:00
cmd_send ( CMD_ACK , bits , 0 , 0 , 0 , 0 ) ;
break ;
}
case CMD_HID_DEMOD_FSK : {
uint32_t high , low ;
2019-04-18 03:30:01 +08:00
CmdHIDdemodFSK ( packet - > core . old . arg [ 0 ] , & high , & low , 1 ) ;
2019-03-10 03:34:41 +08:00
break ;
}
case CMD_HID_SIM_TAG :
2019-04-18 03:30:01 +08:00
CmdHIDsimTAG ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , 1 ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_FSK_SIM_TAG :
2019-04-18 03:30:01 +08:00
CmdFSKsimTAG ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes , 1 ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ASK_SIM_TAG :
2019-04-18 03:30:01 +08:00
CmdASKsimTag ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes , 1 ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_PSK_SIM_TAG :
2019-04-18 03:30:01 +08:00
CmdPSKsimTag ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes , 1 ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_HID_CLONE_TAG :
2019-04-18 03:30:01 +08:00
CopyHIDtoT55x7 ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_IO_DEMOD_FSK : {
uint32_t high , low ;
2019-04-18 03:30:01 +08:00
CmdIOdemodFSK ( packet - > core . old . arg [ 0 ] , & high , & low , 1 ) ;
2019-03-10 03:34:41 +08:00
break ;
}
case CMD_IO_CLONE_TAG :
2019-04-18 03:30:01 +08:00
CopyIOtoT55x7 ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_EM410X_DEMOD : {
uint32_t high ;
uint64_t low ;
2019-04-18 03:30:01 +08:00
CmdEM410xdemod ( packet - > core . old . arg [ 0 ] , & high , & low , 1 ) ;
2019-03-10 03:34:41 +08:00
break ;
}
case CMD_EM410X_WRITE_TAG :
2019-04-18 03:30:01 +08:00
WriteEM410x ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READ_TI_TYPE :
ReadTItag ( ) ;
break ;
case CMD_WRITE_TI_TYPE :
2019-04-18 03:30:01 +08:00
WriteTItag ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_SIMULATE_TAG_125K :
LED_A_ON ( ) ;
2019-04-18 03:30:01 +08:00
SimulateTagLowFrequency ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , 1 ) ;
2019-03-10 03:34:41 +08:00
LED_A_OFF ( ) ;
break ;
case CMD_LF_SIMULATE_BIDIR :
2019-04-18 03:30:01 +08:00
SimulateTagLowFrequencyBidir ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_INDALA_CLONE_TAG :
2019-04-18 03:30:01 +08:00
CopyIndala64toT55x7 ( packet - > core . old . d . asDwords [ 0 ] , packet - > core . old . d . asDwords [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_INDALA_CLONE_TAG_L :
CopyIndala224toT55x7 (
2019-04-18 03:30:01 +08:00
packet - > core . old . d . asDwords [ 0 ] , packet - > core . old . d . asDwords [ 1 ] , packet - > core . old . d . asDwords [ 2 ] , packet - > core . old . d . asDwords [ 3 ] ,
packet - > core . old . d . asDwords [ 4 ] , packet - > core . old . d . asDwords [ 5 ] , packet - > core . old . d . asDwords [ 6 ]
2019-03-10 07:00:59 +08:00
) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_T55XX_READ_BLOCK : {
2019-04-18 03:30:01 +08:00
T55xxReadBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
}
case CMD_T55XX_WRITE_BLOCK :
2019-04-18 03:30:01 +08:00
T55xxWriteBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_T55XX_WAKEUP :
2019-04-18 03:30:01 +08:00
T55xxWakeUp ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_T55XX_RESET_READ :
T55xxResetRead ( ) ;
break ;
case CMD_T55XX_CHKPWDS :
T55xx_ChkPwds ( ) ;
break ;
case CMD_PCF7931_READ :
ReadPCF7931 ( ) ;
break ;
case CMD_PCF7931_WRITE :
WritePCF7931 (
2019-04-18 03:30:01 +08:00
packet - > core . old . d . asBytes [ 0 ] , packet - > core . old . d . asBytes [ 1 ] , packet - > core . old . d . asBytes [ 2 ] , packet - > core . old . d . asBytes [ 3 ] ,
packet - > core . old . d . asBytes [ 4 ] , packet - > core . old . d . asBytes [ 5 ] , packet - > core . old . d . asBytes [ 6 ] , packet - > core . old . d . asBytes [ 9 ] ,
packet - > core . old . d . asBytes [ 7 ] - 128 , packet - > core . old . d . asBytes [ 8 ] - 128 ,
packet - > core . old . arg [ 0 ] ,
packet - > core . old . arg [ 1 ] ,
packet - > core . old . arg [ 2 ]
2019-03-10 07:00:59 +08:00
) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_EM4X_READ_WORD :
2019-04-18 03:30:01 +08:00
EM4xReadWord ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_EM4X_WRITE_WORD :
2019-04-18 03:30:01 +08:00
EM4xWriteWord ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_AWID_DEMOD_FSK : {
uint32_t high , low ;
// Set realtime AWID demodulation
2019-04-18 03:30:01 +08:00
CmdAWIDdemodFSK ( packet - > core . old . arg [ 0 ] , & high , & low , 1 ) ;
2019-03-10 03:34:41 +08:00
break ;
}
2015-10-05 00:01:33 +08:00
case CMD_VIKING_CLONE_TAG :
2019-04-18 03:30:01 +08:00
CopyVikingtoT55xx ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_COTAG :
2019-04-18 03:30:01 +08:00
Cotag ( packet - > core . old . arg [ 0 ] ) ;
2015-10-05 00:01:33 +08:00
break ;
2010-02-21 05:24:25 +08:00
# endif
2012-09-18 21:53:17 +08:00
# ifdef WITH_HITAG
2019-03-12 20:15:39 +08:00
case CMD_SNIFF_HITAG : // Eavesdrop Hitag tag, args = type
2019-04-18 03:30:01 +08:00
SniffHitag ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_SIMULATE_HITAG : // Simulate Hitag tag, args = memory content
2019-04-18 03:30:01 +08:00
SimulateHitagTag ( ( bool ) packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READER_HITAG : // Reader for Hitag tags, args = type and function
2019-04-18 03:30:01 +08:00
ReaderHitag ( ( hitag_function ) packet - > core . old . arg [ 0 ] , ( hitag_data * ) packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_SIMULATE_HITAG_S : // Simulate Hitag s tag, args = memory content
2019-04-18 03:30:01 +08:00
SimulateHitagSTag ( ( bool ) packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_TEST_HITAGS_TRACES : // Tests every challenge within the given file
2019-04-18 03:30:01 +08:00
check_challenges ( ( bool ) packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READ_HITAG_S : //Reader for only Hitag S tags, args = key or challenge
2019-04-18 03:30:01 +08:00
ReadHitagS ( ( hitag_function ) packet - > core . old . arg [ 0 ] , ( hitag_data * ) packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_WR_HITAG_S : //writer for Hitag tags args=data to write,page and key or challenge
2019-04-18 03:30:01 +08:00
if ( ( hitag_function ) packet - > core . old . arg [ 0 ] < 10 ) {
WritePageHitagS ( ( hitag_function ) packet - > core . old . arg [ 0 ] , ( hitag_data * ) packet - > core . old . d . asBytes , packet - > core . old . arg [ 2 ] ) ;
2019-03-13 05:52:15 +08:00
} else {
2019-04-18 03:30:01 +08:00
WriterHitag ( ( hitag_function ) packet - > core . old . arg [ 0 ] , ( hitag_data * ) packet - > core . old . d . asBytes , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
}
break ;
2012-09-18 21:53:17 +08:00
# endif
2015-04-30 06:27:31 +08:00
2010-02-21 05:24:25 +08:00
# ifdef WITH_ISO15693
2019-03-10 03:34:41 +08:00
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 :
AcquireRawAdcSamplesIso15693 ( ) ;
break ;
case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 :
RecordRawAdcSamplesIso15693 ( ) ;
break ;
case CMD_ISO_15693_COMMAND :
2019-04-18 03:30:01 +08:00
DirectTag15693Command ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ISO_15693_FIND_AFI :
2019-04-18 03:30:01 +08:00
BruteforceIso15693Afi ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READER_ISO_15693 :
2019-04-18 03:30:01 +08:00
ReaderIso15693 ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_SIMTAG_ISO_15693 :
2019-04-18 03:30:01 +08:00
SimTagIso15693 ( packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
2010-02-21 05:24:25 +08:00
# endif
2011-12-16 19:00:51 +08:00
# ifdef WITH_LEGICRF
2019-03-10 03:34:41 +08:00
case CMD_SIMULATE_TAG_LEGIC_RF :
2019-04-18 03:30:01 +08:00
LegicRfSimulate ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_WRITER_LEGIC_RF :
2019-04-18 03:30:01 +08:00
LegicRfWriter ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READER_LEGIC_RF :
2019-04-18 03:30:01 +08:00
LegicRfReader ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_LEGIC_INFO :
LegicRfInfo ( ) ;
break ;
case CMD_LEGIC_ESET :
//-----------------------------------------------------------------------------
// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not
// involved in dealing with emulator memory. But if it is called later, it might
// destroy the Emulator Memory.
//-----------------------------------------------------------------------------
// arg0 = offset
// arg1 = num of bytes
FpgaDownloadAndGo ( FPGA_BITSTREAM_HF ) ;
2019-04-18 03:30:01 +08:00
emlSet ( packet - > core . old . d . asBytes , packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
2010-02-21 05:24:25 +08:00
# endif
# ifdef WITH_ISO14443b
2019-03-10 03:34:41 +08:00
case CMD_READ_SRI_TAG :
2019-04-18 03:30:01 +08:00
ReadSTMemoryIso14443b ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
2019-03-12 20:15:39 +08:00
case CMD_SNIFF_ISO_14443B :
2019-03-10 03:34:41 +08:00
SniffIso14443b ( ) ;
break ;
case CMD_SIMULATE_TAG_ISO_14443B :
2019-04-18 03:30:01 +08:00
SimulateIso14443bTag ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ISO_14443B_COMMAND :
2019-04-18 03:30:01 +08:00
//SendRawCommand14443B(packet->core.old.arg[0],packet->core.old.arg[1],packet->core.old.arg[2],packet->core.old.d.asBytes);
SendRawCommand14443B_Ex ( packet ) ;
2019-03-10 03:34:41 +08:00
break ;
2010-02-21 05:24:25 +08:00
# endif
2017-10-21 02:27:44 +08:00
# ifdef WITH_FELICA
2019-03-10 03:34:41 +08:00
case CMD_FELICA_COMMAND :
2019-04-18 03:30:01 +08:00
felica_sendraw ( packet ) ;
2019-03-10 03:34:41 +08:00
break ;
2017-10-21 02:27:44 +08:00
case CMD_FELICA_LITE_SIM :
2019-04-18 03:30:01 +08:00
felica_sim_lite ( packet - > core . old . arg [ 0 ] ) ;
2017-10-21 02:27:44 +08:00
break ;
2019-03-12 20:15:39 +08:00
case CMD_FELICA_SNIFF :
2019-04-18 03:30:01 +08:00
felica_sniff ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2017-10-21 02:27:44 +08:00
break ;
case CMD_FELICA_LITE_DUMP :
2019-03-10 03:34:41 +08:00
felica_dump_lite_s ( ) ;
2017-10-21 02:27:44 +08:00
break ;
# endif
2010-02-21 05:24:25 +08:00
# ifdef WITH_ISO14443a
2019-03-12 20:15:39 +08:00
case CMD_SNIFF_ISO_14443a :
2019-04-18 03:30:01 +08:00
SniffIso14443a ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READER_ISO_14443a :
2019-04-18 03:30:01 +08:00
ReaderIso14443a ( packet ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_SIMULATE_TAG_ISO_14443a :
2019-04-18 03:30:01 +08:00
SimulateIso14443aTag ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ; // ## Simulate iso14443a tag - pass tag type & UID
2019-03-10 03:34:41 +08:00
break ;
case CMD_ANTIFUZZ_ISO_14443a :
2019-04-18 03:30:01 +08:00
iso14443a_antifuzz ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_EPA_PACE_COLLECT_NONCE :
2019-04-18 03:30:01 +08:00
EPA_PACE_Collect_Nonce ( packet ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_EPA_PACE_REPLAY :
2019-04-18 03:30:01 +08:00
EPA_PACE_Replay ( packet ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READER_MIFARE :
2019-04-18 03:30:01 +08:00
ReaderMifare ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_READBL :
2019-04-18 03:30:01 +08:00
MifareReadBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFAREU_READBL :
2019-04-18 03:30:01 +08:00
MifareUReadBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFAREUC_AUTH :
2019-04-18 03:30:01 +08:00
MifareUC_Auth ( packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFAREU_READCARD :
2019-04-18 03:30:01 +08:00
MifareUReadCard ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFAREUC_SETPWD :
2019-04-18 03:30:01 +08:00
MifareUSetPwd ( packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_READSC :
2019-04-18 03:30:01 +08:00
MifareReadSector ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_WRITEBL :
2019-04-18 03:30:01 +08:00
MifareWriteBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
//case CMD_MIFAREU_WRITEBL_COMPAT:
2019-04-18 03:30:01 +08:00
//MifareUWriteBlockCompat(packet->core.old.arg[0], packet->core.old.d.asBytes);
2019-03-10 07:00:59 +08:00
//break;
2019-03-10 03:34:41 +08:00
case CMD_MIFAREU_WRITEBL :
2019-04-18 03:30:01 +08:00
MifareUWriteBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES :
2019-04-18 03:30:01 +08:00
MifareAcquireEncryptedNonces ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_ACQUIRE_NONCES :
2019-04-18 03:30:01 +08:00
MifareAcquireNonces ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_NESTED :
2019-04-18 03:30:01 +08:00
MifareNested ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_CHKKEYS : {
2019-04-18 03:30:01 +08:00
MifareChkKeys ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
}
case CMD_MIFARE_CHKKEYS_FAST : {
2019-04-18 03:30:01 +08:00
MifareChkKeys_fast ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
}
case CMD_SIMULATE_MIFARE_CARD :
2019-04-18 03:30:01 +08:00
Mifare1ksim ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
// emulator
case CMD_MIFARE_SET_DBGMODE :
2019-04-18 03:30:01 +08:00
MifareSetDbgLvl ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_EML_MEMCLR :
2019-04-18 03:30:01 +08:00
MifareEMemClr ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_EML_MEMSET :
2019-04-18 03:30:01 +08:00
MifareEMemSet ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_EML_MEMGET :
2019-04-18 03:30:01 +08:00
MifareEMemGet ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_EML_CARDLOAD :
2019-04-18 03:30:01 +08:00
MifareECardLoad ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
// Work with "magic Chinese" card
case CMD_MIFARE_CSETBLOCK :
2019-04-18 03:30:01 +08:00
MifareCSetBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_CGETBLOCK :
2019-04-18 03:30:01 +08:00
MifareCGetBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_CIDENT :
MifareCIdent ( ) ;
break ;
// mifare sniffer
// case CMD_MIFARE_SNIFFER:
2019-04-18 03:30:01 +08:00
// SniffMifare(packet->core.old.arg[0]);
2019-03-10 03:34:41 +08:00
// break;
case CMD_MIFARE_SETMOD :
2019-04-18 03:30:01 +08:00
MifareSetMod ( packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
//mifare desfire
case CMD_MIFARE_DESFIRE_READBL :
break ;
case CMD_MIFARE_DESFIRE_WRITEBL :
break ;
case CMD_MIFARE_DESFIRE_AUTH1 :
2019-04-18 03:30:01 +08:00
MifareDES_Auth1 ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_DESFIRE_AUTH2 :
2019-04-18 03:30:01 +08:00
//MifareDES_Auth2(packet->core.old.arg[0],packet->core.old.d.asBytes);
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_DES_READER :
2019-04-18 03:30:01 +08:00
//readermifaredes(packet->core.old.arg[0], packet->core.old.arg[1], packet->core.old.d.asBytes);
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_DESFIRE_INFO :
MifareDesfireGetInformation ( ) ;
break ;
case CMD_MIFARE_DESFIRE :
2019-04-18 03:30:01 +08:00
MifareSendCommand ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_MIFARE_COLLECT_NONCES :
break ;
case CMD_MIFARE_NACK_DETECT :
DetectNACKbug ( ) ;
break ;
2011-05-26 20:55:15 +08:00
# endif
2017-11-25 17:20:52 +08:00
2011-12-16 19:00:51 +08:00
# ifdef WITH_ICLASS
2019-03-10 03:34:41 +08:00
// Makes use of ISO14443a FPGA Firmware
2019-03-12 20:15:39 +08:00
case CMD_SNIFF_ICLASS :
2019-03-10 03:34:41 +08:00
SniffIClass ( ) ;
break ;
case CMD_SIMULATE_TAG_ICLASS :
2019-04-18 03:30:01 +08:00
SimulateIClass ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . arg [ 2 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READER_ICLASS :
2019-04-18 03:30:01 +08:00
ReaderIClass ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_READER_ICLASS_REPLAY :
2019-04-18 03:30:01 +08:00
ReaderIClass_Replay ( packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ICLASS_EML_MEMSET :
//iceman, should call FPGADOWNLOAD before, since it corrupts BigBuf
FpgaDownloadAndGo ( FPGA_BITSTREAM_HF ) ;
2019-04-18 03:30:01 +08:00
emlSet ( packet - > core . old . d . asBytes , packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ICLASS_WRITEBLOCK :
2019-04-18 03:30:01 +08:00
iClass_WriteBlock ( packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ICLASS_READCHECK : // auth step 1
2019-04-18 03:30:01 +08:00
iClass_ReadCheck ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ICLASS_READBLOCK :
2019-04-18 03:30:01 +08:00
iClass_ReadBlk ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ICLASS_AUTHENTICATION : //check
2019-04-18 03:30:01 +08:00
iClass_Authentication ( packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ICLASS_CHECK_KEYS :
2019-04-18 03:30:01 +08:00
iClass_Authentication_fast ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ICLASS_DUMP :
2019-04-18 03:30:01 +08:00
iClass_Dump ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_ICLASS_CLONE :
2019-04-18 03:30:01 +08:00
iClass_Clone ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
2011-05-18 20:33:32 +08:00
# endif
2018-07-04 21:29:27 +08:00
2019-03-12 20:15:39 +08:00
# ifdef WITH_HFSNIFF
2019-03-10 03:34:41 +08:00
case CMD_HF_SNIFFER :
2019-04-18 03:30:01 +08:00
HfSniff ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
2015-10-28 04:47:21 +08:00
# endif
2018-07-04 21:29:27 +08:00
2018-07-04 18:19:04 +08:00
# ifdef WITH_SMARTCARD
2019-03-10 03:34:41 +08:00
case CMD_SMART_ATR : {
SmartCardAtr ( ) ;
break ;
}
2019-03-10 07:00:59 +08:00
case CMD_SMART_SETBAUD : {
2019-04-18 03:30:01 +08:00
SmartCardSetBaud ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
}
2019-03-10 07:00:59 +08:00
case CMD_SMART_SETCLOCK : {
2019-04-18 03:30:01 +08:00
SmartCardSetClock ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
}
2018-07-05 22:32:10 +08:00
case CMD_SMART_RAW : {
2019-04-18 03:30:01 +08:00
SmartCardRaw ( packet - > core . old . arg [ 0 ] , packet - > core . old . arg [ 1 ] , packet - > core . old . d . asBytes ) ;
2019-03-10 03:34:41 +08:00
break ;
}
case CMD_SMART_UPLOAD : {
// upload file from client
uint8_t * mem = BigBuf_get_addr ( ) ;
2019-04-18 03:30:01 +08:00
memcpy ( mem + packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes , USB_CMD_DATA_SIZE ) ;
2019-03-10 07:00:59 +08:00
cmd_send ( CMD_ACK , 1 , 0 , 0 , 0 , 0 ) ;
2018-07-04 18:19:04 +08:00
break ;
2018-07-05 16:48:24 +08:00
}
case CMD_SMART_UPGRADE : {
2019-04-18 03:30:01 +08:00
SmartCardUpgrade ( packet - > core . old . arg [ 0 ] ) ;
2019-03-09 15:59:13 +08:00
break ;
2019-03-10 03:34:41 +08:00
}
2019-03-09 15:59:13 +08:00
# endif
2011-05-18 20:33:32 +08:00
2018-07-30 15:54:44 +08:00
# ifdef WITH_FPC
2019-03-10 03:34:41 +08:00
case CMD_FPC_SEND : {
StartTicks ( ) ;
DbpString ( " Mutual USB/FPC sending from device to client " ) ;
/*
char at [ 11 ] = { ' \0 ' } ;
static const char * s_at = " AT+BAUD8 \0 D \0 A " ;
strncat ( at , s_at , sizeof ( at ) - strlen ( at ) - 1 ) ;
DbpString ( " Try AT baud rate setting " ) ;
usart_init ( ) ;
int16_t res = usart_writebuffer ( ( uint8_t * ) & at , sizeof ( at ) ) ;
WaitMS ( 1 ) ;
Dbprintf ( " SEND %d | %c%c%c%c%c%c%c%c%c%c%c " , res , at [ 0 ] , at [ 1 ] , at [ 2 ] , at [ 3 ] , at [ 4 ] , at [ 5 ] , at [ 6 ] , at [ 7 ] , at [ 8 ] , at [ 9 ] , at [ 10 ] ) ;
uint8_t my_rx [ 20 ] ;
memset ( my_rx , 0 , sizeof ( my_rx ) ) ;
res = usart_readbuffer ( my_rx , sizeof ( my_rx ) ) ;
WaitMS ( 1 ) ;
Dbprintf ( " GOT %d | %c%c%c%c%c%c%c%c " , res , my_rx [ 0 ] , my_rx [ 1 ] , my_rx [ 2 ] , my_rx [ 3 ] , my_rx [ 4 ] , my_rx [ 5 ] , my_rx [ 6 ] , my_rx [ 7 ] ) ;
*/
2019-04-03 04:32:45 +08:00
char dest [ USB_CMD_DATA_SIZE ] = { ' \0 ' } ;
2019-04-03 04:06:10 +08:00
if ( usart_dataavailable ( ) ) {
Dbprintf ( " RX DATA! " ) ;
2019-04-03 04:32:45 +08:00
uint16_t len = usart_readbuffer ( ( uint8_t * ) dest ) ;
2019-04-03 04:06:10 +08:00
dest [ len ] = ' \0 ' ;
Dbprintf ( " RX: %d | %02X %02X %02X %02X %02X %02X %02X %02X " , len , dest [ 0 ] , dest [ 1 ] , dest [ 2 ] , dest [ 3 ] , dest [ 4 ] , dest [ 5 ] , dest [ 6 ] , dest [ 7 ] ) ;
}
2019-04-02 07:06:00 +08:00
static const char * welcome = " Proxmark3 Serial interface via FPC ready \r \n " ;
usart_writebuffer ( ( uint8_t * ) welcome , strlen ( welcome ) ) ;
sprintf ( dest , " | bytes 0x%02x 0x%02x 0x%02x 0x%02x \r \n "
2019-04-18 03:30:01 +08:00
, packet - > core . old . d . asBytes [ 0 ]
, packet - > core . old . d . asBytes [ 1 ]
, packet - > core . old . d . asBytes [ 2 ]
, packet - > core . old . d . asBytes [ 3 ]
2019-03-10 07:00:59 +08:00
) ;
2019-04-02 07:06:00 +08:00
usart_writebuffer ( ( uint8_t * ) dest , strlen ( dest ) ) ;
2019-03-10 03:34:41 +08:00
LED_A_ON ( ) ;
//usb
cmd_send ( CMD_DEBUG_PRINT_STRING , strlen ( dest ) , 0 , 0 , dest , strlen ( dest ) ) ;
2019-04-02 07:06:00 +08:00
LED_A_OFF ( ) ;
2019-04-03 04:32:45 +08:00
/*
2019-04-18 05:44:48 +08:00
uint8_t my_rx [ sizeof ( UsbCommandOLD ) ] ;
2019-03-10 03:34:41 +08:00
while ( ! BUTTON_PRESS ( ) & & ! usb_poll_validate_length ( ) ) {
LED_B_INV ( ) ;
2019-04-14 17:10:16 +08:00
if ( usart_readbuffer ( my_rx ) ) {
2019-03-10 03:34:41 +08:00
//UsbPacketReceived(my_rx, sizeof(my_rx));
2019-04-18 05:44:48 +08:00
UsbCommandOLD * my = ( UsbCommandOLD * ) my_rx ;
2019-04-02 07:06:00 +08:00
if ( my - > cmd > 0 ) {
2019-03-10 03:34:41 +08:00
Dbprintf ( " received command: 0x%04x and args: %d %d %d " , my - > cmd , my - > arg [ 0 ] , my - > arg [ 1 ] , my - > arg [ 2 ] ) ;
}
}
}
2019-04-03 04:32:45 +08:00
*/
2019-03-10 03:34:41 +08:00
//cmd_send(CMD_DEBUG_PRINT_STRING, strlen(dest), 0, 0, dest, strlen(dest));
2019-03-10 07:00:59 +08:00
cmd_send ( CMD_ACK , 0 , 0 , 0 , 0 , 0 ) ;
2019-03-10 03:34:41 +08:00
StopTicks ( ) ;
break ;
}
2018-07-30 15:54:44 +08:00
# endif
2019-03-10 03:34:41 +08:00
case CMD_BUFF_CLEAR :
BigBuf_Clear ( ) ;
BigBuf_free ( ) ;
break ;
case CMD_MEASURE_ANTENNA_TUNING :
MeasureAntennaTuning ( ) ;
break ;
case CMD_MEASURE_ANTENNA_TUNING_HF :
MeasureAntennaTuningHf ( ) ;
break ;
case CMD_LISTEN_READER_FIELD :
2019-04-18 03:30:01 +08:00
ListenReaderField ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_FPGA_MAJOR_MODE_OFF : // ## FPGA Control
FpgaWriteConfWord ( FPGA_MAJOR_MODE_OFF ) ;
SpinDelay ( 200 ) ;
LED_D_OFF ( ) ; // LED D indicates field ON or OFF
break ;
2018-04-18 22:17:49 +08:00
# ifdef WITH_LF
2019-03-10 03:34:41 +08:00
case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K : {
LED_B_ON ( ) ;
uint8_t * mem = BigBuf_get_addr ( ) ;
2019-04-18 03:30:01 +08:00
uint32_t startidx = packet - > core . old . arg [ 0 ] ;
uint32_t numofbytes = packet - > core . old . arg [ 1 ] ;
2019-03-10 03:34:41 +08:00
// arg0 = startindex
// arg1 = length bytes to transfer
// arg2 = BigBuf tracelen
2019-04-18 03:30:01 +08:00
//Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, packet->core.old.arg[2]);
2019-03-10 03:34:41 +08:00
2019-03-10 07:00:59 +08:00
for ( size_t i = 0 ; i < numofbytes ; i + = USB_CMD_DATA_SIZE ) {
2019-04-07 17:36:24 +08:00
size_t len = MIN ( ( numofbytes - i ) , USB_CMD_DATA_SIZE ) ;
bool isok = cmd_send ( CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K , i , len , BigBuf_get_traceLen ( ) , mem + startidx + i , len ) ;
2019-03-10 03:34:41 +08:00
if ( isok ! = 0 )
2019-03-10 07:00:59 +08:00
Dbprintf ( " transfer to client failed :: | bytes between %d - %d (%d) " , i , i + len , len ) ;
2019-03-10 03:34:41 +08:00
}
// Trigger a finish downloading signal with an ACK frame
// iceman, when did sending samplingconfig array got attached here?!?
// arg0 = status of download transfer
// arg1 = RFU
// arg2 = tracelen?
// asbytes = samplingconfig array
cmd_send ( CMD_ACK , 1 , 0 , BigBuf_get_traceLen ( ) , getSamplingConfig ( ) , sizeof ( sample_config ) ) ;
LED_B_OFF ( ) ;
break ;
}
2019-03-09 15:59:13 +08:00
# endif
2019-03-10 03:34:41 +08:00
case CMD_UPLOAD_SIM_SAMPLES_125K : {
// iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before.
// to be able to use this one for uploading data to device
// arg1 = 0 upload for LF usage
// 1 upload for HF usage
2019-03-10 07:00:59 +08:00
# define FPGA_LF 1
2019-04-18 03:30:01 +08:00
if ( packet - > core . old . arg [ 1 ] = = FPGA_LF )
2019-03-10 03:34:41 +08:00
FpgaDownloadAndGo ( FPGA_BITSTREAM_LF ) ;
else
FpgaDownloadAndGo ( FPGA_BITSTREAM_HF ) ;
uint8_t * mem = BigBuf_get_addr ( ) ;
2019-04-18 03:30:01 +08:00
memcpy ( mem + packet - > core . old . arg [ 0 ] , packet - > core . old . d . asBytes , USB_CMD_DATA_SIZE ) ;
2019-03-10 07:00:59 +08:00
cmd_send ( CMD_ACK , 1 , 0 , 0 , 0 , 0 ) ;
2019-03-10 03:34:41 +08:00
break ;
}
case CMD_DOWNLOAD_EML_BIGBUF : {
LED_B_ON ( ) ;
uint8_t * mem = BigBuf_get_EM_addr ( ) ;
bool isok = false ;
size_t len = 0 ;
2019-04-18 03:30:01 +08:00
uint32_t startidx = packet - > core . old . arg [ 0 ] ;
uint32_t numofbytes = packet - > core . old . arg [ 1 ] ;
2019-03-10 03:34:41 +08:00
// arg0 = startindex
// arg1 = length bytes to transfer
// arg2 = RFU
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 ! = 0 )
2019-03-10 07:00:59 +08:00
Dbprintf ( " transfer to client failed :: | bytes between %d - %d (%d) " , i , i + len , len ) ;
2019-03-10 03:34:41 +08:00
}
// Trigger a finish downloading signal with an ACK frame
cmd_send ( CMD_ACK , 1 , 0 , 0 , 0 , 0 ) ;
LED_B_OFF ( ) ;
break ;
}
case CMD_READ_MEM :
2019-04-18 03:30:01 +08:00
ReadMem ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
2019-03-09 15:59:13 +08:00
# ifdef WITH_FLASH
2019-03-10 03:34:41 +08:00
case CMD_FLASHMEM_SET_SPIBAUDRATE :
2019-04-18 03:30:01 +08:00
FlashmemSetSpiBaudrate ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_FLASHMEM_READ : {
LED_B_ON ( ) ;
2019-04-18 03:30:01 +08:00
uint32_t startidx = packet - > core . old . arg [ 0 ] ;
uint16_t len = packet - > core . old . arg [ 1 ] ;
2019-03-10 03:34:41 +08:00
Dbprintf ( " FlashMem read | %d - %d | " , startidx , len ) ;
size_t size = MIN ( USB_CMD_DATA_SIZE , len ) ;
if ( ! FlashInit ( ) ) {
break ;
}
uint8_t * mem = BigBuf_malloc ( size ) ;
2019-03-10 07:00:59 +08:00
for ( size_t i = 0 ; i < len ; i + = size ) {
2019-03-10 03:34:41 +08:00
len = MIN ( ( len - i ) , size ) ;
Dbprintf ( " FlashMem reading | %d | %d | %d | " , startidx + i , i , len ) ;
2019-04-07 17:36:24 +08:00
uint16_t isok = Flash_ReadDataCont ( startidx + i , mem , len ) ;
2019-03-10 07:00:59 +08:00
if ( isok = = len ) {
2019-03-10 03:34:41 +08:00
print_result ( " Chunk: " , mem , len ) ;
} else {
Dbprintf ( " FlashMem reading failed | %d | %d " , len , isok ) ;
break ;
}
}
BigBuf_free ( ) ;
FlashStop ( ) ;
LED_B_OFF ( ) ;
break ;
}
case CMD_FLASHMEM_WRITE : {
LED_B_ON ( ) ;
uint8_t isok = 0 ;
uint16_t res = 0 ;
2019-04-18 03:30:01 +08:00
uint32_t startidx = packet - > core . old . arg [ 0 ] ;
uint16_t len = packet - > core . old . arg [ 1 ] ;
uint8_t * data = packet - > core . old . d . asBytes ;
2019-03-10 03:34:41 +08:00
uint32_t tmp = startidx + len ;
if ( ! FlashInit ( ) ) {
break ;
}
Flash_CheckBusy ( BUSY_TIMEOUT ) ;
Flash_WriteEnable ( ) ;
2019-03-10 07:00:59 +08:00
if ( startidx = = DEFAULT_T55XX_KEYS_OFFSET )
2019-03-10 03:34:41 +08:00
Flash_Erase4k ( 3 , 0xC ) ;
2019-03-10 07:00:59 +08:00
else if ( startidx = = DEFAULT_MF_KEYS_OFFSET )
2019-03-10 03:34:41 +08:00
Flash_Erase4k ( 3 , 0xB ) ;
else if ( startidx = = DEFAULT_ICLASS_KEYS_OFFSET )
Flash_Erase4k ( 3 , 0xA ) ;
Flash_CheckBusy ( BUSY_TIMEOUT ) ;
Flash_WriteEnable ( ) ;
// inside 256b page?
2019-03-10 07:00:59 +08:00
if ( ( tmp & 0xFF ) ! = 0 ) {
2019-03-10 03:34:41 +08:00
2019-03-10 07:00:59 +08:00
// is offset+len larger than a page
tmp = ( startidx & 0xFF ) + len ;
if ( tmp > 0xFF ) {
2019-03-10 03:34:41 +08:00
2019-03-10 07:00:59 +08:00
// data spread over two pages.
2019-03-10 03:34:41 +08:00
2019-03-10 07:00:59 +08:00
// offset xxxx10,
uint8_t first_len = ( ~ startidx & 0xFF ) + 1 ;
2019-03-10 03:34:41 +08:00
2019-03-10 07:00:59 +08:00
// first mem page
res = Flash_WriteDataCont ( startidx , data , first_len ) ;
2019-03-10 03:34:41 +08:00
2019-03-13 05:50:29 +08:00
isok = ( res = = first_len ) ? 1 : 0 ;
2019-03-10 07:00:59 +08:00
// second mem page
res = Flash_WriteDataCont ( startidx + first_len , data + first_len , len - first_len ) ;
2019-03-10 03:34:41 +08:00
2019-03-13 05:50:29 +08:00
isok & = ( res = = ( len - first_len ) ) ? 1 : 0 ;
2019-03-10 03:34:41 +08:00
2019-03-10 07:00:59 +08:00
} else {
res = Flash_WriteDataCont ( startidx , data , len ) ;
isok = ( res = = len ) ? 1 : 0 ;
}
2019-03-10 03:34:41 +08:00
} else {
res = Flash_WriteDataCont ( startidx , data , len ) ;
isok = ( res = = len ) ? 1 : 0 ;
}
FlashStop ( ) ;
cmd_send ( CMD_ACK , isok , 0 , 0 , 0 , 0 ) ;
LED_B_OFF ( ) ;
break ;
}
case CMD_FLASHMEM_WIPE : {
LED_B_ON ( ) ;
2019-04-18 03:30:01 +08:00
uint8_t page = packet - > core . old . arg [ 0 ] ;
uint8_t initalwipe = packet - > core . old . arg [ 1 ] ;
2019-03-10 03:34:41 +08:00
bool isok = false ;
2019-03-10 07:00:59 +08:00
if ( initalwipe ) {
2019-03-10 03:34:41 +08:00
isok = Flash_WipeMemory ( ) ;
cmd_send ( CMD_ACK , isok , 0 , 0 , 0 , 0 ) ;
LED_B_OFF ( ) ;
break ;
}
2019-03-10 07:00:59 +08:00
if ( page < 3 )
2019-03-10 03:34:41 +08:00
isok = Flash_WipeMemoryPage ( page ) ;
cmd_send ( CMD_ACK , isok , 0 , 0 , 0 , 0 ) ;
LED_B_OFF ( ) ;
break ;
}
case CMD_FLASHMEM_DOWNLOAD : {
LED_B_ON ( ) ;
uint8_t * mem = BigBuf_malloc ( USB_CMD_DATA_SIZE ) ;
2019-04-18 03:30:01 +08:00
uint32_t startidx = packet - > core . old . arg [ 0 ] ;
uint32_t numofbytes = packet - > core . old . arg [ 1 ] ;
2019-03-10 03:34:41 +08:00
// arg0 = startindex
// arg1 = length bytes to transfer
// arg2 = RFU
if ( ! FlashInit ( ) ) {
break ;
}
for ( size_t i = 0 ; i < numofbytes ; i + = USB_CMD_DATA_SIZE ) {
2019-04-07 17:36:24 +08:00
size_t len = MIN ( ( numofbytes - i ) , USB_CMD_DATA_SIZE ) ;
2019-03-10 03:34:41 +08:00
2019-04-07 17:36:24 +08:00
bool isok = Flash_ReadDataCont ( startidx + i , mem , len ) ;
2019-03-10 07:00:59 +08:00
if ( ! isok )
2019-03-10 03:34:41 +08:00
Dbprintf ( " reading flash memory failed :: | bytes between %d - %d " , i , len ) ;
isok = cmd_send ( CMD_FLASHMEM_DOWNLOADED , i , len , 0 , mem , len ) ;
if ( isok ! = 0 )
Dbprintf ( " transfer to client failed :: | bytes between %d - %d " , i , len ) ;
}
2019-03-10 07:00:59 +08:00
FlashStop ( ) ;
2019-03-10 03:34:41 +08:00
cmd_send ( CMD_ACK , 1 , 0 , 0 , 0 , 0 ) ;
2019-03-13 19:46:03 +08:00
BigBuf_free ( ) ;
2019-03-10 03:34:41 +08:00
LED_B_OFF ( ) ;
break ;
}
case CMD_FLASHMEM_INFO : {
LED_B_ON ( ) ;
2019-03-10 07:00:59 +08:00
rdv40_validation_t * info = ( rdv40_validation_t * ) BigBuf_malloc ( sizeof ( rdv40_validation_t ) ) ;
2019-03-10 03:34:41 +08:00
bool isok = Flash_ReadData ( FLASH_MEM_SIGNATURE_OFFSET , info - > signature , FLASH_MEM_SIGNATURE_LEN ) ;
if ( FlashInit ( ) ) {
2019-03-10 07:00:59 +08:00
Flash_UniqueID ( info - > flashid ) ;
2019-03-10 03:34:41 +08:00
FlashStop ( ) ;
}
cmd_send ( CMD_ACK , isok , 0 , 0 , info , sizeof ( rdv40_validation_t ) ) ;
BigBuf_free ( ) ;
LED_B_OFF ( ) ;
break ;
}
2018-04-18 22:17:49 +08:00
# endif
2019-03-10 03:34:41 +08:00
case CMD_SET_LF_DIVISOR :
FpgaDownloadAndGo ( FPGA_BITSTREAM_LF ) ;
2019-04-18 03:30:01 +08:00
FpgaSendCommand ( FPGA_CMD_SET_DIVISOR , packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
case CMD_SET_ADC_MUX :
2019-04-18 03:30:01 +08:00
switch ( packet - > core . old . arg [ 0 ] ) {
2019-03-10 07:00:59 +08:00
case 0 :
SetAdcMuxFor ( GPIO_MUXSEL_LOPKD ) ;
break ;
case 2 :
SetAdcMuxFor ( GPIO_MUXSEL_HIPKD ) ;
break ;
2018-07-30 15:54:44 +08:00
# ifndef WITH_FPC
2019-03-10 07:00:59 +08:00
case 1 :
SetAdcMuxFor ( GPIO_MUXSEL_LORAW ) ;
break ;
case 3 :
SetAdcMuxFor ( GPIO_MUXSEL_HIRAW ) ;
break ;
2018-07-04 18:19:04 +08:00
# endif
2019-03-10 07:00:59 +08:00
}
2019-03-10 03:34:41 +08:00
break ;
case CMD_VERSION :
SendVersion ( ) ;
break ;
case CMD_STATUS :
SendStatus ( ) ;
break ;
case CMD_PING :
2019-04-18 03:30:01 +08:00
if ( packet - > ng ) {
reply_ng ( CMD_PING , PM3_SUCCESS , packet - > core . ng . data , packet - > length ) ;
2019-04-17 02:00:17 +08:00
} else {
# ifdef WITH_FPC_HOST
2019-04-17 02:49:32 +08:00
cmd_send ( CMD_ACK , reply_via_fpc , 0 , 0 , 0 , 0 ) ;
2019-04-17 02:00:17 +08:00
# else
2019-04-17 02:49:32 +08:00
cmd_send ( CMD_ACK , 0 , 0 , 0 , 0 , 0 ) ;
2019-04-17 02:00:17 +08:00
# endif
2019-04-17 02:49:32 +08:00
}
2019-03-10 03:34:41 +08:00
break ;
2010-02-21 05:24:25 +08:00
# ifdef WITH_LCD
2019-03-10 03:34:41 +08:00
case CMD_LCD_RESET :
LCDReset ( ) ;
break ;
case CMD_LCD :
2019-04-18 03:30:01 +08:00
LCDSend ( packet - > core . old . arg [ 0 ] ) ;
2019-03-10 03:34:41 +08:00
break ;
2010-02-21 05:24:25 +08:00
# endif
2019-03-10 03:34:41 +08:00
case CMD_SETUP_WRITE :
case CMD_FINISH_WRITE :
case CMD_HARDWARE_RESET :
usb_disable ( ) ;
// (iceman) why this wait?
SpinDelay ( 1000 ) ;
AT91C_BASE_RSTC - > RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST ;
// We're going to reset, and the bootrom will take control.
2019-03-10 07:00:59 +08:00
for ( ; ; ) { }
2019-03-10 03:34:41 +08:00
break ;
case CMD_START_FLASH :
2019-03-10 07:00:59 +08:00
if ( common_area . flags . bootrom_present ) {
2019-03-10 03:34:41 +08:00
common_area . command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE ;
}
usb_disable ( ) ;
AT91C_BASE_RSTC - > RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST ;
// We're going to flash, and the bootrom will take control.
2019-03-10 07:00:59 +08:00
for ( ; ; ) { }
2019-03-10 03:34:41 +08:00
break ;
case CMD_DEVICE_INFO : {
uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS ;
if ( common_area . flags . bootrom_present ) {
dev_info | = DEVICE_INFO_FLAG_BOOTROM_PRESENT ;
}
2019-03-10 07:00:59 +08:00
cmd_send ( CMD_DEVICE_INFO , dev_info , 0 , 0 , 0 , 0 ) ;
2019-03-10 03:34:41 +08:00
break ;
2019-03-10 07:00:59 +08:00
}
2019-03-10 03:34:41 +08:00
default :
2019-04-17 02:00:17 +08:00
Dbprintf ( " %s: 0x%04x " , " unknown command: " , cmd ) ;
2019-03-10 03:34:41 +08:00
break ;
}
2010-02-21 05:24:25 +08:00
}
2019-03-10 18:20:22 +08:00
void __attribute__ ( ( noreturn ) ) AppMain ( void ) {
2017-09-29 04:33:03 +08:00
2019-03-10 03:34:41 +08:00
SpinDelay ( 100 ) ;
clear_trace ( ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 07:00:59 +08:00
if ( common_area . magic ! = COMMON_AREA_MAGIC | | common_area . version ! = 1 ) {
2019-03-10 03:34:41 +08:00
/* Initialize common area */
memset ( & common_area , 0 , sizeof ( common_area ) ) ;
common_area . magic = COMMON_AREA_MAGIC ;
common_area . version = 1 ;
}
common_area . flags . osimage_present = 1 ;
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
LEDsoff ( ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
// The FPGA gets its clock from us from PCK0 output, so set that up.
AT91C_BASE_PIOA - > PIO_BSR = GPIO_PCK0 ;
AT91C_BASE_PIOA - > PIO_PDR = GPIO_PCK0 ;
AT91C_BASE_PMC - > PMC_SCER | = AT91C_PMC_PCK0 ;
// PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
AT91C_BASE_PMC - > PMC_PCKR [ 0 ] = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_4 ; // 4 for 24Mhz pck0, 2 for 48 MHZ pck0
AT91C_BASE_PIOA - > PIO_OER = GPIO_PCK0 ;
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
// Reset SPI
AT91C_BASE_SPI - > SPI_CR = AT91C_SPI_SWRST ;
AT91C_BASE_SPI - > SPI_CR = AT91C_SPI_SWRST ; // errata says it needs twice to be correctly set.
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
// Reset SSC
AT91C_BASE_SSC - > SSC_CR = AT91C_SSC_SWRST ;
2010-02-21 05:24:25 +08:00
2019-03-10 03:34:41 +08:00
// Configure MUX
SetAdcMuxFor ( GPIO_MUXSEL_HIPKD ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
// Load the FPGA image, which we have stored in our flash.
// (the HF version by default)
FpgaDownloadAndGo ( FPGA_BITSTREAM_HF ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
StartTickCount ( ) ;
2019-03-09 15:59:13 +08:00
2010-02-21 05:24:25 +08:00
# ifdef WITH_LCD
2019-03-10 03:34:41 +08:00
LCDInit ( ) ;
2010-02-21 05:24:25 +08:00
# endif
2018-04-08 16:51:19 +08:00
# ifdef WITH_SMARTCARD
2019-03-10 03:34:41 +08:00
I2C_init ( ) ;
2018-04-08 16:51:19 +08:00
# endif
2018-07-30 15:54:44 +08:00
2018-07-04 18:19:04 +08:00
# ifdef WITH_FPC
2019-03-10 03:34:41 +08:00
usart_init ( ) ;
2019-03-09 15:59:13 +08:00
# endif
2018-09-03 06:02:44 +08:00
2018-09-12 00:35:07 +08:00
# ifdef WITH_FLASH
2019-03-10 03:34:41 +08:00
loadT55xxConfig ( ) ;
2018-09-12 00:35:07 +08:00
# endif
2019-03-10 03:34:41 +08:00
// This is made as late as possible to ensure enumeration without timeout
// against device such as http://www.hobbytronics.co.uk/usb-host-board-v2
usb_disable ( ) ;
usb_enable ( ) ;
2018-09-03 06:02:44 +08:00
2019-04-18 03:30:01 +08:00
UsbCommandNG rx ;
2019-03-09 15:59:13 +08:00
2019-03-10 07:00:59 +08:00
for ( ; ; ) {
2019-03-10 03:34:41 +08:00
WDT_HIT ( ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
// Check if there is a usb packet available
if ( usb_poll_validate_length ( ) ) {
2019-04-16 16:01:08 +08:00
bool error = false ;
2019-04-18 03:30:01 +08:00
size_t bytes = usb_read_ng ( ( uint8_t * ) & rx , sizeof ( UsbCommandNGPreamble ) ) ;
2019-04-17 02:00:17 +08:00
if ( bytes = = sizeof ( UsbCommandNGPreamble ) ) {
2019-04-18 03:30:01 +08:00
if ( rx . magic = = USB_COMMANDNG_PREAMBLE_MAGIC ) { // New style NG command
2019-04-18 05:44:48 +08:00
if ( rx . length > USB_CMD_DATA_SIZE ) {
2019-04-18 03:30:01 +08:00
Dbprintf ( " Packet frame with incompatible length: 0x%04x " , rx . length ) ;
2019-04-16 16:01:08 +08:00
error = true ;
}
2019-04-18 03:30:01 +08:00
if ( ! error ) { // Get the core and variable length payload
2019-04-18 05:44:48 +08:00
bytes = usb_read_ng ( ( ( uint8_t * ) & rx . core ) , sizeof ( UsbPacketNGCore ) - USB_CMD_DATA_SIZE + rx . length ) ;
if ( bytes ! = sizeof ( UsbPacketNGCore ) - USB_CMD_DATA_SIZE + rx . length ) {
2019-04-18 03:30:01 +08:00
Dbprintf ( " Packet frame error variable part too short? %d/%d " , bytes , rx . length ) ;
2019-04-16 16:01:08 +08:00
error = true ;
}
}
if ( ! error ) { // Get the postamble
2019-04-18 03:30:01 +08:00
bytes = usb_read_ng ( ( ( uint8_t * ) & rx . crc ) , sizeof ( UsbCommandNGPostamble ) ) ;
2019-04-17 02:00:17 +08:00
if ( bytes ! = sizeof ( UsbCommandNGPostamble ) ) {
Dbprintf ( " Packet frame error fetching postamble " ) ;
error = true ;
}
uint8_t first , second ;
2019-04-18 05:44:48 +08:00
compute_crc ( CRC_14443_A , ( uint8_t * ) & rx , sizeof ( UsbCommandNGPreamble ) + sizeof ( UsbPacketNGCore ) - USB_CMD_DATA_SIZE + rx . length , & first , & second ) ;
2019-04-18 03:30:01 +08:00
if ( ( first < < 8 ) + second ! = rx . crc ) {
Dbprintf ( " Packet frame CRC error %02X%02X <> %04X " , first , second , rx . crc ) ;
2019-04-16 16:01:08 +08:00
error = true ;
}
}
if ( ! error ) {
2019-04-17 02:49:32 +08:00
# ifdef WITH_FPC_HOST
reply_via_fpc = false ;
# endif
2019-04-18 03:30:01 +08:00
rx . ng = true ;
UsbPacketReceived ( & rx ) ;
2019-04-16 16:01:08 +08:00
}
} else { // Old style command
2019-04-18 03:30:01 +08:00
uint8_t tmp [ sizeof ( UsbCommandNGPreamble ) ] ;
memcpy ( tmp , & rx , sizeof ( UsbCommandNGPreamble ) ) ;
memcpy ( & rx . core . old , tmp , sizeof ( UsbCommandNGPreamble ) ) ;
2019-04-18 05:44:48 +08:00
bytes = usb_read_ng ( ( ( uint8_t * ) & rx . core . old ) + sizeof ( UsbCommandNGPreamble ) , sizeof ( UsbCommandOLD ) - sizeof ( UsbCommandNGPreamble ) ) ;
if ( bytes ! = sizeof ( UsbCommandOLD ) - sizeof ( UsbCommandNGPreamble ) ) {
Dbprintf ( " Packet frame error var part too short? %d/%d " , bytes , sizeof ( UsbCommandOLD ) - sizeof ( UsbCommandNGPreamble ) ) ;
2019-04-16 16:01:08 +08:00
error = true ;
}
if ( ! error ) {
2019-04-17 02:49:32 +08:00
# ifdef WITH_FPC_HOST
reply_via_fpc = false ;
# endif
2019-04-18 03:30:01 +08:00
rx . ng = false ;
rx . magic = 0 ;
rx . length = USB_CMD_DATA_SIZE ;
rx . crc = 0 ;
UsbPacketReceived ( & rx ) ;
2019-04-16 16:01:08 +08:00
}
}
} else {
2019-04-17 02:00:17 +08:00
Dbprintf ( " Packet frame preamble too short: %d/%d " , bytes , sizeof ( UsbCommandNGPreamble ) ) ;
2019-04-16 16:01:08 +08:00
error = true ;
2019-04-03 04:34:00 +08:00
}
2019-04-18 03:30:01 +08:00
// TODO DOEGOX if error, shall we resync ?
2019-03-10 03:34:41 +08:00
}
2019-04-03 04:06:10 +08:00
# ifdef WITH_FPC_HOST
// Check if there is a FPC packet available
2019-04-18 03:30:01 +08:00
// TODO DOEGOX NG packets support here too
if ( usart_readbuffer ( ( uint8_t * ) & rx ) ) {
2019-04-16 16:01:08 +08:00
reply_via_fpc = true ;
2019-04-18 03:30:01 +08:00
rx . ng = false ;
rx . magic = 0 ;
rx . length = USB_CMD_DATA_SIZE ;
rx . crc = 0 ;
UsbPacketReceived ( & rx ) ;
2019-04-03 04:06:10 +08:00
}
2019-04-18 03:30:01 +08:00
usart_readcheck ( ( uint8_t * ) & rx , sizeof ( rx ) ) ;
2018-07-04 18:19:04 +08:00
# endif
2019-03-09 15:59:13 +08:00
2019-03-10 03:34:41 +08:00
// Press button for one second to enter a possible standalone mode
if ( BUTTON_HELD ( 1000 ) > 0 ) {
2019-03-09 15:59:13 +08:00
2019-03-10 07:00:59 +08:00
/*
* So this is the trigger to execute a standalone mod . Generic entrypoint by following the standalone / standalone . h headerfile
* All standalone mod " main loop " should be the RunMod ( ) function .
* Since the standalone is either LF or HF , the somewhat bisarr defines below exists .
*/
2017-10-29 17:38:49 +08:00
# if defined (WITH_LF) && ( defined (WITH_LF_SAMYRUN) || defined (WITH_LF_HIDBRUTE) || defined (WITH_LF_PROXBRUTE) )
2019-03-10 03:34:41 +08:00
RunMod ( ) ;
2015-07-23 05:00:52 +08:00
# endif
2019-03-09 15:59:13 +08:00
2018-10-17 03:41:05 +08:00
# if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) || defined(WITH_HF_BOG) )
2019-03-10 03:34:41 +08:00
RunMod ( ) ;
2010-02-21 05:24:25 +08:00
# endif
2018-09-07 03:43:20 +08:00
2019-03-10 03:34:41 +08:00
}
}
2010-02-21 05:24:25 +08:00
}