mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
added timeouts
This commit is contained in:
parent
1f08512670
commit
c15266dfc2
2 changed files with 159 additions and 118 deletions
255
armsrc/em4x50.c
255
armsrc/em4x50.c
|
@ -40,6 +40,7 @@
|
||||||
#define EM4X50_T_TAG_WAITING_FOR_SIGNAL 75
|
#define EM4X50_T_TAG_WAITING_FOR_SIGNAL 75
|
||||||
#define EM4X50_T_WAITING_FOR_DBLLIW 1550
|
#define EM4X50_T_WAITING_FOR_DBLLIW 1550
|
||||||
#define EM4X50_T_WAITING_FOR_ACK 4
|
#define EM4X50_T_WAITING_FOR_ACK 4
|
||||||
|
//#define EM4X50_T_SIMULATION_TIMEOUT 100
|
||||||
|
|
||||||
// the following value seems to be critical; if it's too low (e.g. < 120)
|
// the following value seems to be critical; if it's too low (e.g. < 120)
|
||||||
// some cards are no longer readable although they're ok
|
// some cards are no longer readable although they're ok
|
||||||
|
@ -669,62 +670,53 @@ static int get_word_from_bitstream(uint32_t *data) {
|
||||||
return PM3_EOPABORTED;
|
return PM3_EOPABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool em4x50_sim_send_bit(uint8_t bit) {
|
static int em4x50_sim_send_bit(uint8_t bit) {
|
||||||
|
|
||||||
uint16_t check = 0;
|
uint16_t timeout = EM4X50_T_TAG_FULL_PERIOD;
|
||||||
|
|
||||||
for (int t = 0; t < EM4X50_T_TAG_FULL_PERIOD; t++) {
|
for (int t = 0; t < EM4X50_T_TAG_FULL_PERIOD; t++) {
|
||||||
|
|
||||||
// wait until SSC_CLK goes HIGH
|
// wait until SSC_CLK goes HIGH
|
||||||
// used as a simple detection of a reader field?
|
// used as a simple detection of a reader field?
|
||||||
while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
|
while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) && (timeout--));
|
||||||
WDT_HIT();
|
|
||||||
if (check == 1000) {
|
if (timeout == 0) {
|
||||||
if (BUTTON_PRESS())
|
return PM3_ETIMEOUT;
|
||||||
return false;
|
|
||||||
check = 0;
|
|
||||||
}
|
|
||||||
++check;
|
|
||||||
}
|
}
|
||||||
|
timeout = EM4X50_T_TAG_FULL_PERIOD;
|
||||||
|
|
||||||
if (bit)
|
if (bit)
|
||||||
OPEN_COIL();
|
OPEN_COIL();
|
||||||
else
|
else
|
||||||
SHORT_COIL();
|
SHORT_COIL();
|
||||||
|
|
||||||
check = 0;
|
|
||||||
|
|
||||||
//wait until SSC_CLK goes LOW
|
//wait until SSC_CLK goes LOW
|
||||||
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
|
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK && (timeout--));
|
||||||
WDT_HIT();
|
if (timeout == 0) {
|
||||||
if (check == 1000) {
|
return PM3_ETIMEOUT;
|
||||||
if (BUTTON_PRESS())
|
|
||||||
return false;
|
|
||||||
check = 0;
|
|
||||||
}
|
|
||||||
++check;
|
|
||||||
}
|
}
|
||||||
|
timeout = EM4X50_T_TAG_FULL_PERIOD;
|
||||||
|
|
||||||
if (t == EM4X50_T_TAG_HALF_PERIOD)
|
if (t == EM4X50_T_TAG_HALF_PERIOD)
|
||||||
bit ^= 1;
|
bit ^= 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool em4x50_sim_send_byte(uint8_t byte) {
|
static int em4x50_sim_send_byte(uint8_t byte) {
|
||||||
|
|
||||||
// send byte
|
// send byte
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
if (!em4x50_sim_send_bit((byte >> (7 - i)) & 1))
|
if (em4x50_sim_send_bit((byte >> (7 - i)) & 1) == PM3_ETIMEOUT)
|
||||||
return false;
|
return PM3_ETIMEOUT;
|
||||||
|
|
||||||
return true;
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool em4x50_sim_send_byte_with_parity(uint8_t byte) {
|
static int em4x50_sim_send_byte_with_parity(uint8_t byte) {
|
||||||
|
|
||||||
uint8_t parity = 0x0;
|
uint8_t parity = 0x0;
|
||||||
|
|
||||||
|
@ -732,16 +724,18 @@ static bool em4x50_sim_send_byte_with_parity(uint8_t byte) {
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
parity ^= (byte >> i) & 1;
|
parity ^= (byte >> i) & 1;
|
||||||
|
|
||||||
if (em4x50_sim_send_byte(byte) == false)
|
if (em4x50_sim_send_byte(byte) == PM3_ETIMEOUT) {
|
||||||
return false;;
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
if (em4x50_sim_send_bit(parity) == false)
|
if (em4x50_sim_send_bit(parity) == PM3_ETIMEOUT) {
|
||||||
return false;
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool em4x50_sim_send_word(uint32_t word) {
|
static int em4x50_sim_send_word(uint32_t word) {
|
||||||
|
|
||||||
uint8_t cparity = 0x00;
|
uint8_t cparity = 0x00;
|
||||||
|
|
||||||
|
@ -750,8 +744,8 @@ static bool em4x50_sim_send_word(uint32_t word) {
|
||||||
|
|
||||||
// 4 bytes each with even row parity bit
|
// 4 bytes each with even row parity bit
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (em4x50_sim_send_byte_with_parity((word >> ((3 - i) * 8)) & 0xFF) == false) {
|
if (em4x50_sim_send_byte_with_parity((word >> ((3 - i) * 8)) & 0xFF) == PM3_ETIMEOUT) {
|
||||||
return false;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,47 +756,36 @@ static bool em4x50_sim_send_word(uint32_t word) {
|
||||||
cparity ^= (((word >> ((3 - j) * 8)) & 0xFF) >> (7 - i)) & 1;
|
cparity ^= (((word >> ((3 - j) * 8)) & 0xFF) >> (7 - i)) & 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (em4x50_sim_send_byte(cparity) == false)
|
if (em4x50_sim_send_byte(cparity) == PM3_ETIMEOUT) {
|
||||||
return false;
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
// stop bit
|
// stop bit
|
||||||
if (em4x50_sim_send_bit(0) == false)
|
if (em4x50_sim_send_bit(0) == PM3_ETIMEOUT) {
|
||||||
return false;
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_cycles(int maxperiods) {
|
static int wait_cycles(int maxperiods) {
|
||||||
|
|
||||||
int period = 0, check = 0;
|
int EM4X50_T_SIMULATION_TIMEOUT = 500;
|
||||||
|
int period = 0, timeout = EM4X50_T_SIMULATION_TIMEOUT;
|
||||||
|
|
||||||
while (period < maxperiods) {
|
while (period < maxperiods) {
|
||||||
|
|
||||||
while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
|
while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) && (timeout--));
|
||||||
WDT_HIT();
|
if (timeout <= 0) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
if (check == 1000) {
|
|
||||||
if (BUTTON_PRESS()) {
|
|
||||||
return PM3_EOPABORTED;
|
|
||||||
}
|
|
||||||
check = 0;
|
|
||||||
}
|
|
||||||
++check;
|
|
||||||
}
|
}
|
||||||
|
timeout = EM4X50_T_SIMULATION_TIMEOUT;
|
||||||
check = 0;
|
|
||||||
|
|
||||||
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
|
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK && (timeout--));
|
||||||
WDT_HIT();
|
if (timeout <= 0) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
if (check == 1000) {
|
|
||||||
if (BUTTON_PRESS()) {
|
|
||||||
return PM3_EOPABORTED;
|
|
||||||
}
|
|
||||||
check = 0;
|
|
||||||
}
|
|
||||||
++check;
|
|
||||||
}
|
}
|
||||||
|
timeout = EM4X50_T_SIMULATION_TIMEOUT;
|
||||||
|
|
||||||
period++;
|
period++;
|
||||||
}
|
}
|
||||||
|
@ -810,14 +793,21 @@ static int wait_cycles(int maxperiods) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t em4x50_sim_read_bit(void) {
|
static int em4x50_sim_read_bit(void) {
|
||||||
|
|
||||||
|
int EM4X50_T_SIMULATION_TIMEOUT = 500;
|
||||||
int cycles = 0;
|
int cycles = 0;
|
||||||
|
int timeout1 = EM4X50_T_SIMULATION_TIMEOUT;
|
||||||
|
int timeout2 = EM4X50_T_SIMULATION_TIMEOUT;
|
||||||
|
|
||||||
while (cycles < EM4X50_T_TAG_FULL_PERIOD) {
|
while (cycles < EM4X50_T_TAG_FULL_PERIOD) {
|
||||||
|
|
||||||
// wait until reader field disappears
|
// wait until reader field disappears
|
||||||
while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK));
|
while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) && (timeout1--));
|
||||||
|
if (timeout1 <= 0) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
timeout1 = EM4X50_T_SIMULATION_TIMEOUT;
|
||||||
|
|
||||||
// reader field is off, reset timer TC0
|
// reader field is off, reset timer TC0
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
|
@ -829,12 +819,17 @@ static uint8_t em4x50_sim_read_bit(void) {
|
||||||
if (AT91C_BASE_TC0->TC_CV > T0 * EM4X50_ZERO_DETECTION) {
|
if (AT91C_BASE_TC0->TC_CV > T0 * EM4X50_ZERO_DETECTION) {
|
||||||
|
|
||||||
// gap detected; wait until reader field is switched on again
|
// gap detected; wait until reader field is switched on again
|
||||||
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK);
|
while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK && (timeout2--));
|
||||||
|
|
||||||
|
if (timeout2 <= 0) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
timeout2 = EM4X50_T_SIMULATION_TIMEOUT;
|
||||||
|
|
||||||
// now we have a reference "position", from here it will take
|
// now we have a reference "position", from here it will take
|
||||||
// slightly less 32 cycles until the end of the bit period
|
// slightly less 32 cycles until the end of the bit period
|
||||||
wait_cycles(EM4X50_T_TAG_FULL_PERIOD - EM4X50_ZERO_DETECTION);
|
wait_cycles(28);
|
||||||
|
|
||||||
// end of bit period is reached; return with bit value "0"
|
// end of bit period is reached; return with bit value "0"
|
||||||
// (cf. datasheet)
|
// (cf. datasheet)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -851,46 +846,68 @@ static uint8_t em4x50_sim_read_bit(void) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t em4x50_sim_read_byte(void) {
|
static int em4x50_sim_read_byte(void) {
|
||||||
|
|
||||||
uint8_t byte = 0;
|
int bit = 0, byte = 0;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
byte <<= 1;
|
byte <<= 1;
|
||||||
byte |= em4x50_sim_read_bit();
|
bit = em4x50_sim_read_bit();
|
||||||
|
if (bit == PM3_ETIMEOUT) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
byte |= bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return byte;
|
return byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool em4x50_sim_read_byte_with_parity_check(uint8_t *byte) {
|
static int em4x50_sim_read_byte_with_parity_check(uint8_t *byte) {
|
||||||
|
|
||||||
uint8_t parity = 0, pval = 0;
|
int bit = 0, pval = 0;
|
||||||
|
uint8_t parity = 0;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
*byte <<= 1;
|
*byte <<= 1;
|
||||||
*byte |= em4x50_sim_read_bit();
|
bit = em4x50_sim_read_bit();
|
||||||
|
if (bit == PM3_ETIMEOUT) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
*byte |= bit;
|
||||||
|
|
||||||
parity ^= ((*byte) & 1);
|
parity ^= ((*byte) & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pval = em4x50_sim_read_bit();
|
pval = em4x50_sim_read_bit();
|
||||||
|
if (pval == PM3_ETIMEOUT) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
return (parity == pval);
|
return (parity == pval) ? PM3_SUCCESS : PM3_EFAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool em4x50_sim_read_word(uint32_t *word) {
|
static int em4x50_sim_read_word(uint32_t *word) {
|
||||||
|
|
||||||
uint8_t parities = 0, parities_calculated = 0, stop_bit = 0;
|
int stop_bit = 0;
|
||||||
|
int parities = 0, parities_calculated = 0;
|
||||||
uint8_t bytes[4] = {0};
|
uint8_t bytes[4] = {0};
|
||||||
|
|
||||||
// read plain data
|
// read plain data
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
em4x50_sim_read_byte_with_parity_check(&bytes[i]);
|
if (em4x50_sim_read_byte_with_parity_check(&bytes[i]) != PM3_SUCCESS) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read column parities and stop bit
|
// read column parities and stop bit
|
||||||
parities = em4x50_sim_read_byte();
|
parities = em4x50_sim_read_byte();
|
||||||
|
if (parities == PM3_ETIMEOUT) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
stop_bit = em4x50_sim_read_bit();
|
stop_bit = em4x50_sim_read_bit();
|
||||||
|
if (stop_bit == PM3_ETIMEOUT) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
// calculate column parities from data
|
// calculate column parities from data
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
|
@ -904,10 +921,10 @@ static bool em4x50_sim_read_word(uint32_t *word) {
|
||||||
|
|
||||||
// check parities
|
// check parities
|
||||||
if ((parities == parities_calculated) && (stop_bit == 0)) {
|
if ((parities == parities_calculated) && (stop_bit == 0)) {
|
||||||
return true;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return PM3_EFAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void em4x50_sim_send_ack(void) {
|
static void em4x50_sim_send_ack(void) {
|
||||||
|
@ -963,7 +980,9 @@ static int em4x50_sim_handle_login_command(uint32_t *tag) {
|
||||||
|
|
||||||
// read password
|
// read password
|
||||||
uint32_t password = 0;
|
uint32_t password = 0;
|
||||||
bool pwd_ok = em4x50_sim_read_word(&password);
|
int pwd = em4x50_sim_read_word(&password);
|
||||||
|
|
||||||
|
em4x50_sim_read_word(&password);
|
||||||
//wait_cycles(15);
|
//wait_cycles(15);
|
||||||
|
|
||||||
// processing pause time (corresponds to a "1" bit)
|
// processing pause time (corresponds to a "1" bit)
|
||||||
|
@ -972,14 +991,13 @@ static int em4x50_sim_handle_login_command(uint32_t *tag) {
|
||||||
// empirically determined delay (to be examined seperately)
|
// empirically determined delay (to be examined seperately)
|
||||||
wait_cycles(1);
|
wait_cycles(1);
|
||||||
|
|
||||||
if (pwd_ok && (password == reflect32(tag[EM4X50_DEVICE_PASSWORD]))) {
|
if ((pwd == PM3_SUCCESS) && (password == reflect32(tag[EM4X50_DEVICE_PASSWORD]))) {
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
gLogin = true;
|
gLogin = true;
|
||||||
} else {
|
} else {
|
||||||
em4x50_sim_send_nak();
|
em4x50_sim_send_nak();
|
||||||
gLogin = false;
|
gLogin = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue with standard read mode
|
// continue with standard read mode
|
||||||
return EM4X50_COMMAND_STANDARD_READ;
|
return EM4X50_COMMAND_STANDARD_READ;
|
||||||
}
|
}
|
||||||
|
@ -1004,15 +1022,15 @@ static int em4x50_sim_handle_write_command(uint32_t *tag) {
|
||||||
|
|
||||||
// read address
|
// read address
|
||||||
uint8_t address = 0;
|
uint8_t address = 0;
|
||||||
bool addr_ok = em4x50_sim_read_byte_with_parity_check(&address);
|
int addr = em4x50_sim_read_byte_with_parity_check(&address);
|
||||||
// read data
|
// read data
|
||||||
uint32_t data = 0;
|
uint32_t data = 0;
|
||||||
bool word_ok = em4x50_sim_read_word(&data);
|
int word = em4x50_sim_read_word(&data);
|
||||||
|
|
||||||
// write access time
|
// write access time
|
||||||
wait_cycles(EM4X50_T_TAG_TWA);
|
wait_cycles(EM4X50_T_TAG_TWA);
|
||||||
|
|
||||||
if ((addr_ok == false) || (word_ok == false)) {
|
if ((addr != PM3_SUCCESS) || (word != PM3_SUCCESS)) {
|
||||||
em4x50_sim_send_nak();
|
em4x50_sim_send_nak();
|
||||||
return EM4X50_COMMAND_STANDARD_READ;
|
return EM4X50_COMMAND_STANDARD_READ;
|
||||||
}
|
}
|
||||||
|
@ -1103,7 +1121,7 @@ static int em4x50_sim_handle_write_command(uint32_t *tag) {
|
||||||
|
|
||||||
static int em4x50_sim_handle_writepwd_command(uint32_t *tag) {
|
static int em4x50_sim_handle_writepwd_command(uint32_t *tag) {
|
||||||
|
|
||||||
bool pwd_ok = false;
|
int pwd = 0;
|
||||||
|
|
||||||
if (gWritePasswordProcess == false) {
|
if (gWritePasswordProcess == false) {
|
||||||
|
|
||||||
|
@ -1111,14 +1129,14 @@ static int em4x50_sim_handle_writepwd_command(uint32_t *tag) {
|
||||||
|
|
||||||
// read password
|
// read password
|
||||||
uint32_t act_password = 0;
|
uint32_t act_password = 0;
|
||||||
pwd_ok = em4x50_sim_read_word(&act_password);
|
pwd = em4x50_sim_read_word(&act_password);
|
||||||
|
|
||||||
wait_cycles(15);
|
//wait_cycles(15);
|
||||||
|
|
||||||
// processing pause time (corresponds to a "1" bit)
|
// processing pause time (corresponds to a "1" bit)
|
||||||
em4x50_sim_send_bit(1);
|
em4x50_sim_send_bit(1);
|
||||||
|
|
||||||
if (pwd_ok && (act_password == reflect32(tag[EM4X50_DEVICE_PASSWORD]))) {
|
if ((pwd == PM3_SUCCESS) && (act_password == reflect32(tag[EM4X50_DEVICE_PASSWORD]))) {
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
gLogin = true;
|
gLogin = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1138,19 +1156,20 @@ static int em4x50_sim_handle_writepwd_command(uint32_t *tag) {
|
||||||
|
|
||||||
// read new password
|
// read new password
|
||||||
uint32_t new_password = 0;
|
uint32_t new_password = 0;
|
||||||
pwd_ok = em4x50_sim_read_word(&new_password);
|
pwd = em4x50_sim_read_word(&new_password);
|
||||||
|
|
||||||
// write access time
|
// write access time
|
||||||
wait_cycles(EM4X50_T_TAG_TWA);
|
wait_cycles(EM4X50_T_TAG_TWA);
|
||||||
|
|
||||||
if (pwd_ok) {
|
if (pwd == PM3_SUCCESS) {
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
tag[EM4X50_DEVICE_PASSWORD] = reflect32(new_password);
|
tag[EM4X50_DEVICE_PASSWORD] = reflect32(new_password);
|
||||||
} else {
|
} else {
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
return EM4X50_COMMAND_STANDARD_READ;
|
return EM4X50_COMMAND_STANDARD_READ;
|
||||||
}
|
}
|
||||||
//OPEN_COIL();
|
|
||||||
|
//wait_cycles(15);
|
||||||
|
|
||||||
// EEPROM write time
|
// EEPROM write time
|
||||||
wait_cycles(EM4X50_T_TAG_TWEE);
|
wait_cycles(EM4X50_T_TAG_TWEE);
|
||||||
|
@ -1158,7 +1177,7 @@ static int em4x50_sim_handle_writepwd_command(uint32_t *tag) {
|
||||||
// strange: need some sort of 'waveform correction', otherwise ack signal
|
// strange: need some sort of 'waveform correction', otherwise ack signal
|
||||||
// will not be detected; sending a single "1" seems to solve the problem
|
// will not be detected; sending a single "1" seems to solve the problem
|
||||||
em4x50_sim_send_bit(1);
|
em4x50_sim_send_bit(1);
|
||||||
|
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
|
|
||||||
// continue with standard read mode
|
// continue with standard read mode
|
||||||
|
@ -1171,17 +1190,17 @@ static int em4x50_sim_handle_writepwd_command(uint32_t *tag) {
|
||||||
|
|
||||||
static int em4x50_sim_handle_selective_read_command(uint32_t *tag) {
|
static int em4x50_sim_handle_selective_read_command(uint32_t *tag) {
|
||||||
|
|
||||||
int command = PM3_EOPABORTED;
|
int command = 0;
|
||||||
|
|
||||||
// read password
|
// read password
|
||||||
uint32_t address = 0;
|
uint32_t address = 0;
|
||||||
bool addr_ok = em4x50_sim_read_word(&address);
|
int addr = em4x50_sim_read_word(&address);
|
||||||
wait_cycles(15);
|
//wait_cycles(15);
|
||||||
|
|
||||||
// processing pause time (corresponds to a "1" bit)
|
// processing pause time (corresponds to a "1" bit)
|
||||||
em4x50_sim_send_bit(1);
|
em4x50_sim_send_bit(1);
|
||||||
|
|
||||||
if (addr_ok) {
|
if (addr == PM3_SUCCESS) {
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
} else {
|
} else {
|
||||||
em4x50_sim_send_nak();
|
em4x50_sim_send_nak();
|
||||||
|
@ -1224,12 +1243,12 @@ static int em4x50_sim_handle_selective_read_command(uint32_t *tag) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return command;
|
return PM3_EOPABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int em4x50_sim_handle_standard_read_command(uint32_t *tag) {
|
static int em4x50_sim_handle_standard_read_command(uint32_t *tag) {
|
||||||
|
|
||||||
int command = PM3_EOPABORTED;
|
int command = 0;
|
||||||
|
|
||||||
// extract control data
|
// extract control data
|
||||||
int fwr = reflect32(tag[EM4X50_CONTROL]) & 0xFF; // first word read
|
int fwr = reflect32(tag[EM4X50_CONTROL]) & 0xFF; // first word read
|
||||||
|
@ -1264,17 +1283,20 @@ static int em4x50_sim_handle_standard_read_command(uint32_t *tag) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return command;
|
|
||||||
|
return PM3_EOPABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reader requests receive mode (rm) by sending two zeros
|
// reader requests receive mode (rm) by sending two zeros
|
||||||
static int check_rm_request(uint32_t *tag) {
|
static int check_rm_request(uint32_t *tag) {
|
||||||
|
|
||||||
// look for first zero
|
// look for first zero
|
||||||
if (em4x50_sim_read_bit() == 0) {
|
int bit = em4x50_sim_read_bit();
|
||||||
|
if (bit == 0) {
|
||||||
|
|
||||||
// look for second zero
|
// look for second zero
|
||||||
if (em4x50_sim_read_bit() == 0) {
|
bit = em4x50_sim_read_bit();
|
||||||
|
if (bit == 0) {
|
||||||
|
|
||||||
// if command before was EM4X50_COMMAND_WRITE_PASSWORD
|
// if command before was EM4X50_COMMAND_WRITE_PASSWORD
|
||||||
// switch to separate process
|
// switch to separate process
|
||||||
|
@ -1289,7 +1311,7 @@ static int check_rm_request(uint32_t *tag) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return (bit != PM3_ETIMEOUT) ? PM3_SUCCESS : PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int em4x50_sim_send_listen_window(uint32_t *tag) {
|
static int em4x50_sim_send_listen_window(uint32_t *tag) {
|
||||||
|
@ -1785,7 +1807,7 @@ void em4x50_writepwd(em4x50_data_t *etd) {
|
||||||
// simulate uploaded data in emulator memory
|
// simulate uploaded data in emulator memory
|
||||||
void em4x50_sim(uint32_t *password) {
|
void em4x50_sim(uint32_t *password) {
|
||||||
|
|
||||||
int status = PM3_SUCCESS;
|
int command = PM3_ENODATA;
|
||||||
|
|
||||||
uint8_t *em4x50_mem = BigBuf_get_EM_addr();
|
uint8_t *em4x50_mem = BigBuf_get_EM_addr();
|
||||||
uint32_t tag[EM4X50_NO_WORDS] = {0x0};
|
uint32_t tag[EM4X50_NO_WORDS] = {0x0};
|
||||||
|
@ -1806,10 +1828,14 @@ void em4x50_sim(uint32_t *password) {
|
||||||
gLogin = false;
|
gLogin = false;
|
||||||
|
|
||||||
// start with inital command = standard read mode
|
// start with inital command = standard read mode
|
||||||
int command = EM4X50_COMMAND_STANDARD_READ;
|
command = EM4X50_COMMAND_STANDARD_READ;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
|
if (data_available()) {
|
||||||
|
command = PM3_EOPABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
|
||||||
case EM4X50_COMMAND_LOGIN:
|
case EM4X50_COMMAND_LOGIN:
|
||||||
|
@ -1831,24 +1857,25 @@ void em4x50_sim(uint32_t *password) {
|
||||||
case EM4X50_COMMAND_SELECTIVE_READ:
|
case EM4X50_COMMAND_SELECTIVE_READ:
|
||||||
command = em4x50_sim_handle_selective_read_command(tag);
|
command = em4x50_sim_handle_selective_read_command(tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case EM4X50_COMMAND_STANDARD_READ:
|
||||||
command = em4x50_sim_handle_standard_read_command(tag);
|
command = em4x50_sim_handle_standard_read_command(tag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == PM3_EOPABORTED) {
|
if (command == PM3_EOPABORTED) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command == PM3_ETIMEOUT) {
|
||||||
|
command = EM4X50_COMMAND_STANDARD_READ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
status = PM3_ENODATA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
lf_finalize();
|
lf_finalize();
|
||||||
reply_ng(CMD_LF_EM4X50_SIM, status, NULL, 0);
|
reply_ng(CMD_LF_EM4X50_SIM, command, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void em4x50_test(em4x50_test_t *ett) {
|
void em4x50_test(em4x50_test_t *ett) {
|
||||||
|
|
|
@ -1249,11 +1249,25 @@ int CmdEM4x50Sim(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_EM4X50_SIM, (uint8_t *)&password, sizeof(password));
|
SendCommandNG(CMD_LF_EM4X50_SIM, (uint8_t *)&password, sizeof(password));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
WaitForResponse(CMD_LF_EM4X50_SIM, &resp);
|
|
||||||
if (resp.status == PM3_SUCCESS)
|
PrintAndLogEx(INFO, "Press pm3-button to abort simulation");
|
||||||
PrintAndLogEx(INFO, "Done");
|
bool keypress = kbd_enter_pressed();
|
||||||
|
while (keypress == false) {
|
||||||
|
keypress = kbd_enter_pressed();
|
||||||
|
|
||||||
|
if (WaitForResponseTimeout(CMD_LF_EM4X50_SIM, &resp, 1500)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (keypress) {
|
||||||
|
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((resp.status == PM3_SUCCESS) || (resp.status == PM3_EOPABORTED))
|
||||||
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
else
|
else
|
||||||
PrintAndLogEx(FAILED, "No valid em4x50 data in memory.");
|
PrintAndLogEx(FAILED, "No valid em4x50 data in memory");
|
||||||
|
|
||||||
return resp.status;
|
return resp.status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue