diff --git a/CHANGELOG.md b/CHANGELOG.md index 085778f36..aa81e6baa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -434,6 +434,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf mf mad` and `hf mfp mad` MAD decode, check and print commands (@merlokk) - Added `script run luxeodump` (@0xdrrb) - Fix `lf hitag reader 02` - print all bytes (@bosb) + - Fix hitag S simulation (still not working), write, add example HITAG S 256 (@bosb) ### Fixed diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 3b4f05eac..07b445434 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -10,6 +10,7 @@ //----------------------------------------------------------------------------- // Some code was copied from Hitag2.c //----------------------------------------------------------------------------- +// bosb 2020 #include "hitagS.h" @@ -23,6 +24,7 @@ #include "string.h" #include "commonutil.h" #include "hitag2_crypto.h" +#include "lfadc.h" #define CRC_PRESET 0xFF #define CRC_POLYNOM 0x1D @@ -50,6 +52,22 @@ size_t blocknr; bool end = false; //#define SENDBIT_TEST +/* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3 +// UID is 0 1 2 3 // tag.uid is 3210 +// datasheet HitagS_V11.pdf bytes in tables printed 3 2 1 0 + +#db# UID: 5F C2 11 84 +#db# conf0: C9 conf1: 00 conf2: 00 + 3 2 1 0 +#db# Page[ 0]: 84 11 C2 5F uid +#db# Page[ 1]: AA 00 00 C9 conf, HITAG S 256 +#db# Page[ 2]: 4E 4F 54 48 +#db# Page[ 3]: 52 4B 49 4D +#db# Page[ 4]: 00 00 00 00 +#db# Page[ 5]: 00 00 00 00 +#db# Page[ 6]: 00 00 00 00 +#db# Page[ 7]: 4B 4F 5F 57 */ + #define ht2bs_4a(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) #define ht2bs_4b(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) #define ht2bs_5c(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) @@ -86,7 +104,7 @@ bool end = false; #define HITAG_T_TAG_CAPTURE_THREE_HALF 41 #define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 -#define DEBUG 0 +#define DBGLEVEL 0 /* * Implementation of the crc8 calculation from Hitag S @@ -207,6 +225,22 @@ static void hitag_send_bit(int bit) { } static void hitag_send_frame(const uint8_t *frame, size_t frame_len) { + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("hitag_send_frame: (%i) %02X %02X %02X %02X", frame_len, frame[0], frame[1], frame[2], frame[3]); + // The beginning of the frame is hidden in some high level; pause until our bits will have an effect + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + HIGH(GPIO_SSC_DOUT); + switch (m) { + case AC4K: + case MC8K: + while (AT91C_BASE_TC0->TC_CV < T0 * 40) {}; //FADV + break; + case AC2K: + case MC4K: + while (AT91C_BASE_TC0->TC_CV < T0 * 20) {}; //STD + ADV + break; + } + // SOF - send start of frame for (size_t i = 0; i < sof_bits; i++) { hitag_send_bit(1); @@ -299,6 +333,25 @@ static int check_select(uint8_t *rx, uint32_t uid) { return 0; } +void hitagS_set_frame_modulation() { + switch (tag.mode) { + case HT_STANDARD: + sof_bits = 1; + m = MC4K; + break; + case HT_ADVANCED: + sof_bits = 6; + m = MC4K; + break; + case HT_FAST_ADVANCED: + sof_bits = 6; + m = MC8K; + break; + default: + break; + } +} + /* * handles all commands from a reader */ @@ -318,20 +371,28 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, switch (rxlen) { case 5: { //UID request with a selected response protocol mode + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("UID request: length: %i first byte: %02x", rxlen, rx[0]); tag.pstate = HT_READY; tag.tstate = HT_NO_OP; if ((rx[0] & 0xf0) == 0x30) { + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("HT_STANDARD"); tag.mode = HT_STANDARD; sof_bits = 1; m = AC2K; } if ((rx[0] & 0xf0) == 0xc0) { tag.mode = HT_ADVANCED; + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("HT_ADVANCED"); sof_bits = 3; m = AC2K; } if ((rx[0] & 0xf0) == 0xd0) { + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("HT_FAST_ADVANCED"); tag.mode = HT_FAST_ADVANCED; sof_bits = 3; m = AC4K; @@ -344,29 +405,18 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, break; case 45: { //select command from reader received + if (DBGLEVEL >= DBG_EXTENDED) + DbpString("SELECT"); if (check_select(rx, tag.uid) == 1) { + if (DBGLEVEL >= DBG_EXTENDED) + DbpString("SELECT match"); //if the right tag was selected *txlen = 32; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); //send configuration for (int i = 0; i < 4; i++) - tx[i] = (tag.pages[0][1] >> (i * 8)) & 0xff; + tx[i] = tag.pages[1][i]; tx[3] = 0xff; if (tag.mode != HT_STANDARD) { *txlen = 40; @@ -390,22 +440,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, Dbprintf(",{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}", rx[0], rx[1], rx[2], rx[3], rx[4], rx[5], rx[6], rx[7]); - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); for (int i = 0; i < 4; i++) _hitag2_byte(&state); @@ -438,7 +473,10 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } */ } + break; case 40: + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("WRITE"); //data received to be written if (tag.tstate == HT_WRITING_PAGE_DATA) { tag.tstate = HT_NO_OP; @@ -448,44 +486,14 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, *txlen = 2; tx[0] = 0x40; page_to_be_written = 0; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); } else if (tag.tstate == HT_WRITING_BLOCK_DATA) { tag.pages[page_to_be_written / 4][page_to_be_written % 4] = (rx[0] << 24) + (rx[1] << 16) + (rx[2] << 8) + rx[3]; //send ack *txlen = 2; tx[0] = 0x40; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); page_to_be_written++; block_data_left--; if (block_data_left == 0) { @@ -500,29 +508,14 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, //send page data uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); *txlen = 32; - tx[0] = (tag.pages[page / 4][page % 4]) & 0xff; - tx[1] = (tag.pages[page / 4][page % 4] >> 8) & 0xff; - tx[2] = (tag.pages[page / 4][page % 4] >> 16) & 0xff; - tx[3] = (tag.pages[page / 4][page % 4] >> 24) & 0xff; + tx[0] = tag.pages[page][0]; + tx[1] = tag.pages[page][1]; + tx[2] = tag.pages[page][2]; + tx[3] = tag.pages[page][3]; if (tag.LKP && page == 1) tx[3] = 0xff; - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); if (tag.mode != HT_STANDARD) { //add crc8 @@ -543,29 +536,13 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, *txlen = 32 * 4; //send page,...,page+3 data for (int i = 0; i < 4; i++) { - tx[0 + i * 4] = (tag.pages[page / 4][page % 4]) & 0xff; - tx[1 + i * 4] = (tag.pages[page / 4][page % 4] >> 8) & 0xff; - tx[2 + i * 4] = (tag.pages[page / 4][page % 4] >> 16) & 0xff; - tx[3 + i * 4] = (tag.pages[page / 4][page % 4] >> 24) & 0xff; - page++; + tx[0 + i * 4] = tag.pages[page + 0 + i * 4][0]; + tx[1 + i * 4] = tag.pages[page + 1 + i * 4][1]; + tx[2 + i * 4] = tag.pages[page + 2 + i * 4][2]; + tx[3 + i * 4] = tag.pages[page + 3 + i * 4][3]; } - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); if (tag.mode != HT_STANDARD) { //add crc8 @@ -576,29 +553,12 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, tx[16] = crc; } - if ((page - 4) % 4 != 0 || (tag.LKP && (page - 4) == 0)) { + if ((page) % 4 != 0 || (tag.LKP && (page) == 0)) { sof_bits = 0; *txlen = 0; } } else if ((rx[0] & 0xf0) == 0x80) { //write page uint8_t page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); - - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } if ((tag.LCON && page == 1) || (tag.LKP && (page == 2 || page == 3))) { //deny @@ -613,22 +573,7 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } else if ((rx[0] & 0xf0) == 0x90) { //write block uint8_t page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16); - switch (tag.mode) { - case HT_STANDARD: - sof_bits = 1; - m = MC4K; - break; - case HT_ADVANCED: - sof_bits = 6; - m = MC4K; - break; - case HT_FAST_ADVANCED: - sof_bits = 6; - m = MC8K; - break; - default: - break; - } + hitagS_set_frame_modulation(); if (page % 4 != 0 || page == 0) { //deny *txlen = 0; @@ -644,7 +589,8 @@ static void hitagS_handle_reader_command(uint8_t *rx, const size_t rxlen, } break; default: - + if (DBGLEVEL >= DBG_EXTENDED) + Dbprintf("unknown rxlen: (%i) %02X %02X %02X %02X ...", rxlen, rx[0], rx[1], rx[2], rx[3]); break; } } @@ -722,7 +668,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA | (uid[30] << 1) | uid[31]; - if (DEBUG) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("UID: %02X %02X %02X %02X", uid1, uid2, uid3, uid4); tag.uid = (uid4 << 24 | uid3 << 16 | uid2 << 8 | uid1); @@ -816,7 +762,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA tag.LCK1 = response_bit[26]; tag.LCK0 = response_bit[27]; - if (DEBUG) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("conf0: %02X conf1: %02X conf2: %02X", conf_pages[0], conf_pages[1], conf_pages[2]); if (tag.auth == 1) { @@ -839,7 +785,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA tx[5] = auth_ks[1]; tx[6] = auth_ks[2]; tx[7] = auth_ks[3]; - if (DEBUG) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("%02X %02X %02X %02X %02X %02X %02X %02X", tx[0], tx[1], tx[2], tx[3], tx[4], tx[5], tx[6], tx[7]); } else if (htf == 01 || htf == 03) { //RHTS_CHALLENGE //WHTS_CHALLENGE @@ -864,7 +810,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA calc_crc(&crc, ((rx[1] & 0x0f) * 16 + ((rx[2] & 0xf0) / 16)), 8); calc_crc(&crc, ((rx[2] & 0x0f) * 16 + ((rx[3] & 0xf0) / 16)), 8); calc_crc(&crc, ((rx[3] & 0x0f) * 16 + ((rx[4] & 0xf0) / 16)), 8); - if (DEBUG) { + if (DBGLEVEL >= DBG_EXTENDED) { Dbprintf("UID:::%X", tag.uid); Dbprintf("RND:::%X", rnd); } @@ -884,7 +830,7 @@ static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrA pwdl1 = ((rx[3] & 0x0f) * 16 + ((rx[4] & 0xf0) / 16)) ^ _hitag2_byte(&state); } - if (DEBUG) + if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("pwdh0 %02X pwdl0 %02X pwdl1 %02X", pwdh0, pwdl0, pwdl1); //Dbprintf("%X %02X", rnd, ((rx[4] & 0x0f) * 16) + ((rx[5] & 0xf0) / 16)); @@ -930,28 +876,30 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { tag.pstate = HT_READY; tag.tstate = HT_NO_OP; - for (i = 0; i < 16; i++) - for (j = 0; j < 4; j++) - tag.pages[i][j] = 0x0; - // read tag data into memory if (tag_mem_supplied) { + for (i = 0; i < 16; i++) + for (j = 0; j < 4; j++) + tag.pages[i][j] = 0x0; + DbpString("Loading hitagS memory..."); memcpy((uint8_t *)tag.pages, data, 4 * 64); + } else { + // use the last read tag } - tag.uid = (uint32_t)tag.pages[0]; - tag.key = (intptr_t)tag.pages[3]; + tag.uid = (tag.pages[0][3] << 24 | tag.pages[0][2] << 16 | tag.pages[0][1] << 8 | tag.pages[0][0]); + tag.key = (tag.pages[3][3] << 24 | tag.pages[3][2] << 16 | tag.pages[3][1] << 8 | tag.pages[3][0]); tag.key <<= 16; - tag.key += ((tag.pages[2][0]) << 8) + tag.pages[2][1]; - tag.pwdl0 = tag.pages[2][3]; - tag.pwdl1 = tag.pages[2][2]; - tag.pwdh0 = tag.pages[1][0]; + tag.key += ((tag.pages[2][3]) << 8) + tag.pages[2][2]; + tag.pwdl0 = tag.pages[2][0]; + tag.pwdl1 = tag.pages[2][1]; + tag.pwdh0 = tag.pages[1][3]; //con0 tag.max_page = 64; - if ((tag.pages[1][3] & 0x2) == 0 && (tag.pages[1][3] & 0x1) == 1) + if ((tag.pages[1][0] & 0x2) == 0 && (tag.pages[1][0] & 0x1) == 1) tag.max_page = 8; - if ((tag.pages[1][3] & 0x2) == 0 && (tag.pages[1][3] & 0x1) == 0) + if ((tag.pages[1][0] & 0x2) == 0 && (tag.pages[1][0] & 0x1) == 0) tag.max_page = 0; if (DBGLEVEL >= DBG_EXTENDED) for (i = 0; i < tag.max_page; i++) @@ -962,41 +910,42 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { tag.pages[i][0] & 0xff); //con1 tag.auth = 0; - if ((tag.pages[1][2] & 0x80) == 0x80) + if ((tag.pages[1][1] & 0x80) == 0x80) tag.auth = 1; tag.LCON = 0; - if ((tag.pages[1][2] & 0x2) == 0x02) + if ((tag.pages[1][1] & 0x2) == 0x02) tag.LCON = 1; tag.LKP = 0; - if ((tag.pages[1][2] & 0x1) == 0x01) + if ((tag.pages[1][1] & 0x1) == 0x01) tag.LKP = 1; //con2 //0=read write 1=read only tag.LCK7 = 0; - if ((tag.pages[1][1] & 0x80) == 0x80) + if ((tag.pages[1][2] & 0x80) == 0x80) tag.LCK7 = 1; tag.LCK6 = 0; - if ((tag.pages[1][1] & 0x40) == 0x040) + if ((tag.pages[1][2] & 0x40) == 0x040) tag.LCK6 = 1; tag.LCK5 = 0; - if ((tag.pages[1][1] & 0x20) == 0x20) + if ((tag.pages[1][2] & 0x20) == 0x20) tag.LCK5 = 1; tag.LCK4 = 0; - if ((tag.pages[1][1] & 0x10) == 0x10) + if ((tag.pages[1][2] & 0x10) == 0x10) tag.LCK4 = 1; tag.LCK3 = 0; - if ((tag.pages[1][1] & 0x8) == 0x08) + if ((tag.pages[1][2] & 0x8) == 0x08) tag.LCK3 = 1; tag.LCK2 = 0; - if ((tag.pages[1][1] & 0x4) == 0x04) + if ((tag.pages[1][2] & 0x4) == 0x04) tag.LCK2 = 1; tag.LCK1 = 0; - if ((tag.pages[1][1] & 0x2) == 0x02) + if ((tag.pages[1][2] & 0x2) == 0x02) tag.LCK1 = 1; tag.LCK0 = 0; - if ((tag.pages[1][1] & 0x1) == 0x01) + if ((tag.pages[1][2] & 0x1) == 0x01) tag.LCK0 = 1; + // Set up simulator mode, frequency divisor which will drive the FPGA // and analog mux selection. FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -1028,7 +977,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { // TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, // external trigger rising edge, load RA on rising edge of TIOA. AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK - | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; + | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; // Enable and reset counter AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; @@ -1100,12 +1049,13 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { LogTrace(tx, nbytes(txlen), 0, 0, NULL, false); } + // Enable and reset external trigger in timer for capturing future frames + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + // Reset the received frame and response timing info memset(rx, 0x00, sizeof(rx)); response = 0; - // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; LED_B_OFF(); } // Reset the frame length @@ -1114,22 +1064,92 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) { overflow += (AT91C_BASE_TC1->TC_CV / T0); // Reset the timer to restart while-loop that receives frames AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; + } - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - + lf_finalize(); // release allocated memory from BigBuff. BigBuf_free(); - StartTicks(); - DbpString("Sim Stopped"); } +void hitagS_receive_frame(uint8_t *rx, size_t *rxlen, int *response) { + + // Reset values for receiving frames + memset(rx, 0x00, HITAG_FRAME_LEN * sizeof(uint8_t)); + *rxlen = 0; + int lastbit = 1; + bool bSkip = true; + int tag_sof = 1; + *response = 0; + uint32_t errorCount = 0; + + // Receive frame, watch for at most T0*EOF periods + while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { + // Check if falling edge in tag modulation is detected + if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { + // Retrieve the new timing values + int ra = (AT91C_BASE_TC1->TC_RA / T0); + + // Reset timer every frame, we have to capture the last edge for timing + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + + LED_B_ON(); + + // Capture tag frame (manchester decoding using only falling edges) + if (ra >= HITAG_T_EOF) { + if (*rxlen != 0) { + //DbpString("wierd1?"); + } + // Capture the T0 periods that have passed since last communication or field drop (reset) + // We always recieve a 'one' first, which has the falling edge after a half period |-_| + *response = ra - HITAG_T_TAG_HALF_PERIOD; + } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { + // Manchester coding example |-_|_-|-_| (101) + rx[(*rxlen) / 8] |= 0 << (7 - ((*rxlen) % 8)); + (*rxlen)++; + rx[(*rxlen) / 8] |= 1 << (7 - ((*rxlen) % 8)); + (*rxlen)++; + } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { + // Manchester coding example |_-|...|_-|-_| (0...01) + rx[(*rxlen) / 8] |= 0 << (7 - ((*rxlen) % 8)); + (*rxlen)++; + // We have to skip this half period at start and add the 'one' the second time + if (!bSkip) { + rx[(*rxlen) / 8] |= 1 << (7 - ((*rxlen) % 8)); + (*rxlen)++; + } + lastbit = !lastbit; + bSkip = !bSkip; + } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + if (tag_sof) { + // Ignore bits that are transmitted during SOF + tag_sof--; + } else { + // bit is same as last bit + rx[(*rxlen) / 8] |= lastbit << (7 - ((*rxlen) % 8)); + (*rxlen)++; + } + } else { + // Ignore wierd value, is to small to mean anything + errorCount++; + } + } + + // if we saw over 100 wierd values break it probably isn't hitag... + if (errorCount > 100) break; + + // We can break this loop if we received the last bit from a frame + if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { + if ((*rxlen) > 0) + break; + } + } +} + /* * Authenticates to the Tag with the given key or challenge. * If the key was given the password will be decrypted. @@ -1149,7 +1169,6 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { uint8_t *tx = txbuf; size_t txlen = 0; int lastbit = 1; - int reset_sof = 1; int t_wait = HITAG_T_WAIT_MAX; bool bStop = false; int pageNum = 0; @@ -1164,6 +1183,9 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { uint64_t NrAr = 0; uint8_t key_[6]; + tag.pstate = HT_READY; + tag.tstate = HT_NO_OP; + switch (htf) { case RHTSF_CHALLENGE: { DbpString("Authenticating using nr,ar pair:"); @@ -1238,10 +1260,8 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { // synchronized startup procedure while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero - // Reset the received frame, frame count and timing info t_wait = 200; - while (!bStop && !BUTTON_PRESS() && !data_available()) { WDT_HIT(); @@ -1381,85 +1401,12 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) { LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bool bSkip = true; - int tag_sof = reset_sof; - response = 0; - - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); - - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - LED_B_ON(); - - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } - - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } + hitagS_receive_frame(rx, &rxlen, &response); } end = false; - - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - - StartTicks(); - + lf_finalize(); reply_old(CMD_ACK, bSuccessful, 0, 0, 0, 0); } @@ -1479,7 +1426,6 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { uint8_t *tx = txbuf; size_t txlen = 0; int lastbit; - int reset_sof; int t_wait = HITAG_T_WAIT_MAX; bool bStop; unsigned char crc; @@ -1555,6 +1501,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK; // external trigger rising edge, load RA on falling edge of TIOA. AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING @@ -1570,7 +1517,6 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { // Reset the received frame, frame count and timing info lastbit = 1; bStop = false; - reset_sof = 1; t_wait = 200; while (!bStop && !BUTTON_PRESS() && !data_available()) { @@ -1670,87 +1616,13 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) { LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bool bSkip = true; - int tag_sof = reset_sof; - response = 0; - uint32_t errorCount = 0; + hitagS_receive_frame(rx, &rxlen, &response); - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); - - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - LED_B_ON(); - - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - errorCount++; - } - } - - // if we saw over 100 wierd values break it probably isn't hitag... - if (errorCount > 100) break; - - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } } end = false; - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); set_tracing(false); - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - - StartTicks(); + lf_finalize(); reply_old(CMD_ACK, bSuccessful, 0, 0, 0, 0); } @@ -1773,7 +1645,7 @@ void check_challenges(bool file_given, uint8_t *data) { size_t rxlen = 0; uint8_t txbuf[HITAG_FRAME_LEN]; int t_wait = HITAG_T_WAIT_MAX; - int lastbit, reset_sof, STATE = 0;; + int lastbit, STATE = 0;; bool bStop; int response_bit[200]; unsigned char mask = 1; @@ -1834,7 +1706,6 @@ void check_challenges(bool file_given, uint8_t *data) { // Reset the received frame, frame count and timing info lastbit = 1; bStop = false; - reset_sof = 1; t_wait = 200; if (file_given) { @@ -1984,85 +1855,10 @@ void check_challenges(bool file_given, uint8_t *data) { LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, 0, NULL, true); } - // Reset values for receiving frames - memset(rx, 0x00, sizeof(rx)); - rxlen = 0; - lastbit = 1; - bool bSkip = true; - int tag_sof = reset_sof; - response = 0; - - // Receive frame, watch for at most T0*EOF periods - while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_WAIT_MAX) { - // Check if falling edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) { - // Retrieve the new timing values - int ra = (AT91C_BASE_TC1->TC_RA / T0); - - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - LED_B_ON(); - - // Capture tag frame (manchester decoding using only falling edges) - if (ra >= HITAG_T_EOF) { - if (rxlen != 0) { - //DbpString("wierd1?"); - } - // Capture the T0 periods that have passed since last communication or field drop (reset) - // We always recieve a 'one' first, which has the falling edge after a half period |-_| - response = ra - HITAG_T_TAG_HALF_PERIOD; - } else if (ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { - // Manchester coding example |-_|_-|-_| (101) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } else if (ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { - // Manchester coding example |_-|...|_-|-_| (0...01) - rx[rxlen / 8] |= 0 << (7 - (rxlen % 8)); - rxlen++; - // We have to skip this half period at start and add the 'one' the second time - if (!bSkip) { - rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); - rxlen++; - } - lastbit = !lastbit; - bSkip = !bSkip; - } else if (ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - if (tag_sof) { - // Ignore bits that are transmitted during SOF - tag_sof--; - } else { - // bit is same as last bit - rx[rxlen / 8] |= lastbit << (7 - (rxlen % 8)); - rxlen++; - } - } else { - // Ignore wierd value, is to small to mean anything - } - } - - // We can break this loop if we received the last bit from a frame - if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) { - if (rxlen > 0) - break; - } - } + hitagS_receive_frame(rx, &rxlen, &response); } - LEDsoff(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); set_tracing(false); - - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - - StartTicks(); - + lf_finalize(); reply_old(CMD_ACK, bSuccessful, 0, 0, 0, 0); } - - -