mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-21 05:43:23 -07:00
Merge pull request #143 from marshmellow42/master
lfops cleanup, t55xx additions/fixes, PCF7931 input cleanup
This commit is contained in:
commit
9983a92943
27 changed files with 1660 additions and 1393 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -5,6 +5,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- Added viking demod to `lf search` (marshmellow)
|
||||||
|
- `data askvikingdemod` demod viking id tag from graphbuffer (marshmellow)
|
||||||
|
- `lf t55xx resetread` added reset then read command - should allow determining start
|
||||||
|
of stream transmissions (marshmellow)
|
||||||
|
- `lf t55xx wakeup` added wake with password (AOR) to allow lf search or standard lf read after (iceman, marshmellow)
|
||||||
- `hf iclass managekeys` to save, load and manage iclass keys. (adjusted most commands to accept a loaded key in memory) (marshmellow)
|
- `hf iclass managekeys` to save, load and manage iclass keys. (adjusted most commands to accept a loaded key in memory) (marshmellow)
|
||||||
- `hf iclass readblk` to select, authenticate, and read 1 block from an iclass card (marshmellow)
|
- `hf iclass readblk` to select, authenticate, and read 1 block from an iclass card (marshmellow)
|
||||||
- `hf iclass writeblk` to select, authenticate, and write 1 block to an iclass card (or picopass) (marshmellow + others)
|
- `hf iclass writeblk` to select, authenticate, and write 1 block to an iclass card (or picopass) (marshmellow + others)
|
||||||
|
@ -21,6 +26,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Added option c to 'hf list' (mark CRC bytes) (piwi)
|
- Added option c to 'hf list' (mark CRC bytes) (piwi)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- Adjusted lf em410x em410xsim to accept a clock argument
|
||||||
|
- Adjusted lf t55xx dump to allow overriding the safety check and warning text (marshmellow)
|
||||||
|
- Adjusted lf t55xx write input variables (marshmellow)
|
||||||
|
- Adjusted lf t55xx read with password safety check and warning text and adjusted the input variables (marshmellow & iceman)
|
||||||
|
- Adjusted LF FSK demod to account for cross threshold fluctuations (898 count waves will adjust the 9 to 8 now...) more accurate.
|
||||||
|
- Adjusted timings for t55xx commands. more reliable now. (marshmellow & iceman)
|
||||||
|
- `lf cmdread` adjusted input methods and added help text (marshmellow & iceman)
|
||||||
- changed `lf config t <threshold>` to be 0 - 128 and will trigger on + or - threshold value (marshmellow)
|
- changed `lf config t <threshold>` to be 0 - 128 and will trigger on + or - threshold value (marshmellow)
|
||||||
- `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to muliple pages for the larger tags yet)
|
- `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to muliple pages for the larger tags yet)
|
||||||
- Revised workflow for StandAloneMode14a (Craig Young)
|
- Revised workflow for StandAloneMode14a (Craig Young)
|
||||||
|
|
|
@ -50,8 +50,14 @@ uint8_t *BigBuf_get_EM_addr(void)
|
||||||
|
|
||||||
// clear ALL of BigBuf
|
// clear ALL of BigBuf
|
||||||
void BigBuf_Clear(void)
|
void BigBuf_Clear(void)
|
||||||
|
{
|
||||||
|
BigBuf_Clear_ext(true);
|
||||||
|
}
|
||||||
|
// clear ALL of BigBuf
|
||||||
|
void BigBuf_Clear_ext(bool verbose)
|
||||||
{
|
{
|
||||||
memset(BigBuf,0,BIGBUF_SIZE);
|
memset(BigBuf,0,BIGBUF_SIZE);
|
||||||
|
if (verbose)
|
||||||
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ extern uint8_t *BigBuf_get_addr(void);
|
||||||
extern uint8_t *BigBuf_get_EM_addr(void);
|
extern uint8_t *BigBuf_get_EM_addr(void);
|
||||||
extern uint16_t BigBuf_max_traceLen(void);
|
extern uint16_t BigBuf_max_traceLen(void);
|
||||||
extern void BigBuf_Clear(void);
|
extern void BigBuf_Clear(void);
|
||||||
|
extern void BigBuf_Clear_ext(bool verbose);
|
||||||
extern uint8_t *BigBuf_malloc(uint16_t);
|
extern uint8_t *BigBuf_malloc(uint16_t);
|
||||||
extern void BigBuf_free(void);
|
extern void BigBuf_free(void);
|
||||||
extern void BigBuf_free_keep_EM(void);
|
extern void BigBuf_free_keep_EM(void);
|
||||||
|
|
|
@ -15,7 +15,7 @@ APP_CFLAGS = -DWITH_ISO14443a_StandAlone -DWITH_LF -DWITH_ISO15693 -DWITH_ISO144
|
||||||
#-DWITH_LCD
|
#-DWITH_LCD
|
||||||
|
|
||||||
#SRC_LCD = fonts.c LCD.c
|
#SRC_LCD = fonts.c LCD.c
|
||||||
SRC_LF = lfops.c hitag2.c lfsampling.c
|
SRC_LF = lfops.c hitag2.c lfsampling.c pcf7931.c lfdemod.c protocols.c
|
||||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||||
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
|
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
|
||||||
SRC_ISO14443b = iso14443b.c
|
SRC_ISO14443b = iso14443b.c
|
||||||
|
@ -52,7 +52,6 @@ THUMBSRC = start.c \
|
||||||
# These are to be compiled in ARM mode
|
# These are to be compiled in ARM mode
|
||||||
ARMSRC = fpgaloader.c \
|
ARMSRC = fpgaloader.c \
|
||||||
legicrf.c \
|
legicrf.c \
|
||||||
lfdemod.c \
|
|
||||||
$(SRC_ISO14443a) \
|
$(SRC_ISO14443a) \
|
||||||
$(SRC_ISO14443b) \
|
$(SRC_ISO14443b) \
|
||||||
$(SRC_CRAPTO1) \
|
$(SRC_CRAPTO1) \
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "lfsampling.h"
|
#include "lfsampling.h"
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
|
#include "pcf7931.h"
|
||||||
#ifdef WITH_LCD
|
#ifdef WITH_LCD
|
||||||
#include "LCD.h"
|
#include "LCD.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -945,7 +946,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
CmdIOdemodFSK(c->arg[0], 0, 0, 1);
|
CmdIOdemodFSK(c->arg[0], 0, 0, 1);
|
||||||
break;
|
break;
|
||||||
case CMD_IO_CLONE_TAG:
|
case CMD_IO_CLONE_TAG:
|
||||||
CopyIOtoT55x7(c->arg[0], c->arg[1], c->d.asBytes[0]);
|
CopyIOtoT55x7(c->arg[0], c->arg[1]);
|
||||||
break;
|
break;
|
||||||
case CMD_EM410X_DEMOD:
|
case CMD_EM410X_DEMOD:
|
||||||
CmdEM410xdemod(c->arg[0], 0, 0, 1);
|
CmdEM410xdemod(c->arg[0], 0, 0, 1);
|
||||||
|
@ -974,21 +975,22 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]);
|
CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]);
|
||||||
break;
|
break;
|
||||||
case CMD_T55XX_READ_BLOCK:
|
case CMD_T55XX_READ_BLOCK:
|
||||||
T55xxReadBlock(c->arg[1], c->arg[2],c->d.asBytes[0]);
|
T55xxReadBlock(c->arg[0], c->arg[1], c->arg[2]);
|
||||||
break;
|
break;
|
||||||
case CMD_T55XX_WRITE_BLOCK:
|
case CMD_T55XX_WRITE_BLOCK:
|
||||||
T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
|
T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
|
||||||
break;
|
break;
|
||||||
case CMD_T55XX_READ_TRACE:
|
case CMD_T55XX_WAKEUP:
|
||||||
T55xxReadTrace();
|
T55xxWakeUp(c->arg[0]);
|
||||||
|
break;
|
||||||
|
case CMD_T55XX_RESET_READ:
|
||||||
|
T55xxResetRead();
|
||||||
break;
|
break;
|
||||||
case CMD_PCF7931_READ:
|
case CMD_PCF7931_READ:
|
||||||
ReadPCF7931();
|
ReadPCF7931();
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
|
||||||
break;
|
break;
|
||||||
case CMD_PCF7931_WRITE:
|
case CMD_PCF7931_WRITE:
|
||||||
WritePCF7931(c->d.asDwords[0],c->d.asDwords[1],c->d.asDwords[2],c->d.asDwords[3],c->d.asDwords[4],c->d.asDwords[5],c->d.asDwords[6], c->d.asDwords[9], c->d.asDwords[7]-128,c->d.asDwords[8]-128, c->arg[0], c->arg[1], c->arg[2]);
|
WritePCF7931(c->d.asBytes[0],c->d.asBytes[1],c->d.asBytes[2],c->d.asBytes[3],c->d.asBytes[4],c->d.asBytes[5],c->d.asBytes[6], c->d.asBytes[9], c->d.asBytes[7]-128,c->d.asBytes[8]-128, c->arg[0], c->arg[1], c->arg[2]);
|
||||||
break;
|
break;
|
||||||
case CMD_EM4X_READ_WORD:
|
case CMD_EM4X_READ_WORD:
|
||||||
EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
|
EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
|
||||||
|
|
|
@ -58,7 +58,7 @@ extern uint8_t bits_per_sample ;
|
||||||
extern bool averaging;
|
extern bool averaging;
|
||||||
|
|
||||||
void AcquireRawAdcSamples125k(int divisor);
|
void AcquireRawAdcSamples125k(int divisor);
|
||||||
void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,uint8_t *command);
|
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command);
|
||||||
void ReadTItag(void);
|
void ReadTItag(void);
|
||||||
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
|
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
|
||||||
|
|
||||||
|
@ -73,24 +73,18 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol);
|
||||||
void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol); // Realtime demodulation mode for AWID26
|
void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol); // Realtime demodulation mode for AWID26
|
||||||
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol);
|
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol);
|
||||||
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol);
|
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol);
|
||||||
void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an ioProx card to T5557/T5567
|
void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567
|
||||||
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
|
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
|
||||||
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
|
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
|
||||||
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
|
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
|
||||||
void CopyIndala64toT55x7(int hi, int lo); // Clone Indala 64-bit tag by UID to T55x7
|
void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7
|
||||||
void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7); // Clone Indala 224-bit tag by UID to T55x7
|
void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7
|
||||||
|
void T55xxResetRead(void);
|
||||||
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode);
|
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode);
|
||||||
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode );
|
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd);
|
||||||
void T55xxReadTrace(void);
|
void T55xxWakeUp(uint32_t Pwd);
|
||||||
int DemodPCF7931(uint8_t **outBlocks);
|
void TurnReadLFOn();
|
||||||
int IsBlock0PCF7931(uint8_t *Block);
|
//void T55xxReadTrace(void);
|
||||||
int IsBlock1PCF7931(uint8_t *Block);
|
|
||||||
void ReadPCF7931();
|
|
||||||
void SendCmdPCF7931(uint32_t * tab);
|
|
||||||
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p);
|
|
||||||
bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p);
|
|
||||||
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab);
|
|
||||||
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data);
|
|
||||||
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
||||||
void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
||||||
|
|
||||||
|
|
1098
armsrc/lfops.c
1098
armsrc/lfops.c
File diff suppressed because it is too large
Load diff
|
@ -103,7 +103,6 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
|
||||||
FpgaSetupSsc();
|
FpgaSetupSsc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the sample acquisition. If threshold is specified, the actual sampling
|
* Does the sample acquisition. If threshold is specified, the actual sampling
|
||||||
* is not commenced until the threshold has been reached.
|
* is not commenced until the threshold has been reached.
|
||||||
|
@ -154,9 +153,6 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
||||||
if ((trigger_threshold > 0) && (sample < (trigger_threshold+128)) && (sample > (128-trigger_threshold))) //
|
if ((trigger_threshold > 0) && (sample < (trigger_threshold+128)) && (sample > (128-trigger_threshold))) //
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//if (trigger_threshold > 0 && sample < trigger_threshold) //
|
|
||||||
//continue;
|
|
||||||
|
|
||||||
trigger_threshold = 0;
|
trigger_threshold = 0;
|
||||||
sample_total_numbers++;
|
sample_total_numbers++;
|
||||||
|
|
||||||
|
@ -252,3 +248,59 @@ uint32_t SnoopLF()
|
||||||
{
|
{
|
||||||
return ReadLF(false, true);
|
return ReadLF(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds
|
||||||
|
* the data is collected in BigBuf.
|
||||||
|
**/
|
||||||
|
void doT55x7Acquisition(size_t sample_size) {
|
||||||
|
|
||||||
|
#define T55xx_READ_UPPER_THRESHOLD 128+40 // 40 grph
|
||||||
|
#define T55xx_READ_TOL 5
|
||||||
|
|
||||||
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
uint16_t bufsize = BigBuf_max_traceLen();
|
||||||
|
|
||||||
|
if ( bufsize > sample_size )
|
||||||
|
bufsize = sample_size;
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
bool startFound = false;
|
||||||
|
bool highFound = false;
|
||||||
|
uint8_t curSample = 0;
|
||||||
|
uint8_t firstSample = 0;
|
||||||
|
uint16_t skipCnt = 0;
|
||||||
|
while(!BUTTON_PRESS() && skipCnt<1000) {
|
||||||
|
WDT_HIT();
|
||||||
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||||
|
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||||
|
LED_D_ON();
|
||||||
|
}
|
||||||
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
|
curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
LED_D_OFF();
|
||||||
|
|
||||||
|
// skip until the first high sample above threshold
|
||||||
|
if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
|
||||||
|
if (curSample > firstSample)
|
||||||
|
firstSample = curSample;
|
||||||
|
highFound = true;
|
||||||
|
} else if (!highFound) {
|
||||||
|
skipCnt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip until first high samples begin to change
|
||||||
|
if (startFound || curSample < firstSample-T55xx_READ_TOL){
|
||||||
|
// if just found start - recover last sample
|
||||||
|
if (!startFound) {
|
||||||
|
dest[i++] = firstSample;
|
||||||
|
startFound = true;
|
||||||
|
}
|
||||||
|
// collect samples
|
||||||
|
dest[i++] = curSample;
|
||||||
|
if (i >= bufsize-1) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
#ifndef LFSAMPLING_H
|
#ifndef LFSAMPLING_H
|
||||||
#define LFSAMPLING_H
|
#define LFSAMPLING_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds
|
||||||
|
* the data is collected in BigBuf.
|
||||||
|
**/
|
||||||
|
void doT55x7Acquisition(size_t sample_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
|
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
|
||||||
* @return number of bits sampled
|
* @return number of bits sampled
|
||||||
|
@ -41,7 +47,6 @@ uint32_t DoAcquisition_config( bool silent);
|
||||||
**/
|
**/
|
||||||
void LFSetupFPGAForADC(int divisor, bool lf_field);
|
void LFSetupFPGAForADC(int divisor, bool lf_field);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the USB-handler to set the sampling configuration
|
* Called from the USB-handler to set the sampling configuration
|
||||||
* The sampling config is used for std reading and snooping.
|
* The sampling config is used for std reading and snooping.
|
||||||
|
|
526
armsrc/pcf7931.c
Normal file
526
armsrc/pcf7931.c
Normal file
|
@ -0,0 +1,526 @@
|
||||||
|
#include "proxmark3.h"
|
||||||
|
#include "apps.h"
|
||||||
|
#include "lfsampling.h"
|
||||||
|
#include "pcf7931.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
#define T0_PCF 8 //period for the pcf7931 in us
|
||||||
|
#define ALLOC 16
|
||||||
|
|
||||||
|
#define abs(x) ( ((x)<0) ? -(x) : (x) )
|
||||||
|
#define max(x,y) ( x<y ? y:x)
|
||||||
|
|
||||||
|
int DemodPCF7931(uint8_t **outBlocks) {
|
||||||
|
|
||||||
|
uint8_t bits[256] = {0x00};
|
||||||
|
uint8_t blocks[8][16];
|
||||||
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
|
int GraphTraceLen = BigBuf_max_traceLen();
|
||||||
|
if ( GraphTraceLen > 18000 )
|
||||||
|
GraphTraceLen = 18000;
|
||||||
|
|
||||||
|
|
||||||
|
int i, j, lastval, bitidx, half_switch;
|
||||||
|
int clock = 64;
|
||||||
|
int tolerance = clock / 8;
|
||||||
|
int pmc, block_done;
|
||||||
|
int lc, warnings = 0;
|
||||||
|
int num_blocks = 0;
|
||||||
|
int lmin=128, lmax=128;
|
||||||
|
uint8_t dir;
|
||||||
|
|
||||||
|
LFSetupFPGAForADC(95, true);
|
||||||
|
DoAcquisition_default(0, true);
|
||||||
|
|
||||||
|
lmin = 64;
|
||||||
|
lmax = 192;
|
||||||
|
|
||||||
|
i = 2;
|
||||||
|
|
||||||
|
/* Find first local max/min */
|
||||||
|
if(dest[1] > dest[0]) {
|
||||||
|
while(i < GraphTraceLen) {
|
||||||
|
if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dir = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while(i < GraphTraceLen) {
|
||||||
|
if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dir = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastval = i++;
|
||||||
|
half_switch = 0;
|
||||||
|
pmc = 0;
|
||||||
|
block_done = 0;
|
||||||
|
|
||||||
|
for (bitidx = 0; i < GraphTraceLen; i++)
|
||||||
|
{
|
||||||
|
if ( (dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin))
|
||||||
|
{
|
||||||
|
lc = i - lastval;
|
||||||
|
lastval = i;
|
||||||
|
|
||||||
|
// Switch depending on lc length:
|
||||||
|
// Tolerance is 1/8 of clock rate (arbitrary)
|
||||||
|
if (abs(lc-clock/4) < tolerance) {
|
||||||
|
// 16T0
|
||||||
|
if((i - pmc) == lc) { /* 16T0 was previous one */
|
||||||
|
/* It's a PMC ! */
|
||||||
|
i += (128+127+16+32+33+16)-1;
|
||||||
|
lastval = i;
|
||||||
|
pmc = 0;
|
||||||
|
block_done = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pmc = i;
|
||||||
|
}
|
||||||
|
} else if (abs(lc-clock/2) < tolerance) {
|
||||||
|
// 32TO
|
||||||
|
if((i - pmc) == lc) { /* 16T0 was previous one */
|
||||||
|
/* It's a PMC ! */
|
||||||
|
i += (128+127+16+32+33)-1;
|
||||||
|
lastval = i;
|
||||||
|
pmc = 0;
|
||||||
|
block_done = 1;
|
||||||
|
}
|
||||||
|
else if(half_switch == 1) {
|
||||||
|
bits[bitidx++] = 0;
|
||||||
|
half_switch = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
half_switch++;
|
||||||
|
} else if (abs(lc-clock) < tolerance) {
|
||||||
|
// 64TO
|
||||||
|
bits[bitidx++] = 1;
|
||||||
|
} else {
|
||||||
|
// Error
|
||||||
|
warnings++;
|
||||||
|
if (warnings > 10)
|
||||||
|
{
|
||||||
|
Dbprintf("Error: too many detection errors, aborting.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(block_done == 1) {
|
||||||
|
if(bitidx == 128) {
|
||||||
|
for(j=0; j<16; j++) {
|
||||||
|
blocks[num_blocks][j] = 128*bits[j*8+7]+
|
||||||
|
64*bits[j*8+6]+
|
||||||
|
32*bits[j*8+5]+
|
||||||
|
16*bits[j*8+4]+
|
||||||
|
8*bits[j*8+3]+
|
||||||
|
4*bits[j*8+2]+
|
||||||
|
2*bits[j*8+1]+
|
||||||
|
bits[j*8];
|
||||||
|
|
||||||
|
}
|
||||||
|
num_blocks++;
|
||||||
|
}
|
||||||
|
bitidx = 0;
|
||||||
|
block_done = 0;
|
||||||
|
half_switch = 0;
|
||||||
|
}
|
||||||
|
if(i < GraphTraceLen)
|
||||||
|
dir =(dest[i-1] > dest[i]) ? 0 : 1;
|
||||||
|
}
|
||||||
|
if(bitidx==255)
|
||||||
|
bitidx=0;
|
||||||
|
warnings = 0;
|
||||||
|
if(num_blocks == 4) break;
|
||||||
|
}
|
||||||
|
memcpy(outBlocks, blocks, 16*num_blocks);
|
||||||
|
return num_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
int IsBlock0PCF7931(uint8_t *Block) {
|
||||||
|
// Assume RFU means 0 :)
|
||||||
|
if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled
|
||||||
|
return 1;
|
||||||
|
if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ?
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int IsBlock1PCF7931(uint8_t *Block) {
|
||||||
|
// Assume RFU means 0 :)
|
||||||
|
if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0)
|
||||||
|
if((Block[14] & 0x7f) <= 9 && Block[15] <= 9)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadPCF7931() {
|
||||||
|
uint8_t Blocks[8][17];
|
||||||
|
uint8_t tmpBlocks[4][16];
|
||||||
|
int i, j, ind, ind2, n;
|
||||||
|
int num_blocks = 0;
|
||||||
|
int max_blocks = 8;
|
||||||
|
int ident = 0;
|
||||||
|
int error = 0;
|
||||||
|
int tries = 0;
|
||||||
|
|
||||||
|
memset(Blocks, 0, 8*17*sizeof(uint8_t));
|
||||||
|
|
||||||
|
do {
|
||||||
|
memset(tmpBlocks, 0, 4*16*sizeof(uint8_t));
|
||||||
|
n = DemodPCF7931((uint8_t**)tmpBlocks);
|
||||||
|
if(!n)
|
||||||
|
error++;
|
||||||
|
if(error==10 && num_blocks == 0) {
|
||||||
|
Dbprintf("Error, no tag or bad tag");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (tries==20 || error==10) {
|
||||||
|
Dbprintf("Error reading the tag");
|
||||||
|
Dbprintf("Here is the partial content");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<n; i++)
|
||||||
|
Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
|
tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
|
||||||
|
tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
|
||||||
|
if(!ident) {
|
||||||
|
for(i=0; i<n; i++) {
|
||||||
|
if(IsBlock0PCF7931(tmpBlocks[i])) {
|
||||||
|
// Found block 0 ?
|
||||||
|
if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
|
||||||
|
// Found block 1!
|
||||||
|
// \o/
|
||||||
|
ident = 1;
|
||||||
|
memcpy(Blocks[0], tmpBlocks[i], 16);
|
||||||
|
Blocks[0][ALLOC] = 1;
|
||||||
|
memcpy(Blocks[1], tmpBlocks[i+1], 16);
|
||||||
|
Blocks[1][ALLOC] = 1;
|
||||||
|
max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
|
||||||
|
// Debug print
|
||||||
|
Dbprintf("(dbg) Max blocks: %d", max_blocks);
|
||||||
|
num_blocks = 2;
|
||||||
|
// Handle following blocks
|
||||||
|
for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
|
||||||
|
if(j==n) j=0;
|
||||||
|
if(j==i) break;
|
||||||
|
memcpy(Blocks[ind2], tmpBlocks[j], 16);
|
||||||
|
Blocks[ind2][ALLOC] = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(i=0; i<n; i++) { // Look for identical block in known blocks
|
||||||
|
if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
|
||||||
|
for(j=0; j<max_blocks; j++) {
|
||||||
|
if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
|
||||||
|
// Found an identical block
|
||||||
|
for(ind=i-1,ind2=j-1; ind >= 0; ind--,ind2--) {
|
||||||
|
if(ind2 < 0)
|
||||||
|
ind2 = max_blocks;
|
||||||
|
if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
|
||||||
|
// Dbprintf("Tmp %d -> Block %d", ind, ind2);
|
||||||
|
memcpy(Blocks[ind2], tmpBlocks[ind], 16);
|
||||||
|
Blocks[ind2][ALLOC] = 1;
|
||||||
|
num_blocks++;
|
||||||
|
if(num_blocks == max_blocks) goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) {
|
||||||
|
if(ind2 > max_blocks)
|
||||||
|
ind2 = 0;
|
||||||
|
if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
|
||||||
|
// Dbprintf("Tmp %d -> Block %d", ind, ind2);
|
||||||
|
memcpy(Blocks[ind2], tmpBlocks[ind], 16);
|
||||||
|
Blocks[ind2][ALLOC] = 1;
|
||||||
|
num_blocks++;
|
||||||
|
if(num_blocks == max_blocks) goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tries++;
|
||||||
|
if (BUTTON_PRESS()) return;
|
||||||
|
} while (num_blocks != max_blocks);
|
||||||
|
end:
|
||||||
|
Dbprintf("-----------------------------------------");
|
||||||
|
Dbprintf("Memory content:");
|
||||||
|
Dbprintf("-----------------------------------------");
|
||||||
|
for(i=0; i<max_blocks; i++) {
|
||||||
|
if(Blocks[i][ALLOC]==1)
|
||||||
|
Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
|
Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
|
||||||
|
Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
|
||||||
|
else
|
||||||
|
Dbprintf("<missing block %d>", i);
|
||||||
|
}
|
||||||
|
Dbprintf("-----------------------------------------");
|
||||||
|
|
||||||
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Write on a byte of a PCF7931 tag
|
||||||
|
* @param address : address of the block to write
|
||||||
|
@param byte : address of the byte to write
|
||||||
|
@param data : data to write
|
||||||
|
*/
|
||||||
|
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t tab[1024]={0}; // data times frame
|
||||||
|
uint32_t u = 0;
|
||||||
|
uint8_t parity = 0;
|
||||||
|
bool comp = 0;
|
||||||
|
|
||||||
|
//BUILD OF THE DATA FRAME
|
||||||
|
|
||||||
|
//alimentation of the tag (time for initializing)
|
||||||
|
AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab);
|
||||||
|
|
||||||
|
//PMC
|
||||||
|
Dbprintf("Initialization delay : %d us", init_delay);
|
||||||
|
AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab);
|
||||||
|
|
||||||
|
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
|
||||||
|
|
||||||
|
//password indication bit
|
||||||
|
AddBitPCF7931(1, tab, l, p);
|
||||||
|
|
||||||
|
|
||||||
|
//password (on 56 bits)
|
||||||
|
Dbprintf("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", pass1,pass2,pass3,pass4,pass5,pass6,pass7);
|
||||||
|
AddBytePCF7931(pass1, tab, l, p);
|
||||||
|
AddBytePCF7931(pass2, tab, l, p);
|
||||||
|
AddBytePCF7931(pass3, tab, l, p);
|
||||||
|
AddBytePCF7931(pass4, tab, l, p);
|
||||||
|
AddBytePCF7931(pass5, tab, l, p);
|
||||||
|
AddBytePCF7931(pass6, tab, l, p);
|
||||||
|
AddBytePCF7931(pass7, tab, l, p);
|
||||||
|
|
||||||
|
//programming mode (0 or 1)
|
||||||
|
AddBitPCF7931(0, tab, l, p);
|
||||||
|
|
||||||
|
//block adress on 6 bits
|
||||||
|
Dbprintf("Block address : %02x", address);
|
||||||
|
for (u=0; u<6; u++)
|
||||||
|
{
|
||||||
|
if (address&(1<<u)) { // bit 1
|
||||||
|
parity++;
|
||||||
|
AddBitPCF7931(1, tab, l, p);
|
||||||
|
} else{ // bit 0
|
||||||
|
AddBitPCF7931(0, tab, l, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//byte address on 4 bits
|
||||||
|
Dbprintf("Byte address : %02x", byte);
|
||||||
|
for (u=0; u<4; u++)
|
||||||
|
{
|
||||||
|
if (byte&(1<<u)) { // bit 1
|
||||||
|
parity++;
|
||||||
|
AddBitPCF7931(1, tab, l, p);
|
||||||
|
} else{ // bit 0
|
||||||
|
AddBitPCF7931(0, tab, l, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//data on 8 bits
|
||||||
|
Dbprintf("Data : %02x", data);
|
||||||
|
for (u=0; u<8; u++)
|
||||||
|
{
|
||||||
|
if (data&(1<<u)) { // bit 1
|
||||||
|
parity++;
|
||||||
|
AddBitPCF7931(1, tab, l, p);
|
||||||
|
} else{ //bit 0
|
||||||
|
AddBitPCF7931(0, tab, l, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//parity bit
|
||||||
|
if((parity%2)==0){
|
||||||
|
AddBitPCF7931(0, tab, l, p); //even parity
|
||||||
|
}else{
|
||||||
|
AddBitPCF7931(1, tab, l, p);//odd parity
|
||||||
|
}
|
||||||
|
|
||||||
|
//time access memory
|
||||||
|
AddPatternPCF7931(5120+2680, 0, 0, tab);
|
||||||
|
|
||||||
|
//conversion of the scale time
|
||||||
|
for(u=0;u<500;u++){
|
||||||
|
tab[u]=(tab[u] * 3)/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//compennsation of the counter reload
|
||||||
|
while (!comp){
|
||||||
|
comp = 1;
|
||||||
|
for(u=0;tab[u]!=0;u++){
|
||||||
|
if(tab[u] > 0xFFFF){
|
||||||
|
tab[u] -= 0xFFFF;
|
||||||
|
comp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SendCmdPCF7931(tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Send a trame to a PCF7931 tags
|
||||||
|
* @param tab : array of the data frame
|
||||||
|
*/
|
||||||
|
|
||||||
|
void SendCmdPCF7931(uint32_t * tab){
|
||||||
|
uint16_t u=0;
|
||||||
|
uint16_t tempo=0;
|
||||||
|
|
||||||
|
Dbprintf("SENDING DATA FRAME...");
|
||||||
|
|
||||||
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
|
||||||
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||||
|
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU );
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
|
||||||
|
// steal this pin from the SSP and use it to control the modulation
|
||||||
|
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||||
|
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||||
|
|
||||||
|
//initialization of the timer
|
||||||
|
AT91C_BASE_PMC->PMC_PCER |= (0x1 << 12) | (0x1 << 13) | (0x1 << 14);
|
||||||
|
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||||
|
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
|
||||||
|
AT91C_BASE_TCB->TCB_BCR = 1;
|
||||||
|
|
||||||
|
|
||||||
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
|
for(u=0;tab[u]!= 0;u+=3){
|
||||||
|
|
||||||
|
|
||||||
|
// modulate antenna
|
||||||
|
HIGH(GPIO_SSC_DOUT);
|
||||||
|
while(tempo != tab[u]){
|
||||||
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop modulating antenna
|
||||||
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
while(tempo != tab[u+1]){
|
||||||
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// modulate antenna
|
||||||
|
HIGH(GPIO_SSC_DOUT);
|
||||||
|
while(tempo != tab[u+2]){
|
||||||
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_A_OFF();
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
SpinDelay(200);
|
||||||
|
|
||||||
|
|
||||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||||
|
DbpString("FINISH !");
|
||||||
|
DbpString("(Could be usefull to send the same trame many times)");
|
||||||
|
LED(0xFFFF, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add a byte for building the data frame of PCF7931 tags
|
||||||
|
* @param b : byte to add
|
||||||
|
* @param tab : array of the data frame
|
||||||
|
* @param l : offset on low pulse width
|
||||||
|
* @param p : offset on low pulse positioning
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
|
||||||
|
|
||||||
|
uint32_t u;
|
||||||
|
for (u=0; u<8; u++)
|
||||||
|
{
|
||||||
|
if (byte&(1<<u)) { //bit à 1
|
||||||
|
if(AddBitPCF7931(1, tab, l, p)==1)return 1;
|
||||||
|
} else { //bit à 0
|
||||||
|
if(AddBitPCF7931(0, tab, l, p)==1)return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a bits for building the data frame of PCF7931 tags
|
||||||
|
* @param b : bit to add
|
||||||
|
* @param tab : array of the data frame
|
||||||
|
* @param l : offset on low pulse width
|
||||||
|
* @param p : offset on low pulse positioning
|
||||||
|
*/
|
||||||
|
bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){
|
||||||
|
uint8_t u = 0;
|
||||||
|
|
||||||
|
for(u=0;tab[u]!=0;u+=3){} //we put the cursor at the last value of the array
|
||||||
|
|
||||||
|
|
||||||
|
if(b==1){ //add a bit 1
|
||||||
|
if(u==0) tab[u] = 34*T0_PCF+p;
|
||||||
|
else tab[u] = 34*T0_PCF+tab[u-1]+p;
|
||||||
|
|
||||||
|
tab[u+1] = 6*T0_PCF+tab[u]+l;
|
||||||
|
tab[u+2] = 88*T0_PCF+tab[u+1]-l-p;
|
||||||
|
return 0;
|
||||||
|
}else{ //add a bit 0
|
||||||
|
|
||||||
|
if(u==0) tab[u] = 98*T0_PCF+p;
|
||||||
|
else tab[u] = 98*T0_PCF+tab[u-1]+p;
|
||||||
|
|
||||||
|
tab[u+1] = 6*T0_PCF+tab[u]+l;
|
||||||
|
tab[u+2] = 24*T0_PCF+tab[u+1]-l-p;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a custom pattern in the data frame
|
||||||
|
* @param a : delay of the first high pulse
|
||||||
|
* @param b : delay of the low pulse
|
||||||
|
* @param c : delay of the last high pulse
|
||||||
|
* @param tab : array of the data frame
|
||||||
|
*/
|
||||||
|
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){
|
||||||
|
uint32_t u = 0;
|
||||||
|
for(u=0;tab[u]!=0;u+=3){} //we put the cursor at the last value of the array
|
||||||
|
|
||||||
|
if(u==0) tab[u] = a;
|
||||||
|
else tab[u] = a + tab[u-1];
|
||||||
|
|
||||||
|
tab[u+1] = b+tab[u];
|
||||||
|
tab[u+2] = c+tab[u+1];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
14
armsrc/pcf7931.h
Normal file
14
armsrc/pcf7931.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef __PCF7931_H
|
||||||
|
#define __PCF7931_H
|
||||||
|
|
||||||
|
int DemodPCF7931(uint8_t **outBlocks);
|
||||||
|
int IsBlock0PCF7931(uint8_t *Block);
|
||||||
|
int IsBlock1PCF7931(uint8_t *Block);
|
||||||
|
void ReadPCF7931();
|
||||||
|
void SendCmdPCF7931(uint32_t * tab);
|
||||||
|
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p);
|
||||||
|
bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p);
|
||||||
|
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab);
|
||||||
|
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data);
|
||||||
|
|
||||||
|
#endif
|
|
@ -637,6 +637,32 @@ int CmdG_Prox_II_Demod(const char *Cmd)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//by marshmellow
|
||||||
|
//see ASKDemod for what args are accepted
|
||||||
|
int CmdVikingDemod(const char *Cmd)
|
||||||
|
{
|
||||||
|
if (!ASKDemod(Cmd, false, false, 1)) {
|
||||||
|
if (g_debugMode) PrintAndLog("ASKDemod failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
size_t size = DemodBufferLen;
|
||||||
|
//call lfdemod.c demod for gProxII
|
||||||
|
int ans = VikingDemod_AM(DemodBuffer, &size);
|
||||||
|
if (ans < 0) {
|
||||||
|
if (g_debugMode) PrintAndLog("Error Viking_Demod %d", ans);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//got a good demod
|
||||||
|
uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32);
|
||||||
|
uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
|
||||||
|
uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32);
|
||||||
|
uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8);
|
||||||
|
PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum);
|
||||||
|
PrintAndLog("Raw: %08X%08X", raw1,raw2);
|
||||||
|
setDemodBuf(DemodBuffer+ans, 64, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
//by marshmellow - see ASKDemod
|
//by marshmellow - see ASKDemod
|
||||||
int Cmdaskrawdemod(const char *Cmd)
|
int Cmdaskrawdemod(const char *Cmd)
|
||||||
{
|
{
|
||||||
|
@ -1130,8 +1156,6 @@ int CmdFSKdemodParadox(const char *Cmd)
|
||||||
//print ioprox ID and some format details
|
//print ioprox ID and some format details
|
||||||
int CmdFSKdemodIO(const char *Cmd)
|
int CmdFSKdemodIO(const char *Cmd)
|
||||||
{
|
{
|
||||||
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
|
||||||
//set defaults
|
|
||||||
int idx=0;
|
int idx=0;
|
||||||
//something in graphbuffer?
|
//something in graphbuffer?
|
||||||
if (GraphTraceLen < 65) {
|
if (GraphTraceLen < 65) {
|
||||||
|
@ -1220,11 +1244,6 @@ int CmdFSKdemodIO(const char *Cmd)
|
||||||
//print full AWID Prox ID and some bit format details if found
|
//print full AWID Prox ID and some bit format details if found
|
||||||
int CmdFSKdemodAWID(const char *Cmd)
|
int CmdFSKdemodAWID(const char *Cmd)
|
||||||
{
|
{
|
||||||
|
|
||||||
//int verbose=1;
|
|
||||||
//sscanf(Cmd, "%i", &verbose);
|
|
||||||
|
|
||||||
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
|
||||||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
size_t size = getFromGraphBuf(BitStream);
|
size_t size = getFromGraphBuf(BitStream);
|
||||||
if (size==0) return 0;
|
if (size==0) return 0;
|
||||||
|
@ -1423,7 +1442,6 @@ int CmdFSKdemodPyramid(const char *Cmd)
|
||||||
uint32_t fc = 0;
|
uint32_t fc = 0;
|
||||||
uint32_t cardnum = 0;
|
uint32_t cardnum = 0;
|
||||||
uint32_t code1 = 0;
|
uint32_t code1 = 0;
|
||||||
//uint32_t code2 = 0;
|
|
||||||
if (fmtLen==26){
|
if (fmtLen==26){
|
||||||
fc = bytebits_to_byte(BitStream+73, 8);
|
fc = bytebits_to_byte(BitStream+73, 8);
|
||||||
cardnum = bytebits_to_byte(BitStream+81, 16);
|
cardnum = bytebits_to_byte(BitStream+81, 16);
|
||||||
|
@ -1597,61 +1615,33 @@ int CmdIndalaDecode(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint8_t invert=0;
|
uint8_t invert=0;
|
||||||
ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert);
|
size_t size = DemodBufferLen;
|
||||||
if (ans < 1) {
|
size_t startIdx = indala26decode(DemodBuffer, &size, &invert);
|
||||||
|
if (startIdx < 1) {
|
||||||
if (g_debugMode==1)
|
if (g_debugMode==1)
|
||||||
PrintAndLog("Error2: %d",ans);
|
PrintAndLog("Error2: %d",ans);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
char showbits[251]={0x00};
|
setDemodBuf(DemodBuffer, size, startIdx);
|
||||||
if (invert)
|
if (invert)
|
||||||
if (g_debugMode==1)
|
if (g_debugMode==1)
|
||||||
PrintAndLog("Had to invert bits");
|
PrintAndLog("Had to invert bits");
|
||||||
|
|
||||||
|
PrintAndLog("BitLen: %d",DemodBufferLen);
|
||||||
//convert UID to HEX
|
//convert UID to HEX
|
||||||
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
|
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
|
||||||
int idx;
|
uid1=bytebits_to_byte(DemodBuffer,32);
|
||||||
uid1=0;
|
uid2=bytebits_to_byte(DemodBuffer+32,32);
|
||||||
uid2=0;
|
if (DemodBufferLen==64) {
|
||||||
PrintAndLog("BitLen: %d",DemodBufferLen);
|
PrintAndLog("Indala UID=%s (%x%08x)", sprint_bin(DemodBuffer,DemodBufferLen), uid1, uid2);
|
||||||
if (DemodBufferLen==64){
|
|
||||||
for( idx=0; idx<64; idx++) {
|
|
||||||
uid1=(uid1<<1)|(uid2>>31);
|
|
||||||
if (DemodBuffer[idx] == 0) {
|
|
||||||
uid2=(uid2<<1)|0;
|
|
||||||
showbits[idx]='0';
|
|
||||||
} else {
|
} else {
|
||||||
uid2=(uid2<<1)|1;
|
uid3=bytebits_to_byte(DemodBuffer+64,32);
|
||||||
showbits[idx]='1';
|
uid4=bytebits_to_byte(DemodBuffer+96,32);
|
||||||
}
|
uid5=bytebits_to_byte(DemodBuffer+128,32);
|
||||||
}
|
uid6=bytebits_to_byte(DemodBuffer+160,32);
|
||||||
showbits[idx]='\0';
|
uid7=bytebits_to_byte(DemodBuffer+192,32);
|
||||||
PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2);
|
PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)",
|
||||||
}
|
sprint_bin(DemodBuffer,DemodBufferLen), uid1, uid2, uid3, uid4, uid5, uid6, uid7);
|
||||||
else {
|
|
||||||
uid3=0;
|
|
||||||
uid4=0;
|
|
||||||
uid5=0;
|
|
||||||
uid6=0;
|
|
||||||
uid7=0;
|
|
||||||
for( idx=0; idx<DemodBufferLen; idx++) {
|
|
||||||
uid1=(uid1<<1)|(uid2>>31);
|
|
||||||
uid2=(uid2<<1)|(uid3>>31);
|
|
||||||
uid3=(uid3<<1)|(uid4>>31);
|
|
||||||
uid4=(uid4<<1)|(uid5>>31);
|
|
||||||
uid5=(uid5<<1)|(uid6>>31);
|
|
||||||
uid6=(uid6<<1)|(uid7>>31);
|
|
||||||
if (DemodBuffer[idx] == 0) {
|
|
||||||
uid7=(uid7<<1)|0;
|
|
||||||
showbits[idx]='0';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uid7=(uid7<<1)|1;
|
|
||||||
showbits[idx]='1';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
showbits[idx]='\0';
|
|
||||||
PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
|
|
||||||
}
|
}
|
||||||
if (g_debugMode){
|
if (g_debugMode){
|
||||||
PrintAndLog("DEBUG: printing demodbuffer:");
|
PrintAndLog("DEBUG: printing demodbuffer:");
|
||||||
|
@ -2353,6 +2343,7 @@ static command_t CommandTable[] =
|
||||||
{"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"},
|
{"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"},
|
||||||
{"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
|
{"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
|
||||||
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
|
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
|
||||||
|
{"askvikingdemod", CmdVikingDemod, 1, "Demodulate a Viking tag from GraphBuffer"},
|
||||||
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
|
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
|
||||||
{"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
|
{"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
|
||||||
{"bin2hex", Cmdbin2hex, 1, "bin2hex <digits> -- Converts binary to hexadecimal"},
|
{"bin2hex", Cmdbin2hex, 1, "bin2hex <digits> -- Converts binary to hexadecimal"},
|
||||||
|
|
|
@ -17,6 +17,7 @@ int CmdData(const char *Cmd);
|
||||||
void printDemodBuff(void);
|
void printDemodBuff(void);
|
||||||
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
|
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
|
||||||
int CmdAskEM410xDemod(const char *Cmd);
|
int CmdAskEM410xDemod(const char *Cmd);
|
||||||
|
int CmdVikingDemod(const char *Cmd);
|
||||||
int CmdG_Prox_II_Demod(const char *Cmd);
|
int CmdG_Prox_II_Demod(const char *Cmd);
|
||||||
int Cmdaskrawdemod(const char *Cmd);
|
int Cmdaskrawdemod(const char *Cmd);
|
||||||
int Cmdaskmandemod(const char *Cmd);
|
int Cmdaskmandemod(const char *Cmd);
|
||||||
|
|
106
client/cmdlf.c
106
client/cmdlf.c
|
@ -33,17 +33,82 @@
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int usage_lf_cmdread()
|
||||||
|
{
|
||||||
|
PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [H] ");
|
||||||
|
PrintAndLog("Options: ");
|
||||||
|
PrintAndLog(" h This help");
|
||||||
|
PrintAndLog(" L Low frequency (125 KHz)");
|
||||||
|
PrintAndLog(" H High frequency (134 KHz)");
|
||||||
|
PrintAndLog(" d <delay> delay OFF period");
|
||||||
|
PrintAndLog(" z <zero> time period ZERO");
|
||||||
|
PrintAndLog(" o <one> time period ONE");
|
||||||
|
PrintAndLog(" c <cmd> Command bytes");
|
||||||
|
PrintAndLog(" ************* All periods in microseconds");
|
||||||
|
PrintAndLog("Examples:");
|
||||||
|
PrintAndLog(" lf cmdread d 80 z 100 o 200 c 11000");
|
||||||
|
PrintAndLog(" lf cmdread d 80 z 100 o 100 c 11000 H");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* send a command before reading */
|
/* send a command before reading */
|
||||||
int CmdLFCommandRead(const char *Cmd)
|
int CmdLFCommandRead(const char *Cmd)
|
||||||
{
|
{
|
||||||
static char dummy[3];
|
static char dummy[3] = {0x20,0x00,0x00};
|
||||||
|
|
||||||
dummy[0]= ' ';
|
|
||||||
|
|
||||||
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
|
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
|
||||||
sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1));
|
bool errors = FALSE;
|
||||||
// in case they specified 'h'
|
//uint8_t divisor = 95; //125khz
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
int strLength = 0;
|
||||||
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
|
{
|
||||||
|
switch(param_getchar(Cmd, cmdp))
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
return usage_lf_cmdread();
|
||||||
|
case 'H':
|
||||||
|
//divisor = 88;
|
||||||
|
dummy[1]='h';
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
strLength = param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes);
|
||||||
|
cmdp+=2;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
c.arg[0] = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp+=2;
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
c.arg[1] = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp+=2;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
c.arg[2] = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp+=2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(errors) break;
|
||||||
|
}
|
||||||
|
// No args
|
||||||
|
if(cmdp == 0) errors = 1;
|
||||||
|
|
||||||
|
//Validations
|
||||||
|
if(errors) return usage_lf_cmdread();
|
||||||
|
|
||||||
|
// in case they specified 'H'
|
||||||
strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
|
strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -493,7 +558,12 @@ int CmdLFRead(const char *Cmd)
|
||||||
//And ship it to device
|
//And ship it to device
|
||||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
|
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
//WaitForResponse(CMD_ACK,NULL);
|
||||||
|
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
|
||||||
|
PrintAndLog("command execution time out");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,6 +1155,12 @@ int CmdLFfind(const char *Cmd)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ans=CmdVikingDemod("");
|
||||||
|
if (ans>0) {
|
||||||
|
PrintAndLog("\nValid Viking ID Found!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
ans=CmdPSKNexWatch("");
|
ans=CmdPSKNexWatch("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid NexWatch ID Found!");
|
PrintAndLog("\nValid NexWatch ID Found!");
|
||||||
|
@ -1126,13 +1202,17 @@ int CmdLFfind(const char *Cmd)
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"},
|
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
|
||||||
{"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
|
{"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
|
||||||
|
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
|
||||||
|
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"},
|
||||||
|
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
|
||||||
|
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
|
||||||
|
{"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
|
||||||
|
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
|
||||||
|
{"cmdread", CmdLFCommandRead, 0, "<d period> <z period> <o period> <c command> ['H'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'H' for 134)"},
|
||||||
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
|
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
|
||||||
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
|
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
|
||||||
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
|
|
||||||
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
|
|
||||||
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
|
|
||||||
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
||||||
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
|
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
|
||||||
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||||
|
@ -1143,11 +1223,7 @@ static command_t CommandTable[] =
|
||||||
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"},
|
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"},
|
||||||
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||||
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
|
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
|
||||||
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
|
|
||||||
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"},
|
|
||||||
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
|
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
|
||||||
{"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
|
|
||||||
{"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"},
|
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -73,22 +73,23 @@ int CmdEM410xSim(const char *Cmd)
|
||||||
uint8_t uid[5] = {0x00};
|
uint8_t uid[5] = {0x00};
|
||||||
|
|
||||||
if (cmdp == 'h' || cmdp == 'H') {
|
if (cmdp == 'h' || cmdp == 'H') {
|
||||||
PrintAndLog("Usage: lf em4x 410xsim <UID>");
|
PrintAndLog("Usage: lf em4x em410xsim <UID> <clock>");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog(" sample: lf em4x 410xsim 0F0368568B");
|
PrintAndLog(" sample: lf em4x em410xsim 0F0368568B");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* clock is 64 in EM410x tags */
|
||||||
|
uint8_t clock = 64;
|
||||||
|
|
||||||
if (param_gethex(Cmd, 0, uid, 10)) {
|
if (param_gethex(Cmd, 0, uid, 10)) {
|
||||||
PrintAndLog("UID must include 10 HEX symbols");
|
PrintAndLog("UID must include 10 HEX symbols");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
param_getdec(Cmd,1, &clock);
|
||||||
|
|
||||||
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X", uid[0],uid[1],uid[2],uid[3],uid[4]);
|
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
|
||||||
PrintAndLog("Press pm3-button to about simulation");
|
PrintAndLog("Press pm3-button to about simulation");
|
||||||
|
|
||||||
/* clock is 64 in EM410x tags */
|
|
||||||
int clock = 64;
|
|
||||||
|
|
||||||
/* clear our graph */
|
/* clear our graph */
|
||||||
ClearGraph(0);
|
ClearGraph(0);
|
||||||
|
@ -197,21 +198,13 @@ int CmdEM410xWrite(const char *Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Clock
|
// Check Clock
|
||||||
if (card == 1)
|
|
||||||
{
|
|
||||||
// Default: 64
|
// Default: 64
|
||||||
if (clock == 0)
|
if (clock == 0)
|
||||||
clock = 64;
|
clock = 64;
|
||||||
|
|
||||||
// Allowed clock rates: 16, 32 and 64
|
// Allowed clock rates: 16, 32, 40 and 64
|
||||||
if ((clock != 16) && (clock != 32) && (clock != 64)) {
|
if ((clock != 16) && (clock != 32) && (clock != 64) && (clock != 40)) {
|
||||||
PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32 and 64.\n", clock);
|
PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32, 40 and 64.\n", clock);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (clock != 0)
|
|
||||||
{
|
|
||||||
PrintAndLog("Error! Clock rate is only supported on T55x7 tags.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,11 +214,11 @@ int CmdEM410xWrite(const char *Cmd)
|
||||||
// provide for backwards-compatibility for older firmware, and to avoid
|
// provide for backwards-compatibility for older firmware, and to avoid
|
||||||
// having to add another argument to CMD_EM410X_WRITE_TAG, we just store
|
// having to add another argument to CMD_EM410X_WRITE_TAG, we just store
|
||||||
// the clock rate in bits 8-15 of the card value
|
// the clock rate in bits 8-15 of the card value
|
||||||
card = (card & 0xFF) | (((uint64_t)clock << 8) & 0xFF00);
|
card = (card & 0xFF) | ((clock << 8) & 0xFF00);
|
||||||
}
|
} else if (card == 0) {
|
||||||
else if (card == 0)
|
|
||||||
PrintAndLog("Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock);
|
PrintAndLog("Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock);
|
||||||
else {
|
card = (card & 0xFF) | ((clock << 8) & 0xFF00);
|
||||||
|
} else {
|
||||||
PrintAndLog("Error! Bad card type selected.\n");
|
PrintAndLog("Error! Bad card type selected.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -608,7 +601,7 @@ static command_t CommandTable[] =
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
|
{"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
|
||||||
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"},
|
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"},
|
||||||
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
|
{"em410xsim", CmdEM410xSim, 0, "<UID> [clock rate] -- Simulate EM410x tag"},
|
||||||
{"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
{"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
||||||
{"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
{"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
||||||
{"em410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
|
{"em410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Low frequency PCF7931 commands
|
// Low frequency PCF7931 commands
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "util.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmddata.h"
|
#include "cmddata.h"
|
||||||
|
@ -22,103 +22,146 @@
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
struct pcf7931_config configPcf = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},17500,{0,0}};
|
#define PCF7931_DEFAULT_INITDELAY 17500
|
||||||
|
#define PCF7931_DEFAULT_OFFSET_WIDTH 0
|
||||||
|
#define PCF7931_DEFAULT_OFFSET_POSITION 0
|
||||||
|
|
||||||
|
// Default values - Configuration
|
||||||
|
struct pcf7931_config configPcf = {
|
||||||
|
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
|
||||||
|
PCF7931_DEFAULT_INITDELAY,
|
||||||
|
PCF7931_DEFAULT_OFFSET_WIDTH,
|
||||||
|
PCF7931_DEFAULT_OFFSET_POSITION
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resets the configuration settings to default values.
|
||||||
|
int pcf7931_resetConfig(){
|
||||||
|
memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd) );
|
||||||
|
configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY;
|
||||||
|
configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH;
|
||||||
|
configPcf.OffsetPosition = PCF7931_DEFAULT_OFFSET_POSITION;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pcf7931_printConfig(){
|
||||||
|
PrintAndLog("Password (LSB first on bytes) : %s", sprint_hex( configPcf.Pwd, sizeof(configPcf.Pwd)));
|
||||||
|
PrintAndLog("Tag initialization delay : %d us", configPcf.InitDelay);
|
||||||
|
PrintAndLog("Offset low pulses width : %d us", configPcf.OffsetWidth);
|
||||||
|
PrintAndLog("Offset low pulses position : %d us", configPcf.OffsetPosition);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usage_pcf7931_read(){
|
||||||
|
PrintAndLog("Usage: lf pcf7931 read [h] ");
|
||||||
|
PrintAndLog("This command tries to read a PCF7931 tag.");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" h This help");
|
||||||
|
PrintAndLog("Examples:");
|
||||||
|
PrintAndLog(" lf pcf7931 read");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usage_pcf7931_write(){
|
||||||
|
PrintAndLog("Usage: lf pcf7931 write [h] <block address> <byte address> <data>");
|
||||||
|
PrintAndLog("This command tries to write a PCF7931 tag.");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" h This help");
|
||||||
|
PrintAndLog(" blockaddress Block to save [0-7]");
|
||||||
|
PrintAndLog(" byteaddress Index of byte inside block to write [0-15]");
|
||||||
|
PrintAndLog(" data one byte of data (hex)");
|
||||||
|
PrintAndLog("Examples:");
|
||||||
|
PrintAndLog(" lf pcf7931 write 2 1 FF");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usage_pcf7931_config(){
|
||||||
|
PrintAndLog("Usage: lf pcf7931 config [h] [r] <pwd> <delay> <offset width> <offset position>");
|
||||||
|
PrintAndLog("This command tries to set the configuration used with PCF7931 commands");
|
||||||
|
PrintAndLog("The time offsets could be useful to correct slew rate generated by the antenna");
|
||||||
|
PrintAndLog("Caling without some parameter will print the current configuration.");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" h This help");
|
||||||
|
PrintAndLog(" r Reset configuration to default values");
|
||||||
|
PrintAndLog(" pwd Password, hex, 7bytes, LSB-order");
|
||||||
|
PrintAndLog(" delay Tag initialization delay (in us) decimal");
|
||||||
|
PrintAndLog(" offset Low pulses width (in us) decimal");
|
||||||
|
PrintAndLog(" offset Low pulses position (in us) decimal");
|
||||||
|
PrintAndLog("Examples:");
|
||||||
|
PrintAndLog(" lf pcf7931 config");
|
||||||
|
PrintAndLog(" lf pcf7931 config r");
|
||||||
|
PrintAndLog(" lf pcf7931 config 11223344556677 20000");
|
||||||
|
PrintAndLog(" lf pcf7931 config 11223344556677 17500 -10 30");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdLFPCF7931Read(const char *Cmd){
|
||||||
|
|
||||||
|
uint8_t ctmp = param_getchar(Cmd, 0);
|
||||||
|
if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_read();
|
||||||
|
|
||||||
int CmdLFPCF7931Read(const char *Cmd)
|
|
||||||
{
|
|
||||||
UsbCommand c = {CMD_PCF7931_READ};
|
|
||||||
SendCommand(&c);
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
WaitForResponse(CMD_ACK,&resp);
|
UsbCommand c = {CMD_PCF7931_READ, {0, 0, 0}};
|
||||||
return 0;
|
clearCommandBuffer();
|
||||||
}
|
|
||||||
|
|
||||||
int CmdLFPCF7931Config(const char *Cmd)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
res = sscanf(Cmd, "%02x %02x %02x %02x %02x %02x %02x %d %d %d", &configPcf.password[0], &configPcf.password[1], &configPcf.password[2], &configPcf.password[3], &configPcf.password[4], &configPcf.password[5], &configPcf.password[6], &configPcf.init_delay, &configPcf.offset[0], &configPcf.offset[1]);
|
|
||||||
|
|
||||||
if (res >= 7 || res < 1){
|
|
||||||
if(res == 7) configPcf.init_delay = 17500; //default value
|
|
||||||
|
|
||||||
if(res<=8){
|
|
||||||
configPcf.offset[0] = 0; //default value
|
|
||||||
configPcf.offset[1] = 0; //default value
|
|
||||||
}
|
|
||||||
|
|
||||||
if(res < 1){
|
|
||||||
PrintAndLog("Usage: <password byte 1 (in hex, lsb first)> <password byte 2 (in hex, lsb first)> [...] <password byte 7 (in hex, lsb first)> <tag initialization delay (in us)> <optional : offset on the low pulses width (in us)> <optional : offset on the low pulses position (in us)>");
|
|
||||||
PrintAndLog("The time offsets could be usefull to correct slew rate generated by the antenna.");
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLog("Current configuration :");
|
|
||||||
PrintAndLog("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", configPcf.password[0], configPcf.password[1], configPcf.password[2], configPcf.password[3], configPcf.password[4], configPcf.password[5], configPcf.password[6]);
|
|
||||||
PrintAndLog("Tag initialization delay : %d us", configPcf.init_delay);
|
|
||||||
PrintAndLog("Offsets : %d us on the low pulses width, %d us on the low pulses positions", configPcf.offset[0], configPcf.offset[1]);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//default values
|
|
||||||
configPcf.password[0] = 0xFF;
|
|
||||||
configPcf.password[1] = 0xFF;
|
|
||||||
configPcf.password[2] = 0xFF;
|
|
||||||
configPcf.password[3] = 0xFF;
|
|
||||||
configPcf.password[4] = 0xFF;
|
|
||||||
configPcf.password[5] = 0xFF;
|
|
||||||
configPcf.password[6] = 0xFF;
|
|
||||||
|
|
||||||
configPcf.init_delay = 17500;
|
|
||||||
configPcf.offset[0] = 0;
|
|
||||||
configPcf.offset[1] = 0;
|
|
||||||
|
|
||||||
PrintAndLog("Incorrect format");
|
|
||||||
PrintAndLog("Examples of right usage : lf pcf7931 config 11 22 33 44 55 66 77 20000");
|
|
||||||
PrintAndLog(" lf pcf7931 config FF FF FF FF FF FF FF 17500 -10 30");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int CmdLFPCF7931Write(const char *Cmd)
|
|
||||||
{
|
|
||||||
UsbCommand c = {CMD_PCF7931_WRITE};
|
|
||||||
|
|
||||||
int res = 0;
|
|
||||||
res = sscanf(Cmd, "%x %x %x", &c.arg[0], &c.arg[1], &c.arg[2]);
|
|
||||||
|
|
||||||
if(res < 1) {
|
|
||||||
PrintAndLog("Please specify the block address in hex");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (res == 1){
|
|
||||||
PrintAndLog("Please specify the byte address in hex");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(res == 2) {
|
|
||||||
PrintAndLog("Please specify the data in hex (1 byte)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(res == 3) {
|
|
||||||
uint8_t n=0;
|
|
||||||
for(n=0;n<7;n++) c.d.asDwords[n] = configPcf.password[n];
|
|
||||||
c.d.asDwords[7] = (configPcf.offset[0]+128);
|
|
||||||
c.d.asDwords[8] = (configPcf.offset[1]+128);
|
|
||||||
c.d.asDwords[9] = configPcf.init_delay;
|
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
|
||||||
|
PrintAndLog("command execution time out");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("INCORRECT FORMAT");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdLFPCF7931Config(const char *Cmd){
|
||||||
|
|
||||||
|
uint8_t ctmp = param_getchar(Cmd, 0);
|
||||||
|
if ( ctmp == 0) return pcf7931_printConfig();
|
||||||
|
if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_config();
|
||||||
|
if ( ctmp == 'R' || ctmp == 'r' ) return pcf7931_resetConfig();
|
||||||
|
|
||||||
|
if ( param_gethex(Cmd, 0, configPcf.Pwd, 14) ) return usage_pcf7931_config();
|
||||||
|
|
||||||
|
configPcf.InitDelay = (param_get32ex(Cmd,1,0,10) & 0xFFFF);
|
||||||
|
configPcf.OffsetWidth = (int)(param_get32ex(Cmd,2,0,10) & 0xFFFF);
|
||||||
|
configPcf.OffsetPosition = (int)(param_get32ex(Cmd,3,0,10) & 0xFFFF);
|
||||||
|
|
||||||
|
pcf7931_printConfig();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdLFPCF7931Write(const char *Cmd){
|
||||||
|
|
||||||
|
uint8_t ctmp = param_getchar(Cmd, 0);
|
||||||
|
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write();
|
||||||
|
|
||||||
|
uint8_t block = 0, bytepos = 0, data = 0;
|
||||||
|
|
||||||
|
if ( param_getdec(Cmd, 0, &block) ) return usage_pcf7931_write();
|
||||||
|
if ( param_getdec(Cmd, 1, &bytepos) ) return usage_pcf7931_write();
|
||||||
|
|
||||||
|
if ( (block > 7) || (bytepos > 15) ) return usage_pcf7931_write();
|
||||||
|
|
||||||
|
data = param_get8ex(Cmd, 2, 0, 16);
|
||||||
|
|
||||||
|
PrintAndLog("Writing block: %d", block);
|
||||||
|
PrintAndLog(" pos: %d", bytepos);
|
||||||
|
PrintAndLog(" data: 0x%02X", data);
|
||||||
|
|
||||||
|
UsbCommand c = {CMD_PCF7931_WRITE, { block, bytepos, data} };
|
||||||
|
memcpy(c.d.asDwords, configPcf.Pwd, sizeof(configPcf.Pwd) );
|
||||||
|
c.d.asDwords[7] = (configPcf.OffsetWidth + 128);
|
||||||
|
c.d.asDwords[8] = (configPcf.OffsetPosition + 128);
|
||||||
|
c.d.asDwords[9] = configPcf.InitDelay;
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
//no ack?
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"read", CmdLFPCF7931Read, 1, "Read content of a PCF7931 transponder"},
|
{"read", CmdLFPCF7931Read, 0, "Read content of a PCF7931 transponder"},
|
||||||
{"write", CmdLFPCF7931Write, 1, "Write data on a PCF7931 transponder. Usage : lf pcf7931 write <bloc address> <byte address> <data>"},
|
{"write", CmdLFPCF7931Write, 0, "Write data on a PCF7931 transponder."},
|
||||||
{"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
|
{"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,17 +13,23 @@
|
||||||
#define CMDLFPCF7931_H__
|
#define CMDLFPCF7931_H__
|
||||||
|
|
||||||
struct pcf7931_config{
|
struct pcf7931_config{
|
||||||
uint8_t password[7];
|
uint8_t Pwd[7];
|
||||||
uint16_t init_delay;
|
uint16_t InitDelay;
|
||||||
int16_t offset[2];
|
int16_t OffsetWidth;
|
||||||
|
int16_t OffsetPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int pcf7931_resetConfig();
|
||||||
|
int pcf7931_printConfig();
|
||||||
|
|
||||||
|
int usage_pcf7931_read();
|
||||||
|
int usage_pcf7931_write();
|
||||||
|
int usage_pcf7931_config();
|
||||||
|
|
||||||
int CmdLFPCF7931(const char *Cmd);
|
int CmdLFPCF7931(const char *Cmd);
|
||||||
|
|
||||||
int CmdLFPCF7931Read(const char *Cmd);
|
int CmdLFPCF7931Read(const char *Cmd);
|
||||||
|
|
||||||
int CmdLFPCF7931Write(const char *Cmd);
|
int CmdLFPCF7931Write(const char *Cmd);
|
||||||
|
|
||||||
int CmdLFPCF7931Config(const char *Cmd);
|
int CmdLFPCF7931Config(const char *Cmd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,13 +28,21 @@
|
||||||
|
|
||||||
#define CONFIGURATION_BLOCK 0x00
|
#define CONFIGURATION_BLOCK 0x00
|
||||||
#define TRACE_BLOCK 0x01
|
#define TRACE_BLOCK 0x01
|
||||||
|
#define REGULAR_READ_MODE_BLOCK 0xFF
|
||||||
|
|
||||||
// Default configuration
|
// Default configuration
|
||||||
t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00};
|
t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00};
|
||||||
|
|
||||||
|
t55xx_conf_block_t Get_t55xx_Config(){
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
void Set_t55xx_Config(t55xx_conf_block_t conf){
|
||||||
|
config = conf;
|
||||||
|
}
|
||||||
|
|
||||||
int usage_t55xx_config(){
|
int usage_t55xx_config(){
|
||||||
PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>]");
|
PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>]");
|
||||||
PrintAndLog("Options: ");
|
PrintAndLog("Options:");
|
||||||
PrintAndLog(" h This help");
|
PrintAndLog(" h This help");
|
||||||
PrintAndLog(" b <8|16|32|40|50|64|100|128> Set bitrate");
|
PrintAndLog(" b <8|16|32|40|50|64|100|128> Set bitrate");
|
||||||
PrintAndLog(" d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");
|
PrintAndLog(" d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");
|
||||||
|
@ -49,31 +57,41 @@ int usage_t55xx_config(){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_t55xx_read(){
|
int usage_t55xx_read(){
|
||||||
PrintAndLog("Usage: lf t55xx read <block> <password>");
|
PrintAndLog("Usage: lf t55xx read [b <block>] [p <password>] <override_safety> <page1>");
|
||||||
PrintAndLog(" <block>, block number to read. Between 0-7");
|
PrintAndLog("Options:");
|
||||||
PrintAndLog(" <password>, OPTIONAL password (8 hex characters)");
|
PrintAndLog(" b <block> - block number to read. Between 0-7");
|
||||||
|
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
|
||||||
|
PrintAndLog(" o - OPTIONAL override safety check");
|
||||||
|
PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0");
|
||||||
|
PrintAndLog(" ****WARNING****");
|
||||||
|
PrintAndLog(" Use of read with password on a tag not configured for a pwd");
|
||||||
|
PrintAndLog(" can damage the tag");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx read 0 - read data from block 0");
|
PrintAndLog(" lf t55xx read b 0 - read data from block 0");
|
||||||
PrintAndLog(" lf t55xx read 0 feedbeef - read data from block 0 password feedbeef");
|
PrintAndLog(" lf t55xx read b 0 p feedbeef - read data from block 0 password feedbeef");
|
||||||
|
PrintAndLog(" lf t55xx read b 0 p feedbeef o - read data from block 0 password feedbeef safety check");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_t55xx_write(){
|
int usage_t55xx_write(){
|
||||||
PrintAndLog("Usage: lf t55xx wr <block> <data> [password]");
|
PrintAndLog("Usage: lf t55xx wr [b <block>] [d <data>] [p <password>] [1]");
|
||||||
PrintAndLog(" <block>, block number to write. Between 0-7");
|
PrintAndLog("Options:");
|
||||||
PrintAndLog(" <data>, 4 bytes of data to write (8 hex characters)");
|
PrintAndLog(" b <block> - block number to write. Between 0-7");
|
||||||
PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)");
|
PrintAndLog(" d <data> - 4 bytes of data to write (8 hex characters)");
|
||||||
|
PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
|
||||||
|
PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx wr 3 11223344 - write 11223344 to block 3");
|
PrintAndLog(" lf t55xx wr b 3 d 11223344 - write 11223344 to block 3");
|
||||||
PrintAndLog(" lf t55xx wr 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef");
|
PrintAndLog(" lf t55xx wr b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_t55xx_trace() {
|
int usage_t55xx_trace() {
|
||||||
PrintAndLog("Usage: lf t55xx trace [1]");
|
PrintAndLog("Usage: lf t55xx trace [1]");
|
||||||
PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx trace");
|
PrintAndLog(" lf t55xx trace");
|
||||||
|
@ -83,7 +101,8 @@ int usage_t55xx_trace() {
|
||||||
}
|
}
|
||||||
int usage_t55xx_info() {
|
int usage_t55xx_info() {
|
||||||
PrintAndLog("Usage: lf t55xx info [1]");
|
PrintAndLog("Usage: lf t55xx info [1]");
|
||||||
PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx info");
|
PrintAndLog(" lf t55xx info");
|
||||||
|
@ -92,17 +111,21 @@ int usage_t55xx_info() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_t55xx_dump(){
|
int usage_t55xx_dump(){
|
||||||
PrintAndLog("Usage: lf t55xx dump <password>");
|
PrintAndLog("Usage: lf t55xx dump <password> [o]");
|
||||||
PrintAndLog(" <password>, OPTIONAL password 4bytes (8 hex symbols)");
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" <password> - OPTIONAL password 4bytes (8 hex symbols)");
|
||||||
|
PrintAndLog(" o - OPTIONAL override, force pwd read despite danger to card");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx dump");
|
PrintAndLog(" lf t55xx dump");
|
||||||
PrintAndLog(" lf t55xx dump feedbeef");
|
PrintAndLog(" lf t55xx dump feedbeef o");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_t55xx_detect(){
|
int usage_t55xx_detect(){
|
||||||
PrintAndLog("Usage: lf t55xx detect");
|
PrintAndLog("Usage: lf t55xx detect [1]");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx detect");
|
PrintAndLog(" lf t55xx detect");
|
||||||
|
@ -110,18 +133,29 @@ int usage_t55xx_detect(){
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int usage_t55xx_wakup(){
|
||||||
|
PrintAndLog("Usage: lf t55xx wakeup [h] p <password>");
|
||||||
|
PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" h - this help");
|
||||||
|
PrintAndLog(" p <password> - password 4bytes (8 hex symbols)");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("Examples:");
|
||||||
|
PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
int CmdT55xxSetConfig(const char *Cmd) {
|
int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
|
|
||||||
uint8_t offset = 0;
|
uint8_t offset = 0;
|
||||||
bool errors = FALSE;
|
|
||||||
uint8_t cmdp = 0;
|
|
||||||
char modulation[5] = {0x00};
|
char modulation[5] = {0x00};
|
||||||
char tmp = 0x00;
|
char tmp = 0x00;
|
||||||
uint8_t bitRate = 0;
|
uint8_t bitRate = 0;
|
||||||
uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};
|
uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
bool errors = FALSE;
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors)
|
while(param_getchar(Cmd, cmdp) != 0x00 && !errors)
|
||||||
{
|
{
|
||||||
tmp = param_getchar(Cmd, cmdp);
|
tmp = param_getchar(Cmd, cmdp);
|
||||||
|
@ -201,64 +235,91 @@ int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// No args
|
// No args
|
||||||
if (cmdp == 0) {
|
if (cmdp == 0) return printConfiguration( config );
|
||||||
printConfiguration( config );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//Validations
|
//Validations
|
||||||
if (errors)
|
if (errors) return usage_t55xx_config();
|
||||||
return usage_t55xx_config();
|
|
||||||
|
|
||||||
config.block0 = 0;
|
config.block0 = 0;
|
||||||
printConfiguration ( config );
|
return printConfiguration ( config );
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdT55xxReadBlock(const char *Cmd) {
|
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){
|
||||||
int block = -1;
|
|
||||||
int password = 0xFFFFFFFF; //default to blank Block 7
|
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
|
||||||
if (cmdp == 'h' || cmdp == 'H')
|
|
||||||
return usage_t55xx_read();
|
|
||||||
|
|
||||||
int res = sscanf(Cmd, "%d %x", &block, &password);
|
|
||||||
|
|
||||||
if ( res < 1 || res > 2 )
|
|
||||||
return usage_t55xx_read();
|
|
||||||
|
|
||||||
|
|
||||||
if ((block < 0) | (block > 7)) {
|
|
||||||
PrintAndLog("Block must be between 0 and 7");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}};
|
|
||||||
c.d.asBytes[0] = 0x0;
|
|
||||||
|
|
||||||
//Password mode
|
//Password mode
|
||||||
if ( res == 2 ) {
|
if ( usepwd ) {
|
||||||
c.arg[2] = password;
|
// try reading the config block and verify that PWD bit is set before doing this!
|
||||||
c.d.asBytes[0] = 0x1;
|
if ( !override ) {
|
||||||
|
if ( !AquireData(0, CONFIGURATION_BLOCK, false, 0 ) ) return 0;
|
||||||
|
if ( !tryDetectModulation() ) {
|
||||||
|
PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password...");
|
||||||
|
usepwd = false;
|
||||||
|
page1 = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Safety Check Overriden - proceeding despite risk");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCommandBuffer();
|
if (!AquireData(page1, block, usepwd, password) ) return 0;
|
||||||
SendCommand(&c);
|
if (!DecodeT55xxBlock()) return 0;
|
||||||
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
|
|
||||||
PrintAndLog("command execution time out");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t got[12000];
|
|
||||||
GetFromBigBuf(got,sizeof(got),0);
|
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
|
||||||
setGraphBuf(got, 12000);
|
|
||||||
DemodBufferLen=0;
|
|
||||||
if (!DecodeT55xxBlock()) return 3;
|
|
||||||
char blk[10]={0};
|
char blk[10]={0};
|
||||||
sprintf(blk,"%d", block);
|
sprintf(blk,"%d", block);
|
||||||
printT55xxBlock(blk);
|
printT55xxBlock(blk);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdT55xxReadBlock(const char *Cmd) {
|
||||||
|
uint8_t block = REGULAR_READ_MODE_BLOCK;
|
||||||
|
uint32_t password = 0; //default to blank Block 7
|
||||||
|
bool usepwd = false;
|
||||||
|
bool override = false;
|
||||||
|
bool page1 = false;
|
||||||
|
bool errors = false;
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch(param_getchar(Cmd, cmdp)) {
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
return usage_t55xx_read();
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
errors |= param_getdec(Cmd, cmdp+1, &block);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
override = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
case 'P':
|
||||||
|
password = param_get32ex(Cmd, cmdp+1, 0, 16);
|
||||||
|
usepwd = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
page1 = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errors) return usage_t55xx_read();
|
||||||
|
|
||||||
|
if (block > 7 && block != REGULAR_READ_MODE_BLOCK ) {
|
||||||
|
PrintAndLog("Block must be between 0 and 7");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
PrintAndLog("Reading Page %d:", page1);
|
||||||
|
PrintAndLog("blk | hex data | binary");
|
||||||
|
return T55xxReadBlock(block, page1, usepwd, override, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DecodeT55xxBlock(){
|
bool DecodeT55xxBlock(){
|
||||||
|
@ -269,9 +330,6 @@ bool DecodeT55xxBlock(){
|
||||||
uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};
|
uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};
|
||||||
DemodBufferLen = 0x00;
|
DemodBufferLen = 0x00;
|
||||||
|
|
||||||
//trim 1/2 a clock from beginning
|
|
||||||
snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 );
|
|
||||||
CmdLtrim(cmdStr);
|
|
||||||
switch( config.modulation ){
|
switch( config.modulation ){
|
||||||
case DEMOD_FSK:
|
case DEMOD_FSK:
|
||||||
snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );
|
snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );
|
||||||
|
@ -323,17 +381,17 @@ int CmdT55xxDetect(const char *Cmd){
|
||||||
return usage_t55xx_detect();
|
return usage_t55xx_detect();
|
||||||
|
|
||||||
if (strlen(Cmd)==0)
|
if (strlen(Cmd)==0)
|
||||||
AquireData( CONFIGURATION_BLOCK );
|
if ( !AquireData(0, CONFIGURATION_BLOCK, false, 0) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
if ( !tryDetectModulation() )
|
if ( !tryDetectModulation() )
|
||||||
PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
|
PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect configuration?
|
// detect configuration?
|
||||||
bool tryDetectModulation(){
|
bool tryDetectModulation(){
|
||||||
char cmdStr[8] = {0};
|
|
||||||
uint8_t hits = 0;
|
uint8_t hits = 0;
|
||||||
t55xx_conf_block_t tests[15];
|
t55xx_conf_block_t tests[15];
|
||||||
int bitRate=0;
|
int bitRate=0;
|
||||||
|
@ -341,8 +399,6 @@ bool tryDetectModulation(){
|
||||||
save_restoreGB(1);
|
save_restoreGB(1);
|
||||||
if (GetFskClock("", FALSE, FALSE)){
|
if (GetFskClock("", FALSE, FALSE)){
|
||||||
fskClocks(&fc1, &fc2, &clk, FALSE);
|
fskClocks(&fc1, &fc2, &clk, FALSE);
|
||||||
sprintf(cmdStr,"%d", clk/2);
|
|
||||||
CmdLtrim(cmdStr);
|
|
||||||
if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){
|
if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){
|
||||||
tests[hits].modulation = DEMOD_FSK;
|
tests[hits].modulation = DEMOD_FSK;
|
||||||
if (fc1==8 && fc2 == 5)
|
if (fc1==8 && fc2 == 5)
|
||||||
|
@ -369,8 +425,6 @@ bool tryDetectModulation(){
|
||||||
} else {
|
} else {
|
||||||
clk = GetAskClock("", FALSE, FALSE);
|
clk = GetAskClock("", FALSE, FALSE);
|
||||||
if (clk>0) {
|
if (clk>0) {
|
||||||
sprintf(cmdStr,"%d", clk/2);
|
|
||||||
CmdLtrim(cmdStr);
|
|
||||||
if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
|
if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
|
||||||
tests[hits].modulation = DEMOD_ASK;
|
tests[hits].modulation = DEMOD_ASK;
|
||||||
tests[hits].bitrate = bitRate;
|
tests[hits].bitrate = bitRate;
|
||||||
|
@ -404,8 +458,6 @@ bool tryDetectModulation(){
|
||||||
save_restoreGB(0);
|
save_restoreGB(0);
|
||||||
clk = GetNrzClock("", FALSE, FALSE);
|
clk = GetNrzClock("", FALSE, FALSE);
|
||||||
if (clk>0) {
|
if (clk>0) {
|
||||||
sprintf(cmdStr,"%d", clk/2);
|
|
||||||
CmdLtrim(cmdStr);
|
|
||||||
if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
|
if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
|
||||||
tests[hits].modulation = DEMOD_NRZ;
|
tests[hits].modulation = DEMOD_NRZ;
|
||||||
tests[hits].bitrate = bitRate;
|
tests[hits].bitrate = bitRate;
|
||||||
|
@ -427,9 +479,6 @@ bool tryDetectModulation(){
|
||||||
save_restoreGB(0);
|
save_restoreGB(0);
|
||||||
clk = GetPskClock("", FALSE, FALSE);
|
clk = GetPskClock("", FALSE, FALSE);
|
||||||
if (clk>0) {
|
if (clk>0) {
|
||||||
PrintAndLog("clk %d",clk);
|
|
||||||
sprintf(cmdStr,"%d", clk/2);
|
|
||||||
CmdLtrim(cmdStr);
|
|
||||||
if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
|
if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
|
||||||
tests[hits].modulation = DEMOD_PSK1;
|
tests[hits].modulation = DEMOD_PSK1;
|
||||||
tests[hits].bitrate = bitRate;
|
tests[hits].bitrate = bitRate;
|
||||||
|
@ -491,7 +540,7 @@ bool tryDetectModulation(){
|
||||||
bool testModulation(uint8_t mode, uint8_t modread){
|
bool testModulation(uint8_t mode, uint8_t modread){
|
||||||
switch( mode ){
|
switch( mode ){
|
||||||
case DEMOD_FSK:
|
case DEMOD_FSK:
|
||||||
if (modread > 3 && modread < 8) return TRUE;
|
if (modread >= DEMOD_FSK1 && modread <= DEMOD_FSK2a) return TRUE;
|
||||||
break;
|
break;
|
||||||
case DEMOD_ASK:
|
case DEMOD_ASK:
|
||||||
if (modread == DEMOD_ASK) return TRUE;
|
if (modread == DEMOD_ASK) return TRUE;
|
||||||
|
@ -615,14 +664,14 @@ void printT55xxBlock(const char *blockNum){
|
||||||
bits[i - config.offset]=DemodBuffer[i];
|
bits[i - config.offset]=DemodBuffer[i];
|
||||||
|
|
||||||
blockData = PackBits(0, 32, bits);
|
blockData = PackBits(0, 32, bits);
|
||||||
PrintAndLog("[%s] 0x%08X %s", blockNum, blockData, sprint_bin(bits,32));
|
PrintAndLog(" %s | %08X | %s", blockNum, blockData, sprint_bin(bits,32));
|
||||||
}
|
}
|
||||||
|
|
||||||
int special(const char *Cmd) {
|
int special(const char *Cmd) {
|
||||||
uint32_t blockData = 0;
|
uint32_t blockData = 0;
|
||||||
uint8_t bits[32] = {0x00};
|
uint8_t bits[32] = {0x00};
|
||||||
|
|
||||||
PrintAndLog("[OFFSET] [DATA] [BINARY]");
|
PrintAndLog("OFFSET | DATA | BINARY");
|
||||||
PrintAndLog("----------------------------------------------------");
|
PrintAndLog("----------------------------------------------------");
|
||||||
int i,j = 0;
|
int i,j = 0;
|
||||||
for (; j < 64; ++j){
|
for (; j < 64; ++j){
|
||||||
|
@ -632,86 +681,142 @@ int special(const char *Cmd) {
|
||||||
|
|
||||||
blockData = PackBits(0, 32, bits);
|
blockData = PackBits(0, 32, bits);
|
||||||
|
|
||||||
PrintAndLog("[%02d] 0x%08X %s",j , blockData, sprint_bin(bits,32));
|
PrintAndLog(" %02d | 0x%08X | %s",j , blockData, sprint_bin(bits,32));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printConfiguration( t55xx_conf_block_t b){
|
int printConfiguration( t55xx_conf_block_t b){
|
||||||
PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );
|
PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );
|
||||||
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );
|
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );
|
||||||
PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );
|
PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );
|
||||||
PrintAndLog("Offset : %d", b.offset);
|
PrintAndLog("Offset : %d", b.offset);
|
||||||
PrintAndLog("Block0 : 0x%08X", b.block0);
|
PrintAndLog("Block0 : 0x%08X", b.block0);
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdT55xxWriteBlock(const char *Cmd)
|
int CmdT55xxWakeUp(const char *Cmd) {
|
||||||
{
|
uint32_t password = 0;
|
||||||
int block = 8; //default to invalid block
|
uint8_t cmdp = 0;
|
||||||
int data = 0xFFFFFFFF; //default to blank Block
|
bool errors = true;
|
||||||
int password = 0xFFFFFFFF; //default to blank Block 7
|
while(param_getchar(Cmd, cmdp) != 0x00) {
|
||||||
|
switch(param_getchar(Cmd, cmdp)) {
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
return usage_t55xx_wakup();
|
||||||
|
case 'p':
|
||||||
|
case 'P':
|
||||||
|
password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16);
|
||||||
|
cmdp += 2;
|
||||||
|
errors = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errors) return usage_t55xx_wakup();
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}};
|
||||||
if (cmdp == 'h' || cmdp == 'H') {
|
clearCommandBuffer();
|
||||||
usage_t55xx_write();
|
SendCommand(&c);
|
||||||
|
PrintAndLog("Wake up command sent. Try read now");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = sscanf(Cmd, "%d %x %x",&block, &data, &password);
|
int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
|
uint8_t block = 0xFF; //default to invalid block
|
||||||
if ( res < 2 || res > 3) {
|
uint32_t data = 0xFFFFFFFF; //default to blank Block
|
||||||
usage_t55xx_write();
|
uint32_t password = 0xFFFFFFFF; //default to blank Block 7
|
||||||
return 1;
|
bool usepwd = false;
|
||||||
|
bool page1 = false;
|
||||||
|
bool gotdata = false;
|
||||||
|
bool errors = false;
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch(param_getchar(Cmd, cmdp)) {
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
return usage_t55xx_write();
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
errors |= param_getdec(Cmd, cmdp+1, &block);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
data = param_get32ex(Cmd, cmdp+1, 0, 16);
|
||||||
|
gotdata = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
case 'P':
|
||||||
|
password = param_get32ex(Cmd, cmdp+1, 0, 16);
|
||||||
|
usepwd = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
page1 = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (errors || !gotdata) return usage_t55xx_write();
|
||||||
|
|
||||||
if (block > 7) {
|
if (block > 7) {
|
||||||
PrintAndLog("Block number must be between 0 and 7");
|
PrintAndLog("Block number must be between 0 and 7");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};
|
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
c.d.asBytes[0] = 0x0;
|
c.d.asBytes[0] = (page1) ? 0x2 : 0;
|
||||||
|
|
||||||
PrintAndLog("Writing to block: %d data : 0x%08X", block, data);
|
PrintAndLog("Writing to page: %d block: %d data : 0x%08X", page1, block, data);
|
||||||
|
|
||||||
//Password mode
|
//Password mode
|
||||||
if (res == 3) {
|
if (usepwd) {
|
||||||
c.arg[2] = password;
|
c.arg[2] = password;
|
||||||
c.d.asBytes[0] = 0x1;
|
c.d.asBytes[0] |= 0x1;
|
||||||
PrintAndLog("pwd : 0x%08X", password);
|
PrintAndLog("pwd : 0x%08X", password);
|
||||||
}
|
}
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
|
||||||
PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");
|
PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdT55xxReadTrace(const char *Cmd)
|
int CmdT55xxReadTrace(const char *Cmd) {
|
||||||
{
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
bool pwdmode = false;
|
||||||
|
uint32_t password = 0;
|
||||||
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')
|
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')
|
||||||
return usage_t55xx_trace();
|
return usage_t55xx_trace();
|
||||||
|
|
||||||
if (strlen(Cmd)==0)
|
if (strlen(Cmd)==0)
|
||||||
AquireData( TRACE_BLOCK );
|
if ( !AquireData( TRACE_BLOCK, REGULAR_READ_MODE_BLOCK, pwdmode, password ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!DecodeT55xxBlock()) return 1;
|
if (!DecodeT55xxBlock()) return 0;
|
||||||
|
|
||||||
if ( !DemodBufferLen) return 1;
|
if ( !DemodBufferLen) return 0;
|
||||||
|
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
uint8_t repeat = 0;
|
uint8_t repeat = 0;
|
||||||
if (config.offset > 5)
|
if (config.offset > 5)
|
||||||
repeat = 32;
|
repeat = 32;
|
||||||
uint8_t si = config.offset+repeat;
|
uint8_t si = config.offset+repeat;
|
||||||
uint32_t bl0 = PackBits(si, 32, DemodBuffer);
|
uint32_t bl1 = PackBits(si, 32, DemodBuffer);
|
||||||
uint32_t bl1 = PackBits(si+32, 32, DemodBuffer);
|
uint32_t bl2 = PackBits(si+32, 32, DemodBuffer);
|
||||||
|
|
||||||
uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8;
|
uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8;
|
||||||
uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8;
|
uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8;
|
||||||
|
@ -732,7 +837,7 @@ int CmdT55xxReadTrace(const char *Cmd)
|
||||||
|
|
||||||
if ( acl != 0xE0 ) {
|
if ( acl != 0xE0 ) {
|
||||||
PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");
|
PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
|
@ -749,8 +854,8 @@ int CmdT55xxReadTrace(const char *Cmd)
|
||||||
PrintAndLog(" Die Number : %d", dw);
|
PrintAndLog(" Die Number : %d", dw);
|
||||||
PrintAndLog("-------------------------------------------------------------");
|
PrintAndLog("-------------------------------------------------------------");
|
||||||
PrintAndLog(" Raw Data - Page 1");
|
PrintAndLog(" Raw Data - Page 1");
|
||||||
PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(DemodBuffer+config.offset+repeat,32) );
|
PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) );
|
||||||
PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );
|
PrintAndLog(" Block 2 : 0x%08X %s", bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );
|
||||||
PrintAndLog("-------------------------------------------------------------");
|
PrintAndLog("-------------------------------------------------------------");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -779,13 +884,16 @@ int CmdT55xxInfo(const char *Cmd){
|
||||||
Normal mode
|
Normal mode
|
||||||
Extended mode
|
Extended mode
|
||||||
*/
|
*/
|
||||||
|
bool pwdmode = false;
|
||||||
|
uint32_t password = 0;
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')
|
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')
|
||||||
return usage_t55xx_info();
|
return usage_t55xx_info();
|
||||||
|
|
||||||
if (strlen(Cmd)==0)
|
if (strlen(Cmd)==0)
|
||||||
AquireData( CONFIGURATION_BLOCK );
|
if ( !AquireData( 0, CONFIGURATION_BLOCK, pwdmode, password ) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (!DecodeT55xxBlock()) return 1;
|
if (!DecodeT55xxBlock()) return 1;
|
||||||
|
|
||||||
|
@ -836,67 +944,59 @@ int CmdT55xxInfo(const char *Cmd){
|
||||||
|
|
||||||
int CmdT55xxDump(const char *Cmd){
|
int CmdT55xxDump(const char *Cmd){
|
||||||
|
|
||||||
char s[20] = {0x00};
|
uint32_t password = 0;
|
||||||
uint8_t pwd[4] = {0x00};
|
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
if ( cmdp == 'h' || cmdp == 'H') {
|
bool override = false;
|
||||||
usage_t55xx_dump();
|
if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump();
|
||||||
return 0;
|
|
||||||
|
bool usepwd = ( strlen(Cmd) > 0);
|
||||||
|
if ( usepwd ){
|
||||||
|
password = param_get32ex(Cmd, 0, 0, 16);
|
||||||
|
if (param_getchar(Cmd, 1) =='o' )
|
||||||
|
override = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasPwd = ( strlen(Cmd) > 0);
|
PrintAndLog("Reading Page 0:");
|
||||||
if ( hasPwd ){
|
PrintAndLog("blk | hex data | binary");
|
||||||
if (param_gethex(Cmd, 0, pwd, 8)) {
|
for ( uint8_t i = 0; i <8; ++i){
|
||||||
PrintAndLog("password must include 8 HEX symbols");
|
T55xxReadBlock(i, 0, usepwd, override, password);
|
||||||
return 1;
|
/*memset(s,0,sizeof(s));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int i = 0; i <8; ++i){
|
|
||||||
memset(s,0,sizeof(s));
|
|
||||||
if ( hasPwd ) {
|
if ( hasPwd ) {
|
||||||
sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);
|
if ( override ) {
|
||||||
|
sprintf(s,"b %d p %02x%02x%02x%02x o", i, pwd[0],pwd[1],pwd[2],pwd[3]);
|
||||||
} else {
|
} else {
|
||||||
sprintf(s,"%d", i);
|
sprintf(s,"b %d p %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);
|
||||||
}
|
}
|
||||||
CmdT55xxReadBlock(s);
|
} else {
|
||||||
|
sprintf(s,"b %d", i);
|
||||||
}
|
}
|
||||||
return 0;
|
CmdT55xxReadBlock(s);*/
|
||||||
|
}
|
||||||
|
PrintAndLog("Reading Page 1:");
|
||||||
|
PrintAndLog("blk | hex data | binary");
|
||||||
|
for ( uint8_t i = 0; i<4; i++){
|
||||||
|
T55xxReadBlock(i, 1, usepwd, override, password);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AquireData( uint8_t block ){
|
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
|
||||||
|
|
||||||
UsbCommand c;
|
uint8_t arg0 = (page<<1) | pwdmode;
|
||||||
|
UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
|
||||||
if ( block == CONFIGURATION_BLOCK )
|
|
||||||
c.cmd = CMD_T55XX_READ_BLOCK;
|
|
||||||
else if (block == TRACE_BLOCK )
|
|
||||||
c.cmd = CMD_T55XX_READ_TRACE;
|
|
||||||
|
|
||||||
c.arg[0] = 0x00;
|
|
||||||
c.arg[1] = 0x00;
|
|
||||||
c.arg[2] = 0x00;
|
|
||||||
c.d.asBytes[0] = 0x0;
|
|
||||||
|
|
||||||
//Password mode
|
|
||||||
// if ( res == 2 ) {
|
|
||||||
// c.arg[2] = password;
|
|
||||||
// c.d.asBytes[0] = 0x1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
|
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
|
||||||
PrintAndLog("command execution time out");
|
PrintAndLog("command execution time out");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t got[12000];
|
uint8_t got[12000];
|
||||||
GetFromBigBuf(got,sizeof(got),0);
|
GetFromBigBuf(got,sizeof(got),0);
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
WaitForResponse(CMD_ACK,NULL);
|
||||||
setGraphBuf(got, 12000);
|
setGraphBuf(got, sizeof(got));
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * GetBitRateStr(uint32_t id){
|
char * GetBitRateStr(uint32_t id){
|
||||||
|
@ -1072,17 +1172,36 @@ uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdResetRead(const char *Cmd) {
|
||||||
|
UsbCommand c = {CMD_T55XX_RESET_READ, {0,0,0}};
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
|
||||||
|
PrintAndLog("command execution time out");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t got[BIGBUF_SIZE-1];
|
||||||
|
GetFromBigBuf(got,sizeof(got),0);
|
||||||
|
WaitForResponse(CMD_ACK,NULL);
|
||||||
|
setGraphBuf(got, sizeof(got));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
||||||
{"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."},
|
{"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||||
{"read", CmdT55xxReadBlock, 0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"},
|
{"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
|
||||||
{"write", CmdT55xxWriteBlock,0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"},
|
{"resetread",CmdResetRead, 0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
|
||||||
|
{"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
|
||||||
{"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},
|
{"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},
|
||||||
{"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"},
|
{"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"},
|
||||||
{"dump", CmdT55xxDump, 0, "[password] Dump T55xx card block 0-7. [optional password]"},
|
{"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
||||||
{"special", special, 0, "Show block changes with 64 different offsets"},
|
{"special", special, 0, "Show block changes with 64 different offsets"},
|
||||||
|
{"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,9 @@ typedef struct {
|
||||||
RF_128 = 0x07,
|
RF_128 = 0x07,
|
||||||
} bitrate;
|
} bitrate;
|
||||||
} t55xx_conf_block_t;
|
} t55xx_conf_block_t;
|
||||||
|
t55xx_conf_block_t Get_t55xx_Config();
|
||||||
|
void Set_t55xx_Config(t55xx_conf_block_t conf);
|
||||||
|
|
||||||
|
|
||||||
int CmdLFT55XX(const char *Cmd);
|
int CmdLFT55XX(const char *Cmd);
|
||||||
int CmdT55xxSetConfig(const char *Cmd);
|
int CmdT55xxSetConfig(const char *Cmd);
|
||||||
|
@ -47,6 +50,7 @@ int CmdT55xxWriteBlock(const char *Cmd);
|
||||||
int CmdT55xxReadTrace(const char *Cmd);
|
int CmdT55xxReadTrace(const char *Cmd);
|
||||||
int CmdT55xxInfo(const char *Cmd);
|
int CmdT55xxInfo(const char *Cmd);
|
||||||
int CmdT55xxDetect(const char *Cmd);
|
int CmdT55xxDetect(const char *Cmd);
|
||||||
|
int CmdResetRead(const char *Cmd);
|
||||||
|
|
||||||
char * GetBitRateStr(uint32_t id);
|
char * GetBitRateStr(uint32_t id);
|
||||||
char * GetSaferStr(uint32_t id);
|
char * GetSaferStr(uint32_t id);
|
||||||
|
@ -55,12 +59,12 @@ char * GetModelStrFromCID(uint32_t cid);
|
||||||
char * GetSelectedModulationStr( uint8_t id);
|
char * GetSelectedModulationStr( uint8_t id);
|
||||||
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bitstream);
|
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bitstream);
|
||||||
void printT55xxBlock(const char *demodStr);
|
void printT55xxBlock(const char *demodStr);
|
||||||
void printConfiguration( t55xx_conf_block_t b);
|
int printConfiguration( t55xx_conf_block_t b);
|
||||||
|
|
||||||
bool DecodeT55xxBlock();
|
bool DecodeT55xxBlock();
|
||||||
bool tryDetectModulation();
|
bool tryDetectModulation();
|
||||||
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate);
|
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate);
|
||||||
int special(const char *Cmd);
|
int special(const char *Cmd);
|
||||||
int AquireData( uint8_t block );
|
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,7 +73,7 @@ typedef struct {
|
||||||
#define CMD_INDALA_CLONE_TAG_L 0x0213
|
#define CMD_INDALA_CLONE_TAG_L 0x0213
|
||||||
#define CMD_T55XX_READ_BLOCK 0x0214
|
#define CMD_T55XX_READ_BLOCK 0x0214
|
||||||
#define CMD_T55XX_WRITE_BLOCK 0x0215
|
#define CMD_T55XX_WRITE_BLOCK 0x0215
|
||||||
#define CMD_T55XX_READ_TRACE 0x0216
|
#define CMD_T55XX_RESET_READ 0x0216
|
||||||
#define CMD_PCF7931_READ 0x0217
|
#define CMD_PCF7931_READ 0x0217
|
||||||
#define CMD_EM4X_READ_WORD 0x0218
|
#define CMD_EM4X_READ_WORD 0x0218
|
||||||
#define CMD_EM4X_WRITE_WORD 0x0219
|
#define CMD_EM4X_WRITE_WORD 0x0219
|
||||||
|
@ -85,6 +85,7 @@ typedef struct {
|
||||||
#define CMD_ASK_SIM_TAG 0x021F
|
#define CMD_ASK_SIM_TAG 0x021F
|
||||||
#define CMD_PSK_SIM_TAG 0x0220
|
#define CMD_PSK_SIM_TAG 0x0220
|
||||||
#define CMD_AWID_DEMOD_FSK 0x0221
|
#define CMD_AWID_DEMOD_FSK 0x0221
|
||||||
|
#define CMD_T55XX_WAKEUP 0x0224
|
||||||
|
|
||||||
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ local _commands = {
|
||||||
CMD_INDALA_CLONE_TAG_L = 0x0213,
|
CMD_INDALA_CLONE_TAG_L = 0x0213,
|
||||||
CMD_T55XX_READ_BLOCK = 0x0214,
|
CMD_T55XX_READ_BLOCK = 0x0214,
|
||||||
CMD_T55XX_WRITE_BLOCK = 0x0215,
|
CMD_T55XX_WRITE_BLOCK = 0x0215,
|
||||||
CMD_T55XX_READ_TRACE = 0x0216,
|
CMD_T55XX_RESET_READ = 0x0216,
|
||||||
CMD_PCF7931_READ = 0x0217,
|
CMD_PCF7931_READ = 0x0217,
|
||||||
CMD_EM4X_READ_WORD = 0x0218,
|
CMD_EM4X_READ_WORD = 0x0218,
|
||||||
CMD_EM4X_WRITE_WORD = 0x0219,
|
CMD_EM4X_WRITE_WORD = 0x0219,
|
||||||
|
@ -56,7 +56,7 @@ local _commands = {
|
||||||
CMD_ASK_SIM_TAG = 0x021F,
|
CMD_ASK_SIM_TAG = 0x021F,
|
||||||
CMD_PSK_SIM_TAG = 0x0220,
|
CMD_PSK_SIM_TAG = 0x0220,
|
||||||
CMD_AWID_DEMOD_FSK = 0x0221,
|
CMD_AWID_DEMOD_FSK = 0x0221,
|
||||||
|
CMD_T55XX_WAKEUP = 0x0224,
|
||||||
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||||
|
|
||||||
--// For the 13.56 MHz tags
|
--// For the 13.56 MHz tags
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "nonce2key/nonce2key.h"
|
#include "nonce2key/nonce2key.h"
|
||||||
#include "../common/iso15693tools.h"
|
#include "../common/iso15693tools.h"
|
||||||
|
#include "iso14443crc.h"
|
||||||
#include "../common/crc16.h"
|
#include "../common/crc16.h"
|
||||||
#include "../common/crc64.h"
|
#include "../common/crc64.h"
|
||||||
#include "../common/sha1.h"
|
#include "../common/sha1.h"
|
||||||
|
@ -228,6 +229,27 @@ static int l_iso15693_crc(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_iso14443b_crc(lua_State *L)
|
||||||
|
{
|
||||||
|
/* void ComputeCrc14443(int CrcType,
|
||||||
|
const unsigned char *Data, int Length,
|
||||||
|
unsigned char *TransmitFirst,
|
||||||
|
unsigned char *TransmitSecond)
|
||||||
|
*/
|
||||||
|
unsigned char buf[USB_CMD_DATA_SIZE];
|
||||||
|
size_t len = 0;
|
||||||
|
const char *data = luaL_checklstring(L, 1, &len);
|
||||||
|
if (USB_CMD_DATA_SIZE < len)
|
||||||
|
len = USB_CMD_DATA_SIZE-2;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i += 2) {
|
||||||
|
sscanf(&data[i], "%02x", (unsigned int *)&buf[i / 2]);
|
||||||
|
}
|
||||||
|
ComputeCrc14443(CRC_14443_B, buf, len, &buf[len], &buf[len+1]);
|
||||||
|
|
||||||
|
lua_pushlstring(L, (const char *)&buf, len+2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Simple AES 128 cbc hook up to OpenSSL.
|
Simple AES 128 cbc hook up to OpenSSL.
|
||||||
params: key, input
|
params: key, input
|
||||||
|
@ -426,6 +448,7 @@ int set_pm3_libraries(lua_State *L)
|
||||||
{"clearCommandBuffer", l_clearCommandBuffer},
|
{"clearCommandBuffer", l_clearCommandBuffer},
|
||||||
{"console", l_CmdConsole},
|
{"console", l_CmdConsole},
|
||||||
{"iso15693_crc", l_iso15693_crc},
|
{"iso15693_crc", l_iso15693_crc},
|
||||||
|
{"iso14443b_crc", l_iso14443b_crc},
|
||||||
{"aes128_decrypt", l_aes128decrypt_cbc},
|
{"aes128_decrypt", l_aes128decrypt_cbc},
|
||||||
{"aes128_decrypt_ecb", l_aes128decrypt_ecb},
|
{"aes128_decrypt_ecb", l_aes128decrypt_ecb},
|
||||||
{"aes128_encrypt", l_aes128encrypt_cbc},
|
{"aes128_encrypt", l_aes128encrypt_cbc},
|
||||||
|
|
117
common/lfdemod.c
117
common/lfdemod.c
|
@ -282,6 +282,16 @@ int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert)
|
||||||
return bestErr;
|
return bestErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t manchesterEncode2Bytes(uint16_t datain) {
|
||||||
|
uint32_t output = 0;
|
||||||
|
uint8_t curBit = 0;
|
||||||
|
for (uint8_t i=0; i<16; i++) {
|
||||||
|
curBit = (datain >> (15-i) & 1);
|
||||||
|
output |= (1<<(((15-i)*2)+curBit));
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//encode binary data into binary manchester
|
//encode binary data into binary manchester
|
||||||
int ManchesterEncode(uint8_t *BitStream, size_t size)
|
int ManchesterEncode(uint8_t *BitStream, size_t size)
|
||||||
|
@ -369,7 +379,9 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow
|
||||||
if (fclow==0) fclow=8;
|
if (fclow==0) fclow=8;
|
||||||
//set the threshold close to 0 (graph) or 128 std to avoid static
|
//set the threshold close to 0 (graph) or 128 std to avoid static
|
||||||
uint8_t threshold_value = 123;
|
uint8_t threshold_value = 123;
|
||||||
|
size_t preLastSample = 0;
|
||||||
|
size_t LastSample = 0;
|
||||||
|
size_t currSample = 0;
|
||||||
// sync to first lo-hi transition, and threshold
|
// sync to first lo-hi transition, and threshold
|
||||||
|
|
||||||
// Need to threshold first sample
|
// Need to threshold first sample
|
||||||
|
@ -389,13 +401,22 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow
|
||||||
|
|
||||||
// Check for 0->1 transition
|
// Check for 0->1 transition
|
||||||
if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition
|
if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition
|
||||||
if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise
|
preLastSample = LastSample;
|
||||||
|
LastSample = currSample;
|
||||||
|
currSample = idx-last_transition;
|
||||||
|
if (currSample < (fclow-2)){ //0-5 = garbage noise
|
||||||
//do nothing with extra garbage
|
//do nothing with extra garbage
|
||||||
} else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves
|
} else if (currSample < (fchigh-1)) { //6-8 = 8 sample waves
|
||||||
|
if (LastSample > (fchigh-2) && preLastSample < (fchigh-1)){
|
||||||
|
dest[numBits-1]=1; //correct last 9 wave surrounded by 8 waves
|
||||||
|
}
|
||||||
dest[numBits++]=1;
|
dest[numBits++]=1;
|
||||||
} else if ((idx-last_transition) > (fchigh+1) && !numBits) { //12 + and first bit = garbage
|
|
||||||
|
} else if (currSample > (fchigh+1) && !numBits) { //12 + and first bit = garbage
|
||||||
//do nothing with beginning garbage
|
//do nothing with beginning garbage
|
||||||
} else { //9+ = 10 waves
|
} else if (currSample == (fclow+1) && LastSample == (fclow-1)) { // had a 7 then a 9 should be two 8's
|
||||||
|
dest[numBits++]=1;
|
||||||
|
} else { //9+ = 10 sample waves
|
||||||
dest[numBits++]=0;
|
dest[numBits++]=0;
|
||||||
}
|
}
|
||||||
last_transition = idx;
|
last_transition = idx;
|
||||||
|
@ -578,6 +599,25 @@ int IOdemodFSK(uint8_t *dest, size_t size)
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// by marshmellow
|
||||||
|
// find viking preamble 0xF200 in already demoded data
|
||||||
|
int VikingDemod_AM(uint8_t *dest, size_t *size) {
|
||||||
|
//make sure buffer has data
|
||||||
|
if (*size < 64*2) return -2;
|
||||||
|
|
||||||
|
size_t startIdx = 0;
|
||||||
|
uint8_t preamble[] = {1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
|
uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
|
||||||
|
if (errChk == 0) return -4; //preamble not found
|
||||||
|
uint32_t checkCalc = bytebits_to_byte(dest+startIdx,8) ^ bytebits_to_byte(dest+startIdx+8,8) ^ bytebits_to_byte(dest+startIdx+16,8)
|
||||||
|
^ bytebits_to_byte(dest+startIdx+24,8) ^ bytebits_to_byte(dest+startIdx+32,8) ^ bytebits_to_byte(dest+startIdx+40,8)
|
||||||
|
^ bytebits_to_byte(dest+startIdx+48,8) ^ bytebits_to_byte(dest+startIdx+56,8);
|
||||||
|
if ( checkCalc != 0xA8 ) return -5;
|
||||||
|
if (*size != 64) return -6;
|
||||||
|
//return start position
|
||||||
|
return (int) startIdx;
|
||||||
|
}
|
||||||
|
|
||||||
// by marshmellow
|
// by marshmellow
|
||||||
// takes a array of binary values, start position, length of bits per parity (includes parity bit),
|
// takes a array of binary values, start position, length of bits per parity (includes parity bit),
|
||||||
// Parity Type (1 for odd; 0 for even; 2 Always 1's), and binary Length (length to run)
|
// Parity Type (1 for odd; 0 for even; 2 Always 1's), and binary Length (length to run)
|
||||||
|
@ -1033,63 +1073,20 @@ void psk2TOpsk1(uint8_t *BitStream, size_t size)
|
||||||
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert)
|
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert)
|
||||||
{
|
{
|
||||||
//26 bit 40134 format (don't know other formats)
|
//26 bit 40134 format (don't know other formats)
|
||||||
int i;
|
uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
|
||||||
int long_wait=29;//29 leading zeros in format
|
uint8_t preamble_i[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0};
|
||||||
int start;
|
size_t startidx = 0;
|
||||||
int first = 0;
|
if (!preambleSearch(bitStream, preamble, sizeof(preamble), size, &startidx)){
|
||||||
int first2 = 0;
|
// if didn't find preamble try again inverting
|
||||||
int bitCnt = 0;
|
if (!preambleSearch(bitStream, preamble_i, sizeof(preamble_i), size, &startidx)) return -1;
|
||||||
int ii;
|
*invert ^= 1;
|
||||||
// Finding the start of a UID
|
|
||||||
for (start = 0; start <= *size - 250; start++) {
|
|
||||||
first = bitStream[start];
|
|
||||||
for (i = start; i < start + long_wait; i++) {
|
|
||||||
if (bitStream[i] != first) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
if (*size != 64 && *size != 224) return -2;
|
||||||
if (i == (start + long_wait)) {
|
if (*invert==1)
|
||||||
break;
|
for (size_t i = startidx; i < *size; i++)
|
||||||
}
|
bitStream[i] ^= 1;
|
||||||
}
|
|
||||||
if (start == *size - 250 + 1) {
|
|
||||||
// did not find start sequence
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// Inverting signal if needed
|
|
||||||
if (first == 1) {
|
|
||||||
for (i = start; i < *size; i++) {
|
|
||||||
bitStream[i] = !bitStream[i];
|
|
||||||
}
|
|
||||||
*invert = 1;
|
|
||||||
}else *invert=0;
|
|
||||||
|
|
||||||
int iii;
|
return (int) startidx;
|
||||||
//found start once now test length by finding next one
|
|
||||||
for (ii=start+29; ii <= *size - 250; ii++) {
|
|
||||||
first2 = bitStream[ii];
|
|
||||||
for (iii = ii; iii < ii + long_wait; iii++) {
|
|
||||||
if (bitStream[iii] != first2) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (iii == (ii + long_wait)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ii== *size - 250 + 1){
|
|
||||||
// did not find second start sequence
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
bitCnt=ii-start;
|
|
||||||
|
|
||||||
// Dumping UID
|
|
||||||
i = start;
|
|
||||||
for (ii = 0; ii < bitCnt; ii++) {
|
|
||||||
bitStream[ii] = bitStream[i++];
|
|
||||||
}
|
|
||||||
*size=bitCnt;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// by marshmellow - demodulate NRZ wave (both similar enough)
|
// by marshmellow - demodulate NRZ wave (both similar enough)
|
||||||
|
|
|
@ -27,9 +27,9 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t f
|
||||||
int DetectNRZClock(uint8_t dest[], size_t size, int clock);
|
int DetectNRZClock(uint8_t dest[], size_t size, int clock);
|
||||||
int DetectPSKClock(uint8_t dest[], size_t size, int clock);
|
int DetectPSKClock(uint8_t dest[], size_t size, int clock);
|
||||||
int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
|
int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
|
||||||
uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
|
|
||||||
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
|
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
|
||||||
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
||||||
|
uint32_t manchesterEncode2Bytes(uint16_t datain);
|
||||||
int ManchesterEncode(uint8_t *BitStream, size_t size);
|
int ManchesterEncode(uint8_t *BitStream, size_t size);
|
||||||
int manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert);
|
int manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert);
|
||||||
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
|
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
|
||||||
|
@ -41,13 +41,15 @@ void psk1TOpsk2(uint8_t *BitStream, size_t size);
|
||||||
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
|
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
|
||||||
|
|
||||||
//tag specific
|
//tag specific
|
||||||
int FDXBdemodBI(uint8_t *dest, size_t *size);
|
|
||||||
int AWIDdemodFSK(uint8_t *dest, size_t *size);
|
int AWIDdemodFSK(uint8_t *dest, size_t *size);
|
||||||
|
uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
|
||||||
|
int FDXBdemodBI(uint8_t *dest, size_t *size);
|
||||||
int gProxII_Demod(uint8_t BitStream[], size_t *size);
|
int gProxII_Demod(uint8_t BitStream[], size_t *size);
|
||||||
int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||||
int IOdemodFSK(uint8_t *dest, size_t size);
|
int IOdemodFSK(uint8_t *dest, size_t size);
|
||||||
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||||
int PyramiddemodFSK(uint8_t *dest, size_t *size);
|
|
||||||
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||||
|
int PyramiddemodFSK(uint8_t *dest, size_t *size);
|
||||||
|
int VikingDemod_AM(uint8_t *dest, size_t *size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,13 +3,36 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
|
|
||||||
|
// ATA55xx shared presets & routines
|
||||||
|
uint32_t GetT55xxClockBit(uint32_t clock) {
|
||||||
|
switch (clock) {
|
||||||
|
case 128:
|
||||||
|
return T55x7_BITRATE_RF_128;
|
||||||
|
case 100:
|
||||||
|
return T55x7_BITRATE_RF_100;
|
||||||
|
case 64:
|
||||||
|
return T55x7_BITRATE_RF_64;
|
||||||
|
case 50:
|
||||||
|
return T55x7_BITRATE_RF_50;
|
||||||
|
case 40:
|
||||||
|
return T55x7_BITRATE_RF_40;
|
||||||
|
case 32:
|
||||||
|
return T55x7_BITRATE_RF_32;
|
||||||
|
case 16:
|
||||||
|
return T55x7_BITRATE_RF_16;
|
||||||
|
case 8:
|
||||||
|
return T55x7_BITRATE_RF_8;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ON_DEVICE
|
#ifndef ON_DEVICE
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#define prnt PrintAndLog
|
#define prnt PrintAndLog
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// iclass / picopass chip config structures and shared routines
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t app_limit; //[8]
|
uint8_t app_limit; //[8]
|
||||||
uint8_t otp[2]; //[9-10]
|
uint8_t otp[2]; //[9-10]
|
||||||
|
@ -18,8 +41,7 @@ typedef struct {
|
||||||
uint8_t mem_config; //[13]
|
uint8_t mem_config; //[13]
|
||||||
uint8_t eas; //[14]
|
uint8_t eas; //[14]
|
||||||
uint8_t fuses; //[15]
|
uint8_t fuses; //[15]
|
||||||
}picopass_conf_block;
|
} picopass_conf_block;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t csn[8];
|
uint8_t csn[8];
|
||||||
|
@ -28,32 +50,17 @@ typedef struct {
|
||||||
uint8_t key_d[8];
|
uint8_t key_d[8];
|
||||||
uint8_t key_c[8];
|
uint8_t key_c[8];
|
||||||
uint8_t app_issuer_area[8];
|
uint8_t app_issuer_area[8];
|
||||||
|
} picopass_hdr;
|
||||||
|
|
||||||
}picopass_hdr;
|
uint8_t isset(uint8_t val, uint8_t mask) {
|
||||||
|
|
||||||
|
|
||||||
//#define prnt printf
|
|
||||||
/*void prnt(char *fmt,...)
|
|
||||||
{
|
|
||||||
va_list argptr;
|
|
||||||
va_start(argptr, fmt);
|
|
||||||
vprintf(fmt, argptr);
|
|
||||||
printf(" "); // cleaning prompt
|
|
||||||
va_end(argptr);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
uint8_t isset(uint8_t val, uint8_t mask)
|
|
||||||
{
|
|
||||||
return (val & mask);
|
return (val & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t notset(uint8_t val, uint8_t mask){
|
uint8_t notset(uint8_t val, uint8_t mask) {
|
||||||
return !(val & mask);
|
return !(val & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuse_config(const picopass_hdr *hdr)
|
void fuse_config(const picopass_hdr *hdr) {
|
||||||
{
|
|
||||||
uint8_t fuses = hdr->conf.fuses;
|
uint8_t fuses = hdr->conf.fuses;
|
||||||
|
|
||||||
if (isset(fuses,FUSE_FPERS))prnt(" Mode: Personalization [Programmable]");
|
if (isset(fuses,FUSE_FPERS))prnt(" Mode: Personalization [Programmable]");
|
||||||
|
@ -104,8 +111,7 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mem_app_config(const picopass_hdr *hdr)
|
void mem_app_config(const picopass_hdr *hdr) {
|
||||||
{
|
|
||||||
uint8_t mem = hdr->conf.mem_config;
|
uint8_t mem = hdr->conf.mem_config;
|
||||||
uint8_t chip = hdr->conf.chip_config;
|
uint8_t chip = hdr->conf.chip_config;
|
||||||
uint8_t applimit = hdr->conf.app_limit;
|
uint8_t applimit = hdr->conf.app_limit;
|
||||||
|
@ -118,28 +124,25 @@ void mem_app_config(const picopass_hdr *hdr)
|
||||||
prnt(" AA1: blocks 06-%02X", applimit);
|
prnt(" AA1: blocks 06-%02X", applimit);
|
||||||
prnt(" AA2: blocks %02X-%02X", applimit+1, max_blk);
|
prnt(" AA2: blocks %02X-%02X", applimit+1, max_blk);
|
||||||
}
|
}
|
||||||
void print_picopass_info(const picopass_hdr *hdr)
|
void print_picopass_info(const picopass_hdr *hdr) {
|
||||||
{
|
|
||||||
fuse_config(hdr);
|
fuse_config(hdr);
|
||||||
mem_app_config(hdr);
|
mem_app_config(hdr);
|
||||||
}
|
}
|
||||||
void printIclassDumpInfo(uint8_t* iclass_dump)
|
void printIclassDumpInfo(uint8_t* iclass_dump) {
|
||||||
{
|
|
||||||
// picopass_hdr hdr;
|
|
||||||
// memcpy(&hdr, iclass_dump, sizeof(picopass_hdr));
|
|
||||||
print_picopass_info((picopass_hdr *) iclass_dump);
|
print_picopass_info((picopass_hdr *) iclass_dump);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void test()
|
void test() {
|
||||||
{
|
|
||||||
picopass_hdr hdr = {0x27,0xaf,0x48,0x01,0xf9,0xff,0x12,0xe0,0x12,0xff,0xff,0xff,0x7f,0x1f,0xff,0x3c};
|
picopass_hdr hdr = {0x27,0xaf,0x48,0x01,0xf9,0xff,0x12,0xe0,0x12,0xff,0xff,0xff,0x7f,0x1f,0xff,0x3c};
|
||||||
prnt("Picopass configuration:");
|
prnt("Picopass configuration:");
|
||||||
print_picopass_info(&hdr);
|
print_picopass_info(&hdr);
|
||||||
}
|
}
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
test();
|
test();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//ON_DEVICE
|
||||||
|
|
|
@ -210,8 +210,60 @@ NXP/Philips CUSTOM COMMANDS
|
||||||
#define FUSE_FPROD0 0x02
|
#define FUSE_FPROD0 0x02
|
||||||
#define FUSE_RA 0x01
|
#define FUSE_RA 0x01
|
||||||
|
|
||||||
|
|
||||||
void printIclassDumpInfo(uint8_t* iclass_dump);
|
void printIclassDumpInfo(uint8_t* iclass_dump);
|
||||||
void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb);
|
void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb);
|
||||||
|
|
||||||
#endif // PROTOCOLS_H
|
/* T55x7 configuration register definitions */
|
||||||
|
#define T55x7_POR_DELAY 0x00000001
|
||||||
|
#define T55x7_ST_TERMINATOR 0x00000008
|
||||||
|
#define T55x7_PWD 0x00000010
|
||||||
|
#define T55x7_MAXBLOCK_SHIFT 5
|
||||||
|
#define T55x7_AOR 0x00000200
|
||||||
|
#define T55x7_PSKCF_RF_2 0
|
||||||
|
#define T55x7_PSKCF_RF_4 0x00000400
|
||||||
|
#define T55x7_PSKCF_RF_8 0x00000800
|
||||||
|
#define T55x7_MODULATION_DIRECT 0
|
||||||
|
#define T55x7_MODULATION_PSK1 0x00001000
|
||||||
|
#define T55x7_MODULATION_PSK2 0x00002000
|
||||||
|
#define T55x7_MODULATION_PSK3 0x00003000
|
||||||
|
#define T55x7_MODULATION_FSK1 0x00004000
|
||||||
|
#define T55x7_MODULATION_FSK2 0x00005000
|
||||||
|
#define T55x7_MODULATION_FSK1a 0x00006000
|
||||||
|
#define T55x7_MODULATION_FSK2a 0x00007000
|
||||||
|
#define T55x7_MODULATION_MANCHESTER 0x00008000
|
||||||
|
#define T55x7_MODULATION_BIPHASE 0x00010000
|
||||||
|
#define T55x7_MODULATION_DIPHASE 0x00018000
|
||||||
|
#define T55x7_BITRATE_RF_8 0
|
||||||
|
#define T55x7_BITRATE_RF_16 0x00040000
|
||||||
|
#define T55x7_BITRATE_RF_32 0x00080000
|
||||||
|
#define T55x7_BITRATE_RF_40 0x000C0000
|
||||||
|
#define T55x7_BITRATE_RF_50 0x00100000
|
||||||
|
#define T55x7_BITRATE_RF_64 0x00140000
|
||||||
|
#define T55x7_BITRATE_RF_100 0x00180000
|
||||||
|
#define T55x7_BITRATE_RF_128 0x001C0000
|
||||||
|
|
||||||
|
/* T5555 (Q5) configuration register definitions */
|
||||||
|
#define T5555_ST_TERMINATOR 0x00000001
|
||||||
|
#define T5555_MAXBLOCK_SHIFT 0x00000001
|
||||||
|
#define T5555_MODULATION_MANCHESTER 0
|
||||||
|
#define T5555_MODULATION_PSK1 0x00000010
|
||||||
|
#define T5555_MODULATION_PSK2 0x00000020
|
||||||
|
#define T5555_MODULATION_PSK3 0x00000030
|
||||||
|
#define T5555_MODULATION_FSK1 0x00000040
|
||||||
|
#define T5555_MODULATION_FSK2 0x00000050
|
||||||
|
#define T5555_MODULATION_BIPHASE 0x00000060
|
||||||
|
#define T5555_MODULATION_DIRECT 0x00000070
|
||||||
|
#define T5555_INVERT_OUTPUT 0x00000080
|
||||||
|
#define T5555_PSK_RF_2 0
|
||||||
|
#define T5555_PSK_RF_4 0x00000100
|
||||||
|
#define T5555_PSK_RF_8 0x00000200
|
||||||
|
#define T5555_USE_PWD 0x00000400
|
||||||
|
#define T5555_USE_AOR 0x00000800
|
||||||
|
#define T5555_BITRATE_SHIFT 12 //(RF=2n+2) ie 64=2*0x1F+2 or n = (RF-2)/2
|
||||||
|
#define T5555_FAST_WRITE 0x00004000
|
||||||
|
#define T5555_PAGE_SELECT 0x00008000
|
||||||
|
|
||||||
|
uint32_t GetT55xxClockBit(uint32_t clock);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// PROTOCOLS_H
|
||||||
|
|
|
@ -85,7 +85,7 @@ typedef struct{
|
||||||
#define CMD_INDALA_CLONE_TAG_L 0x0213
|
#define CMD_INDALA_CLONE_TAG_L 0x0213
|
||||||
#define CMD_T55XX_READ_BLOCK 0x0214
|
#define CMD_T55XX_READ_BLOCK 0x0214
|
||||||
#define CMD_T55XX_WRITE_BLOCK 0x0215
|
#define CMD_T55XX_WRITE_BLOCK 0x0215
|
||||||
#define CMD_T55XX_READ_TRACE 0x0216
|
#define CMD_T55XX_RESET_READ 0x0216
|
||||||
#define CMD_PCF7931_READ 0x0217
|
#define CMD_PCF7931_READ 0x0217
|
||||||
#define CMD_PCF7931_WRITE 0x0222
|
#define CMD_PCF7931_WRITE 0x0222
|
||||||
#define CMD_EM4X_READ_WORD 0x0218
|
#define CMD_EM4X_READ_WORD 0x0218
|
||||||
|
@ -99,6 +99,7 @@ typedef struct{
|
||||||
#define CMD_ASK_SIM_TAG 0x021F
|
#define CMD_ASK_SIM_TAG 0x021F
|
||||||
#define CMD_PSK_SIM_TAG 0x0220
|
#define CMD_PSK_SIM_TAG 0x0220
|
||||||
#define CMD_AWID_DEMOD_FSK 0x0221
|
#define CMD_AWID_DEMOD_FSK 0x0221
|
||||||
|
#define CMD_T55XX_WAKEUP 0x0224
|
||||||
|
|
||||||
|
|
||||||
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue