// convert human readable UID to 128 bit fdx-b binary array BOOL uid_to_hdx_bin(BYTE *bin, BYTE *uid) { BYTE tmp1[64], crc[8], i; unsigned int country, crctag; unsigned long long id; memset(tmp1, 0x00, 64); // set animal flag if(uid[0] == 'A') tmp1[0]= 0x01; else if(uid[0] != '0') return FALSE; // set data flag if(uid[1] == 'D') tmp1[15]= 0x01; else if(uid[1] != '0') return FALSE; // set country code - 4 hex digits -> 10 bits country= bcdtouint(uid + 2, 4); inttobinarray(tmp1 + 16, country, 10); // set national ID - 12 hex digits -> 38 bits id= bcdtoulonglong(uid + 6, 12); ulonglongtobinarray(tmp1 + 26, id, 38); // reverse binary string_reverse(tmp1, 64); // add header for over-the-air: 10 x 0x00 + 0x01 memset(bin, 0x00, 10); // every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite memset(bin + 10, 0x01, 118); //data is 8 blocks of 8 bits, plus obfuscation bit for(i= 0 ; i < 8 ; ++i) memcpy(bin + 11 + i * 9, tmp1 + i * 8, 8); // calculate & append crc for 64 bits of data for(i= 0 ; i < 8 ; ++i) crc[i]= (BYTE) binarraytoint(tmp1 + i * 8, 8); crctag= crc_ccitt(crc, 8); inttobinarray(bin + 83, crctag >> 8, 8); inttobinarray(bin + 92, crctag, 8); // add trailer for(i= 0 ; i < 3 ; ++i) memset(bin + 101 + i * 9, 0x00, 8); return TRUE; }
// calcuate CRC & send command - response in binarray BOOL hitag1_send_command(BYTE *response, BYTE *command, BOOL reset, BOOL sync, BYTE response_length) { BYTE crc= HITAG1_CRC_PRESET, tmp[HITAG1_MAX_COMMAND_LEN], length; // supplied command is 4 bits + 8 bit address. we add 8 bit CRC // calculate crc length= binstringtobinarray(tmp, command); hitag1_binarray_crc(&crc, tmp, length); // add 8 bit crc to command inttobinarray(tmp + length, (unsigned int) crc, 8); length += 8; // send command - first gap is GAP, not SLEEP if(!rwd_send(tmp, length, reset, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wake_Period, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX)) return FALSE; if(!response_length) return TRUE; // read response as binary data //Manchester_Auto_Correct= TRUE; if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, response, response_length, RFIDlerConfig.Sync, sync ? RFIDlerConfig.SyncBits : 0, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY) == response_length) { // delay for RX->TX time Delay_us((RFIDlerConfig.FrameClock * RFIDlerConfig.RWD_Wait_Switch_RX_TX) / 100); return TRUE; } return FALSE; }
// convert integer to binstring, limited to specified number of LSB void inttobinstring(BYTE *target, unsigned int source, unsigned int bits) { inttobinarray(target, source, bits); binarraytobinstring(target, target, bits); }