mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
add: 'hf 15 list' is now possible, since I like to be able to call both "hf list 15" and "hf 15 list"...
chg: 'hf list 15' better annotations, the flags doens't define the command anymore chg: device side, iso15, experimenting with different settings. The tag still doesn't answer to 0x002B not 0x202B---uid--- commands.
This commit is contained in:
parent
508fa76915
commit
85b1c6bdfb
4 changed files with 256 additions and 220 deletions
|
@ -2,6 +2,7 @@
|
||||||
// Jonathan Westhues, split Nov 2006
|
// Jonathan Westhues, split Nov 2006
|
||||||
// Modified by Greg Jones, Jan 2009
|
// Modified by Greg Jones, Jan 2009
|
||||||
// Modified by Adrian Dabrowski "atrox", Mar-Sept 2010,Oct 2011
|
// Modified by Adrian Dabrowski "atrox", Mar-Sept 2010,Oct 2011
|
||||||
|
// Modified by Christian Herrmann "iceman", 2017
|
||||||
//
|
//
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
// 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
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
@ -69,6 +70,9 @@
|
||||||
// This section basicly contains transmission and receiving of bits
|
// This section basicly contains transmission and receiving of bits
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// 32 + 2 crc + 1
|
||||||
|
#define ISO15_MAX_FRAME 35
|
||||||
|
|
||||||
#define FrameSOF Iso15693FrameSOF
|
#define FrameSOF Iso15693FrameSOF
|
||||||
#define Logic0 Iso15693Logic0
|
#define Logic0 Iso15693Logic0
|
||||||
#define Logic1 Iso15693Logic1
|
#define Logic1 Iso15693Logic1
|
||||||
|
@ -80,7 +84,6 @@
|
||||||
|
|
||||||
int DEBUG = 0;
|
int DEBUG = 0;
|
||||||
|
|
||||||
|
|
||||||
static uint8_t BuildIdentifyRequest(uint8_t **cmdout);
|
static uint8_t BuildIdentifyRequest(uint8_t **cmdout);
|
||||||
//static uint8_t BuildReadBlockRequest(uint8_t **cmdout, uint8_t *uid, uint8_t blockNumber );
|
//static uint8_t BuildReadBlockRequest(uint8_t **cmdout, uint8_t *uid, uint8_t blockNumber );
|
||||||
static uint8_t BuildInventoryResponse(uint8_t **cmdout, uint8_t *uid);
|
static uint8_t BuildInventoryResponse(uint8_t **cmdout, uint8_t *uid);
|
||||||
|
@ -324,7 +327,7 @@ static int DemodAnswer(uint8_t *received, uint8_t *dest, uint16_t samplecount) {
|
||||||
|
|
||||||
i = maxPos + ARRAYLEN(FrameSOF) / skip;
|
i = maxPos + ARRAYLEN(FrameSOF) / skip;
|
||||||
|
|
||||||
uint8_t outBuf[20];
|
uint8_t outBuf[ISO15_MAX_FRAME];
|
||||||
memset(outBuf, 0, sizeof(outBuf));
|
memset(outBuf, 0, sizeof(outBuf));
|
||||||
uint8_t mask = 0x01;
|
uint8_t mask = 0x01;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -367,11 +370,12 @@ static int DemodAnswer(uint8_t *received, uint8_t *dest, uint16_t samplecount) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DEBUG) Dbprintf("ice: demod bytes %u", k);
|
||||||
|
|
||||||
if (mask != 0x01) { // this happens, when we miss the EOF
|
if (mask != 0x01) { // this happens, when we miss the EOF
|
||||||
|
|
||||||
// TODO: for some reason this happens quite often
|
// TODO: for some reason this happens quite often
|
||||||
if (DEBUG) Dbprintf("error, uneven octet! (extra bits!) mask %02x", mask);
|
if (DEBUG) Dbprintf("error, uneven octet! (extra bits!) mask %02x", mask);
|
||||||
|
|
||||||
//if (mask < 0x08) k--; // discard the last uneven octet;
|
//if (mask < 0x08) k--; // discard the last uneven octet;
|
||||||
// 0x08 is an assumption - but works quite often
|
// 0x08 is an assumption - but works quite often
|
||||||
}
|
}
|
||||||
|
@ -391,24 +395,44 @@ static int DemodAnswer(uint8_t *received, uint8_t *dest, uint16_t samplecount) {
|
||||||
// returns:
|
// returns:
|
||||||
// number of decoded bytes
|
// number of decoded bytes
|
||||||
// logging enabled
|
// logging enabled
|
||||||
static int GetIso15693AnswerFromTag(uint8_t *received, int *samples, int *elapsed) {
|
static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) {
|
||||||
|
|
||||||
|
#define SIGNAL_BUFF_SIZE 15000
|
||||||
|
// get current clock
|
||||||
|
uint32_t time_0 = GetCountSspClk();
|
||||||
|
uint32_t time_stop = 0;
|
||||||
bool getNext = false;
|
bool getNext = false;
|
||||||
int counter = 0, ci = 0, cq = 0;
|
int counter = 0, ci = 0, cq = 0;
|
||||||
uint32_t time_0 = 0, time_stop = 0;
|
//volatile uint32_t r;
|
||||||
uint8_t *buf = BigBuf_malloc(7000);
|
uint8_t *buf = BigBuf_malloc(SIGNAL_BUFF_SIZE);
|
||||||
|
|
||||||
// get current clock
|
if (elapsed) *elapsed = 0;
|
||||||
time_0 = GetCountSspClk();
|
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||||
|
|
||||||
|
// for (counter = 0; counter < wait;) {
|
||||||
|
|
||||||
|
// WDT_HIT();
|
||||||
|
|
||||||
|
// if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||||
|
// AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
|
||||||
|
// counter++;
|
||||||
|
// }
|
||||||
|
// if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
|
// r = AT91C_BASE_SSC->SSC_RHR; (void)r;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// counter = 0;
|
||||||
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
AT91C_BASE_SSC->SSC_THR = 0x00; //0x43;
|
||||||
|
// To make use of exact timing of next command from reader!!
|
||||||
|
if (elapsed) (*elapsed)++;
|
||||||
|
}
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
|
|
||||||
ci = (int8_t)AT91C_BASE_SSC->SSC_RHR;
|
ci = (int8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
@ -426,7 +450,7 @@ static int GetIso15693AnswerFromTag(uint8_t *received, int *samples, int *elapse
|
||||||
|
|
||||||
buf[counter++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1));
|
buf[counter++] = (uint8_t)(MAX(ci,cq) + (MIN(ci, cq) >> 1));
|
||||||
|
|
||||||
if (counter >= 7000-1)
|
if (counter >= SIGNAL_BUFF_SIZE)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
cq = ci;
|
cq = ci;
|
||||||
|
@ -434,9 +458,9 @@ static int GetIso15693AnswerFromTag(uint8_t *received, int *samples, int *elapse
|
||||||
getNext = !getNext;
|
getNext = !getNext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time_stop = GetCountSspClk() - time_0;
|
time_stop = GetCountSspClk() - time_0 ;
|
||||||
int len = DemodAnswer(received, buf, counter);
|
int len = DemodAnswer(received, buf, counter);
|
||||||
LogTrace(received, len, time_0, time_stop, NULL, false);
|
LogTrace(received, len, time_0 << 4, time_stop << 4, NULL, false);
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -489,7 +513,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elap
|
||||||
|
|
||||||
time_stop = GetCountSspClk() - time_0;
|
time_stop = GetCountSspClk() - time_0;
|
||||||
int k = DemodAnswer(received, buf, counter);
|
int k = DemodAnswer(received, buf, counter);
|
||||||
LogTrace(received, k, time_0, time_stop, NULL, false);
|
LogTrace(received, k, time_0 << 4, time_stop << 4, NULL, false);
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +560,8 @@ void AcquireRawAdcSamplesIso15693(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogTrace(cmd, cmdlen, time_start, GetCountSspClk()-time_start, NULL, true);
|
|
||||||
|
LogTrace(cmd, cmdlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true);
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||||
|
|
||||||
|
@ -749,9 +774,7 @@ static uint8_t BuildInventoryResponse(uint8_t **out, uint8_t *uid) {
|
||||||
// logging enabled
|
// logging enabled
|
||||||
int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) {
|
int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) {
|
||||||
|
|
||||||
int samples = 0, t_samples = 0;
|
int t_samples = 0, wait = 0, elapsed = 0, answer_len = 0;
|
||||||
int wait = 0, elapsed = 0;
|
|
||||||
int answer_len = 0;
|
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
|
||||||
|
@ -769,12 +792,12 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outda
|
||||||
uint32_t time_start = GetCountSspClk();
|
uint32_t time_start = GetCountSspClk();
|
||||||
|
|
||||||
TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait);
|
TransmitTo15693Tag(ToSend, ToSendMax, &t_samples, &wait);
|
||||||
LogTrace(send, sendlen, time_start, GetCountSspClk()-time_start, NULL, true);
|
LogTrace(send, sendlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true);
|
||||||
|
|
||||||
// Now wait for a response
|
// Now wait for a response
|
||||||
if (outdata != NULL) {
|
if (outdata != NULL) {
|
||||||
LED_B_INV();
|
LED_B_INV();
|
||||||
answer_len = GetIso15693AnswerFromTag(outdata, &samples, &elapsed);
|
answer_len = GetIso15693AnswerFromTag(outdata, &elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
@ -863,11 +886,7 @@ void ReaderIso15693(uint32_t parameter) {
|
||||||
int answerLen1 = 0;
|
int answerLen1 = 0;
|
||||||
//int answerLen2 = 0;
|
//int answerLen2 = 0;
|
||||||
//int answerLen3 = 0;
|
//int answerLen3 = 0;
|
||||||
//int i = 0;
|
int tsamples = 0, wait = 0, elapsed = 0;
|
||||||
int samples = 0;
|
|
||||||
int tsamples = 0;
|
|
||||||
int wait = 0;
|
|
||||||
int elapsed = 0;
|
|
||||||
|
|
||||||
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
||||||
|
|
||||||
|
@ -889,10 +908,10 @@ void ReaderIso15693(uint32_t parameter) {
|
||||||
uint8_t *cmd = NULL;
|
uint8_t *cmd = NULL;
|
||||||
uint8_t cmdlen = BuildIdentifyRequest( &cmd );
|
uint8_t cmdlen = BuildIdentifyRequest( &cmd );
|
||||||
TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait);
|
TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait);
|
||||||
LogTrace(cmd, cmdlen, time_start, GetCountSspClk()-time_start, NULL, true);
|
LogTrace(cmd, cmdlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true);
|
||||||
|
|
||||||
// Now wait for a response
|
// Now wait for a response
|
||||||
answerLen1 = GetIso15693AnswerFromTag(answer1, &samples, &elapsed) ;
|
answerLen1 = GetIso15693AnswerFromTag(answer1, &elapsed) ;
|
||||||
|
|
||||||
// we should do a better check than this
|
// we should do a better check than this
|
||||||
if (answerLen1 >= 12) {
|
if (answerLen1 >= 12) {
|
||||||
|
@ -934,9 +953,9 @@ void ReaderIso15693(uint32_t parameter) {
|
||||||
cmdlen = BuildReadBlockRequest(cmd, uid, i);
|
cmdlen = BuildReadBlockRequest(cmd, uid, i);
|
||||||
|
|
||||||
TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait);
|
TransmitTo15693Tag(ToSend, ToSendMax, &tsamples, &wait);
|
||||||
LogTrace(cmd, cmdlen, time_start, GetCountSspClk()-time_start, NULL, true);
|
LogTrace(cmd, cmdlen, time_start<<4, (GetCountSspClk()-time_start)<<4, NULL, true);
|
||||||
|
|
||||||
answerLen2 = GetIso15693AnswerFromTag(answer2, &samples, &elapsed);
|
answerLen2 = GetIso15693AnswerFromTag(answer2, &elapsed);
|
||||||
if (answerLen2 > 0) {
|
if (answerLen2 > 0) {
|
||||||
Dbprintf("READ SINGLE BLOCK %d returned %d octets:", i, answerLen2);
|
Dbprintf("READ SINGLE BLOCK %d returned %d octets:", i, answerLen2);
|
||||||
DbdecodeIso15693Answer(answerLen2, answer2);
|
DbdecodeIso15693Answer(answerLen2, answer2);
|
||||||
|
@ -969,8 +988,8 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) {
|
||||||
|
|
||||||
Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]);
|
Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]);
|
||||||
|
|
||||||
uint8_t buf[20];
|
uint8_t buf[ISO15_MAX_FRAME];
|
||||||
memset(buf, 0x00, 20);
|
memset(buf, 0x00, sizeof(buf));
|
||||||
|
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
|
||||||
|
@ -990,7 +1009,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) {
|
||||||
|
|
||||||
time_start = GetCountSspClk();
|
time_start = GetCountSspClk();
|
||||||
TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
|
TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
|
||||||
LogTrace(cmd, cmdlen, time_start, GetCountSspClk()-time_start, NULL, true);
|
LogTrace(cmd, cmdlen, time_start << 4, (GetCountSspClk() - time_start) << 4, NULL, true);
|
||||||
|
|
||||||
Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", ans,
|
Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", ans,
|
||||||
buf[0], buf[1], buf[2], buf[3],
|
buf[0], buf[1], buf[2], buf[3],
|
||||||
|
@ -1050,8 +1069,8 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
||||||
|
|
||||||
bool init = true;
|
bool init = true;
|
||||||
int buflen = 0;
|
int buflen = 0;
|
||||||
uint8_t buf[20];
|
uint8_t buf[ISO15_MAX_FRAME];
|
||||||
memset(buf, 0x00, 20);
|
memset(buf, 0x00, sizeof(buf));
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
DbpString("SEND");
|
DbpString("SEND");
|
||||||
|
@ -1061,7 +1080,7 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
||||||
buflen = SendDataTag(data, datalen, init, speed, (recv ? buf : NULL));
|
buflen = SendDataTag(data, datalen, init, speed, (recv ? buf : NULL));
|
||||||
|
|
||||||
if (recv) {
|
if (recv) {
|
||||||
buflen = (buflen > 20) ? 20 : buflen;
|
buflen = (buflen > ISO15_MAX_FRAME) ? ISO15_MAX_FRAME : buflen;
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
cmd_send(CMD_ACK, buflen, 0, 0, buf, buflen);
|
cmd_send(CMD_ACK, buflen, 0, 0, buf, buflen);
|
||||||
|
|
|
@ -136,29 +136,30 @@ void annotateIclass(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) {
|
void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) {
|
||||||
if(cmd[0] == 0x26) {
|
|
||||||
switch(cmd[1]){
|
switch(cmd[1]){
|
||||||
case ISO15693_INVENTORY :snprintf(exp, size, "INVENTORY");break;
|
case ISO15693_INVENTORY :snprintf(exp, size, "INVENTORY");return;
|
||||||
case ISO15693_STAYQUIET :snprintf(exp, size, "STAY_QUIET");break;
|
case ISO15693_STAYQUIET :snprintf(exp, size, "STAY_QUIET");return;
|
||||||
default :snprintf(exp,size,"?"); break;
|
case ISO15693_READBLOCK :snprintf(exp, size, "READBLOCK");return;
|
||||||
}
|
case ISO15693_WRITEBLOCK :snprintf(exp, size, "WRITEBLOCK");return;
|
||||||
} else if(cmd[0] == 0x02) {
|
case ISO15693_LOCKBLOCK :snprintf(exp, size, "LOCKBLOCK");return;
|
||||||
switch (cmd[1]) {
|
case ISO15693_READ_MULTI_BLOCK :snprintf(exp, size, "READ_MULTI_BLOCK");return;
|
||||||
case ISO15693_READBLOCK :snprintf(exp, size, "READBLOCK");break;
|
case ISO15693_SELECT :snprintf(exp, size, "SELECT");return;
|
||||||
case ISO15693_WRITEBLOCK :snprintf(exp, size, "WRITEBLOCK");break;
|
case ISO15693_RESET_TO_READY :snprintf(exp, size, "RESET_TO_READY");return;
|
||||||
case ISO15693_LOCKBLOCK :snprintf(exp, size, "LOCKBLOCK");break;
|
case ISO15693_WRITE_AFI :snprintf(exp, size, "WRITE_AFI");return;
|
||||||
case ISO15693_READ_MULTI_BLOCK :snprintf(exp, size, "READ_MULTI_BLOCK");break;
|
case ISO15693_LOCK_AFI :snprintf(exp, size, "LOCK_AFI");return;
|
||||||
case ISO15693_SELECT :snprintf(exp, size, "SELECT");break;
|
case ISO15693_WRITE_DSFID :snprintf(exp, size, "WRITE_DSFID");return;
|
||||||
case ISO15693_RESET_TO_READY :snprintf(exp, size, "RESET_TO_READY");break;
|
case ISO15693_LOCK_DSFID :snprintf(exp, size, "LOCK_DSFID");return;
|
||||||
case ISO15693_WRITE_AFI :snprintf(exp, size, "WRITE_AFI");break;
|
case ISO15693_GET_SYSTEM_INFO :snprintf(exp, size, "GET_SYSTEM_INFO");return;
|
||||||
case ISO15693_LOCK_AFI :snprintf(exp, size, "LOCK_AFI");break;
|
case ISO15693_READ_MULTI_SECSTATUS :snprintf(exp, size, "READ_MULTI_SECSTATUS");return;
|
||||||
case ISO15693_WRITE_DSFID :snprintf(exp, size, "WRITE_DSFID");break;
|
default: break;
|
||||||
case ISO15693_LOCK_DSFID :snprintf(exp, size, "LOCK_DSFID");break;
|
|
||||||
case ISO15693_GET_SYSTEM_INFO :snprintf(exp, size, "GET_SYSTEM_INFO");break;
|
|
||||||
case ISO15693_READ_MULTI_SECSTATUS :snprintf(exp, size, "READ_MULTI_SECSTATUS");break;
|
|
||||||
default: snprintf(exp,size,"?"); break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( cmd[1] >= 0x2D && cmd[1] <= 0x9F ) snprintf(exp, size, "Optional RFU");
|
||||||
|
else if ( cmd[1] >= 0xA0 && cmd[1] <= 0xDF ) snprintf(exp, size, "Cust IC MFG dependent");
|
||||||
|
else if ( cmd[1] >= 0xE0 && cmd[1] <= 0xFF ) snprintf(exp, size, "Proprietary IC MFG dependent");
|
||||||
|
else
|
||||||
|
snprintf(exp, size, "?");
|
||||||
}
|
}
|
||||||
|
|
||||||
void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){
|
void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){
|
||||||
|
|
322
client/cmdhf15.c
322
client/cmdhf15.c
|
@ -211,8 +211,10 @@ int getUID(uint8_t *buf) {
|
||||||
|
|
||||||
c.arg[0] = AddCrc(c.d.asBytes, 3);
|
c.arg[0] = AddCrc(c.d.asBytes, 3);
|
||||||
|
|
||||||
|
uint8_t retry;
|
||||||
|
|
||||||
// don't give up the at the first try
|
// don't give up the at the first try
|
||||||
for (uint8_t retry = 0; retry < 3; retry++) {
|
for (retry = 0; retry < 3; retry++) {
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
@ -226,6 +228,10 @@ int getUID(uint8_t *buf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // retry
|
} // retry
|
||||||
|
|
||||||
|
if ( retry >= 3 )
|
||||||
|
PrintAndLog("timeout while waiting for reply.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,6 +286,19 @@ int usage_15_read(void){
|
||||||
PrintAndLog("Acquire samples as Reader (enables carrier, send inquiry");
|
PrintAndLog("Acquire samples as Reader (enables carrier, send inquiry");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int usage_15_info(void){
|
||||||
|
PrintAndLog("Usage: hf 15 info [options] <uid|s|u|*>");
|
||||||
|
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(" start#: page number to start 0-255");
|
||||||
|
PrintAndLog(" count#: number of pages");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int usage_15_record(void){
|
int usage_15_record(void){
|
||||||
PrintAndLog("Record activity without enableing carrier");
|
PrintAndLog("Record activity without enableing carrier");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -393,6 +412,99 @@ int CmdHF15Read(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commandline handling: HF15 CMD SYSINFO
|
||||||
|
* get system information from tag/VICC
|
||||||
|
*/
|
||||||
|
int CmdHF15Info(const char *Cmd) {
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
if (strlen(Cmd)<1 || cmdp == 'h' || cmdp == 'H') return usage_15_info();
|
||||||
|
|
||||||
|
UsbCommand resp;
|
||||||
|
uint8_t *recv;
|
||||||
|
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||||
|
uint8_t *req = c.d.asBytes;
|
||||||
|
int reqlen = 0;
|
||||||
|
char cmdbuf[100];
|
||||||
|
char *cmd = cmdbuf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
strncpy(cmd, Cmd, 99);
|
||||||
|
|
||||||
|
int cmdisok = prepareHF15Cmd(&cmd, &c, ISO15_CMD_SYSINFO);
|
||||||
|
if ( !cmdisok )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
reqlen = AddCrc(req, c.arg[0]);
|
||||||
|
c.arg[0] = reqlen;
|
||||||
|
|
||||||
|
PrintAndLog("cmd %s", sprint_hex(c.d.asBytes, reqlen) );
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
|
||||||
|
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
||||||
|
PrintAndLog("iso15693 card select failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t status = resp.arg[0];
|
||||||
|
|
||||||
|
if ( status < 2 ) {
|
||||||
|
PrintAndLog("iso15693 card select failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
PrintAndLog("len %u, recv %s",status, sprint_hex(resp.d.asBytes, status) );
|
||||||
|
|
||||||
|
recv = resp.d.asBytes;
|
||||||
|
|
||||||
|
if (ISO15_CRC_CHECK == Crc(recv, status)) {
|
||||||
|
PrintAndLog("CRC failed");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( recv[0] & ISO15_RES_ERROR ) {
|
||||||
|
PrintAndLog("iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog(" UID : %s", sprintUID(NULL, recv+2));
|
||||||
|
PrintAndLog(" MANUFACTURER : %s", getTagInfo_15(recv+2));
|
||||||
|
PrintAndLog(" raw : %s", sprint_hex(recv, status-2));
|
||||||
|
|
||||||
|
i = 10;
|
||||||
|
|
||||||
|
// DSFID
|
||||||
|
if (recv[1] & 0x01)
|
||||||
|
PrintAndLog(" - DSFID supported, set to %02X", recv[i++]);
|
||||||
|
else
|
||||||
|
PrintAndLog(" - DSFID not supported");
|
||||||
|
|
||||||
|
// AFI
|
||||||
|
if (recv[1] & 0x02)
|
||||||
|
PrintAndLog(" - AFI supported, set to %03X", recv[i++]);
|
||||||
|
else
|
||||||
|
PrintAndLog(" - AFI not supported");
|
||||||
|
|
||||||
|
// memory
|
||||||
|
if (recv[1] & 0x04) {
|
||||||
|
PrintAndLog(" - Tag provides info on memory layout (vendor dependent)");
|
||||||
|
PrintAndLog(" %i (or %i) bytes/page x %i pages \n\r", (recv[i+1] & 0x1F) + 1, (recv[i+1] & 0x1F), recv[i]+1);
|
||||||
|
i += 2;
|
||||||
|
} else {
|
||||||
|
PrintAndLog(" - Tag does not provide information on memory layout");
|
||||||
|
}
|
||||||
|
|
||||||
|
// IC reference
|
||||||
|
if (recv[1] & 0x08)
|
||||||
|
PrintAndLog(" - IC reference given: %02X", recv[i++]);
|
||||||
|
else
|
||||||
|
PrintAndLog(" - IC reference not given");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Record Activity without enabeling carrier
|
// Record Activity without enabeling carrier
|
||||||
//helptext
|
//helptext
|
||||||
int CmdHF15Record(const char *Cmd) {
|
int CmdHF15Record(const char *Cmd) {
|
||||||
|
@ -469,26 +581,33 @@ int CmdHF15DumpMem(const char*Cmd) {
|
||||||
if (cmdp == 'h' || cmdp == 'H') return usage_15_dumpmem();
|
if (cmdp == 'h' || cmdp == 'H') return usage_15_dumpmem();
|
||||||
|
|
||||||
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
||||||
|
|
||||||
|
if (!getUID(uid)) {
|
||||||
|
PrintAndLog("No Tag found.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// detect blocksize from card :)
|
||||||
|
|
||||||
|
PrintAndLog("Reading memory from tag UID %s", sprintUID(NULL, uid));
|
||||||
|
PrintAndLog("Tag Info: %s", getTagInfo_15(uid));
|
||||||
|
|
||||||
|
int reqlen = 0, blocknum = 0;
|
||||||
uint8_t *recv = NULL;
|
uint8_t *recv = NULL;
|
||||||
|
|
||||||
|
uint8_t data[256*4] = {0};
|
||||||
|
memset(data, sizeof(data), 0);
|
||||||
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||||
uint8_t *req = c.d.asBytes;
|
uint8_t *req = c.d.asBytes;
|
||||||
req[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
req[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||||
req[1] = ISO15_CMD_READ;
|
req[1] = ISO15_CMD_READ;
|
||||||
|
|
||||||
int reqlen = 0, blocknum = 0;
|
// copy uid to read command
|
||||||
|
memcpy(req+2, uid, 8);
|
||||||
|
|
||||||
if (!getUID(uid)) {
|
for (int retry = 0; retry < 5; retry++) {
|
||||||
PrintAndLog("No Tag found.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLog("Reading memory from tag UID=%s", sprintUID(NULL, uid));
|
|
||||||
PrintAndLog("Tag Info: %s", getTagInfo_15(uid));
|
|
||||||
|
|
||||||
for (int retry=0; retry<5; retry++) {
|
|
||||||
|
|
||||||
memcpy(&req[2], uid, 8);
|
|
||||||
req[10] = blocknum;
|
req[10] = blocknum;
|
||||||
reqlen = AddCrc(req, 11);
|
reqlen = AddCrc(req, 11);
|
||||||
c.arg[0] = reqlen;
|
c.arg[0] = reqlen;
|
||||||
|
@ -496,7 +615,8 @@ int CmdHF15DumpMem(const char*Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||||
|
|
||||||
uint8_t len = resp.arg[0];
|
uint8_t len = resp.arg[0];
|
||||||
recv = resp.d.asBytes;
|
recv = resp.d.asBytes;
|
||||||
|
|
||||||
|
@ -504,16 +624,27 @@ int CmdHF15DumpMem(const char*Cmd) {
|
||||||
|
|
||||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
if (!(recv[0] & ISO15_RES_ERROR)) {
|
||||||
|
|
||||||
|
memcpy(data + (blocknum * 4), resp.d.asBytes + 1, 4);
|
||||||
|
|
||||||
retry = 0;
|
retry = 0;
|
||||||
PrintAndLog("%Block %02x | %s", blocknum, sprint_hex_ascii( recv, len - 2 ) );
|
|
||||||
blocknum++;
|
blocknum++;
|
||||||
|
|
||||||
|
printf("."); fflush(stdout);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLog("Tag returned Error %i: %s", recv[1], TagErrorStr(recv[1]) );
|
PrintAndLog("Tag returned Error %i: %s", recv[1], TagErrorStr(recv[1]) );
|
||||||
return 1;
|
break;
|
||||||
|
// return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
PrintAndLog("Blk| data | ascii");
|
||||||
|
PrintAndLog("---+---------------------+----------");
|
||||||
|
for (int i=0; i < blocknum; i++) {
|
||||||
|
PrintAndLog("%02x | %s", i, sprint_hex_ascii(data + (i*4) , 4 ) );
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: need fix
|
// TODO: need fix
|
||||||
// if (resp.arg[0]<3)
|
// if (resp.arg[0]<3)
|
||||||
|
@ -524,11 +655,20 @@ int CmdHF15DumpMem(const char*Cmd) {
|
||||||
// PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
|
// PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdHF15List(const char *Cmd) {
|
||||||
|
//PrintAndLog("Deprecated command, use 'hf list 15' instead");
|
||||||
|
CmdHFList("15");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// "HF 15" interface
|
// "HF 15" interface
|
||||||
static command_t CommandTable15[] = {
|
static command_t CommandTable15[] = {
|
||||||
{"help", CmdHF15Help, 1, "This help"},
|
{"help", CmdHF15Help, 1, "This help"},
|
||||||
|
{"list", CmdHF15List, 0, "[Deprecated] List ISO 15693 history"},
|
||||||
{"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
|
{"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
|
||||||
{"read", CmdHF15Read, 0, "Read ISO 15693 tag"},
|
{"read", CmdHF15Read, 0, "Read ISO 15693 tag"},
|
||||||
|
{"info", CmdHF15Info, 0, "Get Card Information"},
|
||||||
{"record", CmdHF15Record, 0, "Record Samples (ISO 15693)"},
|
{"record", CmdHF15Record, 0, "Record Samples (ISO 15693)"},
|
||||||
{"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
|
{"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
|
||||||
{"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
|
{"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
|
||||||
|
@ -553,36 +693,6 @@ int CmdHF15Help(const char *Cmd) {
|
||||||
|
|
||||||
// "HF 15 Cmd" Interface
|
// "HF 15 Cmd" Interface
|
||||||
// Allows direct communication with the tag on command level
|
// Allows direct communication with the tag on command level
|
||||||
int CmdHF15CmdInquiry(const char *Cmd) {
|
|
||||||
|
|
||||||
UsbCommand resp;
|
|
||||||
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;
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommand(&c);
|
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
|
||||||
if (resp.arg[0] >= 12) {
|
|
||||||
recv = resp.d.asBytes;
|
|
||||||
PrintAndLog("UID = %s", sprintUID(NULL, recv+2) );
|
|
||||||
PrintAndLog("Tag Info: %s", getTagInfo_15( recv+2) );
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Response to short, just %i bytes. No tag?\n", resp.arg[0]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrintAndLog("timeout while waiting for reply.");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turns debugging on(1)/off(0)
|
// Turns debugging on(1)/off(0)
|
||||||
int CmdHF15CmdDebug( const char *Cmd) {
|
int CmdHF15CmdDebug( const char *Cmd) {
|
||||||
|
@ -690,7 +800,7 @@ int CmdHF15CmdRaw(const char *Cmd) {
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* **cmd command line
|
* **cmd command line
|
||||||
*/
|
*/
|
||||||
int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdlen) {
|
int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd) {
|
||||||
int temp;
|
int temp;
|
||||||
uint8_t *req = c->d.asBytes;
|
uint8_t *req = c->d.asBytes;
|
||||||
uint8_t uid[8] = {0x00};
|
uint8_t uid[8] = {0x00};
|
||||||
|
@ -724,43 +834,40 @@ int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdle
|
||||||
case 'S':
|
case 'S':
|
||||||
// you must have selected the tag earlier
|
// you must have selected the tag earlier
|
||||||
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_SELECT;
|
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_SELECT;
|
||||||
memcpy(&req[reqlen], &iso15cmd[0], iso15cmdlen);
|
req[reqlen++] = iso15cmd;
|
||||||
reqlen += iso15cmdlen;
|
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'U':
|
case 'U':
|
||||||
// unaddressed mode may not be supported by all vendors
|
// unaddressed mode may not be supported by all vendors
|
||||||
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY;
|
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY;
|
||||||
memcpy(&req[reqlen], &iso15cmd[0], iso15cmdlen);
|
req[reqlen++] = iso15cmd;
|
||||||
reqlen += iso15cmdlen;
|
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
// we scan for the UID ourself
|
// we scan for the UID ourself
|
||||||
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||||
memcpy(&req[reqlen], &iso15cmd[0], iso15cmdlen);
|
req[reqlen++] = iso15cmd;
|
||||||
reqlen += iso15cmdlen;
|
|
||||||
if (!getUID(uid)) {
|
if (!getUID(uid)) {
|
||||||
PrintAndLog("No Tag found");
|
PrintAndLog("No Tag found");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(req+reqlen, uid, 8);
|
memcpy(&req[reqlen], uid, sizeof(uid));
|
||||||
PrintAndLog("Detected UID %s", sprintUID(NULL, uid));
|
PrintAndLog("Detected UID %s", sprintUID(NULL, uid));
|
||||||
reqlen += 8;
|
reqlen += sizeof(uid);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||||
memcpy(&req[reqlen], &iso15cmd[0], iso15cmdlen);
|
req[reqlen++] = iso15cmd;
|
||||||
reqlen += iso15cmdlen;
|
|
||||||
|
|
||||||
// parse UID
|
// parse UID
|
||||||
for (int i=0; i<8 && (*cmd)[i*2] && (*cmd)[i*2+1]; i++) {
|
for (int i=0; i<8 && (*cmd)[i*2] && (*cmd)[i*2+1]; i++) {
|
||||||
sscanf((char[]){(*cmd)[i*2], (*cmd)[i*2+1],0}, "%X", &temp);
|
sscanf((char[]){(*cmd)[i*2], (*cmd)[i*2+1],0}, "%X", &temp);
|
||||||
uid[7-i] = temp&0xff;
|
uid[7-i] = temp & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("Using UID %s", sprintUID(NULL, uid));
|
PrintAndLog("Using UID %s", sprintUID(NULL, uid));
|
||||||
memcpy(&req[reqlen], &uid[0], 8);
|
memcpy(&req[reqlen], uid, sizeof(uid));
|
||||||
reqlen += 8;
|
reqlen += sizeof(uid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// skip to next space
|
// skip to next space
|
||||||
|
@ -772,95 +879,6 @@ int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdle
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Commandline handling: HF15 CMD SYSINFO
|
|
||||||
* get system information from tag/VICC
|
|
||||||
*/
|
|
||||||
int CmdHF15CmdSysinfo(const char *Cmd) {
|
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
|
||||||
if (strlen(Cmd)<1 || cmdp == 'h' || cmdp == 'H') {
|
|
||||||
PrintAndLog("Usage: hf 15 cmd sysinfo [options] <uid|s|u|*>");
|
|
||||||
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(" start#: page number to start 0-255");
|
|
||||||
PrintAndLog(" count#: number of pages");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
UsbCommand resp;
|
|
||||||
uint8_t *recv;
|
|
||||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
|
||||||
uint8_t *req = c.d.asBytes;
|
|
||||||
int reqlen = 0;
|
|
||||||
char cmdbuf[100];
|
|
||||||
char *cmd = cmdbuf;
|
|
||||||
char output[2048] = "\0";
|
|
||||||
int i;
|
|
||||||
|
|
||||||
strncpy(cmd, Cmd, 99);
|
|
||||||
|
|
||||||
prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_SYSINFO},1);
|
|
||||||
reqlen = c.arg[0];
|
|
||||||
|
|
||||||
reqlen = AddCrc(req, reqlen);
|
|
||||||
c.arg[0] = reqlen;
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommand(&c);
|
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) && resp.arg[0] > 2) {
|
|
||||||
recv = resp.d.asBytes;
|
|
||||||
if (ISO15_CRC_CHECK == Crc(recv,resp.arg[0])) {
|
|
||||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
|
||||||
*output=0; // reset outputstring
|
|
||||||
for ( i=1; i<resp.arg[0]-2; i++) {
|
|
||||||
sprintf(output+strlen(output), "%02X ", recv[i]);
|
|
||||||
}
|
|
||||||
strcat(output, "\n\r");
|
|
||||||
strcat(output, "UID = ");
|
|
||||||
strcat(output, sprintUID(NULL, recv+2));
|
|
||||||
strcat(output, "\n\r");
|
|
||||||
strcat(output, getTagInfo_15(recv+2)); //ABC
|
|
||||||
strcat(output, "\n\r");
|
|
||||||
i = 10;
|
|
||||||
if (recv[1] & 0x01)
|
|
||||||
sprintf(output+strlen(output),"DSFID supported, set to %02X\n\r",recv[i++]);
|
|
||||||
else
|
|
||||||
strcat(output,"DSFID not supported\n\r");
|
|
||||||
if (recv[1] & 0x02)
|
|
||||||
sprintf(output+strlen(output),"AFI supported, set to %03X\n\r",recv[i++]);
|
|
||||||
else
|
|
||||||
strcat(output,"AFI not supported\n\r");
|
|
||||||
if (recv[1] & 0x04) {
|
|
||||||
strcat(output,"Tag provides info on memory layout (vendor dependent)\n\r");
|
|
||||||
sprintf(output+strlen(output)," %i (or %i) bytes/page x %i pages \n\r",
|
|
||||||
(recv[i+1]&0x1F)+1, (recv[i+1]&0x1F), recv[i]+1);
|
|
||||||
i+=2;
|
|
||||||
} else
|
|
||||||
strcat(output,"Tag does not provide information on memory layout\n\r");
|
|
||||||
if (recv[1] & 0x08) sprintf(output+strlen(output),"IC reference given: %02X\n\r",recv[i++]);
|
|
||||||
else strcat(output,"IC reference not given\n\r");
|
|
||||||
|
|
||||||
|
|
||||||
PrintAndLog("%s",output);
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Tag returned Error %i: %s",recv[0],TagErrorStr(recv[0]));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrintAndLog("CRC failed");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrintAndLog("timeout while waiting for reply.");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Commandline handling: HF15 CMD READMULTI
|
* Commandline handling: HF15 CMD READMULTI
|
||||||
* Read multiple blocks at once (not all tags support this)
|
* Read multiple blocks at once (not all tags support this)
|
||||||
|
@ -893,7 +911,7 @@ int CmdHF15CmdReadmulti(const char *Cmd) {
|
||||||
|
|
||||||
strncpy(cmd, Cmd, 99);
|
strncpy(cmd, Cmd, 99);
|
||||||
|
|
||||||
prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_READMULTI},1);
|
prepareHF15Cmd(&cmd, &c, ISO15_CMD_READMULTI);
|
||||||
reqlen = c.arg[0];
|
reqlen = c.arg[0];
|
||||||
|
|
||||||
pagenum = strtol(cmd, NULL, 0);
|
pagenum = strtol(cmd, NULL, 0);
|
||||||
|
@ -978,7 +996,7 @@ int CmdHF15CmdRead(const char *Cmd) {
|
||||||
|
|
||||||
strncpy(cmd, Cmd, 99);
|
strncpy(cmd, Cmd, 99);
|
||||||
|
|
||||||
prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_READ},1);
|
prepareHF15Cmd(&cmd, &c,ISO15_CMD_READ);
|
||||||
reqlen = c.arg[0];
|
reqlen = c.arg[0];
|
||||||
|
|
||||||
pagenum = strtol(cmd, NULL, 0);
|
pagenum = strtol(cmd, NULL, 0);
|
||||||
|
@ -1052,7 +1070,7 @@ int CmdHF15CmdWrite(const char *Cmd) {
|
||||||
|
|
||||||
strncpy(cmd,Cmd,99);
|
strncpy(cmd,Cmd,99);
|
||||||
|
|
||||||
prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_WRITE},1);
|
prepareHF15Cmd(&cmd, &c, ISO15_CMD_WRITE);
|
||||||
reqlen=c.arg[0];
|
reqlen=c.arg[0];
|
||||||
|
|
||||||
// *cmd -> page num ; *cmd2 -> data
|
// *cmd -> page num ; *cmd2 -> data
|
||||||
|
@ -1100,12 +1118,10 @@ int CmdHF15CmdWrite(const char *Cmd) {
|
||||||
|
|
||||||
static command_t CommandTable15Cmd[] = {
|
static command_t CommandTable15Cmd[] = {
|
||||||
{"help", CmdHF15CmdHelp, 1, "This Help"},
|
{"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"},
|
// {"select", CmdHF15CmdSelect, 0, "Select an tag with a specific UID for further commands"},
|
||||||
{"read", CmdHF15CmdRead, 0, "Read a block"},
|
{"read", CmdHF15CmdRead, 0, "Read a block"},
|
||||||
{"write", CmdHF15CmdWrite, 0, "Write a block"},
|
{"write", CmdHF15CmdWrite, 0, "Write a block"},
|
||||||
{"readmulti", CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
|
{"readmulti", CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
|
||||||
{"sysinfo", CmdHF15CmdSysinfo, 0, "Get Card Information"},
|
|
||||||
{"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"},
|
{"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ int CmdHF15(const char *Cmd);
|
||||||
|
|
||||||
extern int CmdHF15Demod(const char *Cmd);
|
extern int CmdHF15Demod(const char *Cmd);
|
||||||
extern int CmdHF15Read(const char *Cmd);
|
extern int CmdHF15Read(const char *Cmd);
|
||||||
|
extern int CmdHF15Info(const char *Cmd);
|
||||||
extern int CmdHF15Record(const char *Cmd);
|
extern int CmdHF15Record(const char *Cmd);
|
||||||
extern int HF15Reader(const char *Cmd, bool verbose);
|
extern int HF15Reader(const char *Cmd, bool verbose);
|
||||||
extern int CmdHF15Reader(const char *Cmd);
|
extern int CmdHF15Reader(const char *Cmd);
|
||||||
|
@ -25,9 +26,7 @@ extern int CmdHF15DumpMem(const char*Cmd);
|
||||||
extern int CmdHF15CmdDebug( const char *Cmd);
|
extern int CmdHF15CmdDebug( const char *Cmd);
|
||||||
|
|
||||||
// cmd sub.
|
// cmd sub.
|
||||||
extern int CmdHF15CmdInquiry(const char *Cmd);
|
|
||||||
extern int CmdHF15CmdRaw(const char *cmd);
|
extern int CmdHF15CmdRaw(const char *cmd);
|
||||||
extern int CmdHF15CmdSysinfo(const char *Cmd);
|
|
||||||
extern int CmdHF15CmdReadmulti(const char *Cmd);
|
extern int CmdHF15CmdReadmulti(const char *Cmd);
|
||||||
extern int CmdHF15CmdRead(const char *Cmd);
|
extern int CmdHF15CmdRead(const char *Cmd);
|
||||||
extern int CmdHF15CmdWrite(const char *Cmd);
|
extern int CmdHF15CmdWrite(const char *Cmd);
|
||||||
|
@ -35,4 +34,5 @@ extern int CmdHF15CmdWrite(const char *Cmd);
|
||||||
extern int CmdHF15CmdHelp(const char*Cmd);
|
extern int CmdHF15CmdHelp(const char*Cmd);
|
||||||
extern int CmdHF15Help(const char*Cmd);
|
extern int CmdHF15Help(const char*Cmd);
|
||||||
|
|
||||||
|
extern int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue