void decode_pwm(unsigned long pulses[], unsigned long gaps[], unsigned int count) { unsigned int i; switch(RFIDlerConfig.TagType) { case TAG_TYPE_HITAG1: hitag1_decode_pwm(pulses, gaps, count); break; case TAG_TYPE_HITAG2: hitag2_decode_pwm(pulses, gaps, count); break; case TAG_TYPE_Q5: case TAG_TYPE_T55X7: q5_decode_pwm(pulses, gaps, count); break; case TAG_TYPE_TAMAGOTCHI: tamagotchi_decode_pwm(pulses, gaps, count); break; default: for(i= 0 ; i < count ; ++i) { UserMessageNum("\r\nPulse: %d ", pulses[i]); UserMessageNum("Gap: %d", gaps[i]); } break; } UserMessage("\r\n",""); }
// try to find values that correctly transmit all commands to t55x7 // so that a GET_UID command will return a true value BOOL t55x7_rwd_test(BYTE *pattern) { BYTE gap, one, zero, i, tmp[T55X7_BLOCKSIZE * 2 + 1]; BOOL found= FALSE; // min/max from datasheets for(one= 48 ; one <= 63 ; ++one) for(zero= 16; zero <= 31 ; ++zero) for(gap= 8 ; gap <= 30 ; ++gap) { if(get_user_abort()) return found; RFIDlerConfig.RWD_Gap_Period= gap; RFIDlerConfig.RWD_One_Period= one; RFIDlerConfig.RWD_Zero_Period= zero; if(get_tag_uid(tmp)) { UserMessageNum(" gap: %d", gap); UserMessageNum(" one: %d", one); UserMessageNum(" zero: %d", zero); UserMessage(" UID: %s\r\n", tmp); found= TRUE; } } UserMessage("%s", "\r\n"); return found; }
void printbinarray(unsigned char *bin, unsigned int length) { while(length--) { // normally we are printing 0/1, but if we're looking at anything else we want a space between values if(*bin > 1) UserMessageNum("%d ",*bin); else UserMessageNum("%d",*bin); bin++; } UserMessage("%s", "\r\n"); }
// try to find values that correctly transmit all commands to q5 // to test this properly, q5 should have invalid data in it's data blocks // so that only a GET_TRACE_DATA command will return a true value BOOL q5_rwd_test(BYTE *pattern) { BYTE start_gap, gap, one, zero, i, tmp[Q5_BLOCKSIZE + 1]; BOOL found= FALSE, blank; // min/max from datasheets for(one= 48 ; one <= 63 ; ++one) for(zero= 16; zero <= 31 ; ++zero) for(gap= 10 ; gap <= 50 ; ++gap) for(start_gap= 11 ; start_gap <= 50 ; ++start_gap) { RFIDlerConfig.Manchester= TRUE; blank= TRUE; if(get_user_abort()) return found; RFIDlerConfig.RWD_Gap_Period= gap; RFIDlerConfig.RWD_One_Period= one; RFIDlerConfig.RWD_Zero_Period= zero; // reset tag get_tag_uid(tmp); // try to switch off modulation // send command with start gap: reset with sleep time set to start gap, and wake time set to 0 as we transmit the 1st bit immediately // note that we must also subtract standard gap period as it will be added to the front of the first bit by default. rwd_send(Q5_MODULATION_DEFEAT, strlen(Q5_MODULATION_DEFEAT), NO_RESET, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, start_gap - RFIDlerConfig.RWD_Gap_Period, 0, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX); // read a block with no sync & no manchester - will be all '0' if not modulating RFIDlerConfig.Manchester= FALSE; if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, RFIDlerConfig.DataBits, RFIDlerConfig.Sync, 0, RFIDlerConfig.Timeout, NO_ONESHOT_READ, HEX) == RFIDlerConfig.DataBits) { for(i= 0 ; i < HEXDIGITS(RFIDlerConfig.DataBits) ; ++i) if(tmp[i] != '0') blank= FALSE; RFIDlerConfig.Manchester= TRUE; if(blank && get_tag_uid(tmp) && q5_read_block(tmp, 0)) { UserMessageNum("\r\nFound tag with start_gap %d", start_gap); UserMessageNum(" gap %d", gap); UserMessageNum(" one %d", one); UserMessageNum(" zero %d", zero); found= TRUE; } } } UserMessage("%s", "\r\n"); return found; }
BOOL hitag2_config_block_show(BYTE *config, BYTE *password, BYTE *key) { BYTE value= hextobyte(config); // first byte only used as config UserMessage(" PWD Block (1): %.8s ", password); printhexreadable(password, 4); UserMessage("\r\n\r\n Key Block (2): %.8s ", key); printhexreadable(key, 4); UserMessage("\r\n\r\n Config Block (3): %.8s\r\n\r\n", config); UserMessageNum(" Page 1 & 2: %d = ", GET_CONFIG(value, HITAG2_MASK_PAGE_1_2_OTP_PROTECT, HITAG2_SHIFT_PAGE_1_2_OTP_PROTECT)); if(GET_CONFIG(value, HITAG2_MASK_SECURITY, HITAG2_SHIFT_SECURITY)) UserMessage("%s\r\n", GET_CONFIG(value, HITAG2_MASK_PAGE_1_2_OTP_PROTECT, HITAG2_SHIFT_PAGE_1_2_OTP_PROTECT) ? "No Read / No Write" : "Read / Write"); else UserMessage("%s\r\n", GET_CONFIG(value, HITAG2_MASK_PAGE_1_2_OTP_PROTECT, HITAG2_SHIFT_PAGE_1_2_OTP_PROTECT) ? "Page 1: No Read / No Write, Page 2: Read Only" : "Read / Write"); UserMessageNum(" Page 3: %d = ", GET_CONFIG(value, HITAG2_MASK_PAGE_3_OTP_PROTECT, HITAG2_SHIFT_PAGE_3_OTP_PROTECT)); UserMessage("%s\r\n", GET_CONFIG(value, HITAG2_MASK_PAGE_3_OTP_PROTECT, HITAG2_SHIFT_PAGE_3_OTP_PROTECT) ? "Read Only" : "Read / Write"); UserMessageNum(" Page 4 & 5: %d = ", GET_CONFIG(value, HITAG2_MASK_PAGE_4_5_PROTECT, HITAG2_SHIFT_PAGE_4_5_PROTECT)); UserMessage("%s\r\n", GET_CONFIG(value, HITAG2_MASK_PAGE_4_5_PROTECT, HITAG2_SHIFT_PAGE_4_5_PROTECT) ? "Read Only" : "Read / Write"); UserMessageNum(" Page 6 & 7: %d = ", GET_CONFIG(value, HITAG2_MASK_PAGE_6_7_PROTECT, HITAG2_SHIFT_PAGE_6_7_PROTECT)); UserMessage("%s\r\n", GET_CONFIG(value, HITAG2_MASK_PAGE_6_7_PROTECT, HITAG2_SHIFT_PAGE_6_7_PROTECT) ? "Read Only" : "Read / Write"); UserMessageNum(" Security: %d = ", GET_CONFIG(value, HITAG2_MASK_SECURITY, HITAG2_SHIFT_SECURITY)); UserMessage("%s\r\n", GET_CONFIG(value, HITAG2_MASK_SECURITY, HITAG2_SHIFT_SECURITY) ? "Crypto" : "Password"); UserMessageNum(" Mode: %d = ", GET_CONFIG(value, HITAG2_MASK_MODE, HITAG2_SHIFT_MODE)); UserMessage("%s\r\n", (BYTE *) Hitag2_Modes[GET_CONFIG(value, HITAG2_MASK_MODE, HITAG2_SHIFT_MODE)]); UserMessageNum(" Modulation: %d = ", GET_CONFIG(value, HITAG2_MASK_MODULATION, HITAG2_SHIFT_MODULATION)); UserMessage("%s\r\n", GET_CONFIG(value, HITAG2_MASK_MODULATION, HITAG2_SHIFT_MODULATION) ? "BiPhase" : "Manchester"); UserMessage("\r\n PWD Block (3): %.6s ", config + 2); printhexreadable(config + 2, 3); UserMessage("%s", "\r\n"); return TRUE; }
void debug_show(void) { BYTE i; for(i= 1 ; i < 5 ; ++i) { UserMessageNum("Debug pin %d: ", i); UserMessage("%s\r\n", debug_get(i) ? "OFF" : "ON"); } }
// try to find values that correctly transmit all commands to q5 // to test this properly, q5 should have invalid data in it's data blocks // so that only a GET_TRACE_DATA command will return a true value BOOL q5_rwd_test(BYTE *pattern) { BYTE gap, one, zero, tmp[Q5_BLOCKSIZE + 1]; BOOL found= FALSE, blank; // min/max from datasheets for(one= 48 ; one <= 63 ; ++one) for(zero= 16; zero <= 31 ; ++zero) for(gap= 10 ; gap <= 50 ; ++gap) { RFIDlerConfig.Manchester= TRUE; blank= TRUE; if(get_user_abort()) return found; RFIDlerConfig.RWD_Gap_Period= gap; RFIDlerConfig.RWD_One_Period= one; RFIDlerConfig.RWD_Zero_Period= zero; // reset tag get_tag_uid(tmp); // try to switch off modulation rwd_send(Q5_MODULATION_DEFEAT, strlen(Q5_MODULATION_DEFEAT), NO_RESET, BLOCK, RWD_STATE_START_SEND, RFIDlerConfig.FrameClock, RFIDlerConfig.RWD_Gap_Period, 0, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX); // read a block with no sync & no manchester - will be all '0' if not modulating RFIDlerConfig.Manchester= FALSE; if(read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, RFIDlerConfig.DataBits, RFIDlerConfig.Sync, 0, RFIDlerConfig.Timeout, NO_ONESHOT_READ, HEX) == RFIDlerConfig.DataBits) { if(strcmp(tmp, "0000000000000000") != 0) blank= FALSE; RFIDlerConfig.Manchester= TRUE; if(blank && get_tag_uid(tmp) && q5_read_block(tmp, 0)) { UserMessageNum("\r\nFound tag with gap %d", gap); UserMessageNum(" one %d", one); UserMessageNum(" zero %d", zero); found= TRUE; } } } UserMessage("%s", "\r\n"); return found; }
void xml_indented_array(BYTE *data, BYTE mask, unsigned int length, BYTE indent) { unsigned int i; for(i= 0 ; i < length ; ++i) { if(!(i % 32)) { UserMessage("%s", "\r\n"); space_indent(indent); } UserMessageNum("%02lx", data[i] & mask); } }
// 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"); } }
/// show contents of vtag void vtag_dump(void) { BYTE tmp[MAXBLOCKSIZE + 1], interpret; unsigned int i; UserMessage(" Type: %s", (BYTE *) TagTypes[RFIDlerVTag.TagType]); UserMessage("\r\n Emulating: %s", (BYTE *) TagTypes[RFIDlerVTag.EmulatedTagType]); UserMessage("\r\n Raw UID: %s", RFIDlerVTag.UID); // show interpreted UID if(RFIDlerVTag.EmulatedTagType == TAG_TYPE_NONE) interpret= RFIDlerVTag.TagType; else interpret= RFIDlerVTag.EmulatedTagType; UserMessage("\r\n UID: %s", interpret_uid(tmp, RFIDlerVTag.UID, interpret) ? tmp : (BYTE *) "invalid!"); // show config block if present if(config_block_number(&i, RFIDlerVTag.TagType)) { UserMessage("%s","\r\n\r\n"); config_block_show(&RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * i)], RFIDlerVTag.TagType); } if(RFIDlerVTag.DataBlocks == 0) { UserMessage("%s", "\r\n\r\n"); return; } UserMessage("%s", "\r\n Data:"); tmp[HEXDIGITS(RFIDlerVTag.BlockSize)]= '\0'; for(i= 0 ; i < RFIDlerVTag.DataBlocks ; ++i) { memcpy(tmp, &RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * i)], HEXDIGITS(RFIDlerVTag.BlockSize)); if(tmp[0]) { UserMessageNum("\r\n %d: ", i); UserMessage("%s", tmp); } } UserMessage("%s", "\r\n\r\n"); }
BOOL q5_config_block_show(BYTE *config, BYTE *password) { uint32_t value= hextoulong(config); UserMessage(" Config Block (0): %.8s\r\n\r\n", config); UserMessage(" Page Select: %s\r\n", GET_CONFIG(value, Q5_MASK_PAGE_SELECT, Q5_SHIFT_PAGE_SELECT) ? "True" : "False"); UserMessage(" Fast Write: %s\r\n", GET_CONFIG(value, Q5_MASK_FAST_WRITE, Q5_SHIFT_FAST_WRITE) ? "True" : "False"); UserMessageNum(" Data Rate: %02d = ", GET_CONFIG(value, Q5_MASK_DATA_BIT_RATE, Q5_SHIFT_DATA_BIT_RATE)); UserMessageNum("%d * FC\r\n", GET_CONFIG(value, Q5_MASK_DATA_BIT_RATE, Q5_SHIFT_DATA_BIT_RATE) * 2 + 2); UserMessage(" Use AOR: %s\r\n", GET_CONFIG(value, Q5_MASK_USE_AOR, Q5_SHIFT_USE_AOR) ? "True" : "False"); UserMessage(" Use PWD: %s\r\n", GET_CONFIG(value, Q5_MASK_USE_PWD, Q5_SHIFT_USE_PWD) ? "True" : "False"); UserMessageNum(" PSK Carrier: %d = ", GET_CONFIG(value, Q5_MASK_PSK_CARRIER_FREQ, Q5_SHIFT_PSK_CARRIER_FREQ)); UserMessageNum("%d * FC\r\n", PSK_Rates[GET_CONFIG(value, Q5_MASK_PSK_CARRIER_FREQ, Q5_SHIFT_PSK_CARRIER_FREQ)]); UserMessage(" Inverse Data: %s\r\n", GET_CONFIG(value, Q5_MASK_INVERSE_DATA, Q5_SHIFT_INVERSE_DATA) ? "True" : "False"); UserMessageNum(" Modulation: %d = ", GET_CONFIG(value, Q5_MASK_MODULATION, Q5_SHIFT_MODULATION)); UserMessage("%s\r\n", (BYTE *) Q5_Modulation[GET_CONFIG(value, Q5_MASK_MODULATION, Q5_SHIFT_MODULATION)]); UserMessageNum(" Max Block: %d\r\n", GET_CONFIG(value, Q5_MASK_MAX_BLOCK, Q5_SHIFT_MAX_BLOCK)); UserMessage(" ST: %s\r\n", GET_CONFIG(value, Q5_MASK_ST, Q5_SHIFT_ST) ? "True" : "False"); UserMessage("\r\n PWD Block (7): %.8s ", password); printhexreadable(password, 4); UserMessage("%s", "\r\n"); return TRUE; }
// decode externally sniffed PWM BOOL hitag2_decode_pwm(unsigned long pulses[], unsigned long gaps[], unsigned int count) { unsigned int i, j; BOOL decoded= FALSE, encrypted= FALSE, auth= FALSE; BYTE out[65], tmp[33], x; // max response from hitag2 is 64 bits j= 0; while(j < count) { i= generic_decode_pwm(out, &pulses[j], 10, 256, &gaps[j], 10, 80, count - j); if(i) { // there are only 4 message sizes, so decode accordingly switch(strlen(out)) { // start_auth case 5: auth= FALSE; if(memcmp(out, HITAG2_START_AUTH, 5) == 0) { UserMessage("\r\n%s, START_AUTH", out); auth= TRUE; } else UserMessage("\r\n%s, ?INVALID?", out); encrypted= FALSE; break; // read/write/halt case 10: auth= FALSE; if(encrypted) { UserMessage("\r\n%s, CMD_ENCRYPTED", out); break; } if(memcmp(out, HITAG2_HALT, 2) == 0) { UserMessage("\r\n%s, HALT", out); break; } if(memcmp(out, HITAG2_READ_PAGE, 2) == 0) UserMessage("\r\n%s, READ_PAGE:", out); if(memcmp(out, HITAG2_READ_PAGE_INVERTED, 2) == 0) UserMessage("\r\n%s, READ_PAGE_INVERTED:", out); if(memcmp(out, HITAG2_WRITE_PAGE, 2) == 0) UserMessage("\r\n%s, WRITE_PAGE:", out); binstringtobyte(&x, &out[2], 3); UserMessageNum("%d", x); break; // password or data case 32: if(auth) UserMessage("\r\n%s, PWD:", out); else UserMessage("\r\n%s, DATA:", out); binstringtohex(out, out); UserMessage("%s", out); auth= FALSE; break; // crypto handshake case 64: UserMessage("\r\n%s, PRN:", out); memcpy(tmp, out, 32); tmp[32]= '\0'; binstringtohex(out, tmp); UserMessage("%s: SECRET:", out); binstringtohex(out, out + 32); UserMessage("%s", out); encrypted= TRUE; auth= FALSE; break; default: UserMessage("\r\n%s,?INVALID?", out); } decoded= TRUE; j += i; } else break; } UserMessage("%s", "\r\n"); return decoded; }
BOOL vtag_write_to_tag(BYTE *pass) { unsigned int block, config_block_no; BYTE tmp[MAXBLOCKSIZE + 1]; BOOL auth= FALSE; StoredConfig tmptag; // preserve tag type memcpy(&tmptag, &RFIDlerConfig, sizeof(RFIDlerConfig)); // set real tag to vtag type if not already the same if(RFIDlerConfig.TagType != RFIDlerVTag.TagType) if(!tag_set(RFIDlerVTag.TagType)) { memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return FALSE; } // reset target tag, but don't care if we get UID as it may not be in a valid mode get_tag_uid(tmp); // re-auth if(!tag_login(block, tmp, pass)) tag_auth(block, tmp, pass); // initialise target in default mode // get config block number if(!config_block_number(&config_block_no, RFIDlerConfig.TagType)) return FALSE; // get default config block data tmp[HEXDIGITS(RFIDlerVTag.BlockSize)]= '\0'; if (!config_block(tmp, RFIDlerConfig.TagType, RFIDlerConfig.TagType)) { memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return FALSE; } // write default config if(!write_tag(config_block_no, tmp, VERIFY)) { memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return FALSE; } // reset tag again get_tag_uid(tmp); // write all VTAG blocks with valid data in them // but avoid writing config block until last as tag may stop responding tmp[HEXDIGITS(RFIDlerVTag.BlockSize)]= '\0'; for(block= 0 ; block < RFIDlerVTag.DataBlocks ; ++block) if(block != config_block_no && RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * block)]) { // try to login/auth in case target tag requires it // don't care if we fail if(!(auth= tag_login(block, tmp, pass))) auth= tag_auth(block, tmp, pass); memcpy(tmp, &RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * block)], HEXDIGITS(RFIDlerVTag.BlockSize)); UserMessageNum("\r\n%d: ", block); UserMessage("%s", tmp); // failure allowed as we may be trying to write locked blocks if(!write_tag(block, tmp, VERIFY)) { UserMessage("%s", " Failed!"); if(!auth) UserMessage("%s", " (Auth/Login)"); } } // write config block (no verify as some tags stop talking after config change) if(!tag_login(block, tmp, pass)) tag_auth(block, tmp, pass); tmp[HEXDIGITS(RFIDlerVTag.BlockSize)]= '\0'; memcpy(tmp, &RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * config_block_no)], HEXDIGITS(RFIDlerVTag.BlockSize)); UserMessageNum("\r\n\r\n%d: ", config_block_no); UserMessage("%s", tmp); if(!write_tag(config_block_no, tmp, NO_VERIFY)) { memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return FALSE; } memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return TRUE; }
// copy real tag to vtag or set up emulation BOOL vtag_copy_from_tag(BYTE *tagtype, BYTE *pass) { BYTE tmp[MAXUID + 1], tag, copy= FALSE, i; unsigned int config_block_no, user_block_no; // set target tag type if (strlen(tagtype) == 0) { if(RFIDlerVTag.TagType == TAG_TYPE_NONE) tag= RFIDlerConfig.TagType; else tag= RFIDlerVTag.TagType; } else if(!(tag= tag_get_type(tagtype))) return FALSE; // check we've got a tag to copy if(!get_tag_uid(tmp)) return FALSE; // set vtag to desired type vtag_set_tag_from_type(tag); // if tag & vtag are the same, just copy if(RFIDlerConfig.TagType == tag) { RFIDlerVTag.EmulatedTagType= TAG_TYPE_NONE; // auth if(!tag_login(0, TmpBits, pass)) tag_auth(0, TmpBits, pass); // copy UID strcpy(RFIDlerVTag.UID, tmp); // if no data to copy, we're done. if(RFIDlerVTag.DataBlocks == 0) return TRUE; // copy data blocks for(i= 0 ; i < RFIDlerVTag.DataBlocks ; ++i) { if (!read_tag(RFIDlerVTag.Data + HEXDIGITS(i * RFIDlerVTag.BlockSize), i, i)) UserMessageNum("%d: (fail)\r\n", i); else copy= TRUE; } return copy; } // otherwise, set up emulation RFIDlerVTag.EmulatedTagType= RFIDlerConfig.TagType; strcpy(RFIDlerVTag.UID, tmp); // get config & user data block numbers if(!config_block_number(&config_block_no, tag) || !config_user_block(&user_block_no, tag)) return FALSE; // get & store config block if (!config_block(&RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * config_block_no)], RFIDlerConfig.TagType, tag)) return FALSE; // copy raw hex UID to data blocks memcpy(&RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * user_block_no)], RFIDlerVTag.UID, strlen(RFIDlerVTag.UID)); return TRUE; }
BOOL t55x7_config_block_show(BYTE *config, BYTE *password) { uint32_t value= hextoulong(config); BOOL xmode; UserMessage(" Config Block (0): %.8s\r\n\r\n", config); UserMessageNum(" Master Key: %d = ", GET_CONFIG(value, T55X7_MASK_MASTER_KEY, T55X7_SHIFT_MASTER_KEY)); if(GET_CONFIG(value, T55X7_MASK_MASTER_KEY, T55X7_SHIFT_MASTER_KEY) == T55X7_COMPAT_MODE) UserMessage("%s\r\n", "Compatibility Mode"); else if(GET_CONFIG(value, T55X7_MASK_MASTER_KEY, T55X7_SHIFT_MASTER_KEY) == T55X7_XMODE_MODE) UserMessage("%s\r\n", "Extended Mode"); else UserMessage("%s\r\n", "Undefined Mode"); xmode= GET_CONFIG(value, T55X7_MASK_XMODE, T55X7_SHIFT_XMODE); UserMessage(" X-Mode: %s\r\n", xmode ? "True" : "False"); // display additional/alternate fields if in xmode if(xmode) { UserMessageNum(" Data Rate: %02d = ", GET_CONFIG(value, T55X7_XMODE_MASK_DATA_BIT_RATE, T55X7_SHIFT_DATA_BIT_RATE)); UserMessageNum("%d * FC\r\n", GET_CONFIG(value, T55X7_XMODE_MASK_DATA_BIT_RATE, T55X7_SHIFT_DATA_BIT_RATE) * 2 + 2); UserMessageNum(" Modulation: %02d = ", GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION)); if(GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION) > 8) { if(GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION)== T55X7_MOD_BIPHASE_50) UserMessage("%s\r\n", "BiPhase ('50)"); else if (GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION)== T55X7_MOD_BIPHASE_57) UserMessage("%s\r\n", "BiPhase ('57)"); else UserMessage("%s\r\n", "Invalid"); } else UserMessage("%s\r\n", (BYTE *) T55x7_Compat_Modulation[GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION)]); UserMessage(" SST: %s\r\n", GET_CONFIG(value, T55X7_XMODE_MASK_SST, T55X7_SHIFT_ST_SST) ? "True" : "False"); } else { UserMessageNum(" Data Rate: %02d = ", GET_CONFIG(value, T55X7_COMPAT_MASK_DATA_BIT_RATE, T55X7_SHIFT_DATA_BIT_RATE)); UserMessageNum("%d * FC\r\n", T55x7_Compat_Data_Rates[GET_CONFIG(value, T55X7_COMPAT_MASK_DATA_BIT_RATE, T55X7_SHIFT_DATA_BIT_RATE)]); UserMessageNum(" Modulation: %02d = ", GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION)); if(GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION) > 8) { if(GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION)== 16) UserMessage("%s\r\n", "BiPhase ('50)"); else UserMessage("%s\r\n", "Reserved/Invalid"); } else UserMessage("%s\r\n", (BYTE *) T55x7_Compat_Modulation[GET_CONFIG(value, T55X7_MASK_MODULATION, T55X7_SHIFT_MODULATION)]); UserMessage(" ST: %s\r\n", GET_CONFIG(value, T55X7_COMPAT_MASK_ST, T55X7_SHIFT_ST_SST) ? "True" : "False"); } // display common fields UserMessageNum(" PSK Carrier: %d = ", GET_CONFIG(value, T55X7_MASK_PSK_CARRIER_FREQ, T55X7_SHIFT_PSK_CARRIER_FREQ)); if(GET_CONFIG(value, T55X7_MASK_PSK_CARRIER_FREQ, T55X7_SHIFT_PSK_CARRIER_FREQ) > 2) UserMessage("%s\r\n", "Reserved"); else UserMessageNum("%d * FC\r\n", GET_CONFIG(value, T55X7_MASK_PSK_CARRIER_FREQ, T55X7_SHIFT_PSK_CARRIER_FREQ) * 2 + 2); UserMessageNum(" Maxblock: %d\r\n", GET_CONFIG(value, T55X7_MASK_MAX_BLOCK, T55X7_SHIFT_MAX_BLOCK)); UserMessage(" AOR: %s\r\n", GET_CONFIG(value, T55X7_MASK_AOR, T55X7_SHIFT_AOR) ? "True" : "False"); UserMessage(" OTP: %s\r\n", GET_CONFIG(value, T55X7_MASK_OTP, T55X7_SHIFT_OTP) ? "True" : "False"); UserMessage(" PWD: %s\r\n", GET_CONFIG(value, T55X7_MASK_PWD, T55X7_SHIFT_PWD) ? "True" : "False"); UserMessage(" Fast Write: %s\r\n", GET_CONFIG(value, T55X7_MASK_FAST_WRITE, T55X7_SHIFT_FAST_WRITE) ? "True" : "False"); UserMessage(" Inverse Data: %s\r\n", GET_CONFIG(value, T55X7_MASK_INVERSE_DATA, T55X7_SHIFT_INVERSE_DATA) ? "True" : "False"); UserMessage(" POR Delay: %s\r\n", GET_CONFIG(value, T55X7_MASK_POR_DELAY, T55X7_SHIFT_POR_DELAY) ? "True" : "False"); UserMessage("\r\n PWD Block (7): %.8s ", password); printhexreadable(password, 4); UserMessage("%s", "\r\n"); return TRUE; }
// print binary array as hex void hexprintbinarray(BYTE *bin, unsigned int length) { while(length--) UserMessageNum("%02lx", *(bin++)); }