X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/35147d51e3961db75a852368fffa31006da90199..a501c82b196b614295a6e3bf7481da84affb0d8e:/client/cmdhf14a.c?ds=sidebyside diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index bd19cee4..d1d440ee 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -44,8 +44,8 @@ int CmdHF14AList(const char *Cmd) ShowWaitCycles = true; } - uint8_t got[1920]; - GetFromBigBuf(got,sizeof(got),0); + uint8_t trace[TRACE_BUFFER_SIZE]; + GetFromBigBuf(trace,TRACE_BUFFER_SIZE,0); WaitForResponse(CMD_ACK,NULL); PrintAndLog("Recorded Activity"); @@ -56,122 +56,98 @@ int CmdHF14AList(const char *Cmd) PrintAndLog(" Start | End | Src | Data"); PrintAndLog("-----------|-----------|-----|--------"); - int i = 0; - uint32_t first_timestamp = 0; + uint16_t tracepos = 0; + uint16_t duration; + uint16_t data_len; + uint16_t parity_len; + bool isResponse; uint32_t timestamp; - uint32_t EndOfTransmissionTimestamp = 0; + uint32_t first_timestamp; + uint32_t EndOfTransmissionTimestamp; for (;;) { - if(i >= 1900) { - break; + + if( tracepos >= TRACE_BUFFER_SIZE) break; + + timestamp = *((uint32_t *)(trace + tracepos)); + if(tracepos == 0) { + first_timestamp = timestamp; } - - bool isResponse; - timestamp = *((uint32_t *)(got+i)); - if (timestamp & 0x80000000) { - timestamp &= 0x7fffffff; - isResponse = true; + tracepos += 4; + duration = *((uint16_t *)(trace + tracepos)); + tracepos += 2; + data_len = *((uint16_t *)(trace + tracepos)); + tracepos += 2; + + if (data_len & 0x8000) { + data_len &= 0x7fff; + isResponse = true; } else { - isResponse = false; + isResponse = false; } - if(i==0) { - first_timestamp = timestamp; - } - - int parityBits = *((uint32_t *)(got+i+4)); + parity_len = (data_len-1)/8 + 1; - int len = got[i+8]; - if (len > 100) { - break; - } - if (i + len >= 1900) { - break; - } + if (tracepos + data_len + parity_len >= TRACE_BUFFER_SIZE) { break; } - uint8_t *frame = (got+i+9); + uint8_t *frame = trace + tracepos; + tracepos += data_len; + uint8_t *parityBytes = trace + tracepos; + tracepos += parity_len; // Break and stick with current result if buffer was not completely full - if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break; + if (timestamp == 0x44444444) break; char line[1000] = ""; int j; - if (len) { - for (j = 0; j < len; j++) { - int oddparity = 0x01; - int k; - - for (k=0;k<8;k++) { - oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01); - } + for (j = 0; j < data_len; j++) { + int oddparity = 0x01; + int k; - //if((parityBits >> (len - j - 1)) & 0x01) { - if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) { - sprintf(line+(j*4), "%02x! ", frame[j]); - } else { - sprintf(line+(j*4), "%02x ", frame[j]); - } + for (k=0;k<8;k++) { + oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01); } - } else { - if (ShowWaitCycles) { - uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff; - sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp)); + + uint8_t parityBits = parityBytes[j>>3]; + if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) { + sprintf(line+(j*4), "%02x! ", frame[j]); + } else { + sprintf(line+(j*4), "%02x ", frame[j]); } } - - char *crc; - crc = ""; - if (len > 2) { + + char crc[6] = ""; + if (data_len > 2) { uint8_t b1, b2; - for (j = 0; j < (len - 1); j++) { - // gives problems... search for the reason.. - /*if(frame[j] == 0xAA) { - switch(frame[j+1]) { - case 0x01: - crc = "[1] Two drops close after each other"; - break; - case 0x02: - crc = "[2] Potential SOC with a drop in second half of bitperiod"; - break; - case 0x03: - crc = "[3] Segment Z after segment X is not possible"; - break; - case 0x04: - crc = "[4] Parity bit of a fully received byte was wrong"; - break; - default: - crc = "[?] Unknown error"; - break; - } - break; - }*/ - } - - if (strlen(crc)==0) { - ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2); - if (b1 != frame[len-2] || b2 != frame[len-1]) { - crc = (isResponse & (len < 6)) ? "" : " !crc"; - } else { - crc = ""; - } + ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2); + if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) { + sprintf(crc, (isResponse & (data_len < 6)) ? "" : " !crc"); + } else { + sprintf(crc, ""); } - } else { - crc = ""; // SHORT - } - - i += (len + 9); - - EndOfTransmissionTimestamp = (*((uint32_t *)(got+i))) & 0x7fffffff; - if (!ShowWaitCycles) i += 9; + EndOfTransmissionTimestamp = timestamp + duration; PrintAndLog(" %9d | %9d | %s | %s %s", (timestamp - first_timestamp), (EndOfTransmissionTimestamp - first_timestamp), - (len?(isResponse ? "Tag" : "Rdr"):" "), - line, crc); - + (isResponse ? "Tag" : "Rdr"), + line, + crc); + + bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000; + if (ShowWaitCycles && !isResponse && next_isResponse) { + uint32_t next_timestamp = *((uint32_t *)(trace + tracepos)); + if (next_timestamp != 0x44444444) { + PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d", + (EndOfTransmissionTimestamp - first_timestamp), + (next_timestamp - first_timestamp), + " ", + (next_timestamp - EndOfTransmissionTimestamp)); + } + } + } } return 0; } @@ -202,6 +178,7 @@ int CmdHF14AReader(const char *Cmd) switch (card->sak) { case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break; + case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break; case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break; case 0x08: PrintAndLog("TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1"); break; case 0x09: PrintAndLog("TYPE : NXP MIFARE Mini 0.3k"); break; @@ -399,6 +376,7 @@ int CmdHF14ASim(const char *Cmd) PrintAndLog(" 2 = MIFARE Ultralight"); PrintAndLog(" 3 = MIFARE DESFIRE"); PrintAndLog(" 4 = ISO/IEC 14443-4"); + PrintAndLog(" 5 = MIFARE TNP3XXX"); PrintAndLog(""); return 1; } @@ -627,7 +605,7 @@ static void waitCmd(uint8_t iSelect) UsbCommand resp; char *hexout; - if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { + if (WaitForResponseTimeout(CMD_ACK,&resp,10000)) { recv = resp.d.asBytes; uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0]; PrintAndLog("received %i octets",iLen);