Uart.parityLen = 0; // number of decoded parity bytes
Uart.shiftReg = 0; // shiftreg to hold decoded data bits
Uart.parityBits = 0; // holds 8 parity bits
- Uart.twoBits = 0x0000; // buffer for 2 Bits
- Uart.highCnt = 0;
+ Uart.fourBits = 0x00000000; // buffer for 4 Bits
Uart.startTime = 0;
Uart.endTime = 0;
}
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
{
- Uart.twoBits = (Uart.twoBits << 8) | bit;
+ Uart.fourBits = (Uart.fourBits << 8) | bit;
if (Uart.state == STATE_UNSYNCD) { // not yet synced
- if (Uart.highCnt < 1) { // wait for a stable unmodulated signal
- if (Uart.twoBits == 0xffff) {
- Uart.highCnt++;
- } else {
- Uart.highCnt = 0;
- }
- } else {
- Uart.syncBit = 0xFFFF; // not set
- // we look for a ...1111111100x11111xxxxxx pattern (the start bit)
- if ((Uart.twoBits & 0xDF00) == 0x1F00) Uart.syncBit = 8; // mask is 11x11111 xxxxxxxx,
- // check for 00x11111 xxxxxxxx
- else if ((Uart.twoBits & 0xEF80) == 0x8F80) Uart.syncBit = 7; // both masks shifted right one bit, left padded with '1'
- else if ((Uart.twoBits & 0xF7C0) == 0xC7C0) Uart.syncBit = 6; // ...
- else if ((Uart.twoBits & 0xFBE0) == 0xE3E0) Uart.syncBit = 5;
- else if ((Uart.twoBits & 0xFDF0) == 0xF1F0) Uart.syncBit = 4;
- else if ((Uart.twoBits & 0xFEF8) == 0xF8F8) Uart.syncBit = 3;
- else if ((Uart.twoBits & 0xFF7C) == 0xFC7C) Uart.syncBit = 2;
- else if ((Uart.twoBits & 0xFFBE) == 0xFE3E) Uart.syncBit = 1;
- if (Uart.syncBit != 0xFFFF) { // found a sync bit
- Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
- Uart.startTime -= Uart.syncBit;
- Uart.endTime = Uart.startTime;
- Uart.state = STATE_START_OF_COMMUNICATION;
- }
+ Uart.syncBit = 9999; // not set
+ // we look for a ...xxxx1111111100x11111xxxxxx pattern
+ // (unmodulated, followed by the start bit = 8 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's)
+#define ISO14443A_STARTBIT_MASK 0x007FEF80 // mask is 00000000 01111111 11101111 10000000
+#define ISO14443A_STARTBIT_PATTERN 0x007F8F80 // pattern is 00000000 01111111 10001111 10000000
+ 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) >> 2 == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5;
+ else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 3 == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4;
+ else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 4 == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3;
+ else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 5 == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2;
+ else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 6 == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1;
+ else if ((Uart.fourBits & ISO14443A_STARTBIT_MASK) >> 7 == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0;
+ if (Uart.syncBit != 9999) { // found a sync bit
+ Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
+ Uart.startTime -= Uart.syncBit;
+ Uart.endTime = Uart.startTime;
+ Uart.state = STATE_START_OF_COMMUNICATION;
}
} else {
- if (IsMillerModulationNibble1(Uart.twoBits >> Uart.syncBit)) {
- if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) { // Modulation in both halves - error
+ if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) {
+ if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation in both halves - error
UartReset();
} else { // Modulation in first half = Sequence Z = logic "0"
if (Uart.state == STATE_MILLER_X) { // error - must not follow after X
}
}
} else {
- if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1"
+ if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) { // Modulation second half = Sequence X = logic "1"
Uart.bitCount++;
Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100; // add a 1 to the shiftreg
Uart.state = STATE_MILLER_X;
return TRUE; // we are finished with decoding the raw data sequence
} else {
UartReset(); // Nothing received - start over
- Uart.highCnt = 1;
}
}
if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC
UartReset();
- Uart.highCnt = 1;
} else { // a logic "0"
Uart.bitCount++;
Uart.shiftReg = (Uart.shiftReg >> 1); // add a 0 to the shiftreg
}
/**
- * @brief iso14443B_CRC_Ok Checks CRC in command or response
+ * @brief iso14443A_CRC_check Checks CRC in command or response
+ * @param isResponse
+ * @param data
+ * @param len
+ * @return 0 : CRC-command, CRC not ok
+ * 1 : CRC-command, CRC ok
+ * 2 : Not crc-command
+ */
+
+uint8_t iso14443A_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
+{
+ uint8_t b1,b2;
+
+ if(len <= 2) return 2;
+
+ if(isResponse & (len < 6)) return 2;
+
+ ComputeCrc14443(CRC_14443_A, data, len-2, &b1, &b2);
+ if (b1 != data[len-2] || b2 != data[len-1]) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+
+/**
+ * @brief iso14443B_CRC_check Checks CRC in command or response
* @param isResponse
* @param data
* @param len
ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
if(b1 != data[len-2] || b2 != data[len-1]) {
- return 0;
+ return 0;
+ } else {
+ return 1;
}
- return 1;
}
/**
}
-void 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
uint32_t last_timestamp = timestamp + *duration;
- memcpy(topaz_reader_command, frame, MIN(*data_len, MAX_TOPAZ_READER_CMD_LEN));
+ if ((*data_len != 1) || (frame[0] == TOPAZ_WUPA) || (frame[0] == TOPAZ_REQA)) return false;
+
+ memcpy(topaz_reader_command, frame, *data_len);
while (!is_last_record(*tracepos, trace, traceLen) && !next_record_is_response(*tracepos, trace)) {
uint32_t next_timestamp = *((uint32_t *)(trace + *tracepos));
*tracepos += sizeof(uint32_t);
- last_timestamp = next_timestamp + *((uint16_t *)(trace + *tracepos));
+ uint16_t next_duration = *((uint16_t *)(trace + *tracepos));
*tracepos += sizeof(uint16_t);
uint16_t next_data_len = *((uint16_t *)(trace + *tracepos)) & 0x7FFF;
*tracepos += sizeof(uint16_t);
uint8_t *next_frame = (trace + *tracepos);
*tracepos += next_data_len;
- if (*data_len + next_data_len <= MAX_TOPAZ_READER_CMD_LEN) {
+ if ((next_data_len == 1) && (*data_len + next_data_len <= MAX_TOPAZ_READER_CMD_LEN)) {
memcpy(topaz_reader_command + *data_len, next_frame, next_data_len);
*data_len += next_data_len;
- }
+ last_timestamp = next_timestamp + next_duration;
+ } else {
+ // rewind and exit
+ *tracepos = *tracepos - next_data_len - sizeof(uint16_t) - sizeof(uint16_t) - sizeof(uint32_t);
+ break;
+ }
uint16_t next_parity_len = (next_data_len-1)/8 + 1;
*tracepos += next_parity_len;
}
*duration = last_timestamp - timestamp;
+
+ return true;
}
tracepos += parity_len;
if (protocol == TOPAZ && !isResponse) {
- // topaz reader commands come in 1 or 9 separate frames with 8 Bits each.
+ // topaz reader commands come in 1 or 9 separate frames with 7 or 8 Bits each.
// merge them:
- merge_topaz_reader_frames(timestamp, &duration, &tracepos, traceLen, trace, frame, topaz_reader_command, &data_len);
- frame = topaz_reader_command;
+ if (merge_topaz_reader_frames(timestamp, &duration, &tracepos, traceLen, trace, frame, topaz_reader_command, &data_len)) {
+ frame = topaz_reader_command;
+ }
}
//Check the CRC status
uint8_t crcStatus = 2;
if (data_len > 2) {
- uint8_t b1, b2;
switch (protocol) {
case ICLASS:
crcStatus = iclass_CRC_check(isResponse, frame, data_len);
break;
case ISO_14443B:
- case TOPAZ:
+ case TOPAZ:
crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
break;
case ISO_14443A:
- ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
- if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
- if(!(isResponse & (data_len < 6))) {
- crcStatus = 0;
- }
- }
+ crcStatus = iso14443A_CRC_check(isResponse, frame, data_len);
break;
default:
break;
}
uint8_t parityBits = parityBytes[j>>3];
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
- snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
-
+ snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x!", frame[j]);
} else {
- snprintf(line[j/16]+(( j % 16) * 4),110, "%02x ", frame[j]);
+ snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x ", frame[j]);
}
}
- if(crcStatus == 1 || crcStatus == 2)
+ if(crcStatus == 0 || crcStatus == 1)
{//CRC-command
- char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4)-1;
+ char *pos1 = line[(data_len-2)/16]+(((data_len-2) % 16) * 4);
(*pos1) = '[';
- char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4)-2;
- (*pos2) = ']';
+ char *pos2 = line[(data_len)/16]+(((data_len) % 16) * 4);
+ sprintf(pos2, "%c", ']');
}
if(data_len == 0)
{
int num_lines = MIN((data_len - 1)/16 + 1, 16);
for (int j = 0; j < num_lines ; j++) {
if (j == 0) {
- PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
+ PrintAndLog(" %9d | %9d | %s |%-64s | %s| %s",
(timestamp - first_timestamp),
(EndOfTransmissionTimestamp - first_timestamp),
(isResponse ? "Tag" : "Rdr"),
(j == num_lines-1) ? crc : " ",
(j == num_lines-1) ? explanation : "");
} else {
- PrintAndLog(" | | | %-64s| %s| %s",
+ PrintAndLog(" | | |%-64s | %s| %s",
line[j],
(j == num_lines-1) ? crc : " ",
(j == num_lines-1) ? explanation : "");
protocol = ISO_14443A;
} else if(strcmp(type, "14b") == 0) {
protocol = ISO_14443B;
- } else if(strcmp(type,"nfc")== 0) {
+ } else if(strcmp(type,"topaz")== 0) {
protocol = TOPAZ;
} else if(strcmp(type,"raw")== 0) {
protocol = -1;//No crc, no annotations