mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
next version of half duplex simulation
This commit is contained in:
parent
f6868aadf9
commit
560be30053
1 changed files with 78 additions and 134 deletions
212
armsrc/em4x50.c
212
armsrc/em4x50.c
|
@ -57,12 +57,17 @@
|
||||||
|
|
||||||
int gHigh = 190;
|
int gHigh = 190;
|
||||||
int gLow = 60;
|
int gLow = 60;
|
||||||
|
|
||||||
|
// a global parameter is needed to indicate whether a previous login was
|
||||||
|
// successful, so operations that require authentication may be performed
|
||||||
|
bool gLogin = 0;
|
||||||
|
|
||||||
int gcount = 0;
|
int gcount = 0;
|
||||||
int gcycles = 0;
|
int gcycles = 0;
|
||||||
int rm = 0;
|
int rm = 0;
|
||||||
|
|
||||||
static bool em4x50_sim_send_listen_window(void);
|
static bool em4x50_sim_send_listen_window(uint32_t *tag);
|
||||||
static void em4x50_sim_handle_command(uint8_t command);
|
static void em4x50_sim_handle_command(uint8_t command, uint32_t *tag);
|
||||||
|
|
||||||
void catch_samples(void);
|
void catch_samples(void);
|
||||||
|
|
||||||
|
@ -170,22 +175,19 @@ static void em4x50_setup_read(void) {
|
||||||
|
|
||||||
// Enable Peripheral Clock for
|
// Enable Peripheral Clock for
|
||||||
// TIMER_CLOCK0, used to measure exact timing before answering
|
// TIMER_CLOCK0, used to measure exact timing before answering
|
||||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0);// | (1 << AT91C_ID_TC1);
|
||||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||||
|
|
||||||
// Disable timer during configuration
|
// Disable timer during configuration
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
|
||||||
|
|
||||||
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
|
||||||
|
|
||||||
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||||
|
|
||||||
// Enable and reset counters
|
// Enable and reset counters
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
|
||||||
|
|
||||||
// synchronized startup procedure
|
// synchronized startup procedure
|
||||||
while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC1 returned to zero
|
while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC1 returned to zero
|
||||||
|
@ -289,13 +291,11 @@ static bool invalid_bit(void) {
|
||||||
|
|
||||||
// get sample at 3/4 of bit period
|
// get sample at 3/4 of bit period
|
||||||
wait_timer(T0 * EM4X50_T_TAG_THREE_QUARTER_PERIOD);
|
wait_timer(T0 * EM4X50_T_TAG_THREE_QUARTER_PERIOD);
|
||||||
//wait_timer(T0 * EM4X50_T_TAG_HALF_PERIOD);
|
|
||||||
|
|
||||||
uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
// wait until end of bit period
|
// wait until end of bit period
|
||||||
wait_timer(T0 * EM4X50_T_TAG_QUARTER_PERIOD);
|
wait_timer(T0 * EM4X50_T_TAG_QUARTER_PERIOD);
|
||||||
//wait_timer(T0 * EM4X50_T_TAG_HALF_PERIOD);
|
|
||||||
|
|
||||||
// bit in "undefined" state?
|
// bit in "undefined" state?
|
||||||
if (sample <= gHigh && sample >= gLow)
|
if (sample <= gHigh && sample >= gLow)
|
||||||
|
@ -522,18 +522,14 @@ static int request_receive_mode(void) {
|
||||||
// If <bliw> is true then within the single listen window right after the
|
// If <bliw> is true then within the single listen window right after the
|
||||||
// ack signal a RM request has to be sent.
|
// ack signal a RM request has to be sent.
|
||||||
static bool check_ack(bool bliw) {
|
static bool check_ack(bool bliw) {
|
||||||
int cnt_pulses = 0;
|
int count_cycles = 0;
|
||||||
|
while (count_cycles < EM4X50_T_WAITING_FOR_ACK) {
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
|
||||||
//while (cnt_pulses < EM4X50_T_WAITING_FOR_ACK) {
|
|
||||||
while (AT91C_BASE_TC0->TC_CV < T0 * 4 * EM4X50_T_TAG_FULL_PERIOD) {
|
|
||||||
|
|
||||||
if (BUTTON_PRESS())
|
if (BUTTON_PRESS())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (check_pulse_length(get_pulse_length(), 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
if (check_pulse_length(get_pulse_length(), 2 * EM4X50_T_TAG_FULL_PERIOD)) {
|
||||||
|
|
||||||
catch_samples();
|
//catch_samples();
|
||||||
|
|
||||||
// The received signal is either ACK or NAK.
|
// The received signal is either ACK or NAK.
|
||||||
|
|
||||||
|
@ -570,7 +566,7 @@ static bool check_ack(bool bliw) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cnt_pulses++;
|
count_cycles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -919,6 +915,8 @@ static void em4x50_sim_send_nak(void) {
|
||||||
|
|
||||||
SHORT_COIL();
|
SHORT_COIL();
|
||||||
wait_cycles(EM4X50_T_TAG_HALF_PERIOD);
|
wait_cycles(EM4X50_T_TAG_HALF_PERIOD);
|
||||||
|
|
||||||
|
OPEN_COIL();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -969,68 +967,57 @@ static bool em4x50_sim_send_listen_window(void) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void em4x50_sim_handle_login_command(void) {
|
static void em4x50_sim_handle_login_command(uint32_t *tag) {
|
||||||
|
|
||||||
//uint8_t *em4x50_mem = BigBuf_get_EM_addr();
|
|
||||||
uint32_t password = 0;
|
uint32_t password = 0;
|
||||||
//uint32_t tag[EM4X50_NO_WORDS] = {0x0};
|
|
||||||
|
|
||||||
// read password
|
// read password
|
||||||
password = em4x50_sim_read_word();
|
password = em4x50_sim_read_word();
|
||||||
|
|
||||||
//for (int i = 0; i < EM4X50_NO_WORDS; i++)
|
|
||||||
// tag[i] = reflect32(bytes_to_num(em4x50_mem + (i * 4), 4));
|
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
em4x50_sim_send_ack();
|
// empirically determined delay (to be examined seperately)
|
||||||
|
wait_cycles(1);
|
||||||
/*
|
|
||||||
if (password == tag[0]) {
|
if (password == tag[0]) {
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
|
gLogin = true;
|
||||||
} else {
|
} else {
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_nak();
|
||||||
|
gLogin = false;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// continue with standard read mode
|
// continue with standard read mode
|
||||||
em4x50_sim_handle_command(0);
|
em4x50_sim_handle_command(0, tag);
|
||||||
Dbprintf("password = %08x", password);
|
|
||||||
BigBuf_free();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void em4x50_sim_handle_reset_command(void) {
|
static void em4x50_sim_handle_reset_command(uint32_t *tag) {
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
// send ACK
|
// send ACK
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
|
gLogin = false;
|
||||||
|
|
||||||
// wait for tinit
|
// wait for tinit
|
||||||
wait_timer(T0 * EM4X50_T_TAG_TINIT);
|
wait_cycles(EM4X50_T_TAG_TINIT);
|
||||||
|
|
||||||
// continue with standard read mode
|
// continue with standard read mode
|
||||||
em4x50_sim_handle_command(0);
|
em4x50_sim_handle_command(0, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void em4x50_sim_handle_write_command(void) {
|
static void em4x50_sim_handle_write_command(uint32_t *tag) {
|
||||||
|
|
||||||
uint8_t *em4x50_mem = BigBuf_get_EM_addr();
|
|
||||||
uint8_t address = 0;
|
uint8_t address = 0;
|
||||||
uint32_t data = 0;
|
uint32_t data = 0;
|
||||||
uint32_t tag[EM4X50_NO_WORDS] = {0x0};
|
|
||||||
|
|
||||||
// read address
|
// read address
|
||||||
address = em4x50_sim_read_byte_with_parity_check();
|
address = em4x50_sim_read_byte_with_parity_check();
|
||||||
// read data
|
// read data
|
||||||
data = em4x50_sim_read_word();
|
data = em4x50_sim_read_word();
|
||||||
|
|
||||||
for (int i = 0; i < EM4X50_NO_WORDS; i++) {
|
|
||||||
tag[i] = reflect32(bytes_to_num(em4x50_mem + (i * 4), 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract necessary control data
|
// extract necessary control data
|
||||||
bool raw = (tag[EM4X50_CONTROL] >> CONFIG_BLOCK) & READ_AFTER_WRITE;
|
bool raw = (tag[EM4X50_CONTROL] >> CONFIG_BLOCK) & READ_AFTER_WRITE;
|
||||||
// extract protection data
|
// extract protection data
|
||||||
|
@ -1041,7 +1028,7 @@ static void em4x50_sim_handle_write_command(void) {
|
||||||
tag[address] = data;
|
tag[address] = data;
|
||||||
|
|
||||||
// write access time
|
// write access time
|
||||||
wait_timer(T0 * EM4X50_T_TAG_TWA);
|
wait_cycles(EM4X50_T_TAG_TWA);
|
||||||
|
|
||||||
if ((address >= fwrp) && (address <= lwrp)) {
|
if ((address >= fwrp) && (address <= lwrp)) {
|
||||||
em4x50_sim_send_nak();
|
em4x50_sim_send_nak();
|
||||||
|
@ -1055,28 +1042,24 @@ static void em4x50_sim_handle_write_command(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EEPROM write time
|
// EEPROM write time
|
||||||
//wait_timer(T0 * EM4X50_T_TAG_TWEE);
|
wait_cycles(EM4X50_T_TAG_TWEE);
|
||||||
|
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
|
|
||||||
// if "read after write" (raw) bit is set, repeat written data once
|
// if "read after write" (raw) bit is set, repeat written data once
|
||||||
if (raw) {
|
if (raw) {
|
||||||
em4x50_sim_send_listen_window();
|
em4x50_sim_send_listen_window(tag);
|
||||||
em4x50_sim_send_listen_window();
|
em4x50_sim_send_listen_window(tag);
|
||||||
em4x50_sim_send_word(tag[address]);
|
em4x50_sim_send_word(tag[address]);
|
||||||
}
|
}
|
||||||
|
|
||||||
BigBuf_free();
|
|
||||||
|
|
||||||
// continue with standard read mode
|
// continue with standard read mode
|
||||||
em4x50_sim_handle_command(0);
|
em4x50_sim_handle_command(0, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void em4x50_sim_handle_selective_read_command(void) {
|
static void em4x50_sim_handle_selective_read_command(uint32_t *tag) {
|
||||||
|
|
||||||
uint8_t *em4x50_mem = BigBuf_get_EM_addr();
|
|
||||||
uint32_t address = 0;
|
uint32_t address = 0;
|
||||||
uint32_t tag[EM4X50_NO_WORDS] = {0x0};
|
|
||||||
|
|
||||||
// read password
|
// read password
|
||||||
address = em4x50_sim_read_word();
|
address = em4x50_sim_read_word();
|
||||||
|
@ -1085,10 +1068,6 @@ static void em4x50_sim_handle_selective_read_command(void) {
|
||||||
int fwr = address & 0xFF; // first word read
|
int fwr = address & 0xFF; // first word read
|
||||||
int lwr = (address >> 8) & 0xFF; // last word read
|
int lwr = (address >> 8) & 0xFF; // last word read
|
||||||
|
|
||||||
for (int i = 0; i < EM4X50_NO_WORDS; i++) {
|
|
||||||
tag[i] = reflect32(bytes_to_num(em4x50_mem + (i * 4), 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract protection data
|
// extract protection data
|
||||||
int fwrp = tag[EM4X50_PROTECTION] & 0xFF; // first word read protected
|
int fwrp = tag[EM4X50_PROTECTION] & 0xFF; // first word read protected
|
||||||
int lwrp = (tag[EM4X50_PROTECTION] >> 8) & 0xFF; // last word read protected
|
int lwrp = (tag[EM4X50_PROTECTION] >> 8) & 0xFF; // last word read protected
|
||||||
|
@ -1098,34 +1077,27 @@ static void em4x50_sim_handle_selective_read_command(void) {
|
||||||
|
|
||||||
em4x50_sim_send_ack();
|
em4x50_sim_send_ack();
|
||||||
|
|
||||||
|
// iceman, will need a usb cmd check to break as well
|
||||||
while (BUTTON_PRESS() == false) {
|
while (BUTTON_PRESS() == false) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
em4x50_sim_send_listen_window();
|
em4x50_sim_send_listen_window(tag);
|
||||||
for (int i = fwr; i <= lwr; i++) {
|
for (int i = fwr; i <= lwr; i++) {
|
||||||
|
|
||||||
em4x50_sim_send_listen_window();
|
em4x50_sim_send_listen_window(tag);
|
||||||
|
|
||||||
if ((i >= fwrp) && (i <= lwrp)) {
|
// if not authenticated do not send read protected words
|
||||||
|
if ((gLogin == false) && (i >= fwrp) && (i <= lwrp)) {
|
||||||
em4x50_sim_send_word(0x00);
|
em4x50_sim_send_word(0x00);
|
||||||
} else {
|
} else {
|
||||||
em4x50_sim_send_word(tag[i]);
|
em4x50_sim_send_word(tag[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BigBuf_free();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void em4x50_sim_handle_standard_read_command(void) {
|
static void em4x50_sim_handle_standard_read_command(uint32_t *tag) {
|
||||||
|
|
||||||
uint8_t *em4x50_mem = BigBuf_get_EM_addr();
|
|
||||||
uint32_t tag[EM4X50_NO_WORDS] = {0x0};
|
|
||||||
|
|
||||||
for (int i = 0; i < EM4X50_NO_WORDS; i++) {
|
|
||||||
tag[i] = reflect32(bytes_to_num(em4x50_mem + (i * 4), 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract control data
|
// extract control data
|
||||||
int fwr = tag[CONFIG_BLOCK] & 0xFF; // first word read
|
int fwr = tag[CONFIG_BLOCK] & 0xFF; // first word read
|
||||||
int lwr = (tag[CONFIG_BLOCK] >> 8) & 0xFF; // last word read
|
int lwr = (tag[CONFIG_BLOCK] >> 8) & 0xFF; // last word read
|
||||||
|
@ -1133,13 +1105,14 @@ static void em4x50_sim_handle_standard_read_command(void) {
|
||||||
int fwrp = tag[EM4X50_PROTECTION] & 0xFF; // first word read protected
|
int fwrp = tag[EM4X50_PROTECTION] & 0xFF; // first word read protected
|
||||||
int lwrp = (tag[EM4X50_PROTECTION] >> 8) & 0xFF; // last word read protected
|
int lwrp = (tag[EM4X50_PROTECTION] >> 8) & 0xFF; // last word read protected
|
||||||
|
|
||||||
|
// iceman, will need a usb cmd check to break as well
|
||||||
while (BUTTON_PRESS() == false) {
|
while (BUTTON_PRESS() == false) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
em4x50_sim_send_listen_window();
|
em4x50_sim_send_listen_window(tag);
|
||||||
for (int i = fwr; i <= lwr; i++) {
|
for (int i = fwr; i <= lwr; i++) {
|
||||||
|
|
||||||
em4x50_sim_send_listen_window();
|
em4x50_sim_send_listen_window(tag);
|
||||||
|
|
||||||
if ((i >= fwrp) && (i <= lwrp)) {
|
if ((i >= fwrp) && (i <= lwrp)) {
|
||||||
em4x50_sim_send_word(0x00);
|
em4x50_sim_send_word(0x00);
|
||||||
|
@ -1148,23 +1121,22 @@ static void em4x50_sim_handle_standard_read_command(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BigBuf_free();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void em4x50_sim_handle_command(uint8_t command) {
|
static void em4x50_sim_handle_command(uint8_t command, uint32_t *tag) {
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
|
||||||
case EM4X50_COMMAND_LOGIN:
|
case EM4X50_COMMAND_LOGIN:
|
||||||
em4x50_sim_handle_login_command();
|
em4x50_sim_handle_login_command(tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EM4X50_COMMAND_RESET:
|
case EM4X50_COMMAND_RESET:
|
||||||
em4x50_sim_handle_reset_command();
|
em4x50_sim_handle_reset_command(tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EM4X50_COMMAND_WRITE:
|
case EM4X50_COMMAND_WRITE:
|
||||||
em4x50_sim_handle_write_command();
|
em4x50_sim_handle_write_command(tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EM4X50_COMMAND_WRITE_PASSWORD:
|
case EM4X50_COMMAND_WRITE_PASSWORD:
|
||||||
|
@ -1172,17 +1144,17 @@ static void em4x50_sim_handle_command(uint8_t command) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EM4X50_COMMAND_SELECTIVE_READ:
|
case EM4X50_COMMAND_SELECTIVE_READ:
|
||||||
em4x50_sim_handle_selective_read_command();
|
em4x50_sim_handle_selective_read_command(tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
em4x50_sim_handle_standard_read_command();
|
em4x50_sim_handle_standard_read_command(tag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reader requests receive mode (rm) by sending two zeros
|
// reader requests receive mode (rm) by sending two zeros
|
||||||
static void check_rm_request(void) {
|
static void check_rm_request(uint32_t *tag) {
|
||||||
|
|
||||||
int cond = EM4X50_T_TAG_FULL_PERIOD - EM4X50_TAG_TOLERANCE;
|
int cond = EM4X50_T_TAG_FULL_PERIOD - EM4X50_TAG_TOLERANCE;
|
||||||
|
|
||||||
|
@ -1194,12 +1166,12 @@ static void check_rm_request(void) {
|
||||||
|
|
||||||
// read mode request detected, get command from reader
|
// read mode request detected, get command from reader
|
||||||
uint8_t command = em4x50_sim_read_byte_with_parity_check();
|
uint8_t command = em4x50_sim_read_byte_with_parity_check();
|
||||||
em4x50_sim_handle_command(command);
|
em4x50_sim_handle_command(command, tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool em4x50_sim_send_listen_window(void) {
|
static bool em4x50_sim_send_listen_window(uint32_t *tag) {
|
||||||
|
|
||||||
SHORT_COIL();
|
SHORT_COIL();
|
||||||
wait_cycles(EM4X50_T_TAG_HALF_PERIOD);
|
wait_cycles(EM4X50_T_TAG_HALF_PERIOD);
|
||||||
|
@ -1211,7 +1183,7 @@ static bool em4x50_sim_send_listen_window(void) {
|
||||||
wait_cycles(2 * EM4X50_T_TAG_FULL_PERIOD);
|
wait_cycles(2 * EM4X50_T_TAG_FULL_PERIOD);
|
||||||
|
|
||||||
OPEN_COIL();
|
OPEN_COIL();
|
||||||
check_rm_request();
|
check_rm_request(tag);
|
||||||
|
|
||||||
SHORT_COIL();
|
SHORT_COIL();
|
||||||
wait_cycles(EM4X50_T_TAG_FULL_PERIOD);
|
wait_cycles(EM4X50_T_TAG_FULL_PERIOD);
|
||||||
|
@ -1230,7 +1202,7 @@ static bool login(uint32_t password) {
|
||||||
// send password
|
// send password
|
||||||
em4x50_reader_send_word(password);
|
em4x50_reader_send_word(password);
|
||||||
|
|
||||||
wait_timer(T0 * EM4X50_T_TAG_TPP);
|
wait_timer(T0 * (EM4X50_T_TAG_TPP));
|
||||||
|
|
||||||
// check if ACK is returned
|
// check if ACK is returned
|
||||||
if (check_ack(false)) {
|
if (check_ack(false)) {
|
||||||
|
@ -1377,7 +1349,7 @@ static int reset(void) {
|
||||||
|
|
||||||
// send reset command
|
// send reset command
|
||||||
em4x50_reader_send_byte_with_parity(EM4X50_COMMAND_RESET);
|
em4x50_reader_send_byte_with_parity(EM4X50_COMMAND_RESET);
|
||||||
|
|
||||||
if (check_ack(false))
|
if (check_ack(false))
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
|
@ -1674,60 +1646,36 @@ void em4x50_writepwd(em4x50_data_t *etd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulate uploaded data in emulator memory
|
// simulate uploaded data in emulator memory
|
||||||
// (currently simulation allows only a one-way communication)
|
|
||||||
void em4x50_sim() {
|
void em4x50_sim() {
|
||||||
int status = PM3_SUCCESS;
|
int status = PM3_SUCCESS;
|
||||||
uint8_t *em4x50_mem = BigBuf_get_EM_addr();
|
uint8_t *em4x50_mem = BigBuf_get_EM_addr();
|
||||||
uint32_t words[EM4X50_NO_WORDS] = {0x0};
|
uint32_t tag[EM4X50_NO_WORDS] = {0x0};
|
||||||
|
|
||||||
for (int i = 0; i < EM4X50_NO_WORDS; i++)
|
for (int i = 0; i < EM4X50_NO_WORDS; i++)
|
||||||
words[i] = reflect32(bytes_to_num(em4x50_mem + (i * 4), 4));
|
tag[i] = reflect32(bytes_to_num(em4x50_mem + (i * 4), 4));
|
||||||
|
|
||||||
// only if valid em4x50 data (e.g. uid == serial)
|
// only if valid em4x50 data (e.g. uid == serial)
|
||||||
if (words[EM4X50_DEVICE_SERIAL] != words[EM4X50_DEVICE_ID]) {
|
if (tag[EM4X50_DEVICE_SERIAL] != tag[EM4X50_DEVICE_ID]) {
|
||||||
|
|
||||||
|
// init
|
||||||
em4x50_setup_sim();
|
em4x50_setup_sim();
|
||||||
|
gLogin = false;
|
||||||
|
|
||||||
em4x50_sim_handle_command(0);
|
// start with inital command = standard read mode (= 0)
|
||||||
|
em4x50_sim_handle_command(0, tag);
|
||||||
|
|
||||||
/*
|
|
||||||
// extract control data
|
|
||||||
int fwr = words[CONFIG_BLOCK] & 0xFF; // first word read
|
|
||||||
int lwr = (words[CONFIG_BLOCK] >> 8) & 0xFF; // last word read
|
|
||||||
// extract protection data
|
|
||||||
int fwrp = words[EM4X50_PROTECTION] & 0xFF; // first word read protected
|
|
||||||
int lwrp = (words[EM4X50_PROTECTION] >> 8) & 0xFF; // last word read protected
|
|
||||||
|
|
||||||
// iceman, will need a usb cmd check to break as well
|
|
||||||
while (BUTTON_PRESS() == false) {
|
|
||||||
|
|
||||||
rm = 0;
|
|
||||||
WDT_HIT();
|
|
||||||
em4x50_sim_send_listen_window();
|
|
||||||
for (int i = fwr; i <= lwr; i++) {
|
|
||||||
|
|
||||||
em4x50_sim_send_listen_window();
|
|
||||||
|
|
||||||
if ((i >= fwrp) && (i <= lwrp))
|
|
||||||
em4x50_sim_send_word(0x00);
|
|
||||||
else
|
|
||||||
em4x50_sim_send_word(words[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
status = PM3_ENODATA;
|
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, status, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void em4x50_test(em4x50_test_t *ett) {
|
void em4x50_test(em4x50_test_t *ett) {
|
||||||
|
|
||||||
int status = PM3_EFAILED;
|
int status = 0;
|
||||||
|
|
||||||
// set field on or off
|
// set field on or off
|
||||||
if (ett->field != -1) {
|
if (ett->field != -1) {
|
||||||
|
@ -1791,25 +1739,21 @@ void em4x50_test(em4x50_test_t *ett) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
em4x50_setup_sim();
|
// perform reset
|
||||||
for (;;) {
|
if (ett->reset) {
|
||||||
em4x50_sim_send_listen_window();
|
em4x50_setup_read();
|
||||||
em4x50_sim_send_listen_window();
|
|
||||||
em4x50_sim_send_bit(0);
|
status = PM3_EFAILED;
|
||||||
em4x50_sim_send_bit(0);
|
if (get_signalproperties() && find_em4x50_tag()) {
|
||||||
em4x50_sim_send_bit(0);
|
|
||||||
em4x50_sim_send_ack();
|
if (reset() == PM3_SUCCESS) {
|
||||||
em4x50_sim_send_ack();
|
status = 1;
|
||||||
em4x50_sim_send_bit(0);
|
}
|
||||||
em4x50_sim_send_bit(0);
|
}
|
||||||
em4x50_sim_send_bit(0);
|
|
||||||
em4x50_sim_send_nak();
|
lf_finalize();
|
||||||
em4x50_sim_send_nak();
|
|
||||||
em4x50_sim_send_bit(0);
|
|
||||||
em4x50_sim_send_bit(0);
|
|
||||||
em4x50_sim_send_bit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_ng(CMD_LF_EM4X50_TEST, status, NULL, 0);
|
reply_ng(CMD_LF_EM4X50_TEST, status, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue