// read from start to end blocks. data will need to be large enough // to hold all blocks. BOOL read_tag(BYTE *data, unsigned int startblock, unsigned int endblock) { unsigned int i, p= 0; for(i= startblock; i <= endblock ; ++i, ++p) { switch(RFIDlerConfig.TagType) { case TAG_TYPE_Q5: case TAG_TYPE_T55X7: if(!q5_read_block(data + p * HEXDIGITS(RFIDlerConfig.BlockSize), (BYTE) i)) return FALSE; break; case TAG_TYPE_HITAG1: if (!hitag1_read_page(data + p * HEXDIGITS(RFIDlerConfig.BlockSize), (BYTE) i)) return FALSE; break; case TAG_TYPE_HITAG2: if (!hitag2_read_page(data + p * HEXDIGITS(RFIDlerConfig.BlockSize), (BYTE) i)) return FALSE; break; default: return FALSE; } } return TRUE; }
// attempt to find ideal parameters for GAP, ZERO and ONE periods. // ranges specified in FC void hitag2_test_rwd(unsigned int gapmin, unsigned int gapmax, unsigned int zeromin, unsigned int zeromax, unsigned int onemin, unsigned int onemax, BYTE *pass) { BYTE i, imax, countu, counta, countr; unsigned int gap, zero, one, fc; imax= 5; for(fc= 800 ; fc <= 809 ; ++fc) { for(gap= gapmin ; gap <= gapmax ; ++gap) for(zero= zeromin ; zero <= zeromax ; ++zero) for(one= onemin ; one <= onemax ; ++one) { RFIDlerConfig.FrameClock= (unsigned long) fc; RFIDlerConfig.RWD_Gap_Period= gap; RFIDlerConfig.RWD_Zero_Period= zero; RFIDlerConfig.RWD_One_Period= one; UserMessageNum("\rGap %d", gap); UserMessageNum(" Zero %d", zero); UserMessageNum(" One %d", one); UserMessageNum(" FC %d", fc); for(i= countu= counta= countr= 0 ; i < imax ; ++i) { if(get_user_abort()) return; if(hitag2_get_uid(DataBuff)) { ++countu; if(hitag2_pwd_auth(DataBuff, pass) || hitag2_crypto_auth(DataBuff, pass)) { ++counta; if(hitag2_read_page(DataBuff, 0)) ++countr; } } } if(countu == imax && counta == imax && countr == imax) { UserMessageNum(" - got %d", countu); UserMessageNum(" uids, %d", counta); UserMessageNum(" auths %d", countr); UserMessageNum(" reads, out of %d attempts.\r\n", imax); } } UserMessage("%s", "\r\n"); } }
BOOL hitag2_write_page(BYTE block, BYTE *data) { BYTE command[11], tmp[37], tmp1[37], tmp2[37], tmphex[9]; if(block > HITAG2_DATABLOCKS - 1) return FALSE; // create 10 bit command block: HITAG2_WRIE_PAGE + 3 bits address + invert(HITAG2_WRITE_PAGE + 3 bits address) memcpy(command, HITAG2_WRITE_PAGE, 2); inttobinstring(command + 2, (unsigned int) block, 3); invertbinstring(command + 5, command); command[10]= '\0'; // encrypt command if in crypto mode if(CryptoActive) hitag2_binstring_crypt(tmp, command); else memcpy(tmp, command, 11); // convert data to binstring for send if(hextobinstring(tmp1, data) != 32) return FALSE; // send command with RX->TX delay and no reset if(!rwd_send(tmp, strlen(tmp), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX)) return FALSE; // skip 1/2 bit to synchronise manchester HW_Skip_Bits= 1; // get ACK - 10 bytes + sync if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp2, 15, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == 15) { // check sync bits if (memcmp(tmp2, Hitag2Sync, 5) != 0) return FALSE; // decrypt if(CryptoActive) hitag2_binarray_crypt(tmp2 + 5, tmp2 + 5, 10); // check ACK - should be our original command echo'd back binarraytobinstring(tmp2 + 5, tmp2 + 5, 10); if(memcmp(command, tmp2 + 5, 10) != 0) return FALSE; } // encrypt data if in crypto mode if(CryptoActive) hitag2_binstring_crypt(tmp1, tmp1); // send data with RX->TX delay and no reset if(!rwd_send(tmp1, strlen(tmp1), NO_RESET, BLOCK, RWD_STATE_WAKING, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX)) return FALSE; // no ack, so read back and verify // delay for long enough to allow write plus RX->TX period Delay_us((HITAG2_WRITE_DELAY * RFIDlerConfig.FrameClock + RFIDlerConfig.RWD_Wait_Switch_RX_TX * RFIDlerConfig.FrameClock) / 100); if(!hitag2_read_page(tmp, block)) return FALSE; if(memcmp(tmp, data, 8) != 0) return FALSE; return TRUE; }