add: Topaz mode for "hf 14a raw" (new option -T)

chg: allow tracing without parity
chg: make "hf list topaz" aware of additional commands for Dynamic Memory Model
This commit is contained in:
pwpiwi 2015-03-20 21:06:51 +01:00
commit 48ece4a750
7 changed files with 182 additions and 51 deletions

View file

@ -171,18 +171,19 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
traceLen += iLen; traceLen += iLen;
// parity bytes // parity bytes
if (parity != NULL && iLen != 0) { if (iLen != 0) {
memcpy(trace + traceLen, parity, num_paritybytes); if (parity != NULL) {
memcpy(trace + traceLen, parity, num_paritybytes);
} else {
memset(trace + traceLen, 0x00, num_paritybytes);
}
} }
traceLen += num_paritybytes; traceLen += num_paritybytes;
if(traceLen +4 < max_traceLen)
{ //If it hadn't been cleared, for whatever reason..
memset(trace+traceLen,0x44, 4);
}
return TRUE; return TRUE;
} }
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag) int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
{ {
/** /**
@ -224,6 +225,8 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
return TRUE; return TRUE;
} }
// Emulator memory // Emulator memory
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){ uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
uint8_t* mem = BigBuf_get_EM_addr(); uint8_t* mem = BigBuf_get_EM_addr();

View file

@ -213,6 +213,12 @@ void AppendCrc14443a(uint8_t* data, int len)
ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1); ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
} }
void AppendCrc14443b(uint8_t* data, int len)
{
ComputeCrc14443(CRC_14443_B,data,len,data+len,data+len+1);
}
//============================================================================= //=============================================================================
// ISO 14443 Type A - Miller decoder // ISO 14443 Type A - Miller decoder
//============================================================================= //=============================================================================
@ -238,8 +244,6 @@ static tUart Uart;
// 0111 - a 2 tick wide pause shifted left // 0111 - a 2 tick wide pause shifted left
// 1001 - a 2 tick wide pause shifted right // 1001 - a 2 tick wide pause shifted right
const bool Mod_Miller_LUT[] = { const bool Mod_Miller_LUT[] = {
// TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE,
// TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE
FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE,
FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
}; };
@ -279,8 +283,8 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
// Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111) // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
// we therefore look for a ...xx11111111111100x11111xxxxxx... pattern // we therefore look for a ...xx11111111111100x11111xxxxxx... pattern
// (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's) // (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's)
#define ISO14443A_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000 #define ISO14443A_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000
#define ISO14443A_STARTBIT_PATTERN 0x07FF8F80 // pattern is 00000111 11111111 10001111 10000000 #define ISO14443A_STARTBIT_PATTERN 0x07FF8F80 // pattern is 00000111 11111111 10001111 10000000
if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7; if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7;
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6; else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6;
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5; else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5;
@ -655,7 +659,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
TRUE)) break; TRUE)) break;
} }
/* And ready to receive another command. */ /* And ready to receive another command. */
UartInit(receivedCmd, receivedCmdPar); UartReset();
/* And also reset the demod code, which might have been */ /* And also reset the demod code, which might have been */
/* false-triggered by the commands from the reader. */ /* false-triggered by the commands from the reader. */
DemodReset(); DemodReset();
@ -680,6 +684,9 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
// And ready to receive another response. // And ready to receive another response.
DemodReset(); DemodReset();
// And reset the Miller decoder including itS (now outdated) input buffer
UartInit(receivedCmd, receivedCmdPar);
LED_C_OFF(); LED_C_OFF();
} }
TagIsActive = (Demod.state != DEMOD_UNSYNCD); TagIsActive = (Demod.state != DEMOD_UNSYNCD);
@ -1337,7 +1344,7 @@ void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8
} }
// Only transmit parity bit if we transmitted a complete byte // Only transmit parity bit if we transmitted a complete byte
if (j == 8) { if (j == 8 && parity != NULL) {
// Get the parity bit // Get the parity bit
if (parity[i>>3] & (0x80 >> (i&0x0007))) { if (parity[i>>3] & (0x80 >> (i&0x0007))) {
// Sequence X // Sequence X
@ -1631,6 +1638,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
} }
} }
void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing) void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
{ {
CodeIso14443aBitsAsReaderPar(frame, bits, par); CodeIso14443aBitsAsReaderPar(frame, bits, par);
@ -1646,11 +1654,13 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t
} }
} }
void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing) void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing)
{ {
ReaderTransmitBitsPar(frame, len*8, par, timing); ReaderTransmitBitsPar(frame, len*8, par, timing);
} }
void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
{ {
// Generate parity and redirect // Generate parity and redirect
@ -1659,6 +1669,7 @@ void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
ReaderTransmitBitsPar(frame, len, par, timing); ReaderTransmitBitsPar(frame, len, par, timing);
} }
void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
{ {
// Generate parity and redirect // Generate parity and redirect
@ -1932,15 +1943,38 @@ void ReaderIso14443a(UsbCommand *c)
if(param & ISO14A_RAW) { if(param & ISO14A_RAW) {
if(param & ISO14A_APPEND_CRC) { if(param & ISO14A_APPEND_CRC) {
AppendCrc14443a(cmd,len); if(param & ISO14A_TOPAZMODE) {
AppendCrc14443b(cmd,len);
} else {
AppendCrc14443a(cmd,len);
}
len += 2; len += 2;
if (lenbits) lenbits += 16; if (lenbits) lenbits += 16;
} }
if(lenbits>0) { if(lenbits>0) { // want to send a specific number of bits (e.g. short commands)
GetParity(cmd, lenbits/8, par); if(param & ISO14A_TOPAZMODE) {
ReaderTransmitBitsPar(cmd, lenbits, par, NULL); int bits_to_send = lenbits;
} else { uint16_t i = 0;
ReaderTransmit(cmd,len, NULL); ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL); // first byte is always short (7bits) and no parity
bits_to_send -= 7;
while (bits_to_send > 0) {
ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 8), NULL, NULL); // following bytes are 8 bit and no parity
bits_to_send -= 8;
}
} else {
GetParity(cmd, lenbits/8, par);
ReaderTransmitBitsPar(cmd, lenbits, par, NULL); // bytes are 8 bit with odd parity
}
} else { // want to send complete bytes only
if(param & ISO14A_TOPAZMODE) {
uint16_t i = 0;
ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL); // first byte: 7 bits, no paritiy
while (i < len) {
ReaderTransmitBitsPar(&cmd[i++], 8, NULL, NULL); // following bytes: 8 bits, no paritiy
}
} else {
ReaderTransmit(cmd,len, NULL); // 8 bits, odd parity
}
} }
arg0 = ReaderReceive(buf, par); arg0 = ReaderReceive(buf, par);
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf)); cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
@ -2824,6 +2858,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
// And ready to receive another response. // And ready to receive another response.
DemodReset(); DemodReset();
// And reset the Miller decoder including its (now outdated) input buffer
UartInit(receivedCmd, receivedCmdPar);
} }
TagIsActive = (Demod.state != DEMOD_UNSYNCD); TagIsActive = (Demod.state != DEMOD_UNSYNCD);
} }

