|
@@ -1,10 +1,9 @@
|
|
|
#include "gen4_poller_i.h"
|
|
#include "gen4_poller_i.h"
|
|
|
|
|
|
|
|
#include "bit_buffer.h"
|
|
#include "bit_buffer.h"
|
|
|
-#include "core/log.h"
|
|
|
|
|
|
|
+#include "protocols/gen4/gen4_poller.h"
|
|
|
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
|
|
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
|
|
|
#include <nfc/helpers/nfc_util.h>
|
|
#include <nfc/helpers/nfc_util.h>
|
|
|
-#include <stdint.h>
|
|
|
|
|
|
|
|
|
|
#define GEN4_CMD_PREFIX (0xCF)
|
|
#define GEN4_CMD_PREFIX (0xCF)
|
|
|
|
|
|
|
@@ -13,13 +12,16 @@
|
|
|
#define GEN4_CMD_GET_REVISION (0xCC)
|
|
#define GEN4_CMD_GET_REVISION (0xCC)
|
|
|
#define GEN4_CMD_WRITE (0xCD)
|
|
#define GEN4_CMD_WRITE (0xCD)
|
|
|
#define GEN4_CMD_READ (0xCE)
|
|
#define GEN4_CMD_READ (0xCE)
|
|
|
|
|
+#define GEN4_CMD_SET_DW_BLOCK_0 (0xCF)
|
|
|
#define GEN4_CMD_SET_CFG (0xF0)
|
|
#define GEN4_CMD_SET_CFG (0xF0)
|
|
|
#define GEN4_CMD_FUSE_CFG (0xF1)
|
|
#define GEN4_CMD_FUSE_CFG (0xF1)
|
|
|
#define GEN4_CMD_SET_PWD (0xFE)
|
|
#define GEN4_CMD_SET_PWD (0xFE)
|
|
|
|
|
|
|
|
-#define CONFIG_SIZE (32)
|
|
|
|
|
|
|
+#define GEM4_RESPONSE_SUCCESS (0x02)
|
|
|
|
|
+
|
|
|
|
|
+#define CONFIG_SIZE_MAX (32)
|
|
|
|
|
+#define CONFIG_SIZE_MIN (30)
|
|
|
#define REVISION_SIZE (5)
|
|
#define REVISION_SIZE (5)
|
|
|
-#define SHD_MODE_RESPONSE_SIZE (2)
|
|
|
|
|
|
|
|
|
|
static Gen4PollerError gen4_poller_process_error(Iso14443_3aError error) {
|
|
static Gen4PollerError gen4_poller_process_error(Iso14443_3aError error) {
|
|
|
Gen4PollerError ret = Gen4PollerErrorNone;
|
|
Gen4PollerError ret = Gen4PollerErrorNone;
|
|
@@ -33,8 +35,10 @@ static Gen4PollerError gen4_poller_process_error(Iso14443_3aError error) {
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Gen4PollerError
|
|
|
|
|
- gen4_poller_set_shadow_mode(Gen4Poller* instance, uint32_t password, uint8_t mode) {
|
|
|
|
|
|
|
+Gen4PollerError gen4_poller_set_shadow_mode(
|
|
|
|
|
+ Gen4Poller* instance,
|
|
|
|
|
+ uint32_t password,
|
|
|
|
|
+ Gen4PollerShadowMode mode) {
|
|
|
Gen4PollerError ret = Gen4PollerErrorNone;
|
|
Gen4PollerError ret = Gen4PollerErrorNone;
|
|
|
bit_buffer_reset(instance->tx_buffer);
|
|
bit_buffer_reset(instance->tx_buffer);
|
|
|
|
|
|
|
@@ -54,14 +58,51 @@ Gen4PollerError
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
|
|
|
- if(rx_bytes != SHD_MODE_RESPONSE_SIZE) {
|
|
|
|
|
|
|
+ uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
|
|
|
+
|
|
|
|
|
+ FURI_LOG_D(TAG, "Card response: 0x%02X, Shadow mode set: 0x%02X", response, mode);
|
|
|
|
|
+
|
|
|
|
|
+ if(response != GEM4_RESPONSE_SUCCESS) {
|
|
|
ret = Gen4PollerErrorProtocol;
|
|
ret = Gen4PollerErrorProtocol;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ } while(false);
|
|
|
|
|
+
|
|
|
|
|
+ return ret;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+Gen4PollerError gen4_poller_set_direct_write_block_0_mode(
|
|
|
|
|
+ Gen4Poller* instance,
|
|
|
|
|
+ uint32_t password,
|
|
|
|
|
+ Gen4PollerDirectWriteBlock0Mode mode) {
|
|
|
|
|
+ Gen4PollerError ret = Gen4PollerErrorNone;
|
|
|
|
|
+ bit_buffer_reset(instance->tx_buffer);
|
|
|
|
|
+
|
|
|
|
|
+ do {
|
|
|
|
|
+ uint8_t password_arr[4] = {};
|
|
|
|
|
+ nfc_util_num2bytes(password, COUNT_OF(password_arr), password_arr);
|
|
|
|
|
+ bit_buffer_append_byte(instance->tx_buffer, GEN4_CMD_PREFIX);
|
|
|
|
|
+ bit_buffer_append_bytes(instance->tx_buffer, password_arr, COUNT_OF(password_arr));
|
|
|
|
|
+ bit_buffer_append_byte(instance->tx_buffer, GEN4_CMD_SET_DW_BLOCK_0);
|
|
|
|
|
+ bit_buffer_append_byte(instance->tx_buffer, mode);
|
|
|
|
|
+
|
|
|
|
|
+ Iso14443_3aError error = iso14443_3a_poller_send_standard_frame(
|
|
|
|
|
+ instance->iso3_poller, instance->tx_buffer, instance->rx_buffer, GEN4_POLLER_MAX_FWT);
|
|
|
|
|
+
|
|
|
|
|
+ if(error != Iso14443_3aErrorNone) {
|
|
|
|
|
+ ret = gen4_poller_process_error(error);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
|
|
|
|
|
|
- FURI_LOG_D(TAG, "Card response: %X, Shadow mode set: %u", response, mode);
|
|
|
|
|
|
|
+ FURI_LOG_D(
|
|
|
|
|
+ TAG, "Card response: 0x%02X, Direct write to block 0 mode set: 0x%02X", response, mode);
|
|
|
|
|
+
|
|
|
|
|
+ if(response != GEM4_RESPONSE_SUCCESS) {
|
|
|
|
|
+ ret = Gen4PollerErrorProtocol;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
} while(false);
|
|
} while(false);
|
|
|
|
|
|
|
@@ -90,11 +131,11 @@ Gen4PollerError
|
|
|
|
|
|
|
|
size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
|
|
|
|
|
|
- if(rx_bytes != CONFIG_SIZE) {
|
|
|
|
|
|
|
+ if(rx_bytes != CONFIG_SIZE_MAX || rx_bytes != CONFIG_SIZE_MIN) {
|
|
|
ret = Gen4PollerErrorProtocol;
|
|
ret = Gen4PollerErrorProtocol;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- bit_buffer_write_bytes(instance->rx_buffer, config_result, CONFIG_SIZE);
|
|
|
|
|
|
|
+ bit_buffer_write_bytes(instance->rx_buffer, config_result, CONFIG_SIZE_MAX);
|
|
|
} while(false);
|
|
} while(false);
|
|
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
@@ -157,8 +198,11 @@ Gen4PollerError gen4_poller_set_config(
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
|
|
|
- if(rx_bytes != 2) {
|
|
|
|
|
|
|
+ uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
|
|
|
+
|
|
|
|
|
+ FURI_LOG_D(TAG, "Card response to set default config command: 0x%02X", response);
|
|
|
|
|
+
|
|
|
|
|
+ if(response != GEM4_RESPONSE_SUCCESS) {
|
|
|
ret = Gen4PollerErrorProtocol;
|
|
ret = Gen4PollerErrorProtocol;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -225,8 +269,16 @@ Gen4PollerError
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
|
|
|
- if(rx_bytes != 2) {
|
|
|
|
|
|
|
+ uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer);
|
|
|
|
|
+
|
|
|
|
|
+ FURI_LOG_D(
|
|
|
|
|
+ TAG,
|
|
|
|
|
+ "Trying to change password from 0x%08lX to 0x%08lX. Card response: 0x%02X",
|
|
|
|
|
+ pwd_current,
|
|
|
|
|
+ pwd_new,
|
|
|
|
|
+ response);
|
|
|
|
|
+
|
|
|
|
|
+ if(response != GEM4_RESPONSE_SUCCESS) {
|
|
|
ret = Gen4PollerErrorProtocol;
|
|
ret = Gen4PollerErrorProtocol;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|