Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion armsrc/appmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,15 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_HID_SIM_TAG:
CmdHIDsimTAG(c->arg[0], c->arg[1], 1); // Simulate HID tag by ID
break;
case CMD_HID_CLONE_TAG: // Clone HID tag by ID to T55x7
case CMD_HID_CLONE_TAG: // Clone HID tag by ID to T55x7
CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
break;
case CMD_IO_DEMOD_FSK:
CmdIOdemodFSK(1, 0, 0, 1); // Demodulate IO tag
break;
case CMD_IO_CLONE_TAG: // Clone IO tag by ID to T55x7
CopyIOtoT55x7(c->arg[0], c->arg[1], c->d.asBytes[0]);
break;
case CMD_EM410X_WRITE_TAG:
WriteEM410x(c->arg[0], c->arg[1], c->arg[2]);
break;
Expand Down
2 changes: 2 additions & 0 deletions armsrc/apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ void AcquireRawBitsTI(void);
void SimulateTagLowFrequency(int period, int gap, int ledcontrol);
void CmdHIDsimTAG(int hi, int lo, int ledcontrol);
void CmdHIDdemodFSK(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 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);
Expand Down
278 changes: 278 additions & 0 deletions armsrc/lfops.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,264 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
}
}

void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
uint8_t *dest = (uint8_t *)BigBuf;
int m=0, n=0, i=0, idx=0, lastval=0;
int found=0;
uint32_t code=0, code2=0;
//uint32_t hi2=0, hi=0, lo=0;

FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);

// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);

// Give it a bit of time for the resonant antenna to settle.
SpinDelay(50);

// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();

for(;;) {
WDT_HIT();
if (ledcontrol)
LED_A_ON();
if(BUTTON_PRESS()) {
DbpString("Stopped");
if (ledcontrol)
LED_A_OFF();
return;
}

i = 0;
m = sizeof(BigBuf);
memset(dest,128,m);
for(;;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x43;
if (ledcontrol)
LED_D_ON();
}
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// we don't care about actual value, only if it's more or less than a
// threshold essentially we capture zero crossings for later analysis
if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
i++;
if (ledcontrol)
LED_D_OFF();
if(i >= m) {
break;
}
}
}

// FSK demodulator

// sync to first lo-hi transition
for( idx=1; idx<m; idx++) {
if (dest[idx-1]<dest[idx])
lastval=idx;
break;
}
WDT_HIT();

// count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
// or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
// between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
for( i=0; idx<m; idx++) {
if (dest[idx-1]<dest[idx]) {
dest[i]=idx-lastval;
if (dest[i] <= 8) {
dest[i]=1;
} else {
dest[i]=0;
}

lastval=idx;
i++;
}
}
m=i;
WDT_HIT();

