diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index ad11e8f19..61b7e76cb 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -42,7 +42,7 @@ static bool command_parity = true; #define EM4X70_T_TAG_TIMEOUT (4 * EM4X70_T_TAG_FULL_PERIOD) // Timeout if we ever get a pulse longer than this #define EM4X70_T_WAITING_FOR_LIW 50 // Pulses to wait for listen window - +#define EM4X70_T_READ_HEADER_LEN 16 // Read header length (16 bit periods) #define EM4X70_COMMAND_RETRIES 5 // Attempts to send/read command #define EM4X70_MAX_RECEIVE_LENGTH 96 // Maximum bits to expect from any command @@ -73,7 +73,7 @@ static bool command_parity = true; static uint8_t bits2byte(const uint8_t *bits, int length); static void bits2bytes(const uint8_t *bits, int length, uint8_t *out); -static int em4x70_receive(uint8_t *bits); +static int em4x70_receive(uint8_t *bits, size_t length); static bool find_listen_window(bool command); static void init_tag(void) { @@ -329,8 +329,8 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon // Receive header, 20-bit g(RN), LIW uint8_t grnd[EM4X70_MAX_RECEIVE_LENGTH] = {0}; - int num = em4x70_receive(grnd); - if (num < 10) { + int num = em4x70_receive(grnd, 20); + if (num < 20) { Dbprintf("Auth failed"); return PM3_ESOFT; } @@ -369,7 +369,7 @@ static int send_pin(const uint32_t pin) { WaitTicks(EM4X70_T_TAG_WEE); // <-- Receive header + ID uint8_t tag_id[EM4X70_MAX_RECEIVE_LENGTH]; - int num = em4x70_receive(tag_id); + int num = em4x70_receive(tag_id, 32); if (num < 32) { Dbprintf("Invalid ID Received"); return PM3_ESOFT; @@ -480,7 +480,7 @@ static uint8_t bits2byte(const uint8_t *bits, int length) { return byte; } -static bool send_command_and_read(uint8_t command, uint8_t resp_len_bits, uint8_t *out_bytes) { +static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t length) { int retries = EM4X70_COMMAND_RETRIES; while (retries) { @@ -488,13 +488,14 @@ static bool send_command_and_read(uint8_t command, uint8_t resp_len_bits, uint8_ if (find_listen_window(true)) { uint8_t bits[EM4X70_MAX_RECEIVE_LENGTH] = {0}; + size_t out_length_bits = length * 8; em4x70_send_nibble(command, command_parity); - int len = em4x70_receive(bits); - if (len < resp_len_bits) { - Dbprintf("Invalid data received length: %d", len); + int len = em4x70_receive(bits, out_length_bits); + if (len < out_length_bits) { + Dbprintf("Invalid data received length: %d, expected %d", len, out_length_bits); return false; } - bits2bytes(bits, len, out_bytes); + bits2bytes(bits, len, bytes); return true; } } @@ -510,7 +511,7 @@ static bool send_command_and_read(uint8_t command, uint8_t resp_len_bits, uint8_ */ static bool em4x70_read_id(void) { - return send_command_and_read(EM4X70_COMMAND_ID, 32, &tag.data[4]); + return send_command_and_read(EM4X70_COMMAND_ID, &tag.data[4], 4); } @@ -521,7 +522,7 @@ static bool em4x70_read_id(void) { */ static bool em4x70_read_um1(void) { - return send_command_and_read(EM4X70_COMMAND_UM1, 32, &tag.data[0]); + return send_command_and_read(EM4X70_COMMAND_UM1, &tag.data[0], 4); } @@ -533,7 +534,7 @@ static bool em4x70_read_um1(void) { */ static bool em4x70_read_um2(void) { - return send_command_and_read(EM4X70_COMMAND_UM2, 64, &tag.data[24]); + return send_command_and_read(EM4X70_COMMAND_UM2, &tag.data[24], 8); } @@ -543,7 +544,7 @@ static bool find_em4x70_Tag(void) { return find_listen_window(false); } -static int em4x70_receive(uint8_t *bits) { +static int em4x70_receive(uint8_t *bits, size_t length) { uint32_t pl; int bit_pos = 0; @@ -558,10 +559,8 @@ static int em4x70_receive(uint8_t *bits) { WaitTicks(6 * EM4X70_T_TAG_FULL_PERIOD); // wait until we get the transition from 1's to 0's which is 1.5 full windows - int pulse_count = 0; - while (pulse_count < 12) { + for(int i = 0; i < EM4X70_T_READ_HEADER_LEN; i++) { pl = get_pulse_length(edge); - pulse_count++; if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) { foundheader = true; break; @@ -575,23 +574,26 @@ static int em4x70_receive(uint8_t *bits) { // Skip next 3 0's, header check consumes the first 0 for (int i = 0; i < 3; i++) { - get_pulse_length(edge); + // If pulse length is not 1 bit, then abort early + if(!check_pulse_length(get_pulse_length(edge), EM4X70_T_TAG_FULL_PERIOD)) { + return 0; + } } // identify remaining bits based on pulse lengths // between listen windows only pulse lengths of 1, 1.5 and 2 are possible - while (bit_pos < EM4X70_MAX_RECEIVE_LENGTH) { + while (bit_pos < length) { pl = get_pulse_length(edge); if (check_pulse_length(pl, EM4X70_T_TAG_FULL_PERIOD)) { - // pulse length = 1 + // pulse length 1 -> assign bit bits[bit_pos++] = edge == FALLING_EDGE ? 1 : 0; } else if (check_pulse_length(pl, 3 * EM4X70_T_TAG_HALF_PERIOD)) { - // pulse length = 1.5 -> flip edge detection + // pulse length 1.5 -> 2 bits + flip edge detection if (edge == FALLING_EDGE) { bits[bit_pos++] = 0; bits[bit_pos++] = 0; @@ -604,7 +606,7 @@ static int em4x70_receive(uint8_t *bits) { } else if (check_pulse_length(pl, 2 * EM4X70_T_TAG_FULL_PERIOD)) { - // pulse length of 2 + // pulse length of 2 -> two bits if (edge == FALLING_EDGE) { bits[bit_pos++] = 0; bits[bit_pos++] = 1; @@ -613,16 +615,13 @@ static int em4x70_receive(uint8_t *bits) { bits[bit_pos++] = 0; } - } else if (((edge == FALLING_EDGE) && check_pulse_length(pl, (2*EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_FULL_PERIOD)) || - ((edge == RISING_EDGE) && check_pulse_length(pl, (2*EM4X70_T_TAG_FULL_PERIOD) + EM4X70_T_TAG_HALF_PERIOD))) { - - // LIW detected (either invert or normal) - return --bit_pos; + } else { + // Listen Window, or invalid bit + break; } } - // Should not get here - return --bit_pos; + return bit_pos; } void em4x70_info(em4x70_data_t *etd) {