## [unreleased][unreleased]
### Added
+- `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 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)
- Added option c to 'hf list' (mark CRC bytes) (piwi)
### Changed
+- 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)
- `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)
// clear ALL of BigBuf
void BigBuf_Clear(void)
+{
+ BigBuf_Clear_ext(true);
+}
+// clear ALL of BigBuf
+void BigBuf_Clear_ext(bool verbose)
{
memset(BigBuf,0,BIGBUF_SIZE);
- Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
+ if (verbose)
+ Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
}
extern uint8_t *BigBuf_get_EM_addr(void);
extern uint16_t BigBuf_max_traceLen(void);
extern void BigBuf_Clear(void);
+extern void BigBuf_Clear_ext(bool verbose);
extern uint8_t *BigBuf_malloc(uint16_t);
extern void BigBuf_free(void);
extern void BigBuf_free_keep_EM(void);
#-DWITH_LCD
#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_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
SRC_ISO14443b = iso14443b.c
# These are to be compiled in ARM mode
ARMSRC = fpgaloader.c \
legicrf.c \
- lfdemod.c \
$(SRC_ISO14443a) \
$(SRC_ISO14443b) \
$(SRC_CRAPTO1) \
#include "lfsampling.h"
#include "BigBuf.h"
#include "mifareutil.h"
+#include "pcf7931.h"
#ifdef WITH_LCD
#include "LCD.h"
#endif
CmdIOdemodFSK(c->arg[0], 0, 0, 1);
break;
case CMD_IO_CLONE_TAG:
- CopyIOtoT55x7(c->arg[0], c->arg[1], c->d.asBytes[0]);
+ CopyIOtoT55x7(c->arg[0], c->arg[1]);
break;
case CMD_EM410X_DEMOD:
CmdEM410xdemod(c->arg[0], 0, 0, 1);
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;
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;
case CMD_T55XX_WRITE_BLOCK:
T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
- cmd_send(CMD_ACK,0,0,0,0,0);
break;
- case CMD_T55XX_READ_TRACE:
- T55xxReadTrace();
+ case CMD_T55XX_WAKEUP:
+ T55xxWakeUp(c->arg[0]);
+ break;
+ case CMD_T55XX_RESET_READ:
+ T55xxResetRead();
break;
case CMD_PCF7931_READ:
ReadPCF7931();
- cmd_send(CMD_ACK,0,0,0,0,0);
break;
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;
case CMD_EM4X_READ_WORD:
EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
break;
case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
- break;
+ break;
#endif
#ifdef WITH_HITAG
extern bool averaging;
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 WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
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 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 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 CopyIndala64toT55x7(int hi, int 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 CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-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 T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode );
-void T55xxReadTrace(void);
-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);
+void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd);
+void T55xxWakeUp(uint32_t Pwd);
+void TurnReadLFOn();
+//void T55xxReadTrace(void);
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);
#include "string.h"
#include "lfdemod.h"
#include "lfsampling.h"
+#include "protocols.h"
#include "usb_cdc.h" //test
/**
* @param period_1
* @param command
*/
-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)
{
int divisor_used = 95; // 125 KHz
memset(dest+(*n), c ^ *phase, clock);
*phase ^= 1;
}
-
}
// args clock, ask/man or askraw, invert, transmission separator
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
}
/*------------------------------
- * T5555/T5557/T5567 routines
+ * T5555/T5557/T5567/T5577 routines
*------------------------------
*/
-/* 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_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
-#define T5555_FAST_WRITE 0x00004000
-#define T5555_PAGE_SELECT 0x00008000
+/* NOTE: T55x7/T5555 configuration register definitions moved to protocols.h */
/*
- * Relevant times in microsecond
+ * Relevant communication times in microsecond
* To compensate antenna falling times shorten the write times
* and enlarge the gap ones.
+ * Q5 tags seems to have issues when these values changes.
*/
#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
+#define READ_GAP 52*8
-#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
+// VALUES TAKEN FROM EM4x function: SendForward
+// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
+// WRITE_GAP = 128; (16*8)
+// WRITE_1 = 256 32*8; (32*8)
-// Write one bit to card
-void T55xxWriteBit(int bit)
-{
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+// These timings work for 4469/4269/4305 (with the 55*8 above)
+// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8);
+
+// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
+// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
+// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
+// T0 = TIMER_CLOCK1 / 125000 = 192
+// 1 Cycle = 8 microseconds(us) == 1 field clock
+
+void TurnReadLFOn(int delay) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- if (bit == 0)
- SpinDelayUs(WRITE_0);
+ // Give it a bit of time for the resonant antenna to settle.
+ SpinDelayUs(delay); //155*8 //50*8
+}
+
+// Write one bit to card
+void T55xxWriteBit(int bit) {
+ if (!bit)
+ TurnReadLFOn(WRITE_0);
else
- SpinDelayUs(WRITE_1);
+ TurnReadLFOn(WRITE_1);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(WRITE_GAP);
}
+// Send T5577 reset command then read stream (see if we can identify the start of the stream)
+void T55xxResetRead(void) {
+ LED_A_ON();
+ //clear buffer now so it does not interfere with timing later
+ BigBuf_Clear_ext(false);
+
+ // Set up FPGA, 125kHz
+ LFSetupFPGAForADC(95, true);
+
+ // Trigger T55x7 in mode.
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelayUs(START_GAP);
+
+ // reset tag - op code 00
+ T55xxWriteBit(0);
+ T55xxWriteBit(0);
+
+ // Turn field on to read the response
+ TurnReadLFOn(READ_GAP);
+
+ // Acquisition
+ doT55x7Acquisition(BigBuf_max_traceLen());
+
+ // Turn the field off
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ cmd_send(CMD_ACK,0,0,0,0,0);
+ LED_A_OFF();
+}
+
// Write one card block in page 0, no lock
-void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
-{
+void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
+ LED_A_ON();
+ bool PwdMode = arg & 0x1;
+ uint8_t Page = (arg & 0x2)>>1;
uint32_t i = 0;
// Set up FPGA, 125kHz
- // Wait for config.. (192+8190xPOW)x8 == 67ms
- LFSetupFPGAForADC(0, true);
+ LFSetupFPGAForADC(95, true);
- // Now start writting
+ // Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
- // Opcode
+ // Opcode 10
T55xxWriteBit(1);
- T55xxWriteBit(0); //Page 0
- if (PwdMode == 1){
- // Pwd
+ T55xxWriteBit(Page); //Page 0
+ if (PwdMode){
+ // Send Pwd
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Pwd & i);
}
- // Lock bit
+ // Send Lock bit
T55xxWriteBit(0);
- // Data
+ // Send Data
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Data & i);
- // Block
+ // Send Block number
for (i = 0x04; i != 0; i >>= 1)
T55xxWriteBit(Block & i);
- // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
+ // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
// so wait a little more)
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- SpinDelay(20);
+ TurnReadLFOn(20 * 1000);
+ //could attempt to do a read to confirm write took
+ // as the tag should repeat back the new block
+ // until it is reset, but to confirm it we would
+ // need to know the current block 0 config mode
+
+ // turn field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LED_A_OFF();
}
-void TurnReadLFOn(){
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- // Give it a bit of time for the resonant antenna to settle.
- SpinDelayUs(8*150);
+// Write one card block in page 0, no lock
+void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
+ T55xxWriteBlockExt(Data, Block, Pwd, arg);
+ cmd_send(CMD_ACK,0,0,0,0,0);
}
-
// Read one card block in page 0
-void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
-{
+void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
+ LED_A_ON();
+ bool PwdMode = arg0 & 0x1;
+ uint8_t Page = (arg0 & 0x2) >> 1;
uint32_t i = 0;
- uint8_t *dest = BigBuf_get_addr();
- uint16_t bufferlength = BigBuf_max_traceLen();
- if ( bufferlength > T55xx_SAMPLES_SIZE )
- bufferlength = T55xx_SAMPLES_SIZE;
+ bool RegReadMode = (Block == 0xFF);
- // Clear destination buffer before sending the command
- memset(dest, 0x80, bufferlength);
+ //clear buffer now so it does not interfere with timing later
+ BigBuf_Clear_ext(false);
- // Set up FPGA, 125kHz
- // Wait for config.. (192+8190xPOW)x8 == 67ms
- LFSetupFPGAForADC(0, true);
+ //make sure block is at max 7
+ Block &= 0x7;
+
+ // Set up FPGA, 125kHz to power up the tag
+ LFSetupFPGAForADC(95, true);
+
+ // Trigger T55x7 Direct Access Mode with start gap
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
- // Opcode
+ // Opcode 1[page]
T55xxWriteBit(1);
- T55xxWriteBit(0); //Page 0
- if (PwdMode == 1){
- // Pwd
+ T55xxWriteBit(Page); //Page 0
+
+ if (PwdMode){
+ // Send Pwd
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Pwd & i);
}
- // Lock bit
+ // Send a zero bit separation
T55xxWriteBit(0);
- // Block
- for (i = 0x04; i != 0; i >>= 1)
- T55xxWriteBit(Block & i);
+
+ // Send Block number (if direct access mode)
+ if (!RegReadMode)
+ for (i = 0x04; i != 0; i >>= 1)
+ T55xxWriteBit(Block & i);
// Turn field on to read the response
- TurnReadLFOn();
- // Now do the acquisition
- i = 0;
- for(;;) {
- 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) {
- dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- i++;
- LED_D_OFF();
- if (i >= bufferlength) break;
- }
- }
+ TurnReadLFOn(READ_GAP);
- cmd_send(CMD_ACK,0,0,0,0,0);
+ // Acquisition
+ doT55x7Acquisition(12000);
+
+ // Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- LED_D_OFF();
+ cmd_send(CMD_ACK,0,0,0,0,0);
+ LED_A_OFF();
}
-// Read card traceability data (page 1)
-void T55xxReadTrace(void){
-
+void T55xxWakeUp(uint32_t Pwd){
+ LED_B_ON();
uint32_t i = 0;
- uint8_t *dest = BigBuf_get_addr();
- uint16_t bufferlength = BigBuf_max_traceLen();
- if ( bufferlength > T55xx_SAMPLES_SIZE )
- bufferlength= T55xx_SAMPLES_SIZE;
-
- // Clear destination buffer before sending the command
- memset(dest, 0x80, bufferlength);
-
- LFSetupFPGAForADC(0, true);
+
+ // Set up FPGA, 125kHz
+ LFSetupFPGAForADC(95, true);
+
+ // Trigger T55x7 Direct Access Mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
-
- // Opcode
+
+ // Opcode 10
T55xxWriteBit(1);
- T55xxWriteBit(1); //Page 1
+ T55xxWriteBit(0); //Page 0
- // Turn field on to read the response
- TurnReadLFOn();
+ // Send Pwd
+ for (i = 0x80000000; i != 0; i >>= 1)
+ T55xxWriteBit(Pwd & i);
- // Now do the acquisition
- for(;;) {
- 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) {
- dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- i++;
- LED_D_OFF();
+ // Turn and leave field on to let the begin repeating transmission
+ TurnReadLFOn(20*1000);
+}
- if (i >= bufferlength) break;
- }
- }
+/*-------------- Cloning routines -----------*/
- cmd_send(CMD_ACK,0,0,0,0,0);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- LED_D_OFF();
+void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
+ // write last block first and config block last (if included)
+ for (uint8_t i = numblocks+startblock; i > startblock; i--) {
+ //Dbprintf("write- Blk: %d, d:%08X",i-1,blockdata[i-1]);
+ T55xxWriteBlockExt(blockdata[i-1],i-1,0,0);
+ }
}
-/*-------------- Cloning routines -----------*/
// Copy HID id to card and setup block 0 config
-void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
-{
- int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format
- int last_block = 0;
+void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) {
+ uint32_t data[] = {0,0,0,0,0,0,0};
+ //int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format
+ uint8_t last_block = 0;
- if (longFMT){
+ if (longFMT) {
// Ensure no more than 84 bits supplied
if (hi2>0xFFFFF) {
DbpString("Tags can only have 84 bits.");
}
// Build the 6 data blocks for supplied 84bit ID
last_block = 6;
- data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded)
- for (int i=0;i<4;i++) {
- if (hi2 & (1<<(19-i)))
- data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10
- else
- data1 |= (1<<((3-i)*2)); // 0 -> 01
- }
-
- data2 = 0;
- for (int i=0;i<16;i++) {
- if (hi2 & (1<<(15-i)))
- data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data2 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data3 = 0;
- for (int i=0;i<16;i++) {
- if (hi & (1<<(31-i)))
- data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data3 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data4 = 0;
- for (int i=0;i<16;i++) {
- if (hi & (1<<(15-i)))
- data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data4 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data5 = 0;
- for (int i=0;i<16;i++) {
- if (lo & (1<<(31-i)))
- data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data5 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data6 = 0;
- for (int i=0;i<16;i++) {
- if (lo & (1<<(15-i)))
- data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data6 |= (1<<((15-i)*2)); // 0 -> 01
- }
- }
- else {
+ // load preamble (1D) & long format identifier (9E manchester encoded)
+ data[1] = 0x1D96A900 | (manchesterEncode2Bytes((hi2 >> 16) & 0xF) & 0xFF);
+ // load raw id from hi2, hi, lo to data blocks (manchester encoded)
+ data[2] = manchesterEncode2Bytes(hi2 & 0xFFFF);
+ data[3] = manchesterEncode2Bytes(hi >> 16);
+ data[4] = manchesterEncode2Bytes(hi & 0xFFFF);
+ data[5] = manchesterEncode2Bytes(lo >> 16);
+ data[6] = manchesterEncode2Bytes(lo & 0xFFFF);
+ } else {
// Ensure no more than 44 bits supplied
if (hi>0xFFF) {
DbpString("Tags can only have 44 bits.");
return;
}
-
// Build the 3 data blocks for supplied 44bit ID
last_block = 3;
-
- data1 = 0x1D000000; // load preamble
-
- for (int i=0;i<12;i++) {
- if (hi & (1<<(11-i)))
- data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
- else
- data1 |= (1<<((11-i)*2)); // 0 -> 01
- }
-
- data2 = 0;
- for (int i=0;i<16;i++) {
- if (lo & (1<<(31-i)))
- data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data2 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data3 = 0;
- for (int i=0;i<16;i++) {
- if (lo & (1<<(15-i)))
- data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data3 |= (1<<((15-i)*2)); // 0 -> 01
- }
+ // load preamble
+ data[1] = 0x1D000000 | (manchesterEncode2Bytes(hi) & 0xFFFFFF);
+ data[2] = manchesterEncode2Bytes(lo >> 16);
+ data[3] = manchesterEncode2Bytes(lo & 0xFFFF);
}
+ // load chip config block
+ data[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT;
+
+ //TODO add selection of chip for Q5 or T55x7
+ // data[0] = (((50-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | last_block << T5555_MAXBLOCK_SHIFT;
LED_D_ON();
// Program the data blocks for supplied ID
// and the block 0 for HID format
- T55xxWriteBlock(data1,1,0,0);
- T55xxWriteBlock(data2,2,0,0);
- T55xxWriteBlock(data3,3,0,0);
-
- if (longFMT) { // if long format there are 6 blocks
- T55xxWriteBlock(data4,4,0,0);
- T55xxWriteBlock(data5,5,0,0);
- T55xxWriteBlock(data6,6,0,0);
- }
-
- // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long)
- T55xxWriteBlock(T55x7_BITRATE_RF_50 |
- T55x7_MODULATION_FSK2a |
- last_block << T55x7_MAXBLOCK_SHIFT,
- 0,0,0);
+ WriteT55xx(data, 0, last_block+1);
LED_D_OFF();
DbpString("DONE!");
}
-void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT)
-{
- int data1=0, data2=0; //up to six blocks for long format
-
- data1 = hi; // load preamble
- data2 = lo;
+void CopyIOtoT55x7(uint32_t hi, uint32_t lo) {
+ uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo};
+ //TODO add selection of chip for Q5 or T55x7
+ // data[0] = (((64-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT;
LED_D_ON();
// Program the data blocks for supplied ID
- // and the block 0 for HID format
- T55xxWriteBlock(data1,1,0,0);
- T55xxWriteBlock(data2,2,0,0);
+ // and the block 0 config
+ WriteT55xx(data, 0, 3);
- //Config Block
- T55xxWriteBlock(0x00147040,0,0,0);
LED_D_OFF();
DbpString("DONE!");
}
+// Clone Indala 64-bit tag by UID to T55x7
+void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) {
+ //Program the 2 data blocks for supplied 64bit UID
+ // and the Config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2)
+ uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo};
+ //TODO add selection of chip for Q5 or T55x7
+ // data[0] = (((32-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT;
+
+ WriteT55xx(data, 0, 3);
+ //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
+ // T5567WriteBlock(0x603E1042,0);
+ DbpString("DONE!");
+}
+// 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) {
+ //Program the 7 data blocks for supplied 224bit UID
+ uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7};
+ // and the block 0 for Indala224 format
+ //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7)
+ data[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (7 << T55x7_MAXBLOCK_SHIFT);
+ //TODO add selection of chip for Q5 or T55x7
+ // data[0] = (((32-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_PSK1 | 7 << T5555_MAXBLOCK_SHIFT;
+ WriteT55xx(data, 0, 8);
+ //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
+ // T5567WriteBlock(0x603E10E2,0);
+ DbpString("DONE!");
+}
+
// Define 9bit header for EM410x tags
-#define EM410X_HEADER 0x1FF
+#define EM410X_HEADER 0x1FF
#define EM410X_ID_LENGTH 40
-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) {
int i, id_bit;
uint64_t id = EM410X_HEADER;
uint64_t rev_id = 0; // reversed ID
LED_D_ON();
// Write EM410x ID
- T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0);
- T55xxWriteBlock((uint32_t)id, 2, 0, 0);
-
- // Config for EM410x (RF/64, Manchester, Maxblock=2)
- if (card) {
- // Clock rate is stored in bits 8-15 of the card value
- clock = (card & 0xFF00) >> 8;
- Dbprintf("Clock rate: %d", clock);
- switch (clock)
- {
- case 32:
- clock = T55x7_BITRATE_RF_32;
- break;
- case 16:
- clock = T55x7_BITRATE_RF_16;
- break;
- case 0:
- // A value of 0 is assumed to be 64 for backwards-compatibility
- // Fall through...
- case 64:
- clock = T55x7_BITRATE_RF_64;
- break;
- default:
+ uint32_t data[] = {0, id>>32, id & 0xFFFFFFFF};
+
+ clock = (card & 0xFF00) >> 8;
+ clock = (clock == 0) ? 64 : clock;
+ Dbprintf("Clock rate: %d", clock);
+ if (card & 0xFF) { //t55x7
+ clock = GetT55xxClockBit(clock);
+ if (clock == 0) {
Dbprintf("Invalid clock rate: %d", clock);
return;
}
-
- // Writing configuration for T55x7 tag
- T55xxWriteBlock(clock |
- T55x7_MODULATION_MANCHESTER |
- 2 << T55x7_MAXBLOCK_SHIFT,
- 0, 0, 0);
+ data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT);
+ } else { //t5555 (Q5)
+ clock = (clock-2)>>1; //n = (RF-2)/2
+ data[0] = (clock << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
}
- else
- // Writing configuration for T5555(Q5) tag
- T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT |
- T5555_MODULATION_MANCHESTER |
- 2 << T5555_MAXBLOCK_SHIFT,
- 0, 0, 0);
+
+ WriteT55xx(data, 0, 3);
LED_D_OFF();
Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555",
(uint32_t)(id >> 32), (uint32_t)id);
}
-// Clone Indala 64-bit tag by UID to T55x7
-void CopyIndala64toT55x7(int hi, int lo)
-{
-
- //Program the 2 data blocks for supplied 64bit UID
- // and the block 0 for Indala64 format
- T55xxWriteBlock(hi,1,0,0);
- T55xxWriteBlock(lo,2,0,0);
- //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2)
- T55xxWriteBlock(T55x7_BITRATE_RF_32 |
- T55x7_MODULATION_PSK1 |
- 2 << T55x7_MAXBLOCK_SHIFT,
- 0, 0, 0);
- //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
- // T5567WriteBlock(0x603E1042,0);
-
- DbpString("DONE!");
-
-}
-
-void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7)
-{
-
- //Program the 7 data blocks for supplied 224bit UID
- // and the block 0 for Indala224 format
- T55xxWriteBlock(uid1,1,0,0);
- T55xxWriteBlock(uid2,2,0,0);
- T55xxWriteBlock(uid3,3,0,0);
- T55xxWriteBlock(uid4,4,0,0);
- T55xxWriteBlock(uid5,5,0,0);
- T55xxWriteBlock(uid6,6,0,0);
- T55xxWriteBlock(uid7,7,0,0);
- //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7)
- T55xxWriteBlock(T55x7_BITRATE_RF_32 |
- T55x7_MODULATION_PSK1 |
- 7 << T55x7_MAXBLOCK_SHIFT,
- 0,0,0);
- //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
- // T5567WriteBlock(0x603E10E2,0);
-
- DbpString("DONE!");
-
-}
-
-
-#define abs(x) ( ((x)<0) ? -(x) : (x) )
-#define max(x,y) ( x<y ? y:x)
-
-int DemodPCF7931(uint8_t **outBlocks) {
- uint8_t BitStream[256];
- uint8_t Blocks[8][16];
- uint8_t *GraphBuffer = BigBuf_get_addr();
- int GraphTraceLen = BigBuf_max_traceLen();
- 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, 0);
-
-
- lmin = 64;
- lmax = 192;
-
- i = 2;
-
- /* Find first local max/min */
- if(GraphBuffer[1] > GraphBuffer[0]) {
- while(i < GraphTraceLen) {
- if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax)
- break;
- i++;
- }
- dir = 0;
- }
- else {
- while(i < GraphTraceLen) {
- if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin)
- break;
- i++;
- }
- dir = 1;
- }
-
- lastval = i++;
- half_switch = 0;
- pmc = 0;
- block_done = 0;
-
- for (bitidx = 0; i < GraphTraceLen; i++)
- {
- if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[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) {
- BitStream[bitidx++] = 0;
- half_switch = 0;
- }
- else
- half_switch++;
- } else if (abs(lc-clock) < tolerance) {
- // 64TO
- BitStream[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*BitStream[j*8+7]+
- 64*BitStream[j*8+6]+
- 32*BitStream[j*8+5]+
- 16*BitStream[j*8+4]+
- 8*BitStream[j*8+3]+
- 4*BitStream[j*8+2]+
- 2*BitStream[j*8+1]+
- BitStream[j*8];
- }
- num_blocks++;
- }
- bitidx = 0;
- block_done = 0;
- half_switch = 0;
- }
- if(i < GraphTraceLen)
- {
- if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
- else dir = 1;
- }
- }
- if(bitidx==255)
- bitidx=0;
- warnings = 0;
- if(num_blocks == 4) break;
- }
- memcpy(outBlocks, Blocks, 16*num_blocks);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-
- 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;
-}
-
-#define ALLOC 16
-
-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("-----------------------------------------");
-
-
- return ;
-}
-
-
//-----------------------------------
// EM4469 / EM4305 routines
//-----------------------------------
LED_D_ON();
- //Field on
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
+ // Set up FPGA, 125kHz
+ LFSetupFPGAForADC(95, true);
// force 1st mod pulse (start gap must be longer for 4305)
fwd_bit_sz--; //prepare next bit modulation
uint8_t fwd_bit_count;
uint8_t *dest = BigBuf_get_addr();
- int m=0, i=0;
+ uint16_t bufferlength = BigBuf_max_traceLen();
+ uint32_t i = 0;
+
+ // Clear destination buffer before sending the command
+ memset(dest, 0x80, bufferlength);
//If password mode do login
if (PwdMode == 1) EM4xLogin(Pwd);
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
fwd_bit_count += Prepare_Addr( Address );
- m = BigBuf_max_traceLen();
- // Clear destination buffer before sending the command
- memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
i++;
- if (i >= m) break;
+ if (i >= bufferlength) break;
}
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ cmd_send(CMD_ACK,0,0,0,0,0);
LED_D_OFF();
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
-
-
-#define T0_PCF 8 //period for the pcf7931 in us
-
-/* 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;
-}
\ No newline at end of file
FpgaSetupSsc();
}
-
/**
* Does the sample acquisition. If threshold is specified, the actual sampling
* is not commenced until the threshold has been reached.
if ((trigger_threshold > 0) && (sample < (trigger_threshold+128)) && (sample > (128-trigger_threshold))) //
continue;
- //if (trigger_threshold > 0 && sample < trigger_threshold) //
- //continue;
-
trigger_threshold = 0;
sample_total_numbers++;
{
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;
+ }
+ }
+ }
+}
#ifndef 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.
* @return number of bits sampled
**/
void LFSetupFPGAForADC(int divisor, bool lf_field);
-
/**
* Called from the USB-handler to set the sampling configuration
* The sampling config is used for std reading and snooping.
--- /dev/null
+#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;
+}
--- /dev/null
+#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
//print ioprox ID and some format details
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;
//something in graphbuffer?
if (GraphTraceLen < 65) {
//print full AWID Prox ID and some bit format details if found
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};
size_t size = getFromGraphBuf(BitStream);
if (size==0) return 0;
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
- //uint32_t code2 = 0;
if (fmtLen==26){
fc = bytebits_to_byte(BitStream+73, 8);
cardnum = bytebits_to_byte(BitStream+81, 16);
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 */
int CmdLFCommandRead(const char *Cmd)
{
- static char dummy[3];
-
- dummy[0]= ' ';
-
+ static char dummy[3] = {0x20,0x00,0x00};
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));
- // in case they specified 'h'
+ bool errors = FALSE;
+ //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);
+
+ clearCommandBuffer();
SendCommand(&c);
return 0;
}
//And ship it to device
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
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;
}
static command_t CommandTable[] =
{
{"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... }"},
+ {"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"},
{"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)"},
{"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"},
{"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)"},
{"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"},
- {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
- {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"},
{NULL, NULL, 0, NULL}
};
}
// Check Clock
- if (card == 1)
- {
- // Default: 64
- if (clock == 0)
- clock = 64;
-
- // Allowed clock rates: 16, 32 and 64
- if ((clock != 16) && (clock != 32) && (clock != 64)) {
- PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32 and 64.\n", clock);
- return 0;
- }
- }
- else if (clock != 0)
- {
- PrintAndLog("Error! Clock rate is only supported on T55x7 tags.\n");
+ // Default: 64
+ if (clock == 0)
+ clock = 64;
+
+ // Allowed clock rates: 16, 32, 40 and 64
+ if ((clock != 16) && (clock != 32) && (clock != 64) && (clock != 40)) {
+ PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32, 40 and 64.\n", clock);
return 0;
}
// provide for backwards-compatibility for older firmware, and to avoid
// having to add another argument to CMD_EM410X_WRITE_TAG, we just store
// the clock rate in bits 8-15 of the card value
- card = (card & 0xFF) | (((uint64_t)clock << 8) & 0xFF00);
- }
- else if (card == 0)
+ card = (card & 0xFF) | ((clock << 8) & 0xFF00);
+ } else if (card == 0) {
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");
return 0;
}
//-----------------------------------------------------------------------------
// Low frequency PCF7931 commands
//-----------------------------------------------------------------------------
-
#include <stdio.h>
#include <string.h>
#include "proxmark3.h"
#include "ui.h"
+#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
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 CmdLFPCF7931Read(const char *Cmd)
-{
- UsbCommand c = {CMD_PCF7931_READ};
- SendCommand(&c);
- UsbCommand resp;
- WaitForResponse(CMD_ACK,&resp);
- 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 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 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 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);
- return 0;
- }
-
- PrintAndLog("INCORRECT FORMAT");
- return 0;
+ UsbCommand resp;
+ UsbCommand c = {CMD_PCF7931_READ, {0, 0, 0}};
+ clearCommandBuffer();
+ SendCommand(&c);
+ if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
+ PrintAndLog("command execution time out");
+ return 1;
+ }
+ 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[] =
{
- {"help", CmdHelp, 1, "This help"},
- {"read", CmdLFPCF7931Read, 1, "Read content of a PCF7931 transponder"},
- {"write", CmdLFPCF7931Write, 1, "Write data on a PCF7931 transponder. Usage : lf pcf7931 write <bloc address> <byte address> <data>"},
- {"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
- {NULL, NULL, 0, NULL}
+ {"help", CmdHelp, 1, "This help"},
+ {"read", CmdLFPCF7931Read, 0, "Read content of a PCF7931 transponder"},
+ {"write", CmdLFPCF7931Write, 0, "Write data on a PCF7931 transponder."},
+ {"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
+ {NULL, NULL, 0, NULL}
};
int CmdLFPCF7931(const char *Cmd)
{
- CmdsParse(CommandTable, Cmd);
- return 0;
+ CmdsParse(CommandTable, Cmd);
+ return 0;
}
int CmdHelp(const char *Cmd)
{
- CmdsHelp(CommandTable);
- return 0;
+ CmdsHelp(CommandTable);
+ return 0;
}
#define CMDLFPCF7931_H__
struct pcf7931_config{
- uint8_t password[7];
- uint16_t init_delay;
- int16_t offset[2];
+ uint8_t Pwd[7];
+ uint16_t InitDelay;
+ 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 CmdLFPCF7931Read(const char *Cmd);
-
int CmdLFPCF7931Write(const char *Cmd);
-
int CmdLFPCF7931Config(const char *Cmd);
#endif
\r
#define CONFIGURATION_BLOCK 0x00\r
#define TRACE_BLOCK 0x01\r
+#define REGULAR_READ_MODE_BLOCK 0xFF\r
\r
// Default configuration\r
t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00};\r
\r
+t55xx_conf_block_t Get_t55xx_Config(){\r
+ return config;\r
+}\r
+void Set_t55xx_Config(t55xx_conf_block_t conf){\r
+ config = conf;\r
+}\r
+\r
int usage_t55xx_config(){\r
PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>]");\r
- PrintAndLog("Options: ");\r
+ PrintAndLog("Options:");\r
PrintAndLog(" h This help");\r
PrintAndLog(" b <8|16|32|40|50|64|100|128> Set bitrate");\r
PrintAndLog(" d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");\r
return 0;\r
}\r
int usage_t55xx_read(){\r
- PrintAndLog("Usage: lf t55xx read <block> <password>");\r
- PrintAndLog(" <block>, block number to read. Between 0-7");\r
- PrintAndLog(" <password>, OPTIONAL password (8 hex characters)");\r
+ PrintAndLog("Usage: lf t55xx read [b <block>] [p <password>] <override_safety> <page1>");\r
+ PrintAndLog("Options:");\r
+ PrintAndLog(" b <block> - block number to read. Between 0-7");\r
+ PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");\r
+ PrintAndLog(" o - OPTIONAL override safety check");\r
+ PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0");\r
+ PrintAndLog(" ****WARNING****");\r
+ PrintAndLog(" Use of read with password on a tag not configured for a pwd");\r
+ PrintAndLog(" can damage the tag");\r
PrintAndLog("");\r
PrintAndLog("Examples:");\r
- PrintAndLog(" lf t55xx read 0 - read data from block 0");\r
- PrintAndLog(" lf t55xx read 0 feedbeef - read data from block 0 password feedbeef");\r
+ PrintAndLog(" lf t55xx read b 0 - read data from block 0");\r
+ PrintAndLog(" lf t55xx read b 0 p feedbeef - read data from block 0 password feedbeef");\r
+ PrintAndLog(" lf t55xx read b 0 p feedbeef o - read data from block 0 password feedbeef safety check");\r
PrintAndLog("");\r
return 0;\r
}\r
int usage_t55xx_write(){\r
- PrintAndLog("Usage: lf t55xx wr <block> <data> [password]");\r
- PrintAndLog(" <block>, block number to write. Between 0-7");\r
- PrintAndLog(" <data>, 4 bytes of data to write (8 hex characters)");\r
- PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)");\r
+ PrintAndLog("Usage: lf t55xx wr [b <block>] [d <data>] [p <password>] [1]");\r
+ PrintAndLog("Options:");\r
+ PrintAndLog(" b <block> - block number to write. Between 0-7");\r
+ PrintAndLog(" d <data> - 4 bytes of data to write (8 hex characters)");\r
+ PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");\r
+ PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");\r
PrintAndLog("");\r
PrintAndLog("Examples:");\r
- PrintAndLog(" lf t55xx wr 3 11223344 - write 11223344 to block 3");\r
- PrintAndLog(" lf t55xx wr 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef");\r
+ PrintAndLog(" lf t55xx wr b 3 d 11223344 - write 11223344 to block 3");\r
+ PrintAndLog(" lf t55xx wr b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef");\r
PrintAndLog("");\r
return 0;\r
}\r
int usage_t55xx_trace() {\r
PrintAndLog("Usage: lf t55xx trace [1]");\r
- PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
+ PrintAndLog("Options:");\r
+ PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");\r
PrintAndLog("");\r
PrintAndLog("Examples:");\r
PrintAndLog(" lf t55xx trace");\r
}\r
int usage_t55xx_info() {\r
PrintAndLog("Usage: lf t55xx info [1]");\r
- PrintAndLog(" [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
+ PrintAndLog("Options:");\r
+ PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");\r
PrintAndLog("");\r
PrintAndLog("Examples:");\r
PrintAndLog(" lf t55xx info");\r
return 0;\r
}\r
int usage_t55xx_dump(){\r
- PrintAndLog("Usage: lf t55xx dump <password>");\r
- PrintAndLog(" <password>, OPTIONAL password 4bytes (8 hex symbols)");\r
+ PrintAndLog("Usage: lf t55xx dump <password> [o]");\r
+ PrintAndLog("Options:");\r
+ PrintAndLog(" <password> - OPTIONAL password 4bytes (8 hex symbols)");\r
+ PrintAndLog(" o - OPTIONAL override, force pwd read despite danger to card");\r
PrintAndLog("");\r
PrintAndLog("Examples:");\r
PrintAndLog(" lf t55xx dump");\r
- PrintAndLog(" lf t55xx dump feedbeef");\r
+ PrintAndLog(" lf t55xx dump feedbeef o");\r
PrintAndLog("");\r
return 0;\r
}\r
int usage_t55xx_detect(){\r
- PrintAndLog("Usage: lf t55xx detect");\r
+ PrintAndLog("Usage: lf t55xx detect [1]");\r
+ PrintAndLog("Options:");\r
+ PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");\r
PrintAndLog("");\r
PrintAndLog("Examples:");\r
PrintAndLog(" lf t55xx detect");\r
PrintAndLog("");\r
return 0;\r
}\r
+int usage_t55xx_wakup(){\r
+ PrintAndLog("Usage: lf t55xx wakeup [h] p <password>");\r
+ PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");\r
+ PrintAndLog("Options:");\r
+ PrintAndLog(" h - this help");\r
+ PrintAndLog(" p <password> - password 4bytes (8 hex symbols)");\r
+ PrintAndLog("");\r
+ PrintAndLog("Examples:");\r
+ PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");\r
+ return 0;\r
+}\r
\r
static int CmdHelp(const char *Cmd);\r
\r
int CmdT55xxSetConfig(const char *Cmd) {\r
\r
uint8_t offset = 0;\r
- bool errors = FALSE;\r
- uint8_t cmdp = 0;\r
char modulation[5] = {0x00};\r
char tmp = 0x00;\r
uint8_t bitRate = 0;\r
uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};\r
+ uint8_t cmdp = 0;\r
+ bool errors = FALSE;\r
while(param_getchar(Cmd, cmdp) != 0x00 && !errors)\r
{\r
tmp = param_getchar(Cmd, cmdp);\r
}\r
\r
// No args\r
- if (cmdp == 0) {\r
- printConfiguration( config );\r
- return 0;\r
- }\r
+ if (cmdp == 0) return printConfiguration( config );\r
+\r
//Validations\r
- if (errors)\r
- return usage_t55xx_config();\r
+ if (errors) return usage_t55xx_config();\r
\r
- config.block0 = 0;\r
- printConfiguration ( config );\r
- return 0;\r
+ config.block0 = 0;\r
+ return printConfiguration ( config );\r
}\r
\r
-int CmdT55xxReadBlock(const char *Cmd) {\r
- int block = -1;\r
- int password = 0xFFFFFFFF; //default to blank Block 7\r
-\r
- char cmdp = param_getchar(Cmd, 0);\r
- if (cmdp == 'h' || cmdp == 'H')\r
- return usage_t55xx_read();\r
-\r
- int res = sscanf(Cmd, "%d %x", &block, &password);\r
+int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){\r
+ //Password mode\r
+ if ( usepwd ) {\r
+ // try reading the config block and verify that PWD bit is set before doing this!\r
+ if ( !override ) {\r
+ if ( !AquireData(0, CONFIGURATION_BLOCK, false, 0 ) ) return 0;\r
+ if ( !tryDetectModulation() ) {\r
+ PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");\r
+ return 0;\r
+ } else {\r
+ PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password..."); \r
+ usepwd = false;\r
+ page1 = false;\r
+ }\r
+ } else {\r
+ PrintAndLog("Safety Check Overriden - proceeding despite risk");\r
+ }\r
+ }\r
\r
- if ( res < 1 || res > 2 )\r
- return usage_t55xx_read();\r
+ if (!AquireData(page1, block, usepwd, password) ) return 0;\r
+ if (!DecodeT55xxBlock()) return 0;\r
\r
- \r
- if ((block < 0) | (block > 7)) {\r
- PrintAndLog("Block must be between 0 and 7");\r
- return 1;\r
- } \r
-\r
- UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}};\r
- c.d.asBytes[0] = 0x0; \r
+ char blk[10]={0};\r
+ sprintf(blk,"%d", block);\r
+ printT55xxBlock(blk); \r
+ return 1;\r
+}\r
\r
- //Password mode\r
- if ( res == 2 ) {\r
- c.arg[2] = password;\r
- c.d.asBytes[0] = 0x1; \r
+int CmdT55xxReadBlock(const char *Cmd) {\r
+ uint8_t block = REGULAR_READ_MODE_BLOCK;\r
+ uint32_t password = 0; //default to blank Block 7\r
+ bool usepwd = false;\r
+ bool override = false;\r
+ bool page1 = false;\r
+ bool errors = false;\r
+ uint8_t cmdp = 0;\r
+ while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
+ switch(param_getchar(Cmd, cmdp)) {\r
+ case 'h':\r
+ case 'H':\r
+ return usage_t55xx_read();\r
+ case 'b':\r
+ case 'B':\r
+ errors |= param_getdec(Cmd, cmdp+1, &block);\r
+ cmdp += 2;\r
+ break;\r
+ case 'o':\r
+ case 'O':\r
+ override = true;\r
+ cmdp++;\r
+ break;\r
+ case 'p':\r
+ case 'P':\r
+ password = param_get32ex(Cmd, cmdp+1, 0, 16);\r
+ usepwd = true;\r
+ cmdp += 2;\r
+ break;\r
+ case '1':\r
+ page1 = true;\r
+ cmdp++;\r
+ break;\r
+ default:\r
+ PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+ errors = true;\r
+ break;\r
+ }\r
}\r
+ if (errors) return usage_t55xx_read();\r
\r
- clearCommandBuffer();\r
- SendCommand(&c);\r
- if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
- PrintAndLog("command execution time out");\r
- return 2;\r
+ if (block > 7 && block != REGULAR_READ_MODE_BLOCK ) {\r
+ PrintAndLog("Block must be between 0 and 7");\r
+ return 0;\r
}\r
- \r
- uint8_t got[12000];\r
- GetFromBigBuf(got,sizeof(got),0);\r
- WaitForResponse(CMD_ACK,NULL);\r
- setGraphBuf(got, 12000);\r
- DemodBufferLen=0;\r
- if (!DecodeT55xxBlock()) return 3;\r
- char blk[10]={0};\r
- sprintf(blk,"%d", block);\r
- printT55xxBlock(blk);\r
- return 0;\r
+ PrintAndLog("Reading Page %d:", page1); \r
+ PrintAndLog("blk | hex data | binary");\r
+ return T55xxReadBlock(block, page1, usepwd, override, password);\r
}\r
\r
bool DecodeT55xxBlock(){\r
uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};\r
DemodBufferLen = 0x00;\r
\r
- //trim 1/2 a clock from beginning\r
- snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 );\r
- CmdLtrim(cmdStr);\r
switch( config.modulation ){\r
case DEMOD_FSK:\r
snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );\r
return usage_t55xx_detect();\r
\r
if (strlen(Cmd)==0)\r
- AquireData( CONFIGURATION_BLOCK );\r
+ if ( !AquireData(0, CONFIGURATION_BLOCK, false, 0) )\r
+ return 0;\r
\r
if ( !tryDetectModulation() )\r
PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");\r
\r
- return 0;\r
+ return 1;\r
}\r
\r
// detect configuration?\r
bool tryDetectModulation(){\r
- char cmdStr[8] = {0};\r
uint8_t hits = 0;\r
t55xx_conf_block_t tests[15];\r
int bitRate=0;\r
save_restoreGB(1);\r
if (GetFskClock("", FALSE, FALSE)){ \r
fskClocks(&fc1, &fc2, &clk, FALSE);\r
- sprintf(cmdStr,"%d", clk/2);\r
- CmdLtrim(cmdStr);\r
if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){\r
tests[hits].modulation = DEMOD_FSK;\r
if (fc1==8 && fc2 == 5)\r
} else {\r
clk = GetAskClock("", FALSE, FALSE);\r
if (clk>0) {\r
- sprintf(cmdStr,"%d", clk/2);\r
- CmdLtrim(cmdStr);\r
if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {\r
tests[hits].modulation = DEMOD_ASK;\r
tests[hits].bitrate = bitRate;\r
save_restoreGB(0);\r
clk = GetNrzClock("", FALSE, FALSE);\r
if (clk>0) {\r
- sprintf(cmdStr,"%d", clk/2);\r
- CmdLtrim(cmdStr);\r
if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {\r
tests[hits].modulation = DEMOD_NRZ;\r
tests[hits].bitrate = bitRate;\r
save_restoreGB(0);\r
clk = GetPskClock("", FALSE, FALSE);\r
if (clk>0) {\r
- PrintAndLog("clk %d",clk);\r
- sprintf(cmdStr,"%d", clk/2);\r
- CmdLtrim(cmdStr); \r
if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {\r
tests[hits].modulation = DEMOD_PSK1;\r
tests[hits].bitrate = bitRate;\r
bool testModulation(uint8_t mode, uint8_t modread){\r
switch( mode ){\r
case DEMOD_FSK:\r
- if (modread > 3 && modread < 8) return TRUE;\r
+ if (modread >= DEMOD_FSK1 && modread <= DEMOD_FSK2a) return TRUE;\r
break;\r
case DEMOD_ASK:\r
if (modread == DEMOD_ASK) return TRUE;\r
bits[i - config.offset]=DemodBuffer[i];\r
\r
blockData = PackBits(0, 32, bits);\r
- PrintAndLog("[%s] 0x%08X %s", blockNum, blockData, sprint_bin(bits,32));\r
+ PrintAndLog(" %s | %08X | %s", blockNum, blockData, sprint_bin(bits,32));\r
}\r
\r
int special(const char *Cmd) {\r
uint32_t blockData = 0;\r
uint8_t bits[32] = {0x00};\r
\r
- PrintAndLog("[OFFSET] [DATA] [BINARY]");\r
+ PrintAndLog("OFFSET | DATA | BINARY");\r
PrintAndLog("----------------------------------------------------");\r
int i,j = 0;\r
for (; j < 64; ++j){\r
\r
blockData = PackBits(0, 32, bits);\r
\r
- PrintAndLog("[%02d] 0x%08X %s",j , blockData, sprint_bin(bits,32)); \r
+ PrintAndLog(" %02d | 0x%08X | %s",j , blockData, sprint_bin(bits,32)); \r
}\r
return 0;\r
}\r
\r
-void printConfiguration( t55xx_conf_block_t b){\r
+int printConfiguration( t55xx_conf_block_t b){\r
PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );\r
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );\r
PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );\r
PrintAndLog("Offset : %d", b.offset);\r
PrintAndLog("Block0 : 0x%08X", b.block0);\r
PrintAndLog("");\r
+ return 0;\r
}\r
\r
-int CmdT55xxWriteBlock(const char *Cmd)\r
-{\r
- int block = 8; //default to invalid block\r
- int data = 0xFFFFFFFF; //default to blank Block \r
- int password = 0xFFFFFFFF; //default to blank Block 7\r
- \r
- char cmdp = param_getchar(Cmd, 0);\r
- if (cmdp == 'h' || cmdp == 'H') {\r
- usage_t55xx_write();\r
- return 0;\r
+int CmdT55xxWakeUp(const char *Cmd) {\r
+ uint32_t password = 0;\r
+ uint8_t cmdp = 0;\r
+ bool errors = true;\r
+ while(param_getchar(Cmd, cmdp) != 0x00) {\r
+ switch(param_getchar(Cmd, cmdp)) {\r
+ case 'h':\r
+ case 'H':\r
+ return usage_t55xx_wakup();\r
+ case 'p':\r
+ case 'P':\r
+ password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16);\r
+ cmdp += 2;\r
+ errors = false;\r
+ break;\r
+ default:\r
+ PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+ errors = true;\r
+ break;\r
+ }\r
}\r
- \r
- int res = sscanf(Cmd, "%d %x %x",&block, &data, &password);\r
- \r
- if ( res < 2 || res > 3) {\r
- usage_t55xx_write();\r
- return 1;\r
+ if (errors) return usage_t55xx_wakup();\r
+\r
+ UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}};\r
+ clearCommandBuffer();\r
+ SendCommand(&c);\r
+ PrintAndLog("Wake up command sent. Try read now");\r
+ return 0;\r
+}\r
+\r
+int CmdT55xxWriteBlock(const char *Cmd) {\r
+ uint8_t block = 0xFF; //default to invalid block\r
+ uint32_t data = 0xFFFFFFFF; //default to blank Block \r
+ uint32_t password = 0xFFFFFFFF; //default to blank Block 7\r
+ bool usepwd = false;\r
+ bool page1 = false; \r
+ bool gotdata = false;\r
+ bool errors = false;\r
+ uint8_t cmdp = 0;\r
+ while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
+ switch(param_getchar(Cmd, cmdp)) {\r
+ case 'h':\r
+ case 'H':\r
+ return usage_t55xx_write();\r
+ case 'b':\r
+ case 'B':\r
+ errors |= param_getdec(Cmd, cmdp+1, &block);\r
+ cmdp += 2;\r
+ break;\r
+ case 'd':\r
+ case 'D':\r
+ data = param_get32ex(Cmd, cmdp+1, 0, 16);\r
+ gotdata = true;\r
+ cmdp += 2;\r
+ break;\r
+ case 'p':\r
+ case 'P':\r
+ password = param_get32ex(Cmd, cmdp+1, 0, 16);\r
+ usepwd = true;\r
+ cmdp += 2;\r
+ break;\r
+ case '1':\r
+ page1 = true;\r
+ cmdp++;\r
+ break;\r
+ default:\r
+ PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+ errors = true;\r
+ break;\r
+ }\r
}\r
+ if (errors || !gotdata) return usage_t55xx_write();\r
\r
if (block > 7) {\r
PrintAndLog("Block number must be between 0 and 7");\r
- return 1;\r
+ return 0;\r
}\r
\r
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
UsbCommand resp;\r
- c.d.asBytes[0] = 0x0; \r
+ c.d.asBytes[0] = (page1) ? 0x2 : 0; \r
\r
- PrintAndLog("Writing to block: %d data : 0x%08X", block, data);\r
+ PrintAndLog("Writing to page: %d block: %d data : 0x%08X", page1, block, data);\r
\r
//Password mode\r
- if (res == 3) {\r
+ if (usepwd) {\r
c.arg[2] = password;\r
- c.d.asBytes[0] = 0x1; \r
+ c.d.asBytes[0] |= 0x1; \r
PrintAndLog("pwd : 0x%08X", password);\r
}\r
clearCommandBuffer();\r
SendCommand(&c);\r
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){\r
PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");\r
- return -1;\r
+ return 0;\r
}\r
- return 0;\r
+ return 1;\r
}\r
\r
-int CmdT55xxReadTrace(const char *Cmd)\r
-{\r
+int CmdT55xxReadTrace(const char *Cmd) {\r
char cmdp = param_getchar(Cmd, 0);\r
- \r
+ bool pwdmode = false;\r
+ uint32_t password = 0;\r
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') \r
return usage_t55xx_trace();\r
\r
if (strlen(Cmd)==0)\r
- AquireData( TRACE_BLOCK );\r
+ if ( !AquireData( TRACE_BLOCK, REGULAR_READ_MODE_BLOCK, pwdmode, password ) )\r
+ return 0;\r
\r
- if (!DecodeT55xxBlock()) return 1;\r
+ if (!DecodeT55xxBlock()) return 0;\r
+\r
+ if ( !DemodBufferLen) return 0;\r
\r
- if ( !DemodBufferLen) return 1;\r
- \r
RepaintGraphWindow();\r
uint8_t repeat = 0;\r
if (config.offset > 5) \r
repeat = 32;\r
uint8_t si = config.offset+repeat;\r
- uint32_t bl0 = PackBits(si, 32, DemodBuffer);\r
- uint32_t bl1 = PackBits(si+32, 32, DemodBuffer);\r
+ uint32_t bl1 = PackBits(si, 32, DemodBuffer);\r
+ uint32_t bl2 = PackBits(si+32, 32, DemodBuffer);\r
\r
uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8;\r
uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8;\r
\r
if ( acl != 0xE0 ) {\r
PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");\r
- return 1;\r
+ return 0;\r
}\r
\r
PrintAndLog("");\r
PrintAndLog(" Die Number : %d", dw);\r
PrintAndLog("-------------------------------------------------------------");\r
PrintAndLog(" Raw Data - Page 1");\r
- PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(DemodBuffer+config.offset+repeat,32) );\r
- PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );\r
+ PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) );\r
+ PrintAndLog(" Block 2 : 0x%08X %s", bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );\r
PrintAndLog("-------------------------------------------------------------");\r
\r
/*\r
Normal mode\r
Extended mode\r
*/\r
+ bool pwdmode = false;\r
+ uint32_t password = 0;\r
char cmdp = param_getchar(Cmd, 0);\r
\r
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')\r
return usage_t55xx_info();\r
\r
if (strlen(Cmd)==0)\r
- AquireData( CONFIGURATION_BLOCK );\r
+ if ( !AquireData( 0, CONFIGURATION_BLOCK, pwdmode, password ) )\r
+ return 1;\r
\r
if (!DecodeT55xxBlock()) return 1;\r
\r
\r
int CmdT55xxDump(const char *Cmd){\r
\r
- char s[20] = {0x00};\r
- uint8_t pwd[4] = {0x00};\r
-\r
+ uint32_t password = 0;\r
char cmdp = param_getchar(Cmd, 0);\r
- if ( cmdp == 'h' || cmdp == 'H') {\r
- usage_t55xx_dump();\r
- return 0;\r
- }\r
-\r
- bool hasPwd = ( strlen(Cmd) > 0); \r
- if ( hasPwd ){\r
- if (param_gethex(Cmd, 0, pwd, 8)) {\r
- PrintAndLog("password must include 8 HEX symbols");\r
- return 1;\r
- }\r
+ bool override = false;\r
+ if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump();\r
+\r
+ bool usepwd = ( strlen(Cmd) > 0); \r
+ if ( usepwd ){\r
+ password = param_get32ex(Cmd, 0, 0, 16);\r
+ if (param_getchar(Cmd, 1) =='o' )\r
+ override = true;\r
}\r
\r
- for ( int i = 0; i <8; ++i){\r
- memset(s,0,sizeof(s));\r
+ PrintAndLog("Reading Page 0:"); \r
+ PrintAndLog("blk | hex data | binary");\r
+ for ( uint8_t i = 0; i <8; ++i){\r
+ T55xxReadBlock(i, 0, usepwd, override, password);\r
+ /*memset(s,0,sizeof(s));\r
if ( hasPwd ) {\r
- sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);\r
+ if ( override ) {\r
+ sprintf(s,"b %d p %02x%02x%02x%02x o", i, pwd[0],pwd[1],pwd[2],pwd[3]); \r
+ } else {\r
+ sprintf(s,"b %d p %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]); \r
+ }\r
} else {\r
- sprintf(s,"%d", i);\r
+ sprintf(s,"b %d", i);\r
}\r
- CmdT55xxReadBlock(s);\r
+ CmdT55xxReadBlock(s);*/\r
}\r
- return 0;\r
+ PrintAndLog("Reading Page 1:"); \r
+ PrintAndLog("blk | hex data | binary");\r
+ for ( uint8_t i = 0; i<4; i++){\r
+ T55xxReadBlock(i, 1, usepwd, override, password); \r
+ }\r
+ return 1;\r
}\r
\r
-int AquireData( uint8_t block ){\r
-\r
- UsbCommand c;\r
- \r
- if ( block == CONFIGURATION_BLOCK ) \r
- c.cmd = CMD_T55XX_READ_BLOCK;\r
- else if (block == TRACE_BLOCK )\r
- c.cmd = CMD_T55XX_READ_TRACE;\r
- \r
- c.arg[0] = 0x00;\r
- c.arg[1] = 0x00;\r
- c.arg[2] = 0x00;\r
- c.d.asBytes[0] = 0x0; \r
+int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){\r
\r
- //Password mode\r
- // if ( res == 2 ) {\r
- // c.arg[2] = password;\r
- // c.d.asBytes[0] = 0x1; \r
- // }\r
+ uint8_t arg0 = (page<<1) | pwdmode;\r
+ UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};\r
\r
clearCommandBuffer();\r
SendCommand(&c);\r
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
PrintAndLog("command execution time out");\r
- return 1;\r
+ return 0;\r
}\r
\r
uint8_t got[12000];\r
GetFromBigBuf(got,sizeof(got),0);\r
WaitForResponse(CMD_ACK,NULL);\r
- setGraphBuf(got, 12000);\r
- return 0;\r
+ setGraphBuf(got, sizeof(got));\r
+ return 1;\r
}\r
\r
char * GetBitRateStr(uint32_t id){\r
return tmp;\r
}\r
\r
+int CmdResetRead(const char *Cmd) {\r
+ UsbCommand c = {CMD_T55XX_RESET_READ, {0,0,0}};\r
+\r
+ clearCommandBuffer();\r
+ SendCommand(&c);\r
+ if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
+ PrintAndLog("command execution time out");\r
+ return 0;\r
+ }\r
+\r
+ uint8_t got[BIGBUF_SIZE-1];\r
+ GetFromBigBuf(got,sizeof(got),0);\r
+ WaitForResponse(CMD_ACK,NULL);\r
+ setGraphBuf(got, sizeof(got));\r
+ return 1;\r
+}\r
+\r
static command_t CommandTable[] =\r
{\r
- {"help", CmdHelp, 1, "This help"},\r
- {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
- {"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."},\r
- {"read", CmdT55xxReadBlock, 0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"},\r
- {"write", CmdT55xxWriteBlock,0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"},\r
- {"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},\r
- {"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"},\r
- {"dump", CmdT55xxDump, 0, "[password] Dump T55xx card block 0-7. [optional password]"},\r
- {"special", special, 0, "Show block changes with 64 different offsets"},\r
+ {"help", CmdHelp, 1, "This help"},\r
+ {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
+ {"detect", CmdT55xxDetect, 0, "[1] Try detecting the tag modulation from reading the configuration block."},\r
+ {"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},\r
+ {"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)"},\r
+ {"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},\r
+ {"trace", CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},\r
+ {"info", CmdT55xxInfo, 0, "[1] Show T55xx configuration data (page 0/ blk 0)"},\r
+ {"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},\r
+ {"special", special, 0, "Show block changes with 64 different offsets"},\r
+ {"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},\r
{NULL, NULL, 0, NULL}\r
};\r
\r
RF_128 = 0x07,\r
} bitrate;\r
} t55xx_conf_block_t;\r
+t55xx_conf_block_t Get_t55xx_Config();\r
+void Set_t55xx_Config(t55xx_conf_block_t conf);\r
+\r
\r
int CmdLFT55XX(const char *Cmd);\r
int CmdT55xxSetConfig(const char *Cmd);\r
int CmdT55xxReadTrace(const char *Cmd);\r
int CmdT55xxInfo(const char *Cmd);\r
int CmdT55xxDetect(const char *Cmd);\r
+int CmdResetRead(const char *Cmd);\r
\r
char * GetBitRateStr(uint32_t id);\r
char * GetSaferStr(uint32_t id);\r
char * GetSelectedModulationStr( uint8_t id);\r
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bitstream);\r
void printT55xxBlock(const char *demodStr);\r
-void printConfiguration( t55xx_conf_block_t b);\r
+int printConfiguration( t55xx_conf_block_t b);\r
\r
bool DecodeT55xxBlock();\r
bool tryDetectModulation();\r
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate);\r
int special(const char *Cmd);\r
-int AquireData( uint8_t block );\r
+int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );\r
\r
#endif\r
#define CMD_INDALA_CLONE_TAG_L 0x0213
#define CMD_T55XX_READ_BLOCK 0x0214
#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_EM4X_READ_WORD 0x0218
#define CMD_EM4X_WRITE_WORD 0x0219
#define CMD_ASK_SIM_TAG 0x021F
#define CMD_PSK_SIM_TAG 0x0220
#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_INDALA_CLONE_TAG_L = 0x0213,
CMD_T55XX_READ_BLOCK = 0x0214,
CMD_T55XX_WRITE_BLOCK = 0x0215,
- CMD_T55XX_READ_TRACE = 0x0216,
+ CMD_T55XX_RESET_READ = 0x0216,
CMD_PCF7931_READ = 0x0217,
CMD_EM4X_READ_WORD = 0x0218,
CMD_EM4X_WRITE_WORD = 0x0219,
CMD_ASK_SIM_TAG = 0x021F,
CMD_PSK_SIM_TAG = 0x0220,
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 */
--// For the 13.56 MHz tags
#include "util.h"
#include "nonce2key/nonce2key.h"
#include "../common/iso15693tools.h"
+#include "iso14443crc.h"
#include "../common/crc16.h"
#include "../common/crc64.h"
#include "../common/sha1.h"
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.
params: key, input
{"clearCommandBuffer", l_clearCommandBuffer},
{"console", l_CmdConsole},
{"iso15693_crc", l_iso15693_crc},
+ {"iso14443b_crc", l_iso14443b_crc},
{"aes128_decrypt", l_aes128decrypt_cbc},
{"aes128_decrypt_ecb", l_aes128decrypt_ecb},
{"aes128_encrypt", l_aes128encrypt_cbc},
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
//encode binary data into binary manchester
int ManchesterEncode(uint8_t *BitStream, size_t size)
if (fclow==0) fclow=8;
//set the threshold close to 0 (graph) or 128 std to avoid static
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
// Need to threshold first sample
// Check for 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
- } 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;
- } 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
- } 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;
}
last_transition = idx;
int DetectNRZClock(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);
-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 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 manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert);
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
//tag specific
-int FDXBdemodBI(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 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 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 PyramiddemodFSK(uint8_t *dest, size_t *size);
#endif
#include <stdint.h>
#include <stdarg.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
#include "ui.h"
#define prnt PrintAndLog
-#endif
-
-
+// iclass / picopass chip config structures and shared routines
typedef struct {
uint8_t app_limit; //[8]
uint8_t otp[2]; //[9-10]
uint8_t mem_config; //[13]
uint8_t eas; //[14]
uint8_t fuses; //[15]
-}picopass_conf_block;
-
+} picopass_conf_block;
typedef struct {
uint8_t csn[8];
uint8_t key_d[8];
uint8_t key_c[8];
uint8_t app_issuer_area[8];
+} picopass_hdr;
-}picopass_hdr;
-
-
-//#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)
-{
+uint8_t isset(uint8_t val, uint8_t 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);
}
-void fuse_config(const picopass_hdr *hdr)
-{
+void fuse_config(const picopass_hdr *hdr) {
uint8_t fuses = hdr->conf.fuses;
if (isset(fuses,FUSE_FPERS))prnt(" Mode: Personalization [Programmable]");
}
}
-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 chip = hdr->conf.chip_config;
uint8_t applimit = hdr->conf.app_limit;
prnt(" AA1: blocks 06-%02X", applimit);
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);
mem_app_config(hdr);
}
-void printIclassDumpInfo(uint8_t* iclass_dump)
-{
-// picopass_hdr hdr;
-// memcpy(&hdr, iclass_dump, sizeof(picopass_hdr));
+void printIclassDumpInfo(uint8_t* 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};
prnt("Picopass configuration:");
print_picopass_info(&hdr);
}
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
test();
return 0;
}
*/
+
+#endif
+//ON_DEVICE
#define FUSE_FPROD0 0x02
#define FUSE_RA 0x01
-
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);
-#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
#define CMD_INDALA_CLONE_TAG_L 0x0213
#define CMD_T55XX_READ_BLOCK 0x0214
#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_WRITE 0x0222
#define CMD_EM4X_READ_WORD 0x0218
#define CMD_ASK_SIM_TAG 0x021F
#define CMD_PSK_SIM_TAG 0x0220
#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 */