// we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
lastval=dest[0];
idx=0;
i=0;
n=0;
for( idx=0; idx<m; idx++) {
if (dest[idx]==lastval) {
n++;
} else {
// a bit time is five fc/10 or six fc/8 cycles so figure out how many bits a pattern width represents,
// an extra fc/8 pattern preceeds every 4 bits (about 200 cycles) just to complicate things but it gets
// swallowed up by rounding
// expected results are 1 or 2 bits, any more and it's an invalid manchester encoding
// special start of frame markers use invalid manchester states (no transitions) by using sequences
// like 111000
if (dest[idx-1]) {
n=(n+1)/7; // fc/8 in sets of 7
} else {
n=(n+1)/6; // fc/10 in sets of 6
}
switch (n) { // stuff appropriate bits in buffer
case 0:
case 1: // one bit
dest[i++]=dest[idx-1]^1;
//Dbprintf("%d",dest[idx-1]);
break;
case 2: // two bits
dest[i++]=dest[idx-1]^1;
dest[i++]=dest[idx-1]^1;
//Dbprintf("%d",dest[idx-1]);
//Dbprintf("%d",dest[idx-1]);
break;
case 3: // 3 bit start of frame markers
for(int j=0; j<3; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 4:
for(int j=0; j<4; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 5:
for(int j=0; j<5; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 6:
for(int j=0; j<6; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 7:
for(int j=0; j<7; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 8:
for(int j=0; j<8; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 9:
for(int j=0; j<9; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 10:
for(int j=0; j<10; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 11:
for(int j=0; j<11; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
case 12:
for(int j=0; j<12; j++){
dest[i++]=dest[idx-1]^1;
// Dbprintf("%d",dest[idx-1]);
}
break;
default: // this shouldn't happen, don't stuff any bits
//Dbprintf("%d",dest[idx-1]);
break;
}
n=0;
lastval=dest[idx];
}
}//end for
/*for(int j=0; j<64;j+=8){
Dbprintf("%d%d%d%d%d%d%d%d",dest[j],dest[j+1],dest[j+2],dest[j+3],dest[j+4],dest[j+5],dest[j+6],dest[j+7]);
}
Dbprintf("\n");*/
m=i;
WDT_HIT();

for( idx=0; idx<m-9; idx++) {
if ( !(dest[idx]) && !(dest[idx+1]) && !(dest[idx+2]) && !(dest[idx+3]) && !(dest[idx+4]) && !(dest[idx+5]) && !(dest[idx+6]) && !(dest[idx+7]) && !(dest[idx+8])&& (dest[idx+9])){
found=1;
//idx+=9;
if (found) {
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+8], dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+16],dest[idx+17],dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+24],dest[idx+25],dest[idx+26],dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35],dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44],dest[idx+45],dest[idx+46],dest[idx+47]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53],dest[idx+54],dest[idx+55]);
Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);

short version='\x00';
char unknown='\x00';
uint16_t number=0;
for(int j=14;j<18;j++){
//Dbprintf("%d",dest[idx+j]);
version <<=1;
if (dest[idx+j]) version |= 1;
}
for(int j=19;j<27;j++){
//Dbprintf("%d",dest[idx+j]);
unknown <<=1;
if (dest[idx+j]) unknown |= 1;
}
for(int j=36;j<45;j++){
//Dbprintf("%d",dest[idx+j]);
number <<=1;
if (dest[idx+j]) number |= 1;
}
for(int j=46;j<53;j++){
//Dbprintf("%d",dest[idx+j]);
number <<=1;
if (dest[idx+j]) number |= 1;
}
for(int j=0; j<32; j++){
code <<=1;
if(dest[idx+j]) code |= 1;
}
for(int j=32; j<64; j++){
code2 <<=1;
if(dest[idx+j]) code2 |= 1;
}

Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,unknown,number,code,code2);
if (ledcontrol)
LED_D_OFF();
}
// if we're only looking for one tag
if (findone){
//*high = hi;
//*low = lo;
LED_A_OFF();
return;
}

//hi=0;
//lo=0;
found=0;
}

}
}
WDT_HIT();
}

/*------------------------------
* T5555/T5557/T5567 routines
*------------------------------
Expand Down Expand Up @@ -1166,6 +1424,26 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
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;

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);

//Config Block
T55xxWriteBlock(0x00147040,0,0,0);
LED_D_OFF();

DbpString("DONE!");
}

// Define 9bit header for EM410x tags
#define EM410X_HEADER 0x1FF
#define EM410X_ID_LENGTH 40
Expand Down
1 change: 1 addition & 0 deletions client/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ CMDSRCS = nonce2key/crapto1.c\
cmdhw.c \
cmdlf.c \
cmdlfhid.c \
cmdlfio.c \
cmdlfem4x.c \
cmdlfhitag.c \
cmdlfti.c \
Expand Down
4 changes: 3 additions & 1 deletion client/cmdlf.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "cmdlfhitag.h"
#include "cmdlft55xx.h"
#include "cmdlfpcf7931.h"
#include "cmdlfio.h"

static int CmdHelp(const char *Cmd);

Expand Down Expand Up @@ -128,7 +129,7 @@ int CmdFlexdemod(const char *Cmd)
RepaintGraphWindow();
return 0;
}

int CmdIndalaDemod(const char *Cmd)
{
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
Expand Down Expand Up @@ -532,6 +533,7 @@ static command_t CommandTable[] =
{"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"indalaclone", CmdIndalaClone, 1, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
{"read", CmdLFRead, 0, "['h'|<divisor>] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"},
Expand Down
2 changes: 2 additions & 0 deletions include/usb_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ typedef struct {
#define CMD_PCF7931_READ 0x0217
#define CMD_EM4X_READ_WORD 0x0218
#define CMD_EM4X_WRITE_WORD 0x0219
#define CMD_IO_DEMOD_FSK 0x021A
#define CMD_IO_CLONE_TAG 0x021B
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */

// For the 13.56 MHz tags
Expand Down