|
@@ -1,12 +1,10 @@
|
|
|
-#include "core/log.h"
|
|
|
|
|
#include "gen4_poller_i.h"
|
|
#include "gen4_poller_i.h"
|
|
|
|
|
+#include "protocols/gen4/gen4_poller.h"
|
|
|
#include <nfc/protocols/iso14443_3a/iso14443_3a.h>
|
|
#include <nfc/protocols/iso14443_3a/iso14443_3a.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 <nfc/nfc_poller.h>
|
|
#include <nfc/nfc_poller.h>
|
|
|
|
|
|
|
|
-#include <furi/furi.h>
|
|
|
|
|
-
|
|
|
|
|
#define GEN4_POLLER_THREAD_FLAG_DETECTED (1U << 0)
|
|
#define GEN4_POLLER_THREAD_FLAG_DETECTED (1U << 0)
|
|
|
|
|
|
|
|
typedef NfcCommand (*Gen4PollerStateHandler)(Gen4Poller* instance);
|
|
typedef NfcCommand (*Gen4PollerStateHandler)(Gen4Poller* instance);
|
|
@@ -171,12 +169,16 @@ NfcCommand gen4_poller_request_mode_handler(Gen4Poller* instance) {
|
|
|
instance->state = Gen4PollerStateRequestWriteData;
|
|
instance->state = Gen4PollerStateRequestWriteData;
|
|
|
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetPassword) {
|
|
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetPassword) {
|
|
|
instance->state = Gen4PollerStateChangePassword;
|
|
instance->state = Gen4PollerStateChangePassword;
|
|
|
- } else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetDefaultCFG) {
|
|
|
|
|
|
|
+ } else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetDefaultCfg) {
|
|
|
instance->state = Gen4PollerStateSetDefaultConfig;
|
|
instance->state = Gen4PollerStateSetDefaultConfig;
|
|
|
- } else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeGetCFG) {
|
|
|
|
|
|
|
+ } else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeGetCfg) {
|
|
|
instance->state = Gen4PollerStateGetCurrentConfig;
|
|
instance->state = Gen4PollerStateGetCurrentConfig;
|
|
|
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeGetRevision) {
|
|
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeGetRevision) {
|
|
|
instance->state = Gen4PollerStateGetRevision;
|
|
instance->state = Gen4PollerStateGetRevision;
|
|
|
|
|
+ } else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetShadowMode) {
|
|
|
|
|
+ instance->state = Gen4PollerStateSetShadowMode;
|
|
|
|
|
+ } else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetDirectWriteBlock0Mode) {
|
|
|
|
|
+ instance->state = Gen4PollerStateSetDirectWriteBlock0;
|
|
|
} else {
|
|
} else {
|
|
|
instance->state = Gen4PollerStateFail;
|
|
instance->state = Gen4PollerStateFail;
|
|
|
}
|
|
}
|
|
@@ -269,13 +271,13 @@ static NfcCommand gen4_poller_write_mf_classic(Gen4Poller* instance) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- instance->config[6] = Gen4PollerShadowModeIgnore;
|
|
|
|
|
|
|
+ instance->config[6] = Gen4PollerShadowModeDisabled;
|
|
|
instance->config[24] = iso3_data->atqa[0];
|
|
instance->config[24] = iso3_data->atqa[0];
|
|
|
instance->config[25] = iso3_data->atqa[1];
|
|
instance->config[25] = iso3_data->atqa[1];
|
|
|
instance->config[26] = iso3_data->sak;
|
|
instance->config[26] = iso3_data->sak;
|
|
|
instance->config[27] = 0x00;
|
|
instance->config[27] = 0x00;
|
|
|
- instance->config[28] = instance->total_blocks;
|
|
|
|
|
- instance->config[29] = 0x01;
|
|
|
|
|
|
|
+ instance->config[28] = instance->total_blocks - 1;
|
|
|
|
|
+ instance->config[29] = Gen4PollerDirectWriteBlock0ModeDisabled;
|
|
|
|
|
|
|
|
Gen4PollerError error = gen4_poller_set_config(
|
|
Gen4PollerError error = gen4_poller_set_config(
|
|
|
instance, instance->password, instance->config, sizeof(instance->config), false);
|
|
instance, instance->password, instance->config, sizeof(instance->config), false);
|
|
@@ -348,13 +350,13 @@ static NfcCommand gen4_poller_write_mf_ultralight(Gen4Poller* instance) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- instance->config[6] = Gen4PollerShadowModeHighSpeedIgnore;
|
|
|
|
|
|
|
+ instance->config[6] = Gen4PollerShadowModeHighSpeedDisabled;
|
|
|
instance->config[24] = iso3_data->atqa[0];
|
|
instance->config[24] = iso3_data->atqa[0];
|
|
|
instance->config[25] = iso3_data->atqa[1];
|
|
instance->config[25] = iso3_data->atqa[1];
|
|
|
instance->config[26] = iso3_data->sak;
|
|
instance->config[26] = iso3_data->sak;
|
|
|
instance->config[27] = 0x00;
|
|
instance->config[27] = 0x00;
|
|
|
- instance->config[28] = instance->total_blocks;
|
|
|
|
|
- instance->config[29] = 0x01;
|
|
|
|
|
|
|
+ instance->config[28] = instance->total_blocks - 1;
|
|
|
|
|
+ instance->config[29] = Gen4PollerDirectWriteBlock0ModeDisabled;
|
|
|
|
|
|
|
|
Gen4PollerError error = gen4_poller_set_config(
|
|
Gen4PollerError error = gen4_poller_set_config(
|
|
|
instance, instance->password, instance->config, sizeof(instance->config), false);
|
|
instance, instance->password, instance->config, sizeof(instance->config), false);
|
|
@@ -534,6 +536,44 @@ NfcCommand gen4_poller_get_revision_handler(Gen4Poller* instance) {
|
|
|
return command;
|
|
return command;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+NfcCommand gen4_poller_set_shadow_mode_handler(Gen4Poller* instance) {
|
|
|
|
|
+ NfcCommand command = NfcCommandContinue;
|
|
|
|
|
+
|
|
|
|
|
+ do {
|
|
|
|
|
+ Gen4PollerError error =
|
|
|
|
|
+ gen4_poller_set_shadow_mode(instance, instance->password, instance->shadow_mode);
|
|
|
|
|
+
|
|
|
|
|
+ if(error != Gen4PollerErrorNone) {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to set shadow mode: %d", error);
|
|
|
|
|
+ instance->state = Gen4PollerStateFail;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ instance->state = Gen4PollerStateSuccess;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
+
|
|
|
|
|
+ return command;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+NfcCommand gen4_poller_set_direct_write_block_0_mode_handler(Gen4Poller* instance) {
|
|
|
|
|
+ NfcCommand command = NfcCommandContinue;
|
|
|
|
|
+
|
|
|
|
|
+ do {
|
|
|
|
|
+ Gen4PollerError error = gen4_poller_set_direct_write_block_0_mode(
|
|
|
|
|
+ instance, instance->password, instance->direct_write_block_0_mode);
|
|
|
|
|
+
|
|
|
|
|
+ if(error != Gen4PollerErrorNone) {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to set direct write to block 0 mode: %d", error);
|
|
|
|
|
+ instance->state = Gen4PollerStateFail;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ instance->state = Gen4PollerStateSuccess;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
+
|
|
|
|
|
+ return command;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
NfcCommand gen4_poller_success_handler(Gen4Poller* instance) {
|
|
NfcCommand gen4_poller_success_handler(Gen4Poller* instance) {
|
|
|
NfcCommand command = NfcCommandContinue;
|
|
NfcCommand command = NfcCommandContinue;
|
|
|
|
|
|
|
@@ -568,6 +608,8 @@ static const Gen4PollerStateHandler gen4_poller_state_handlers[Gen4PollerStateNu
|
|
|
[Gen4PollerStateSetDefaultConfig] = gen4_poller_set_default_cfg_handler,
|
|
[Gen4PollerStateSetDefaultConfig] = gen4_poller_set_default_cfg_handler,
|
|
|
[Gen4PollerStateGetCurrentConfig] = gen4_poller_get_current_cfg_handler,
|
|
[Gen4PollerStateGetCurrentConfig] = gen4_poller_get_current_cfg_handler,
|
|
|
[Gen4PollerStateGetRevision] = gen4_poller_get_revision_handler,
|
|
[Gen4PollerStateGetRevision] = gen4_poller_get_revision_handler,
|
|
|
|
|
+ [Gen4PollerStateSetShadowMode] = gen4_poller_set_shadow_mode_handler,
|
|
|
|
|
+ [Gen4PollerStateSetDirectWriteBlock0] = gen4_poller_set_direct_write_block_0_mode_handler,
|
|
|
[Gen4PollerStateSuccess] = gen4_poller_success_handler,
|
|
[Gen4PollerStateSuccess] = gen4_poller_success_handler,
|
|
|
[Gen4PollerStateFail] = gen4_poller_fail_handler,
|
|
[Gen4PollerStateFail] = gen4_poller_fail_handler,
|
|
|
|
|
|