View file

@ -145,7 +145,6 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
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)
{ {
switch(cmd[0]) { switch(cmd[0]) {
case TOPAZ_REQA :snprintf(exp, size, "REQA");break; case TOPAZ_REQA :snprintf(exp, size, "REQA");break;
case TOPAZ_WUPA :snprintf(exp, size, "WUPA");break; case TOPAZ_WUPA :snprintf(exp, size, "WUPA");break;
@ -154,6 +153,10 @@ void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
case TOPAZ_READ :snprintf(exp, size, "READ");break; case TOPAZ_READ :snprintf(exp, size, "READ");break;
case TOPAZ_WRITE_E :snprintf(exp, size, "WRITE-E");break; case TOPAZ_WRITE_E :snprintf(exp, size, "WRITE-E");break;
case TOPAZ_WRITE_NE :snprintf(exp, size, "WRITE-NE");break; case TOPAZ_WRITE_NE :snprintf(exp, size, "WRITE-NE");break;
case TOPAZ_RSEG :snprintf(exp, size, "RSEG");break;
case TOPAZ_READ8 :snprintf(exp, size, "READ8");break;
case TOPAZ_WRITE_E8 :snprintf(exp, size, "WRITE-E8");break;
case TOPAZ_WRITE_NE8 :snprintf(exp, size, "WRITE-NE8");break;
default: snprintf(exp,size,"?"); break; default: snprintf(exp,size,"?"); break;
} }
} }
@ -319,7 +322,7 @@ bool next_record_is_response(uint16_t tracepos, uint8_t *trace)
bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, uint8_t *trace, uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len) bool merge_topaz_reader_frames(uint32_t timestamp, uint32_t *duration, uint16_t *tracepos, uint16_t traceLen, uint8_t *trace, uint8_t *frame, uint8_t *topaz_reader_command, uint16_t *data_len)
{ {
#define MAX_TOPAZ_READER_CMD_LEN 9 #define MAX_TOPAZ_READER_CMD_LEN 16
uint32_t last_timestamp = timestamp + *duration; uint32_t last_timestamp = timestamp + *duration;
@ -479,7 +482,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
int num_lines = MIN((data_len - 1)/16 + 1, 16); int num_lines = MIN((data_len - 1)/16 + 1, 16);
for (int j = 0; j < num_lines ; j++) { for (int j = 0; j < num_lines ; j++) {
if (j == 0) { if (j == 0) {
PrintAndLog(" %9d | %9d | %s |%-64s | %s| %s", PrintAndLog(" %10d | %10d | %s |%-64s | %s| %s",
(timestamp - first_timestamp), (timestamp - first_timestamp),
(EndOfTransmissionTimestamp - first_timestamp), (EndOfTransmissionTimestamp - first_timestamp),
(isResponse ? "Tag" : "Rdr"), (isResponse ? "Tag" : "Rdr"),
@ -487,7 +490,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
(j == num_lines-1) ? crc : " ", (j == num_lines-1) ? crc : " ",
(j == num_lines-1) ? explanation : ""); (j == num_lines-1) ? explanation : "");
} else { } else {
PrintAndLog(" | | |%-64s | %s| %s", PrintAndLog(" | | |%-64s | %s| %s",
line[j], line[j],
(j == num_lines-1) ? crc : " ", (j == num_lines-1) ? crc : " ",
(j == num_lines-1) ? explanation : ""); (j == num_lines-1) ? explanation : "");

View file

@ -509,20 +509,22 @@ int CmdHF14ASnoop(const char *Cmd) {
return 0; return 0;
} }
int CmdHF14ACmdRaw(const char *cmd) { int CmdHF14ACmdRaw(const char *cmd) {
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
uint8_t reply=1; bool reply=1;
uint8_t crc=0; bool crc = FALSE;
uint8_t power=0; bool power = FALSE;
uint8_t active=0; bool active = FALSE;
uint8_t active_select=0; bool active_select = FALSE;
uint16_t numbits=0; uint16_t numbits = 0;
uint32_t timeout=0; bool bTimeout = FALSE;
uint8_t bTimeout=0; uint32_t timeout = 0;
bool topazmode = FALSE;
char buf[5]=""; char buf[5]="";
int i=0; int i = 0;
uint8_t data[USB_CMD_DATA_SIZE]; uint8_t data[USB_CMD_DATA_SIZE];
uint16_t datalen=0; uint16_t datalen = 0;
uint32_t temp; uint32_t temp;
if (strlen(cmd)<2) { if (strlen(cmd)<2) {
@ -534,9 +536,11 @@ int CmdHF14ACmdRaw(const char *cmd) {
PrintAndLog(" -s active signal field ON with select"); PrintAndLog(" -s active signal field ON with select");
PrintAndLog(" -b number of bits to send. Useful for send partial byte"); PrintAndLog(" -b number of bits to send. Useful for send partial byte");
PrintAndLog(" -t timeout in ms"); PrintAndLog(" -t timeout in ms");
PrintAndLog(" -T use Topaz protocol to send command");
return 0; return 0;
} }
// strip // strip
while (*cmd==' ' || *cmd=='\t') cmd++; while (*cmd==' ' || *cmd=='\t') cmd++;
@ -545,19 +549,19 @@ int CmdHF14ACmdRaw(const char *cmd) {
if (cmd[i]=='-') { if (cmd[i]=='-') {
switch (cmd[i+1]) { switch (cmd[i+1]) {
case 'r': case 'r':
reply=0; reply = FALSE;
break; break;
case 'c': case 'c':
crc=1; crc = TRUE;
break; break;
case 'p': case 'p':
power=1; power = TRUE;
break; break;
case 'a': case 'a':
active=1; active = TRUE;
break; break;
case 's': case 's':
active_select=1; active_select = TRUE;
break; break;
case 'b': case 'b':
sscanf(cmd+i+2,"%d",&temp); sscanf(cmd+i+2,"%d",&temp);
@ -567,13 +571,16 @@ int CmdHF14ACmdRaw(const char *cmd) {
i-=2; i-=2;
break; break;
case 't': case 't':
bTimeout=1; bTimeout = TRUE;
sscanf(cmd+i+2,"%d",&temp); sscanf(cmd+i+2,"%d",&temp);
timeout = temp; timeout = temp;
i+=3; i+=3;
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; } while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
i-=2; i-=2;
break; break;
case 'T':
topazmode = TRUE;
break;
default: default:
PrintAndLog("Invalid option"); PrintAndLog("Invalid option");
return 0; return 0;
@ -603,10 +610,15 @@ int CmdHF14ACmdRaw(const char *cmd) {
PrintAndLog("Invalid char on input"); PrintAndLog("Invalid char on input");
return 0; return 0;
} }
if(crc && datalen>0 && datalen<sizeof(data)-2) if(crc && datalen>0 && datalen<sizeof(data)-2)
{ {
uint8_t first, second; uint8_t first, second;
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second); if (topazmode) {
ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
} else {
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
}
data[datalen++] = first; data[datalen++] = first;
data[datalen++] = second; data[datalen++] = second;
} }
@ -619,7 +631,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
} }
if(bTimeout){ if(bTimeout){
#define MAX_TIMEOUT 40542464 // (2^32-1) * (8*16) / 13560000Hz * 1000ms/s = #define MAX_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
c.arg[0] |= ISO14A_SET_TIMEOUT; c.arg[0] |= ISO14A_SET_TIMEOUT;
if(timeout > MAX_TIMEOUT) { if(timeout > MAX_TIMEOUT) {
timeout = MAX_TIMEOUT; timeout = MAX_TIMEOUT;
@ -627,11 +639,16 @@ int CmdHF14ACmdRaw(const char *cmd) {
} }
c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
} }
if(power) if(power)
c.arg[0] |= ISO14A_NO_DISCONNECT; c.arg[0] |= ISO14A_NO_DISCONNECT;
if(datalen>0)
if(datalen > 0)
c.arg[0] |= ISO14A_RAW; c.arg[0] |= ISO14A_RAW;
if(topazmode)
c.arg[0] |= ISO14A_TOPAZMODE;
// Max buffer is USB_CMD_DATA_SIZE // Max buffer is USB_CMD_DATA_SIZE
c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); c.arg[1] = (datalen & 0xFFFF) | (numbits << 16);
memcpy(c.d.asBytes,data,datalen); memcpy(c.d.asBytes,data,datalen);
@ -647,6 +664,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
return 0; return 0;
} }
static void waitCmd(uint8_t iSelect) static void waitCmd(uint8_t iSelect)
{ {
uint8_t *recv; uint8_t *recv;
@ -656,7 +674,7 @@ static void waitCmd(uint8_t iSelect)
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
recv = resp.d.asBytes; recv = resp.d.asBytes;
uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0]; uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0];
PrintAndLog("received %i octets",iLen); PrintAndLog("received %i octets", iLen);
if(!iLen) if(!iLen)
return; return;
hexout = (char *)malloc(iLen * 3 + 1); hexout = (char *)malloc(iLen * 3 + 1);

View file

@ -17,6 +17,71 @@
#include "cmdhftopaz.h" #include "cmdhftopaz.h"
#include "cmdhf14a.h" #include "cmdhf14a.h"
#include "ui.h" #include "ui.h"
#include "mifare.h"
#include "proxmark3.h"
#include "iso14443crc.h"
#include "protocols.h"
static void topaz_switch_on_field(void)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE, 0, 0}};
SendCommand(&c);
UsbCommand resp;
WaitForResponse(CMD_ACK, &resp);
}
static void topaz_switch_off_field(void)
{
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
SendCommand(&c);
UsbCommand resp;
WaitForResponse(CMD_ACK, &resp);
}
static void topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE, len, 0}};
memcpy(c.d.asBytes, cmd, len);
SendCommand(&c);
UsbCommand resp;
WaitForResponse(CMD_ACK, &resp);
memcpy(response, resp.d.asBytes, resp.arg[0]);
}
static void topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response)
{
if (len > 1) {
uint8_t first, second;
ComputeCrc14443(CRC_14443_B, cmd, len, &first, &second);
cmd[len] = first;
cmd[len+1] = second;
}
topaz_send_cmd_raw(cmd, len+2, response);
}
static void topaz_select(uint8_t *atqa, uint8_t *uid)
{
// ToDo: implement anticollision
uint8_t rid_cmd[] = {TOPAZ_RID, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t wupa_cmd[] = {TOPAZ_WUPA};
topaz_switch_on_field();
topaz_send_cmd(wupa_cmd, sizeof(wupa_cmd), atqa);
topaz_send_cmd(rid_cmd, sizeof(rid_cmd) - 2, uid);
topaz_switch_off_field();
}
int CmdHFTopazReader(const char *Cmd) int CmdHFTopazReader(const char *Cmd)
{ {

View file

@ -176,6 +176,11 @@ NXP/Philips CUSTOM COMMANDS
#define TOPAZ_READ 0x01 // Read (a single byte) #define TOPAZ_READ 0x01 // Read (a single byte)
#define TOPAZ_WRITE_E 0x53 // Write-with-erase (a single byte) #define TOPAZ_WRITE_E 0x53 // Write-with-erase (a single byte)
#define TOPAZ_WRITE_NE 0x1a // Write-no-erase (a single byte) #define TOPAZ_WRITE_NE 0x1a // Write-no-erase (a single byte)
// additional commands for Dynamic Memory Model
#define TOPAZ_RSEG 0x10 // Read segment
#define TOPAZ_READ8 0x02 // Read (eight bytes)
#define TOPAZ_WRITE_E8 0x54 // Write-with-erase (eight bytes)
#define TOPAZ_WRITE_NE8 0x1B // Write-no-erase (eight bytes)
#define ISO_14443A 0 #define ISO_14443A 0

View file

@ -26,14 +26,15 @@ typedef struct {
} __attribute__((__packed__)) iso14a_card_select_t; } __attribute__((__packed__)) iso14a_card_select_t;
typedef enum ISO14A_COMMAND { typedef enum ISO14A_COMMAND {
ISO14A_CONNECT = 1, ISO14A_CONNECT = (1 << 0),
ISO14A_NO_DISCONNECT = 2, ISO14A_NO_DISCONNECT = (1 << 1),
ISO14A_APDU = 4, ISO14A_APDU = (1 << 2),
ISO14A_RAW = 8, ISO14A_RAW = (1 << 3),
ISO14A_REQUEST_TRIGGER = 0x10, ISO14A_REQUEST_TRIGGER = (1 << 4),
ISO14A_APPEND_CRC = 0x20, ISO14A_APPEND_CRC = (1 << 5),
ISO14A_SET_TIMEOUT = 0x40, ISO14A_SET_TIMEOUT = (1 << 6),
ISO14A_NO_SELECT = 0x80 ISO14A_NO_SELECT = (1 << 7),
ISO14A_TOPAZMODE = (1 << 8)
} iso14a_command_t; } iso14a_command_t;
#endif // _MIFARE_H_ #endif // _MIFARE_H_