// watch external clock for PWM messages // specify minimum gap to look for in us void sniff_pwm(unsigned int min) { BOOL toggle; BOOL abort= FALSE; unsigned long i, count, pulsecount= 0L, gaps[DETECT_BUFFER_SIZE], pulses[DETECT_BUFFER_SIZE]; // make sure local clock isn't running & switch to input stop_HW_clock(); COIL_MODE_READER(); READER_CLOCK_ENABLE_OFF(LOW); toggle= SNIFFER_COIL; // wait for 100 ticks to make sure we're settled toggle= SNIFFER_COIL; while(count < 100) { while(SNIFFER_COIL == toggle) // check for user abort if(get_user_abort()) return; ++count; toggle= !toggle; } // watch for gaps / pulses i= 0; GetTimer_us(RESET); while(!abort) { while(SNIFFER_COIL == toggle) // check for user abort if((abort= get_user_abort())) break; toggle= !toggle; count= GetTimer_us(RESET); // check if it was a gap if(count > min) { pulses[i]= pulsecount; gaps[i++]= count; pulsecount= 0L; } else pulsecount += count; if(i == DETECT_BUFFER_SIZE) { decode_pwm(pulses, gaps, i); i= 0; } } decode_pwm(pulses, gaps, i); }
// 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; }
// 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"); } }
// 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; }
// 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; }