mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-06 13:11:18 -07:00
Issue 20 patch (refactored code of the iso15693 implementation as well as several enhancements) [Adrian Dabrowski "atrox"]
This commit is contained in:
parent
6c1e2d95f4
commit
9455b51c2a
14 changed files with 1902 additions and 656 deletions
|
@ -87,4 +87,24 @@ macport stuff should do ;)
|
|||
= Linux =
|
||||
============
|
||||
|
||||
1 - Download
|
||||
|
||||
A precompiled DevKitARM cross compiler tool chain package can be found at
|
||||
http://sourceforge.net/projects/devkitpro/files/devkitARM
|
||||
Select the one you need (32bit or 64bit) and unpack to a convinient place, eg
|
||||
$HOME/proxmark3/. It will create a devkitARM/ subdirectory.
|
||||
|
||||
Of course, you will need a general compiling environment on your computer for
|
||||
the client and the libusb headers. In most distributions you will get all you
|
||||
need with the lsb-package (Linux Standard Base). In debian/ubuntu you simply
|
||||
call `aptitude install lsb libusb-dev`.
|
||||
|
||||
For the graphical plot view, you might need the qtlibs (debian/ubuntu:
|
||||
libqt4-dev), too.
|
||||
|
||||
2 - Set Environment
|
||||
|
||||
export DEVKITPRO=$HOME/proxmark3/
|
||||
export DEVKITARM=$DEVKITPRO/devkitARM
|
||||
export PATH=${PATH}:${DEVKITARM}/bin
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ APP_CFLAGS = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b
|
|||
|
||||
#SRC_LCD = fonts.c LCD.c
|
||||
SRC_LF = lfops.c hitag2.c
|
||||
SRC_ISO15693 = iso15693.c
|
||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||
SRC_ISO14443a = iso14443a.c
|
||||
SRC_ISO14443b = iso14443.c
|
||||
|
||||
|
|
|
@ -124,6 +124,29 @@ void Dbprintf(const char *fmt, ...) {
|
|||
DbpString(output_string);
|
||||
}
|
||||
|
||||
// prints HEX & ASCII
|
||||
void Dbhexdump(int len, uint8_t *d) {
|
||||
int l=0,i;
|
||||
char ascii[9];
|
||||
|
||||
while (len>0) {
|
||||
if (len>8) l=8;
|
||||
else l=len;
|
||||
|
||||
memcpy(ascii,d,l);
|
||||
ascii[l]=0;
|
||||
|
||||
// filter safe ascii
|
||||
for (i=0;i<l;i++)
|
||||
if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
|
||||
|
||||
Dbprintf("%-8s %*D",ascii,l,d," ");
|
||||
|
||||
len-=8;
|
||||
d+=8;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read an ADC channel and block till it completes, then return the result
|
||||
// in ADC units (0 to 1023). Also a routine to average 32 samples and
|
||||
|
@ -598,6 +621,24 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ISO15693
|
||||
case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693:
|
||||
RecordRawAdcSamplesIso15693();
|
||||
break;
|
||||
|
||||
case CMD_ISO_15693_COMMAND:
|
||||
DirectTag15693Command(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
|
||||
break;
|
||||
|
||||
case CMD_ISO_15693_FIND_AFI:
|
||||
BruteforceIso15693Afi(c->arg[0]);
|
||||
break;
|
||||
|
||||
case CMD_ISO_15693_DEBUG:
|
||||
SetDebugIso15693(c->arg[0]);
|
||||
break;
|
||||
|
||||
#endif
|
||||
case CMD_BUFF_CLEAR:
|
||||
BufferClear();
|
||||
break;
|
||||
|
|
|
@ -31,6 +31,7 @@ void SamyRun(void);
|
|||
//void DbpIntegers(int a, int b, int c);
|
||||
void DbpString(char *str);
|
||||
void Dbprintf(const char *fmt, ...);
|
||||
void Dbhexdump(int len, uint8_t *d);
|
||||
|
||||
void ToSendStuffBit(int b);
|
||||
void ToSendReset(void);
|
||||
|
@ -107,9 +108,13 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack);
|
|||
void ReaderMifare(uint32_t parameter);
|
||||
|
||||
/// iso15693.h
|
||||
void RecordRawAdcSamplesIso15693(void);
|
||||
void AcquireRawAdcSamplesIso15693(void);
|
||||
void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg
|
||||
void SimTagIso15693(uint32_t parameter); // simulate an ISO15693 tag - greg
|
||||
void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox
|
||||
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]); // send arbitrary commands from CLI - atrox
|
||||
void SetDebugIso15693(uint32_t flag);
|
||||
|
||||
/// util.h
|
||||
|
||||
|
|
1178
armsrc/iso15693.c
1178
armsrc/iso15693.c
File diff suppressed because it is too large
Load diff
|
@ -69,3 +69,47 @@ char* strncat(char *dest, const char *src, unsigned int n)
|
|||
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* strcat(char *dest, const char *src)
|
||||
{
|
||||
unsigned int dest_len = strlen(dest);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; src[i] != '\0' ; i++)
|
||||
dest[dest_len + i] = src[i];
|
||||
dest[dest_len + i] = '\0';
|
||||
|
||||
return dest;
|
||||
}
|
||||
////////////////////////////////////////// code to do 'itoa'
|
||||
|
||||
/* reverse: reverse string s in place */
|
||||
void strreverse(char s[])
|
||||
{
|
||||
int c, i, j;
|
||||
|
||||
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
|
||||
c = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = c;
|
||||
}
|
||||
}
|
||||
|
||||
/* itoa: convert n to characters in s */
|
||||
void itoa(int n, char s[])
|
||||
{
|
||||
int i, sign;
|
||||
|
||||
if ((sign = n) < 0) /* record sign */
|
||||
n = -n; /* make n positive */
|
||||
i = 0;
|
||||
do { /* generate digits in reverse order */
|
||||
s[i++] = n % 10 + '0'; /* get next digit */
|
||||
} while ((n /= 10) > 0); /* delete it */
|
||||
if (sign < 0)
|
||||
s[i++] = '-';
|
||||
s[i] = '\0';
|
||||
strreverse(s);
|
||||
}
|
||||
|
||||
//////////////////////////////////////// END 'itoa' CODE
|
||||
|
|
|
@ -17,5 +17,9 @@ void *memcpy(void *dest, const void *src, int len);
|
|||
void *memset(void *dest, int c, int len);
|
||||
int memcmp(const void *av, const void *bv, int len);
|
||||
char *strncat(char *dest, const char *src, unsigned int n);
|
||||
char *strcat(char *dest, const char *src);
|
||||
void strreverse(char s[]);
|
||||
void itoa(int n, char s[]);
|
||||
|
||||
|
||||
#endif /* __STRING_H */
|
||||
|
|
|
@ -42,6 +42,7 @@ endif
|
|||
CMDSRCS = \
|
||||
crc16.c \
|
||||
iso14443crc.c \
|
||||
iso15693tools.c \
|
||||
data.c \
|
||||
graph.c \
|
||||
ui.c \
|
||||
|
|
698
client/cmdhf15.c
698
client/cmdhf15.c
|
@ -1,5 +1,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||
// Modified 2010 by <adrian -at- atrox.at>
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
|
@ -7,6 +8,18 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// High frequency ISO15693 commands
|
||||
//-----------------------------------------------------------------------------
|
||||
// There are three basic operation modes, depending on which device (proxmark/pc)
|
||||
// the signal processing, (de)modulation, transmission protocol and logic is done.
|
||||
// Mode 1:
|
||||
// All steps are done on the proxmark, the output of the commands is returned via
|
||||
// USB-debug-print commands.
|
||||
// Mode 2:
|
||||
// The protocol is done on the PC, passing only Iso15693 data frames via USB. This
|
||||
// allows direct communication with a tag on command level
|
||||
// Mode 3:
|
||||
// The proxmark just samples the antenna and passes this "analog" data via USB to
|
||||
// the client. Signal Processing & decoding is done on the pc. This is the slowest
|
||||
// variant, but offers the possibility to analyze the waveforms directly.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -18,77 +31,121 @@
|
|||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhf15.h"
|
||||
#include "iso15693tools.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
#define FrameSOF Iso15693FrameSOF
|
||||
#define Logic0 Iso15693Logic0
|
||||
#define Logic1 Iso15693Logic1
|
||||
#define FrameEOF Iso15693FrameEOF
|
||||
|
||||
#define Crc(data,datalen) Iso15693Crc(data,datalen)
|
||||
#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
|
||||
#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static uint16_t Iso15693Crc(uint8_t *v, int n)
|
||||
// structure and database for uid -> tagtype lookups
|
||||
typedef struct {
|
||||
uint64_t uid;
|
||||
int mask; // how many MSB bits used
|
||||
char* desc;
|
||||
} productName;
|
||||
|
||||
|
||||
const productName uidmapping[] = {
|
||||
{ 0xE007000000000000LL, 16, "Texas Instrument; " },
|
||||
{ 0xE007000000000000LL, 20, "Texas Instrument; Tag-it HF-I Plus Inlay; 64x32bit" },
|
||||
{ 0xE007100000000000LL, 20, "Texas Instrument; Tag-it HF-I Plus Chip; 64x32bit" },
|
||||
{ 0xE007C00000000000LL, 23, "Texas Instrument; Tag-it HF-I Standard; 8x32bit" },
|
||||
{ 0xE007C40000000000LL, 23, "Texas Instrument; Tag-it HF-I Pro; 8x23bit; password" },
|
||||
{ 0xE005000000000000LL, 16, "Infineon" },
|
||||
{ 0xE005400000000000LL, 24, "Infineon; 56x32bit" },
|
||||
{ 0xE004000000000000LL, 16, "Philips" },
|
||||
{ 0xE002000000000000LL, 16, "STMicroelectronics" },
|
||||
{ 0xE016000000000000LL, 16, "EM-Marin SA (Skidata)" },
|
||||
{ 0xE016040000000000LL, 24, "EM-Marin SA (Skidata Keycard-eco); no memory" },
|
||||
{ 0xE016100000000000LL, 24, "EM-Marin SA (Skidata); EM4135; 36x64bit start page 13" },
|
||||
{ 0,0,"no tag-info available" } // must be the last entry
|
||||
};
|
||||
|
||||
|
||||
// fast method to just read the UID of an tag (collission detection not supported)
|
||||
// *buf shouls be large enough to fit the 64bit uid
|
||||
// returns 1 if suceeded
|
||||
int getUID(uint8_t *buf)
|
||||
{
|
||||
uint32_t reg;
|
||||
int i, j;
|
||||
UsbCommand *r;
|
||||
uint8_t *recv;
|
||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||
uint8_t *req=c.d.asBytes;
|
||||
int reqlen=0;
|
||||
|
||||
reg = 0xffff;
|
||||
for (i = 0; i < n; i++) {
|
||||
reg = reg ^ ((uint32_t)v[i]);
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (reg & 0x0001) {
|
||||
reg = (reg >> 1) ^ 0x8408;
|
||||
} else {
|
||||
reg = (reg >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int retry=0;retry<3; retry++) { // don't give up the at the first try
|
||||
|
||||
return (uint16_t)~reg;
|
||||
req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
|
||||
ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
|
||||
req[1]=ISO15_CMD_INVENTORY;
|
||||
req[2]=0; // mask length
|
||||
reqlen=AddCrc(req,3);
|
||||
c.arg[0]=reqlen;
|
||||
|
||||
SendCommand(&c);
|
||||
|
||||
r=WaitForResponseTimeout(CMD_ACK,1000);
|
||||
|
||||
if (r!=NULL) {
|
||||
recv = r->d.asBytes;
|
||||
if (r->arg[0]>=12 && ISO15_CRC_CHECK==Crc(recv,12)) {
|
||||
memcpy(buf,&recv[2],8);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} // retry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get a product description based on the UID
|
||||
// uid[8] tag uid
|
||||
// returns description of the best match
|
||||
static char* getTagInfo(uint8_t *uid) {
|
||||
uint64_t myuid,mask,t;
|
||||
int i=0, best=-1;
|
||||
memcpy(&myuid,uid,sizeof(uint64_t));
|
||||
while (uidmapping[i].mask>0) {
|
||||
mask=(~0LL) <<(64-uidmapping[i].mask);
|
||||
if ((myuid & mask) == uidmapping[i].uid) {
|
||||
if (best==-1) {
|
||||
best=i;
|
||||
} else {
|
||||
if (uidmapping[i].mask>uidmapping[best].mask) {
|
||||
best=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (best>=0) return uidmapping[best].desc;
|
||||
|
||||
return uidmapping[i].desc;
|
||||
}
|
||||
|
||||
|
||||
// will return a clear-text message to an errorcode
|
||||
static char* TagErrorStr(uint8_t error) {
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Mode 3
|
||||
int CmdHF15Demod(const char *Cmd)
|
||||
{
|
||||
// The sampling rate is 106.353 ksps/s, for T = 18.8 us
|
||||
|
||||
// SOF defined as
|
||||
// 1) Unmodulated time of 56.64us
|
||||
// 2) 24 pulses of 423.75khz
|
||||
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
|
||||
|
||||
static const int FrameSOF[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1,
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1
|
||||
};
|
||||
static const int Logic0[] = {
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1,
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1
|
||||
};
|
||||
static const int Logic1[] = {
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1,
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1
|
||||
};
|
||||
|
||||
// EOF defined as
|
||||
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
|
||||
// 2) 24 pulses of 423.75khz
|
||||
// 3) Unmodulated time of 56.64us
|
||||
|
||||
static const int FrameEOF[] = {
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1,
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
int i, j;
|
||||
int max = 0, maxPos = 0;
|
||||
|
||||
|
@ -162,6 +219,9 @@ int CmdHF15Demod(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// * Acquire Samples as Reader (enables carrier, sends inquiry)
|
||||
int CmdHF15Read(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693};
|
||||
|
@ -169,6 +229,14 @@ int CmdHF15Read(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Record Activity without enabeling carrier
|
||||
int CmdHF15Record(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693};
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHF15Reader(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_READER_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
|
||||
|
@ -176,6 +244,7 @@ int CmdHF15Reader(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Simulation is still not working very good
|
||||
int CmdHF15Sim(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_SIMTAG_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
|
||||
|
@ -183,24 +252,525 @@ int CmdHF15Sim(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] =
|
||||
// finds the AFI (Application Family Idendifier) of a card, by trying all values
|
||||
// (There is no standard way of reading the AFI, allthough some tags support this)
|
||||
int CmdHF15Afi(const char *Cmd)
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
UsbCommand c = {CMD_ISO_15693_FIND_AFI, {strtol(Cmd, NULL, 0), 0, 0}};
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Reads all memory pages
|
||||
int CmdHF15DumpMem(const char*Cmd) {
|
||||
UsbCommand *r;
|
||||
uint8_t uid[8];
|
||||
uint8_t *recv=NULL;
|
||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||
uint8_t *req=c.d.asBytes;
|
||||
int reqlen=0;
|
||||
int blocknum=0;
|
||||
char output[80];
|
||||
|
||||
if (!getUID(uid)) {
|
||||
PrintAndLog("No Tag found.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PrintAndLog("Reading memory from tag UID=%s",sprintUID(NULL,uid));
|
||||
PrintAndLog("Tag Info: %s",getTagInfo(uid));
|
||||
|
||||
for (int retry=0; retry<5; retry++) {
|
||||
|
||||
req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
|
||||
ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||
req[1]=ISO15_CMD_READ;
|
||||
memcpy(&req[2],uid,8);
|
||||
req[10]=blocknum;
|
||||
reqlen=AddCrc(req,11);
|
||||
c.arg[0]=reqlen;
|
||||
|
||||
SendCommand(&c);
|
||||
|
||||
r=WaitForResponseTimeout(CMD_ACK,1000);
|
||||
|
||||
if (r!=NULL) {
|
||||
recv = r->d.asBytes;
|
||||
if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
|
||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
||||
retry=0;
|
||||
*output=0; // reset outputstring
|
||||
sprintf(output, "Block %2i ",blocknum);
|
||||
for ( int i=1; i<r->arg[0]-2; i++) { // data in hex
|
||||
sprintf(output+strlen(output),"%02hX ",recv[i]);
|
||||
}
|
||||
strcat(output," ");
|
||||
for ( int i=1; i<r->arg[0]-2; i++) { // data in cleaned ascii
|
||||
sprintf(output+strlen(output),"%c",(recv[i]>31 && recv[i]<127)?recv[i]:'.');
|
||||
}
|
||||
PrintAndLog("%s",output);
|
||||
blocknum++;
|
||||
// PrintAndLog("bn=%i",blocknum);
|
||||
} else {
|
||||
PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
|
||||
return 0;
|
||||
}
|
||||
} // else PrintAndLog("crc");
|
||||
} // else PrintAndLog("r null");
|
||||
|
||||
} // retry
|
||||
if (r && r->arg[0]<3)
|
||||
PrintAndLog("Lost Connection");
|
||||
else if (r && ISO15_CRC_CHECK!=Crc(r->d.asBytes,r->arg[0]))
|
||||
PrintAndLog("CRC Failed");
|
||||
else
|
||||
PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// "HF 15" interface
|
||||
|
||||
static command_t CommandTable15[] =
|
||||
{
|
||||
{"help", CmdHF15Help, 1, "This help"},
|
||||
{"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
|
||||
{"read", CmdHF15Read, 0, "Read HF tag (ISO 15693)"},
|
||||
{"record", CmdHF15Record, 0, "Record Samples (ISO 15693)"}, // atrox
|
||||
{"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
|
||||
{"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
|
||||
{"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
|
||||
{"findafi", CmdHF15Afi, 0, "Brute force AFI of an ISO15693 tag"},
|
||||
{"dumpmemory", CmdHF15DumpMem, 0, "Read all memory pages of an ISO15693 tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdHF15(const char *Cmd)
|
||||
{
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
CmdsParse(CommandTable15, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd)
|
||||
int CmdHF15Help(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable);
|
||||
CmdsHelp(CommandTable15);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// "HF 15 Cmd" Interface
|
||||
// Allows direct communication with the tag on command level
|
||||
|
||||
int CmdHF15CmdInquiry(const char *Cmd)
|
||||
{
|
||||
UsbCommand *r;
|
||||
uint8_t *recv;
|
||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||
uint8_t *req=c.d.asBytes;
|
||||
int reqlen=0;
|
||||
|
||||
req[0]= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
|
||||
ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
|
||||
req[1]=ISO15_CMD_INVENTORY;
|
||||
req[2]=0; // mask length
|
||||
reqlen=AddCrc(req,3);
|
||||
c.arg[0]=reqlen;
|
||||
|
||||
SendCommand(&c);
|
||||
|
||||
r=WaitForResponseTimeout(CMD_ACK,1000);
|
||||
|
||||
if (r!=NULL) {
|
||||
if (r->arg[0]>=12) {
|
||||
recv = r->d.asBytes;
|
||||
PrintAndLog("UID=%s",sprintUID(NULL,&recv[2]));
|
||||
PrintAndLog("Tag Info: %s",getTagInfo(&recv[2]));
|
||||
} else {
|
||||
PrintAndLog("Response to short, just %i bytes. No tag?\n",r->arg[0]);
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("timeout.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Turns debugging on(1)/off(0)
|
||||
int CmdHF15CmdDebug( const char *cmd) {
|
||||
int debug=atoi(cmd);
|
||||
if (strlen(cmd)<1) {
|
||||
PrintAndLog("Usage: hf 15 cmd debug <0/1>");
|
||||
PrintAndLog(" 0..no debugging output 1..turn debugging on");
|
||||
return 0;
|
||||
}
|
||||
|
||||
UsbCommand c = {CMD_ISO_15693_DEBUG, {debug, 0, 0}};
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHF15CmdRaw (const char *cmd) {
|
||||
UsbCommand *r;
|
||||
uint8_t *recv;
|
||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||
int reply=1;
|
||||
int fast=1;
|
||||
int crc=0;
|
||||
char buf[5]="";
|
||||
int i=0;
|
||||
uint8_t data[100];
|
||||
unsigned int datalen=0, temp;
|
||||
|
||||
|
||||
if (strlen(cmd)<3) {
|
||||
PrintAndLog("Usage: hf 15 cmd raw [-r] [-2] [-c] <0A 0B 0C ... hex>");
|
||||
PrintAndLog(" -r do not read response");
|
||||
PrintAndLog(" -2 use slower '1 out of 256' mode");
|
||||
PrintAndLog(" -c calculate and append CRC");
|
||||
PrintAndLog(" Tip: turn on debugging for verbose output");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// strip
|
||||
while (*cmd==' ' || *cmd=='\t') cmd++;
|
||||
|
||||
while (cmd[i]!='\0') {
|
||||
if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; }
|
||||
if (cmd[i]=='-') {
|
||||
switch (cmd[i+1]) {
|
||||
case 'r':
|
||||
case 'R':
|
||||
reply=0;
|
||||
break;
|
||||
case '2':
|
||||
fast=0;
|
||||
break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
crc=1;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Invalid option");
|
||||
return 0;
|
||||
}
|
||||
i+=2;
|
||||
continue;
|
||||
}
|
||||
if ((cmd[i]>='0' && cmd[i]<='9') ||
|
||||
(cmd[i]>='a' && cmd[i]<='f') ||
|
||||
(cmd[i]>='A' && cmd[i]<='F') ) {
|
||||
buf[strlen(buf)+1]=0;
|
||||
buf[strlen(buf)]=cmd[i];
|
||||
i++;
|
||||
|
||||
if (strlen(buf)>=2) {
|
||||
sscanf(buf,"%x",&temp);
|
||||
data[datalen]=(uint8_t)(temp & 0xff);
|
||||
datalen++;
|
||||
*buf=0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
PrintAndLog("Invalid char on input");
|
||||
return 0;
|
||||
}
|
||||
if (crc) datalen=AddCrc(data,datalen);
|
||||
|
||||
c.arg[0]=datalen;
|
||||
c.arg[1]=fast;
|
||||
c.arg[2]=reply;
|
||||
memcpy(c.d.asBytes,data,datalen);
|
||||
|
||||
SendCommand(&c);
|
||||
|
||||
if (reply) {
|
||||
r=WaitForResponseTimeout(CMD_ACK,1000);
|
||||
|
||||
if (r!=NULL) {
|
||||
recv = r->d.asBytes;
|
||||
PrintAndLog("received %i octets",r->arg[0]);
|
||||
// TODO: output
|
||||
} else {
|
||||
PrintAndLog("timeout while waiting for reply.");
|
||||
}
|
||||
|
||||
} // if reply
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdlen) {
|
||||
int temp;
|
||||
uint8_t *req=c->d.asBytes, uid[8];
|
||||
uint32_t reqlen=0;
|
||||
|
||||
// strip
|
||||
while (**cmd==' ' || **cmd=='\t') (*cmd)++;
|
||||
|
||||
if (strstr(*cmd,"-2")==*cmd) {
|
||||
c->arg[1]=0; // quse 1of256
|
||||
(*cmd)+=2;
|
||||
}
|
||||
|
||||
// strip
|
||||
while (**cmd==' ' || **cmd=='\t') (*cmd)++;
|
||||
|
||||
if (strstr(*cmd,"-o")==*cmd) {
|
||||
req[reqlen]=ISO15_REQ_OPTION;
|
||||
(*cmd)+=2;
|
||||
}
|
||||
|
||||
// strip
|
||||
while (**cmd==' ' || **cmd=='\t') (*cmd)++;
|
||||
|
||||
switch (**cmd) {
|
||||
case 0:
|
||||
PrintAndLog("missing addr");
|
||||
return 0;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
// you must have selected the tag earlier
|
||||
req[reqlen++]|= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
|
||||
ISO15_REQ_NONINVENTORY | ISO15_REQ_SELECT;
|
||||
memcpy(&req[reqlen],&iso15cmd[0],iso15cmdlen);
|
||||
reqlen+=iso15cmdlen;
|
||||
break;
|
||||
case 'u':
|
||||
case 'U':
|
||||
// unaddressed mode may not be supported by all vendors
|
||||
req[reqlen++]|= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
|
||||
ISO15_REQ_NONINVENTORY;
|
||||
memcpy(&req[reqlen],&iso15cmd[0],iso15cmdlen);
|
||||
reqlen+=iso15cmdlen;
|
||||
break;
|
||||
case '*':
|
||||
req[reqlen++]|= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
|
||||
ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||
memcpy(&req[reqlen],&iso15cmd[0],iso15cmdlen);
|
||||
reqlen+=iso15cmdlen;
|
||||
if (!getUID(uid)) {
|
||||
PrintAndLog("No Tag found");
|
||||
return 0;
|
||||
}
|
||||
memcpy(req+reqlen,uid,8);
|
||||
PrintAndLog("Detected UID %s",sprintUID(NULL,uid));
|
||||
reqlen+=8;
|
||||
break;
|
||||
default:
|
||||
req[reqlen++]|= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH |
|
||||
ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||
memcpy(&req[reqlen],&iso15cmd[0],iso15cmdlen);
|
||||
reqlen+=iso15cmdlen;
|
||||
|
||||
/* sscanf(cmd,"%hX%hX%hX%hX%hX%hX%hX%hX",
|
||||
(short unsigned int *)&uid[7],(short unsigned int *)&uid[6],
|
||||
(short unsigned int *)&uid[5],(short unsigned int *)&uid[4],
|
||||
(short unsigned int *)&uid[3],(short unsigned int *)&uid[2],
|
||||
(short unsigned int *)&uid[1],(short unsigned int *)&uid[0]); */
|
||||
for (int i=0;i<8 && (*cmd)[i*2] && (*cmd)[i*2+1];i++) { // parse UID
|
||||
sscanf((char[]){(*cmd)[i*2],(*cmd)[i*2+1],0},"%X",&temp);
|
||||
uid[7-i]=temp&0xff;
|
||||
}
|
||||
|
||||
PrintAndLog("Using UID %s",sprintUID(NULL,uid));
|
||||
memcpy(&req[reqlen],&uid[0],8);
|
||||
reqlen+=8;
|
||||
}
|
||||
// skip to next space
|
||||
while (**cmd!=' ' && **cmd!='\t') (*cmd)++;
|
||||
// skip over the space
|
||||
while (**cmd==' ' || **cmd=='\t') (*cmd)++;
|
||||
|
||||
c->arg[0]=reqlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int CmdHF15CmdRead(const char *Cmd) {
|
||||
UsbCommand *r;
|
||||
uint8_t *recv;
|
||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||
uint8_t *req=c.d.asBytes;
|
||||
int reqlen=0, pagenum;
|
||||
char cmdbuf[100];
|
||||
char *cmd=cmdbuf;
|
||||
char output[100]="";
|
||||
|
||||
strncpy(cmd,Cmd,99);
|
||||
|
||||
// usage:
|
||||
if (strlen(cmd)<3) {
|
||||
PrintAndLog("Usage: hf 15 cmd read [options] <uid|s|*> <page#>");
|
||||
PrintAndLog(" options:");
|
||||
PrintAndLog(" -2 use slower '1 out of 256' mode");
|
||||
PrintAndLog(" uid (either): ");
|
||||
PrintAndLog(" <8B hex> full UID eg E011223344556677");
|
||||
PrintAndLog(" s selected tag");
|
||||
PrintAndLog(" u unaddressed mode");
|
||||
PrintAndLog(" * scan for tag");
|
||||
PrintAndLog(" page#: page number 0-255");
|
||||
return 0;
|
||||
}
|
||||
|
||||
prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_READ},1);
|
||||
reqlen=c.arg[0];
|
||||
|
||||
pagenum=strtol(cmd,NULL,0);
|
||||
/*if (pagenum<0) {
|
||||
PrintAndLog("invalid pagenum");
|
||||
return 0;
|
||||
} */
|
||||
|
||||
req[reqlen++]=(uint8_t)pagenum;
|
||||
|
||||
reqlen=AddCrc(req,reqlen);
|
||||
|
||||
c.arg[0]=reqlen;
|
||||
|
||||
SendCommand(&c);
|
||||
|
||||
r=WaitForResponseTimeout(CMD_ACK,1000);
|
||||
|
||||
if (r!=NULL && r->arg[0]>2) {
|
||||
recv = r->d.asBytes;
|
||||
if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
|
||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
||||
*output=0; // reset outputstring
|
||||
//sprintf(output, "Block %2i ",blocknum);
|
||||
for ( int i=1; i<r->arg[0]-2; i++) {
|
||||
sprintf(output+strlen(output),"%02hX ",recv[i]);
|
||||
}
|
||||
strcat(output," ");
|
||||
for ( int i=2; i<r->arg[0]-2; i++) {
|
||||
sprintf(output+strlen(output),"%c",recv[i]>31 || recv[i]<127?recv[i]:'.');
|
||||
}
|
||||
PrintAndLog("%s",output);
|
||||
} else {
|
||||
PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("CRC failed");
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("no answer");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHF15CmdWrite(const char *Cmd) {
|
||||
UsbCommand *r;
|
||||
uint8_t *recv;
|
||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||
uint8_t *req=c.d.asBytes;
|
||||
int reqlen=0, pagenum, temp;
|
||||
char cmdbuf[100];
|
||||
char *cmd=cmdbuf;
|
||||
char *cmd2;
|
||||
|
||||
strncpy(cmd,Cmd,99);
|
||||
|
||||
// usage:
|
||||
if (strlen(cmd)<3) {
|
||||
PrintAndLog("Usage: hf 15 cmd write [options] <uid|s|*> <page#> <hexdata>");
|
||||
PrintAndLog(" options:");
|
||||
PrintAndLog(" -2 use slower '1 out of 256' mode");
|
||||
PrintAndLog(" -o set OPTION Flag (needed for TI)");
|
||||
PrintAndLog(" uid (either): ");
|
||||
PrintAndLog(" <8B hex> full UID eg E011223344556677");
|
||||
PrintAndLog(" s selected tag");
|
||||
PrintAndLog(" u unaddressed mode");
|
||||
PrintAndLog(" * scan for tag");
|
||||
PrintAndLog(" page#: page number 0-255");
|
||||
PrintAndLog(" hexdata: data to be written eg AA BB CC DD");
|
||||
return 0;
|
||||
}
|
||||
|
||||
prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_WRITE},1);
|
||||
reqlen=c.arg[0];
|
||||
|
||||
// *cmd -> page num ; *cmd2 -> data
|
||||
cmd2=cmd;
|
||||
while (*cmd2!=' ' && *cmd2!='\t' && *cmd2) cmd2++;
|
||||
*cmd2=0;
|
||||
cmd2++;
|
||||
|
||||
pagenum=strtol(cmd,NULL,0);
|
||||
/*if (pagenum<0) {
|
||||
PrintAndLog("invalid pagenum");
|
||||
return 0;
|
||||
} */
|
||||
req[reqlen++]=(uint8_t)pagenum;
|
||||
|
||||
|
||||
while (cmd2[0] && cmd2[1]) { // hexdata, read by 2 hexchars
|
||||
if (*cmd2==' ') {
|
||||
cmd2++;
|
||||
continue;
|
||||
}
|
||||
sscanf((char[]){cmd2[0],cmd2[1],0},"%X",&temp);
|
||||
req[reqlen++]=temp & 0xff;
|
||||
cmd2+=2;
|
||||
}
|
||||
|
||||
reqlen=AddCrc(req,reqlen);
|
||||
|
||||
c.arg[0]=reqlen;
|
||||
|
||||
SendCommand(&c);
|
||||
|
||||
r=WaitForResponseTimeout(CMD_ACK,2000);
|
||||
|
||||
if (r!=NULL && r->arg[0]>2) {
|
||||
recv = r->d.asBytes;
|
||||
if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
|
||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
||||
PrintAndLog("OK");
|
||||
} else {
|
||||
PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("CRC failed");
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("no answer");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static command_t CommandTable15Cmd[] =
|
||||
{
|
||||
{"help", CmdHF15CmdHelp, 1, "This Help"},
|
||||
{"inquiry", CmdHF15CmdInquiry, 0, "Search for tags in range"},
|
||||
/*
|
||||
{"select", CmdHF15CmdSelect, 0, "Select an tag with a specific UID for further commands"},
|
||||
*/
|
||||
{"read", CmdHF15CmdRead, 0, "Read a block"},
|
||||
{"write", CmdHF15CmdWrite, 0, "Write a block"},
|
||||
/*
|
||||
{"readmulti",CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
|
||||
*/
|
||||
{"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"},
|
||||
{"debug", CmdHF15CmdDebug, 0, "Turn debugging on/off"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdHF15Cmd(const char *Cmd)
|
||||
{
|
||||
CmdsParse(CommandTable15Cmd, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHF15CmdHelp(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable15Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,5 +17,9 @@ int CmdHF15Demod(const char *Cmd);
|
|||
int CmdHF15Read(const char *Cmd);
|
||||
int CmdHF15Reader(const char *Cmd);
|
||||
int CmdHF15Sim(const char *Cmd);
|
||||
int CmdHF15Record(const char *Cmd);
|
||||
int CmdHF15Cmd(const char*Cmd);
|
||||
int CmdHF15CmdHelp(const char*Cmd);
|
||||
int CmdHF15Help(const char*Cmd);
|
||||
|
||||
#endif
|
||||
|
|
67
common/iso15693tools.c
Normal file
67
common/iso15693tools.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// ISO15693 CRC & other commons
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "proxmark3.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
//#include "iso15693tools.h"
|
||||
|
||||
// The CRC as described in ISO 15693-Part 3-Annex C
|
||||
// v buffer with data
|
||||
// n length
|
||||
// returns crc as 16bit value
|
||||
uint16_t Iso15693Crc(uint8_t *v, int n)
|
||||
{
|
||||
uint32_t reg;
|
||||
int i, j;
|
||||
|
||||
reg = 0xffff;
|
||||
for(i = 0; i < n; i++) {
|
||||
reg = reg ^ ((uint32_t)v[i]);
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (reg & 0x0001) {
|
||||
reg = (reg >> 1) ^ 0x8408;
|
||||
} else {
|
||||
reg = (reg >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ~(uint16_t)(reg & 0xffff);
|
||||
}
|
||||
|
||||
// adds a CRC to a dataframe
|
||||
// req[] iso15963 frame without crc
|
||||
// n length without crc
|
||||
// returns the new length of the dataframe.
|
||||
int Iso15693AddCrc(uint8_t *req, int n) {
|
||||
uint16_t crc=Iso15693Crc(req,n);
|
||||
req[n] = crc & 0xff;
|
||||
req[n+1] = crc >> 8;
|
||||
return n+2;
|
||||
}
|
||||
|
||||
|
||||
int sprintf(char *str, const char *format, ...);
|
||||
|
||||
// returns a string representation of the UID
|
||||
// UID is transmitted and stored LSB first, displayed MSB first
|
||||
// target char* buffer, where to put the UID, if NULL a static buffer is returned
|
||||
// uid[] the UID in transmission order
|
||||
// return: ptr to string
|
||||
char* Iso15693sprintUID(char *target,uint8_t *uid) {
|
||||
static char tempbuf[9]="";
|
||||
if (target==NULL) target=tempbuf;
|
||||
sprintf(target,"%02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX",
|
||||
uid[7],uid[6],uid[5],uid[4],uid[3],uid[2],uid[1],uid[0]);
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
|
127
common/iso15693tools.h
Normal file
127
common/iso15693tools.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
// ISO15693 commons
|
||||
// Adrian Dabrowski 2010, GPLv2
|
||||
|
||||
#ifndef ISO15693_H__
|
||||
#define ISO15693_H__
|
||||
|
||||
// ISO15693 CRC
|
||||
#define ISO15_CRC_PRESET (uint16_t)0xFFFF
|
||||
#define ISO15_CRC_POLY (uint16_t)0x8408
|
||||
#define ISO15_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
|
||||
|
||||
// REQUEST FLAGS
|
||||
|
||||
#define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
|
||||
#define ISO15_REQ_SUBCARRIER_TWO 0x01 // Tag should respond using two subcarriers (FSK)
|
||||
#define ISO15_REQ_DATARATE_LOW 0x00 // Tag should respond using low data rate
|
||||
#define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
|
||||
#define ISO15_REQ_NONINVENTORY 0x00
|
||||
#define ISO15_REQ_INVENTORY 0x04 // This is an inventory request - see inventory flags
|
||||
#define ISO15_REQ_PROTOCOL_NONEXT 0x00
|
||||
#define ISO15_REQ_PROTOCOL_EXT 0x08 // RFU
|
||||
|
||||
// REQUEST FLAGS when INVENTORY is not set
|
||||
|
||||
#define ISO15_REQ_SELECT 0x10 // only selected cards response
|
||||
#define ISO15_REQ_ADDRESS 0x20 // this req contains an address
|
||||
#define ISO15_REQ_OPTION 0x40 // Command specific option selector
|
||||
|
||||
//REQUEST FLAGS when INVENTORY is set
|
||||
|
||||
#define ISO15_REQINV_AFI 0x10 // AFI Field is present
|
||||
#define ISO15_REQINV_SLOT1 0x20 // 1 Slot
|
||||
#define ISO15_REQINV_SLOT16 0x00 // 16 Slots
|
||||
#define ISO15_REQINV_OPTION 0x40 // Command specific option selector
|
||||
|
||||
//RESPONSE FLAGS
|
||||
#define ISO15_RES_ERROR 0x01
|
||||
#define ISO15_RES_EXT 0x08 // Protocol Extention
|
||||
|
||||
// RESPONSE ERROR CODES
|
||||
#define ISO15_NOERROR 0x00
|
||||
#define ISO15_ERROR_CMD_NOT_SUP 0x01 // Command not supported
|
||||
#define ISO15_ERROR_CMD_NOT_REC 0x02 // Command not recognized (eg. parameter error)
|
||||
#define ISO15_ERROR_CMD_OPTION 0x03 // Command option not supported
|
||||
#define ISO15_ERROR_GENERIC 0x0F // No additional Info about this error
|
||||
#define ISO15_ERROR_BLOCK_UNAVAILABLE 0x10
|
||||
#define ISO15_ERROR_BLOCK_LOCKED_ALREADY 0x11 // cannot lock again
|
||||
#define ISO15_ERROR_BLOCK_LOCKED 0x12 // cannot be changed
|
||||
#define ISO15_ERROR_BLOCK_WRITE 0x13 // Writing was unsuccessful
|
||||
#define ISO15_ERROR_BLOCL_WRITELOCK 0x14 // Locking was unsuccessful
|
||||
|
||||
// COMMAND CODES
|
||||
#define ISO15_CMD_INVENTORY 0x01
|
||||
#define ISO15_CMD_STAYQUIET 0x02
|
||||
#define ISO15_CMD_READ 0x20
|
||||
#define ISO15_CMD_WRITE 0x21
|
||||
#define ISO15_CMD_LOCK 0x22
|
||||
#define ISO15_CMD_READMULTI 0x23
|
||||
#define ISO15_CMD_WRITEMULTI 0x24
|
||||
#define ISO15_CMD_SELECT 0x25
|
||||
#define ISO15_CMD_RESET 0x26
|
||||
#define ISO15_CMD_WRITEAFI 0x27
|
||||
#define ISO15_CMD_LOCKAFI 0x28
|
||||
#define ISO15_CMD_WRITEDSFID 0x29
|
||||
#define ISO15_CMD_LOCKDSFID 0x2A
|
||||
#define ISO15_CMD_SYSINFO 0x2B
|
||||
#define ISO15_CMD_SECSTATUS 0x2C
|
||||
|
||||
|
||||
uint16_t Iso15693Crc(uint8_t *v, int n);
|
||||
int Iso15693AddCrc(uint8_t *req, int n);
|
||||
char* Iso15693sprintUID(char *target,uint8_t *uid);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Map a sequence of octets (~layer 2 command) into the set of bits to feed
|
||||
// to the FPGA, to transmit that command to the tag.
|
||||
// Mode: highspeed && one subcarrier (ASK)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The sampling rate is 106.353 ksps/s, for T = 18.8 us
|
||||
|
||||
// SOF defined as
|
||||
// 1) Unmodulated time of 56.64us
|
||||
// 2) 24 pulses of 423.75khz
|
||||
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
|
||||
|
||||
static const int Iso15693FrameSOF[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1,
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1
|
||||
};
|
||||
static const int Iso15693Logic0[] = {
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1,
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1
|
||||
};
|
||||
static const int Iso15693Logic1[] = {
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1,
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1
|
||||
};
|
||||
|
||||
// EOF defined as
|
||||
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
|
||||
// 2) 24 pulses of 423.75khz
|
||||
// 3) Unmodulated time of 56.64us
|
||||
|
||||
static const int Iso15693FrameEOF[] = {
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1,
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -75,6 +75,11 @@ typedef struct {
|
|||
#define CMD_READ_SRIX4K_TAG 0x0304
|
||||
#define CMD_READER_ISO_15693 0x0310
|
||||
#define CMD_SIMTAG_ISO_15693 0x0311
|
||||
#define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312
|
||||
#define CMD_ISO_15693_COMMAND 0x0313
|
||||
#define CMD_ISO_15693_COMMAND_DONE 0x0314
|
||||
#define CMD_ISO_15693_FIND_AFI 0x0315
|
||||
#define CMD_ISO_15693_DEBUG 0x0316
|
||||
#define CMD_SIMULATE_TAG_HF_LISTEN 0x0380
|
||||
#define CMD_SIMULATE_TAG_ISO_14443 0x0381
|
||||
#define CMD_SNOOP_ISO_14443 0x0382
|
||||
|
|
|
@ -37,7 +37,7 @@ def invert(data):
|
|||
return out
|
||||
|
||||
# do the actual search
|
||||
def search(data,target):
|
||||
def search(target,data):
|
||||
location= string.find(data,target)
|
||||
if location >= 0:
|
||||
print '*** Match at bit %d:' % location,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue